2010-08-05 12 views
5

Sto sviluppando un'applicazione con un server TCP e diversi server/ascoltatori UDP. Ogni server è un thread separato, uguale ai thread worker per le connessioni TCP stabilite. Sto chiamando WSAStartup() in ciascuno dei thread.La chiamata a WSAStartup() da più thread può causare un deadlock?

A volte, la chiamata WSAStartup() si blocca (mi sembra un deadlock). Ecco l'analisi dello stack:

[email protected]() 
    [email protected]() + 0xc bytes 
    [email protected]() + 0x8c bytes 
    [email protected]() + 0x46 bytes 
    [email protected]() + 0x17d bytes 
    [email protected]() + 0x18 bytes 
    [email protected]() + 0x3e bytes 
    vld.dll!03203723() 
    [Frames below may be incorrect and/or missing, no symbols loaded for vld.dll] 
    ws2_32.dll!CheckForHookersOrChainers() + 0x22 bytes 
    [email protected]() + 0xa7 bytes 

Questo deadlock avviene durante la faze inizializzazione. Vedo che il server TCP viene avviato e che viene stabilita una connessione TCP, mentre viene avviato solo uno dei server UDP. La traccia dello stack proviene dalla funzione che dovrebbe avviare il resto dei server UDP. La mia ipotesi è che mentre sto cercando di avviare UDP sever e chiamare WSACStartup(), un altro battistrada sta gestendo un'altra operazione di socket, ad esempio una nuova connessione TCP e chiama anche WSAStartup()?

La mia domanda è se chiamare WSAStartup() da più thread può causare questo deadlock? Inoltre, ho controllato che WSACleanup() chiamato prima del deadlock, e non lo è. L'esecuzione non raggiunge mai nessuno di WSACleanup().

Sono consapevole del fatto che solo una chiamata a WSAStartup dovrebbe essere sufficiente, ma chiamando WSAStartup() più volte, non dovrebbe essere un problema (MSDN] 1): "Un'applicazione può chiamare WSAStartup più di una volta se ha bisogno di ottenere le informazioni sulla struttura WSADATA più di una volta. " Quindi, vorrei stabilire se questo deadlock è causato da WSAStartup() o qualcos'altro.

+0

Questa non è una risposta alla tua domanda, ma lo considerano usare il boost ASIO (http://www.boost.org/doc/libs/1_43_0/doc/html/boost_asio.html)?Ho avuto molto più tempo per risolvere problemi come il tuo con quella libreria. – nabulke

+0

Nikolai, ho usato la spinta prima e mi piace. Da quando ho avviato questa app con WinSock mi piacerebbe andare in fondo a questo problema. Solo per i curiosi, immagino :) –

+0

Hai guardato gli stack di chiamate degli altri thread? –

risposta

2

Non è necessario chiamare lo WSAStartup() più volte. Una volta per programma va bene.

+1

Imho, la domanda afferma chiaramente che topic starter ha letto questa parte di MSDN e invece di soluzione per "evitare" il problema (che è sicuramente una buona soluzione) - sta cercando di trovare la causa principale. – Andrey

+0

È come la vecchia battuta: "Dottore, fa male quando lo faccio". "Quindi non farlo, allora." –

+1

Deve essere chiamato sul battistrada che crea il socket. – rxantos

0

Penso che Luke abbia ragione. Non è possibile chiamare WSAStartup() in DllMain() o in inizializzatori di variabili globali/statiche. Cambia il tuo codice in modo che non accada.

+0

Sto lavorando su un'applicazione standalone e sto usando DLL di sistema, quindi non ho DLLMain(). Tutte le mie chiamate a WSAStartup() sono nelle funzioni thread: http://msdn.microsoft.com/en-us/library/ms686736(VS.85).aspx PS. ecco l'elenco delle librerie aggiuntive: - ws2_32.lib - strsafe.lib - shell32.lib –

+0

Dai uno sguardo più da vicino all'elenco delle DLL caricate nella versione "release" della tua applicazione (senza profiler, rilevatori di perdite , eccetera). È probabile che una di quelle DLL stia intrappolando le funzioni di Windows. Il Process Explorer di SysInternals ti aiuterà molto. – Andrey

0

WSAStartup in realtà non porta a LoadLibrary di alcun tipo, quindi non mi sento come si tratta di un caso loader lock.

Invece, è ovvio che Windows API viene intrappolato nel tuo caso (il termine trap è migliore qui, perché hook ha un altro significato in Windows).

Quindi, credo che il problema non sia nell'uso simultaneo di WSAStartup, ma negli effetti collaterali di trap di terze parti rispetto alle funzioni API di Windows originali nel processo. Penso che sia necessario ripulire il proprio ambiente da qualsiasi influenza esterna (trappole API da parte vostra o da software antivirus, qualunque cosa).

proposito, assicurarsi che ogni filo tuo fornisce WSAStartup con la propria copia separata del parametro di uscita WSADATA

+1

Sei sicuro che non faccia una chiamata ** LoadLibrary **? –

+0

Hai ragione, non ricordo perché ho pensato in quel modo, ma in realtà può caricare DLL helper in base a MSDN - quindi il blocco del caricatore potrebbe essere un problema. Penso ancora, guardando lo stack, che la causa principale sia in una trappola che ha intercettato WSAStartup. – Andrey

3

La funzione WSAStartup porta normalmente a DLL helper protocollo specifico corso di caricamento. Di conseguenza, la funzione WSAStartup non deve essere chiamata dalla funzione DllMain in una DLL dell'applicazione. Questo può potenzialmente causare deadlock. Dllmain viene chiamato nella sezione critica del caricatore DLL che è la ragione principale di questo deadlock.
Per maggiori dettagli: http://msdn.microsoft.com/en-us/library/windows/desktop/ms742213%28v=vs.85%29.aspx

Problemi correlati