Quelle est la meilleure façon d’attacher un débogueur à un processus dans VC++ au bon moment ?

StackOverflow https://stackoverflow.com/questions/663449

Question

Lors du débogage, vous devez parfois attacher un processus déjà en cours d'exécution au lieu de simplement démarrer l'application dans un débogueur.

Il m'est courant de lancer un appel Sleep() ou MessageBox, afin qu'il soit plus facile d'attacher un débogueur.Je crains que certains d'entre eux ne soient éventuellement affectés au contrôle de source.

Quelle est la meilleure chose à faire pour éviter cette situation tout en retardant suffisamment de temps pour pouvoir attacher votre débogueur à un processus en cours d'exécution ?

Garder la boîte de veille ou de message avec un #ifdef _DEBUG est une façon, mais je me demande s'il existe une meilleure façon.

Avec un sommeil, vous avez également le problème de ne pas vous attacher à temps.Avec une MessageBox, vous avez le problème de déboguer à distance ou de déboguer un processus qui n'a pas d'interface graphique visible (par exemple, exécuté en tant que service sur Vista).

Était-ce utile?

Autres conseils

Pour attacher un débogueur à un moment donné, vous avez plusieurs options:

Le plus simple consiste simplement à appeler DebugBreak, ce qui est à peu près équivalent à __asm int 3, mais fonctionne également sur d'autres architectures (MSVC pour x64 n'autorise pas l'assemblage en ligne, si mes souvenirs sont exacts). Cela ouvrira la fenêtre du débogueur juste à temps et vous pourrez choisir parmi les débogueurs enregistrés (Visual Studio) à attacher au processus.

Vous pouvez également passer un appel à Sleep, ce qui vous permet de joindre le débogueur. Vous devez utiliser #ifdef _DEBUG autour de cela pour vous assurer que vous ne livrez pas avec ce code inclus.

Une question: pourquoi ne pouvez-vous pas exécuter le code à partir de l'EDI? Est-ce un service ou une DLL chargée par IIS ou similaire?

Dans ce cas, vous pouvez extraire la ImageFileExecutionOptions clé de registre, qui vous permet de joindre un débogueur au moment du démarrage du processus.

Si vous utilisez cdb pour cela, vous pouvez le configurer en tant que serveur ou client pour une instance WinDbg et le déboguer de cette manière. C'est ce que j'ai fait par le passé en utilisant WinDbg comme débogueur de noyau et en utilisant ImageFileExecutionOptions pour démarrer ntsd -d avec le processus nommé. WinDbg passe ainsi en mode utilisateur. C'est parfois une technique utile.

Une autre variante, que j’utilise parfois est

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

il devrait simplement attendre en silence que vous attachez votre débogueur au processus.

Freddy et Reoa ont les bonnes solutions. Mais je voulais ajouter une raison pour laquelle ne pas utiliser un MessageBox.

L’affichage d’une MessageBox n’arrête que partiellement votre application. Étant donné que vous affichez l'interface utilisateur, une pompe de message est toujours en cours d'exécution sur au moins un thread de votre programme. Donc, si votre code fait l'une des choses suivantes.

  1. Communique via les messages Windows
  2. a une interface utilisateur non-triviale
  3. est multi-threadé

Vous demanderez essentiellement un débogueur dans un état mais en vous attachant à votre programme dans un état complètement différent. Cela peut conduire à des situations et des bugs déroutants.

Nous avons récemment modifié notre base de code afin de ne jamais afficher de MessageBox afin de faciliter la pause pour cette raison même. Cela produit un très mauvais comportement pour une application non triviale.

Il est difficile de s’attacher au "bon moment" ... Une option consiste à inclure des instructions DebugBreak () explicites dans le code afin de forcer le problème et de les protéger avec #ifdef _DEBUG serait une bonne idée. Nous utilisons une macro ASSERT pouvant appeler DebugBreak (), vous pouvez donc écrire ASSERT (false)

Une autre option à envisager consiste à utiliser les "options d'exécution du fichier image" pour lancer le débogueur automatiquement. Voir ce blog et la documentation MSDN .

Chercher:

DebugBreak , __debugbreak et amis

ou

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

__asm int 3 

Ce point d'arrêt actif fera apparaître la boîte de dialogue de débogage, qui vous permettra de vous connecter au processus. Enveloppez cela dans #ifdef _DEBUG et vous ne le ferez que dans les versions de débogage.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top