Как отладить ошибку сегментации Python?
Как я могу отладить ошибку сегментации Python?
Мы пытаемся запустить наш код Python на SuSE 12.3. Мы получаем воспроизводимые ошибки сегментации. Код Python работает на других платформах без ошибок сегментации, в течение многих лет.
Мы только кодируем Python, без расширения C....
Каков наилучший способ отладки этого? Я немного знаю, но это было десять лет назад....
Python 2.7.5
Обновить
Ошибка сегментации происходит при отключении интерпретатора.
Я могу запустить скрипт несколько раз:
python -m pdb myscript.py arg1 arg1
continue
run
continue
run
Но ошибки сегментации случаются, если я оставляю pdb с помощью ctrl-d.
Обновление 2
Теперь я пытаюсь отладить его с помощью 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
Обновление 3
Я установил gdbinit с http://hg.python.org/cpython/file/default/Misc/gdbinit и символы отладки с http://download.opensuse.org/debug/distribution/12.3/repo/oss/suse/x86_64/
(gdb) pystack
No symbol "_PyUnicode_AsString" in current context.
Что теперь?
Обновление 4 Мы установили новый RPM (python-2.7.5-3.1.x86_64). Мы получаем меньше segfaults, но они все еще случаются. Вот ссылка на репозиторий:
http://download.opensuse.org/repositories/devel:/languages:/python:/Factory/openSUSE_12.3/x86_64/
Обновление 5 решило мою начальную проблему:
Это был http://bugs.python.org/issue1856 (завершение работы (выход) может зависнуть или segfault с работающими потоками демона)
Связанный: Обнаружить, что интерпретатор выключен в потоке демона
4 ответа
Может быть, запущен поток демона? Есть воспроизводимая ошибка, которая была исправлена только для 3.x, но не для 2.x:
http://bugs.python.org/issue1856:
shutdown (exit) can hang or segfault with daemon threads running
Это ответ на мой собственный вопрос. Потребовалось некоторое время, чтобы найти корень проблемы.
Вот следующий вопрос: Как обойти эту ошибку: Обнаружить, что интерпретатор выключен в потоке демона
Я добрался до этого вопроса из-за Segmentation fault
, но не на выходе, просто в общем, и я обнаружил, что ничто другое не помогло так эффективно, как обработчик ошибок. Это часть Python 3.3, и вы можете установить в 2.7, используя pip
,
Tl ;dr для пользователей python3.
Во-первых, из документов:
Faulthandler - это встроенный модуль, начиная с Python 3.3
Использование кода:
faulthandler.enable()
// bad code goes here
Использование оболочки:
$ python3 -q -X faulthandler
>>> /// bad cod goes here
Вы можете сделать это с помощью обработчика ошибок, как упоминалось, например, import faulthandler; Faulthandler.enable() просто добавьте эту строку рядом с оператором импорта и запустите код, это поможет отладить вас или попытается показать вам ближайшую строку в вашем коде, которая вызвала ошибку сегментации, тогда вы можете вносить изменения везде, где это необходимо. Надеюсь, это поможет!
Если вы выполняете только код Python (даже через импортированные сторонние модули), то, вероятно, segfault означает, что в интерпретаторе или в одном из его встроенных модулей Си есть ошибка.
Вы можете либо построить CPython и попытаться отладить его самостоятельно, либо попытаться создать наименьший скрипт, который воспроизводит сбой и сообщает о проблеме.
Вы можете использовать модуль Python Debugger, импортировав pdb:
python -m pdb myscript.py