90 votes

Comment déboguer une erreur de segmentation Python ?

Comment déboguer une erreur de segmentation Python ?

Nous essayons d'exécuter notre code python sur SuSE 12.3. Nous obtenons des défauts de segmentation reproductibles. Le code python fonctionne depuis des années sur d'autres plateformes sans défaut de segmentation.

Nous ne codons que Python, pas d'extension C ....

Quelle est la meilleure façon de déboguer ce problème ? Je connais un peu l'ansi c, mais c'était il y a dix ans ....

Python 2.7.5

Mise à jour

Le défaut de segmentation se produit à l'arrêt de l'interpréteur.

Je peux exécuter le script plusieurs fois :

python -m pdb myscript.py arg1 arg1
continue
run
continue
run

Mais les défauts de segmentation se produisent, si je quitte le pdb avec ctrl-d.

Mise à jour 2

J'essaie maintenant de le déboguer avec gdb :

gdb 
> file python
> run myscript.py arg1 arg2
Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7fffefbe2700 (LWP 15483)]
0x00007ffff7aef93c in PyEval_EvalFrameEx () from /usr/lib64/libpython2.7.so.1.0
(gdb) bt
#0  0x00007ffff7aef93c in PyEval_EvalFrameEx () from /usr/lib64/libpython2.7.so.1.0
#1  0x00007ffff7af5303 in PyEval_EvalCodeEx () from /usr/lib64/libpython2.7.so.1.0
#2  0x00007ffff7adc858 in ?? () from /usr/lib64/libpython2.7.so.1.0
#3  0x00007ffff7ad840d in PyObject_Call () from /usr/lib64/libpython2.7.so.1.0
#4  0x00007ffff7af1082 in PyEval_EvalFrameEx () from /usr/lib64/libpython2.7.so.1.0
#5  0x00007ffff7af233d in PyEval_EvalFrameEx () from /usr/lib64/libpython2.7.so.1.0
#6  0x00007ffff7af233d in PyEval_EvalFrameEx () from /usr/lib64/libpython2.7.so.1.0
#7  0x00007ffff7af5303 in PyEval_EvalCodeEx () from /usr/lib64/libpython2.7.so.1.0
#8  0x00007ffff7adc5b6 in ?? () from /usr/lib64/libpython2.7.so.1.0
#9  0x00007ffff7ad840d in PyObject_Call () from /usr/lib64/libpython2.7.so.1.0
#10 0x00007ffff7ad9171 in ?? () from /usr/lib64/libpython2.7.so.1.0
#11 0x00007ffff7ad840d in PyObject_Call () from /usr/lib64/libpython2.7.so.1.0
#12 0x00007ffff7aeeb62 in PyEval_CallObjectWithKeywords () from /usr/lib64/libpython2.7.so.1.0
#13 0x00007ffff7acc757 in ?? () from /usr/lib64/libpython2.7.so.1.0
#14 0x00007ffff7828e0f in start_thread () from /lib64/libpthread.so.0
#15 0x00007ffff755c7dd in clone () from /lib64/libc.so.6

Mise à jour 3

J'ai installé gdbinit à partir de http://hg.python.org/cpython/file/default/Misc/gdbinit et les symboles de débogage de http://download.opensuse.org/debug/distribution/12.3/repo/oss/suse/x86_64/

(gdb) pystack
No symbol "_PyUnicode_AsString" in current context.

Et maintenant ?

Mise à jour 4 Nous avons installé un nouveau RPM (python-2.7.5-3.1.x86_64). Nous obtenons moins de segfaults, mais ils se produisent toujours. Voici le lien vers le dépôt :

http://download.opensuse.org/repositories/devel:/languages:/python:/Factory/openSUSE_12.3/x86_64/

Mise à jour 5 A résolu mon problème initial :

C'était http://bugs.python.org/issue1856 (l'arrêt (sortie) peut se bloquer ou se mettre en défaut avec les threads du démon en cours d'exécution)

En rapport : Détecter l'arrêt de l'interpréteur dans le thread du démon

67voto

mariotomo Points 2076

J'en suis arrivé à cette question à cause de la Segmentation fault mais pas sur la sortie, juste en général, et j'ai trouvé que rien d'autre n'aidait aussi efficacement que faussaire . Il fait partie de Python 3.3, et vous pouvez l'installer en 2.7 en utilisant pip .

50voto

Olshansk Points 577

Tl;dr pour les utilisateurs de python3.

Tout d'abord, à partir des docs :

faussaire est un module intégré depuis Python 3.3.

Utilisation du code :

import faulthandler

faulthandler.enable()
// bad code goes here

Utilisation du shell :

$ python3 -q -X faulthandler
>>> /// bad cod goes here

10voto

guettli Points 3284

Peut-être y a-t-il un fil de démon en cours d'exécution ? Il y a un bogue reproductible, qui n'a été corrigé que pour la version 3.x, mais pas pour la 2.x :

http://bugs.python.org/issue1856 :

shutdown (exit) can hang or segfault with daemon threads running

C'est la réponse à ma propre question. Il a fallu du temps pour trouver la racine du problème.

Voici la question suivante : Comment coder autour de ce bug : Détecter l'arrêt de l'interpréteur dans le fil d'exécution du démon

8voto

Abhi Points 31

Vous pouvez le faire avec faulthandler comme mentionné. Par exemple

import faulthandler; faulthandler.enable()

Il suffit d'ajouter cette ligne près de votre import et exécuter le code. Il vous aidera à déboguer ou essaiera de vous montrer la ligne la plus proche dans votre code qui a causé le défaut de segmentation. Vous pourrez alors apporter les modifications nécessaires.

6voto

icecrime Points 23650

Si vous n'exécutez rien d'autre que du code Python (même à travers vos modules tiers importés), un défaut de segmentation signifie probablement qu'il y a un bogue dans l'interpréteur ou dans l'un de ses modules C intégrés.

Vous pouvez soit construire CPython et essayer de le déboguer soi-même ou bien essayer de produire le plus petit script qui reproduit le crash et déposer une question .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X