In Delphi, è OutputDebugString thread-safe?
-
21-08-2019 - |
Domanda
è
OutputDebugString(PAnsiChar(''));
thread-safe?
I / abbiamo usato in thread per il debugging, e non è mai venuto in mente, se devo fare un modo diverso.
(Delphi 7)
Soluzione
Non ti preoccupare, lo è.
Quando OutputDebugString () viene chiamato da un'applicazione, ci vogliono questi passi. Si noti che un fallimento in qualsiasi punto abbandona tutto e tratta la richiesta di debug come un no-op (la stringa non viene inviato ovunque).
- Apri DBWinMutex e aspettare finché non avremo accesso esclusivo ad esso.
- Visualizza la mappa del segmento DBWIN_BUFFER nella memoria: se non è trovato, non v'è alcun debugger in esecuzione in modo l'intera richiesta viene ignorata.
- Aprire gli eventi DBWIN_BUFFER_READY e DBWIN_DATA_READY. come nel caso di il segmento di memoria condivisa, oggetti mancanti significa che non è debugger disponibili.
- attendere l'evento DBWIN_BUFFER_READY da segnalare: questo dice che il buffer di memoria non è più in uso. La maggior parte del tempo, questo evento sarà segnalato immediatamente quando è esaminato, ma non lo farà aspettare più di 10 secondi per il buffer di diventare pronto (un timeout abbandona la richiesta).
- Copia fino a circa di 4 KB di dati nel buffer di memoria, e negozio l'ID processo corrente lì. Sempre mettere un byte NUL alla fine della stringa.
- Dite al debugger che il buffer è pronto impostando il evento DBWIN_DATA_READY. Il debugger prende da lì.
- Rilasciare il mutex
- Chiudere gli oggetti di evento e di Sezione, anche se manteniamo la maniglia per il mutex intorno per più tardi.
Altri suggerimenti
Beh, non che non è vero, lo è, ma solo in modo che non si deve prendere solo parola Lieven per esso:
Passaggio di dati tra il applicazione e il debugger è fatto tramite un pezzo 4kByte di memoria condivisa, con un mutex e due oggetti evento proteggere l'accesso ad esso. Queste sono le quattro oggetti del kernel coinvolti.
Capire Win32 OutputDebugString è un eccellente articolo sulla questione.
Non ho avuto problemi una volta, però, con stringhe in una DLL ISAPI. Per qualche strano motivo il booleano IsMultiThread definito System.pas non è stato impostato!
Si stava causando AccessViolations strani, una volta che il filo era in esecuzione più di un filo ... Un semplice "IsMultiThread: = true;" in un'unità di inizializzazione riparato.