pyplot Python traçant un défaut de segmentation




seaborn title (4)

Je développe des extensions C à partir de python et j'obtiens quelques segfaults (inévitables lors du développement ...).

Je cherche un moyen d'afficher à quelle ligne de code se produit la segfault (une idée est comme tracer chaque ligne de code), comment je peux faire ça?

https://code.i-harness.com


Il existe quelques extensions python non documentées pour gdb.

À partir de la source Python, Tools/gdb/libpython.py (il n'est pas inclus dans une installation normale).

Mettez ceci dans sys.path

Alors:

# gdb /gps/python2.7_x64/bin/python coredump
...
Core was generated by `/usr/bin/python script.py'.
Program terminated with signal 11, Segmentation fault.
#0  call_function (oparg=<optimized out>, pp_stack=0x7f9084d15dc0) at Python/ceval.c:4037
...
(gdb) python
>import libpython
>
>end
(gdb) bt
#0  call_function (oparg=<optimized out>, pp_stack=0x7f9084d15dc0) at Python/ceval.c:4037
#1  PyEval_EvalFrameEx ([email protected]=
    Frame 0x7f9084d20ad0, 
    for file /usr/lib/python2.7/site-packages/librabbitmq/__init__.py, line 220, 
    in drain_events (self=<Connection(channels={1: <Channel(channel_id=1, connection=<...>, is_open=True, connect_timeout=4, _default_channel=<....(truncated), [email protected]=0) at Python/ceval.c:2681
...
(gdb) py-list
 218            else:
 219                timeout = float(timeout)
>220            self._basic_recv(timeout)
 221
 222        def channel(self, channel_id=None):

Comme vous pouvez le voir, nous avons maintenant une visibilité sur la pile Python correspondant à la chaîne d'appel CPython.

Quelques mises en garde:

  • Votre version de gdb doit être supérieure à 7 et doit être compilée avec --with-python
  • gdb embarque python (en liant à libpython ), il ne l'exécute pas dans un sous-shell. Cela signifie qu'il ne correspond pas nécessairement à la version de python qui est sur $PATH .
  • Vous devez télécharger libpython.py partir de n'importe quelle version de la source Python correspondant à celle de gdb .
  • Vous devrez peut-être exécuter gdb en tant que root - si c'est le cas, vous devrez peut-être configurer sys.path pour qu'il corresponde à celui du code que vous déboguez.

Si vous ne pouvez pas copier libpython.py dans sys.path vous pouvez ajouter son emplacement à sys.path comme ceci:

(gdb) python
>import sys
>sys.path.append('/path/to/containing/dir/')
>import libpython
>
>end

Ceci est quelque peu mal documenté dans les docs de développement python , le wiki fedora et le wiki python

Si vous avez un gdb plus ancien ou que vous ne pouvez pas le faire, il y a aussi un gdbinit dans la source Python que vous pouvez copier dans ~/.gdbinit et ajouter des fonctionnalités similaires


Je suis venu ici à la recherche d'une solution au même problème, et aucune des autres réponses ne m'a aidé. Qu'est-ce que l'aide a été faulthandler , et vous pouvez l'installer dans Python 2.7 en utilisant simplement pip install .

faulthandler été présenté à Python seulement dans la version 3.3, qui a été libérée en septembre 2012, qui était après que la plupart des autres réponses ici aient été écrites.


Si vous êtes sur Linux, lancez python sous gdb

gdb python
(gdb) run /path/to/script.py
## wait for segfault ##
(gdb) backtrace
## stack trace of the c code

Voici un moyen d'afficher le nom de fichier et le numéro de ligne de chaque ligne de Python exécutée par votre code:

import sys

def trace(frame, event, arg):
    print "%s, %s:%d" % (event, frame.f_code.co_filename, frame.f_lineno)
    return trace

def test():
    print "Line 8"
    print "Line 9"

sys.settrace(trace)
test()

Sortie:

call, test.py:7
line, test.py:8
Line 8
line, test.py:9
Line 9
return, test.py:9

(Vous voudrez probablement écrire la sortie de trace dans un fichier, bien sûr.)





debugging