web-dev-qa-db-fra.com

Ce qui provoque un Sigtrap dans une session de débogage

Dans mon programme c ++, j'utilise une bibliothèque qui "enverra?" un Sigtrap sur certaines opérations lorsque je le débogue (en utilisant gdb comme débogueur). Je peux alors choisir si je souhaite continuer ou arrêter le programme. Si je choisis de continuer le programme fonctionne comme prévu, mais la définition de points d'arrêt personnalisés après la capture d'un Sigtrap provoque le blocage du débogueur/programme.

Donc, voici mes questions:

  1. Qu'est-ce qui cause un tel Sigtrap? Est-ce une ligne de code restante qui peut être supprimée, ou est-ce causé par le débogueur lorsqu'il "trouve quelque chose qu'il n'aime pas"?
  2. Un sigtrap, d'une manière générale, est-il une mauvaise chose, et si c'est le cas, pourquoi le programme fonctionne-t-il parfaitement lorsque je compile une version et non une version de débogage?
  3. Qu'est-ce qu'un Sigtrap indique?

Ceci est une approche plus générale d'une question que j'ai postée hier Boost Filesystem: le constructeur recursive_directory_iterator provoque des SIGTRAPS et des problèmes de débogage .
Je pense que ma question était loin d'être précise, et je ne veux pas que vous résolviez mon problème, mais aidez-moi (et j'espère que d'autres) à comprendre le contexte.

Merci beaucoup.

33
zitroneneis

Avec les processeurs qui prennent en charge les points d'arrêt d'instructions ou les points d'observation des données, le débogueur demande au processeur de surveiller les accès aux instructions à une adresse spécifique, ou les données sont lues/écrites à une adresse spécifique, puis s'exécutent à pleine vitesse.

Lorsque le processeur détecte l'événement, il se piège dans le noyau et le noyau envoie SIGTRAP au processus en cours de débogage. Normalement, SIGTRAP tuerait le processus, mais comme il est en cours de débogage, le débogueur sera informé du signal et le traiter, principalement en vous permettant d'inspecter l'état du processus avant de poursuivre l'exécution.

Avec des processeurs qui ne prennent pas en charge les points d'arrêt ou les points d'observation, l'environnement de débogage complet se fait probablement par le biais de l'interprétation de code et de l'émulation de mémoire, ce qui est extrêmement lent. (J'imagine que des astuces intelligentes pourraient être effectuées en définissant des indicateurs de page pour interdire la lecture ou l'écriture, selon ce qui doit être piégé, et en laissant le noyau corriger les pages, en signalant le débogueur, puis en restreignant à nouveau les indicateurs de page. Cela pourrait probablement prendre en charge près de -un nombre arbitraire de points de surveillance et de points d'arrêt et ne s'exécutent que légèrement plus lentement pour les cas où le point de surveillance ou le point d'arrêt n'est pas fréquemment consulté.)

La question que j'ai placée dans le champ de commentaire semble à propos ici, uniquement parce que Windows n'envoie pas réellement un SIGTRAP, mais signale plutôt un point d'arrêt à sa manière. Je suppose que lorsque vous déboguez des programmes, que les versions de débogage des bibliothèques système sont utilisées et que les accès à la mémoire semblent avoir un sens. Vous pouvez avoir un bogue dans votre programme qui est surchargé au moment de l'exécution, mais peut en fait causer d'autres problèmes ailleurs.

Je n'ai pas fait de développement sur Windows, mais peut-être pourriez-vous obtenir plus de détails en consultant votre journal des événements Windows?

37
sarnold

En travaillant dans Eclipse avec le compilateur minGW/gcc, j'ai réalisé qu'il réagissait très mal avec les vecteurs dans mon code, ce qui entraînait un signal SIGTRAP peu clair et parfois même un comportement de débogueur anormal (c'est-à-dire sautant quelque part dans le code et continuant l'exécution du code dans ordre inverse!).

J'ai copié les fichiers de mon projet dans VisualStudio et résolu les problèmes, puis copié les modifications sur Eclipse et le tour est joué, comme un charme. Les raisons étaient comme des différences d'initialisation vectorielle avec les fonctions reserve () et resize (), ou essayer d'accéder à des éléments hors des limites du tableau de vecteurs.

J'espère que cela aidera quelqu'un d'autre.

3
Hack06