Domanda

Durante il debug, a volte è necessario allegare un processo già in esecuzione invece di avviare semplicemente l'applicazione in un debugger.

È normale che io inserisca una chiamata Sleep() o MessageBox, in modo che sia più semplice collegare un debugger.Temo che alcuni di questi possano eventualmente essere impegnati nel controllo del codice sorgente.

Qual è la cosa migliore da fare per evitare questa situazione ritardando comunque abbastanza tempo in modo da poter collegare il debugger a un processo in esecuzione?

Proteggere la finestra di sonno o di messaggio con un #ifdef _DEBUG è un modo, ma mi chiedo se esiste un modo migliore.

Con un Sonno hai anche il problema che potresti non attaccarti in tempo.Con un MessageBox hai il problema che potresti eseguire il debug in remoto o eseguire il debug di un processo che non ha una GUI visibile (esempio in esecuzione come servizio su Vista)

Altri suggerimenti

Per collegare un debugger in un determinato punto, hai diverse opzioni:

Il più semplice è solo chiamare DebugBreak, che è praticamente equivalente a __asm int 3, ma funziona anche su altre architetture (MSVC per x64 non consente l'assemblaggio in linea, se ricordo bene). Verrà visualizzata la finestra del debugger just-in-time e sarai in grado di selezionare tra i debugger registrati (ad esempio Visual Studio) da allegare al processo.

In alternativa, puoi presentare una chiamata a Sleep, dandoti l'opportunità di collegare il debugger. Dovresti usare #ifdef _DEBUG in questo caso, per assicurarti di non spedire effettivamente con questo codice incluso.

Una domanda: perché non puoi eseguire il codice dall'IDE? È un servizio o una DLL caricata su IIS o simile?

In questo caso, puoi controllare la ImageFileExecutionOptions chiave di registro, che ti consente di collegare un debugger nel momento in cui inizia il processo.

Se usi cdb per questo, puoi configurarlo come server o client su un'istanza di WinDbg, ed eseguire il debug in quel modo. L'ho fatto in passato usando WinDbg come debugger del kernel e usando ImageFileExecutionOptions per iniziare ntsd -d con il processo indicato. Ciò causa l'entrata in modalità utente di WinDbg. Questa è talvolta una tecnica utile.

un'altra variante, che a volte uso è

while( !::IsDebuggerPresent() )
    ::Sleep( 100 ); // to avoid 100% CPU load

dovrebbe solo attendere in silenzio fino a quando non si allega il debugger al processo.

Freddy e Reoa hanno le soluzioni giuste. Ma volevo aggiungere un motivo per non usare un MessageBox.

La visualizzazione di un MessageBox arresta solo parzialmente l'applicazione. Poiché stai visualizzando l'interfaccia utente, un pump dei messaggi è ancora in esecuzione su almeno un thread nel tuo programma. Quindi, se il codice esegue una delle seguenti operazioni.

  1. Comunica tramite messaggi di Windows
  2. Ha un'interfaccia utente non banale
  3. È multi-thread

In sostanza, si richiede un debugger in uno stato ma si collega al programma in uno stato completamente diverso. Questo può portare a situazioni sconcertanti e bug.

Di recente abbiamo apportato una modifica alla nostra base di codice per non mostrare mai un MessageBox al fine di facilitare l'interruzione proprio per questo motivo. Produce un comportamento pessimo per un'applicazione non banale.

Dover allegare al 'giusto punto' è una seccatura ... un'opzione è ma esplicite istruzioni DebugBreak () nel codice per forzare il problema e proteggerle con #ifdef _DEBUG sarebbe una buona idea. Usiamo una macro ASSERT che può chiamare DebugBreak (), quindi puoi semplicemente scrivere ASSERT (false)

Un'altra opzione da considerare è l'utilizzo delle "opzioni di esecuzione del file immagine" per avviare automaticamente il debugger. Vedi questo blog e la MSDN .

Cercare:

DebugBreak, __debugbreak e amici

O

static void timeToChase() { __asm ​​{ int 3;};}

__asm int 3 

Questo breakpoint duro farà apparire la finestra di dialogo di debug, che ti permetterà di collegarti al processo. Avvolgilo in #ifdef _DEBUG e lo colpirai solo nelle build di debug.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top