web-dev-qa-db-fra.com

segfault uniquement lorsque vous n'utilisez PAS le débogueur

J'ai un programme C multithread, qui génère systématiquement un défaut de segmentation à un point spécifique du programme. Lorsque je l'exécute avec gdb, aucun défaut n'est affiché. Pouvez-vous penser à une raison pour laquelle la panne peut se produire uniquement lorsque vous n'utilisez pas le débogueur? C'est assez ennuyeux de ne pas pouvoir l'utiliser pour trouver le problème!

51
Benubird

Classique Heisenbug . De Wikipédia:

Le temps peut également être un facteur de heisenbugs. L'exécution d'un programme sous le contrôle d'un débogueur peut modifier le calendrier d'exécution du programme par rapport à l'exécution normale. Les bogues sensibles au temps tels que les conditions de concurrence peuvent ne pas se reproduire lorsque le programme est ralenti par des lignes source à pas à pas dans le débogueur. Cela est particulièrement vrai lorsque le comportement implique une interaction avec une entité qui n'est pas sous le contrôle d'un débogueur, comme lors du débogage du traitement de paquets réseau entre deux machines et qu'une seule est sous contrôle du débogueur.

Le débogueur peut modifier la synchronisation et masquer une condition de concurrence.

Sous Linux, GDB désactive également la randomisation de l'espace d'adressage, et votre plantage peut être spécifique à la disposition de l'espace d'adressage. Essayez (gdb) set disable-randomization off.

Finalement, ulimit -c unlimited et le débogage post mortem (déjà suggéré par Robie) peuvent fonctionner.

74
Mehrdad

Peut-être que lorsque vous utilisez gdb, la mémoire est mappée dans un emplacement que votre flux supérieur/inférieur ne piétine pas la mémoire qui provoque un crash. Ou ce pourrait être une condition de course qui ne se déclenche plus. Bien que cela ne semble pas intuitif, vous devriez être heureux votre programme était assez sympa pour vous planter.

Quelques suggestions

  1. Essayez un analyseur de code statique comme le libre cppcheck
  2. Essayez un débogueur malloc () comme libefence
  3. Essayez de le faire passer par valgrind
7
SiegeX

En le déboguant, vous modifiez l'environnement dans lequel il s'exécute. Il semble que vous ayez affaire à une sorte de condition de concurrence critique, et en le déboguant, les choses sont planifiées légèrement différemment afin de ne pas rencontrer le problème. Cela, ou les choses sont stockées d'une manière légèrement différente afin que cela ne se produise pas. Êtes-vous capable de mettre une sortie de débogage dans le code pour aider à résoudre le problème? Cela peut avoir moins d'impact et vous permettre de trouver votre problème.

5
Mark Loeser

J'ai déjà eu ce problème avant! C'était une condition de concurrence, et quand je passais à travers le code avec un débogueur, le thread dans lequel j'étais était suffisamment lent pour ne pas déclencher la condition de concurrence. Assez horrible.

2
rook