Я запускаю пользовательское приложение Python 2.7.3 на CherryPy в Linux. Когда я использовал сценарий службы в /etc/init.d/ для запуска или остановки службы, я столкнулся с ошибкой сегментации (SIGSEGV). Как ни странно, я не получил SIGSEGV, если запускал команду запуска или остановки вручную из оболочки, используя «python /path/to/file.py --stop». Сервисный скрипт выполняет ту же команду.
После некоторой отладки я случайно обнаружил, что мой /tmp был смонтирован с параметром «noexec». Я удалил параметр «noexec», и приложение могло запускаться и останавливаться с помощью служебных сценариев без каких-либо ошибок сегментации.
Когда я впервые столкнулся с проблемой, я запустил strace и создал дамп ядра. Ни один из инструментов не дал мне никаких указаний на то, что /tmp был виновником. Мой вопрос таков: как я мог использовать strace или gdb, чтобы помочь мне определить, что «noexec» в /tmp вызывает ошибки сегментации?
Вот некоторый вывод gdb при анализе дампа ядра:
(gdb) bt full #0 PyObject_Malloc (nbytes=4) at Objects/obmalloc.c:788 bp = 0x7f6b0fd1c6e800 \Address 0x7f6b0fd1c6e800 out of bounds\ pool = 0x7f6b0fd1c000 next = \value optimized out\ size = 0 #1 0x00007f6b0f7fd8e6 in _PyUnicode_New (length=1) at Objects/unicodeobject.c:345 new_size = 4 unicode = 0x3873480 #2 0x00007f6b0f7fdd4e in PyUnicodeUCS2_FromUnicode (u=0x38367cc, size=) at Objects/unicodeobject.c:461 unicode = \value optimized out\
(Есть гораздо больше вывода, это только первые несколько строк)
Вот некоторый вывод strace об ошибке:
3046 open("/usr/local/python2.7/lib/python2.7/site-packages/oauthlib/common.py", O_RDONLY) = 9 3046 fstat(9, {st_mode=S_IFREG|0644, st_size=13310, ...}) = 0 3046 open("/usr/local/python2.7/lib/python2.7/site-packages/oauthlib/common.pyc", O_RDONLY) = 10 3046 fstat(10, {st_mode=S_IFREG|0644, st_size=16043, ...}) = 0 3046 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fbc9ff9d000 3046 read(10, "\3\363\r\n}\321\322Tc\0\0\0\0\0\0\0\0\5\0\0\0@@\2\0sd\2\0\0d\0"..., 4096) = 4096 3046 fstat(10, {st_mode=S_IFREG|0644, st_size=16043, ...}) = 0 3046 read(10, "\0\0\0C@\2\0s\330\0\0\0t\0\0|\0\0t\1\0\203\2\0s\36\0t\0\0|\0"..., 8192) = 8192 3046 read(10, "thon2.7/site-packages/oauthlib/c"..., 4096) = 3755 3046 read(10, "", 4096) = 0 3046 close(10) = 0 3046 munmap(0x7fbc9ff9d000, 4096) = 0 3046 --- SIGSEGV (Segmentation fault) @ 0 (0) ---
После устранения проблемы, вот фрагмент из strace, из того же места, где он пытается загрузить oauthlib/common.pyc — обратите внимание, что единственное отличие заключается в том, что brk() перед munmap():
3416 open("/usr/local/python2.7/lib/python2.7/site-packages/oauthlib/common.pyc", O_RDONLY) = 10 3416 fstat(10, {st_mode=S_IFREG|0644, st_size=16043, ...}) = 0 3416 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f5791f2c000 3416 read(10, "\3\363\r\n}\321\322Tc\0\0\0\0\0\0\0\0\5\0\0\0@@\2\0sd\2\0\0d\0"..., 4096) = 4096 3416 fstat(10, {st_mode=S_IFREG|0644, st_size=16043, ...}) = 0 3416 read(10, "\0\0\0C@\2\0s\330\0\0\0t\0\0|\0\0t\1\0\203\2\0s\36\0t\0\0|\0"..., 8192) = 8192 3416 read(10, "thon2.7/site-packages/oauthlib/c"..., 4096) = 3755 3416 read(10, "", 4096) = 0 3416 brk(0x372f000) = 0x372f000 3416 close(10) = 0 3416 munmap(0x7f5791f2c000, 4096) = 0 3416 close(9) = 0
Какая информация может помочь мне обвинить параметры монтирования /tmp?
env
в своем сценарии запуска, и вы сможете имитировать выполнение из строки cmd. Например,$TMP $PATH $LD_LIBRARY_PATH
может быть другим. - person Dima Tisnek   schedule 06.02.2015/var/tmp
... - person Dima Tisnek   schedule 06.02.2015