当使用noexec挂载/ tmp时,为什么在Python中出现Segmentation Fault?

时间:2015-02-05 22:20:19

标签: python debugging gdb sigsegv strace

我在Linux上运行CherryPy上的自定义Python 2.7.3应用程序。当我在/etc/init.d/中使用服务脚本来启动或停止服务时,我遇到了分段错误(SIGSEGV)。奇怪的是,如果我使用" python /path/to/file.py --stop"手动从shell运行启动或停止命令,我没有收到SIGSEGV。服务脚本执行相同的命令。

经过一些调试,偶然的机会,我发现我的/ tmp安装了" noexec"选项。我删除了" noexec"选项和应用程序能够通过服务脚本启动和停止,而不会出现任何分段错误。

当我第一次遇到这个问题时,我运行了strace并生成了一个核心转储。两种工具都没有给我任何迹象表明/ tmp是罪魁祸首。我的问题是:我怎么能用strace或gdb来帮助我识别" noexec" on / 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的同一点 - 请注意,在munmap()之前,唯一的区别似乎是brk():< / p>

    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的挂载选项?

1 个答案:

答案 0 :(得分:1)

对于那些将遇到与我相同的问题并找到此页面的人: 我的CherryPy server.py在python3.8的Win10系统上运行良好,但由于具有python3.6.1的Linux系统上的分段错误而失败。 在Linux上切换到python3.8解决了我的问题。