使用名为guppy(heapy)的Python工具时C代码中的Segfault

时间:2011-07-22 22:23:15

标签: python c memory-management cython python-stackless

所以我在两台不同的机器上使用Python Stackless with heapy,它们具有相同的架构,但C编译器略有不同。 Heapy在第一个上运行得非常好,但是我在第二个上获得了核心转储。

Python 2.7.1 Stackless 3.1b3 060516 (release27-maint, Jul 20 2011, 13:26:38)
[GCC 3.4.3 (MontaVista 3.4.3-25.0.116.0601565 2006-09-20)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from guppy import hpy;
>>> h=hpy()
>>> h.heap()
Segmentation fault (core dumped)

我不知道如何解决这个问题。任何建议赞赏。

如果你想知道,这就是另一个有效的方式:

Python 2.7.1 Stackless 3.1b3 060516 (python-2.71:88862M, Jul 21 2011, 16:57:52)
[GCC 3.4.6 20060404 (Red Hat 3.4.6-11)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from guppy import hpy;
>>> h=hpy()
>>> h.heap()
Partition of a set of 26124 objects. Total size = 1940540 bytes.
 Index  Count   %     Size   % Cumulative  % Kind (class / dict of class)
     0  11693  45   727628  37    727628  37 str
     1   5848  22   211232  11    938860  48 tuple
     2    324   1   128352   7   1067212  55 dict (no owner)
     3    232   1   122120   6   1189332  61 type
     4    232   1   117184   6   1306516  67 dict of type
     5   1612   6   116064   6   1422580  73 types.CodeType
     6     67   0   107416   6   1529996  79 dict of module
     7   1576   6    88256   5   1618252  83 function
     8    126   0    67440   3   1685692  87 dict of class
     9   1163   4    46520   2   1732212  89 __builtin__.wrapper_descriptor
<94 more rows. Type e.g. '_.more' to view.>

编辑:

好的,正如@Employed Russian建议的那样,这里是gdb backtrace:

Linux(debug)# gdb /x86/bin/python2.7
GNU gdb 6.3 (MontaVista 6.3-20.0.75.0601655 2006-10-01)
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "i586-montavista-linux"...Using host libthread_db library "/lib/tls/libthread_db.so.1".

(gdb) run

Starting program: /x86/bin/python2.7
Python 2.7.1 Stackless 3.1b3 060516 (release27-maint, Jul 20 2011, 13:26:38)
[GCC 3.4.3 (MontaVista 3.4.3-25.0.116.0601565 2006-09-20)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from guppy import hpy;
>>> h=hpy()
>>> h.heap()

Program received signal SIGSEGV, Segmentation fault.
0xb7bd5b0f in frame_traverse (ta=0xbfff7d00) at src/heapy/stdtypes.c:320
320     src/heapy/stdtypes.c: No such file or directory.
        in src/heapy/stdtypes.c
(gdb) where
#0  0xb7bd5b0f in frame_traverse (ta=0xbfff7d00) at src/heapy/stdtypes.c:320
#1  0xb7bccb8a in xt_hd_traverse (xt=0x758b0000, obj=0x80e5634,
    visit=0x80e5634, arg=0x80e5634) at hv.c:298
#2  0xb7bccf75 in hv_std_traverse (hv=0x80e5634, obj=0x80e5634,
    visit=0xb7bcee20 <hv_heap_rec>, arg=0xbfff7df0) at hv.c:513
#3  0xb7bd3e6e in rootstate_traverse (ta=0x80e5634) at rootstate.c:281
#4  0xb7bccb8a in xt_hd_traverse (xt=0x758b0000, obj=0x80e5634,
    visit=0x80e5634, arg=0x80e5634) at hv.c:298
#5  0xb7bccf75 in hv_std_traverse (hv=0x80e5634, obj=0xb7bd9600,
    visit=0xb7bcee20 <hv_heap_rec>, arg=0xbfff7df0) at hv.c:513
#6  0xb7bcef24 in hv_heap (self=0xb7b60994, args=0x0, kwds=0x1923cc4d)
    at hv.c:871
#7  0xb7f255bc in PyEval_EvalFrame_value ()
   from /usr/lib/libpython2.7.so.1.0
#8  0xb7f272f2 in PyEval_EvalFrameEx_slp ()
   from /usr/lib/libpython2.7.so.1.0
#9  0xb7f27012 in PyEval_EvalFrame_value ()
   from /usr/lib/libpython2.7.so.1.0
#10 0xb7f272f2 in PyEval_EvalFrameEx_slp ()
   from /usr/lib/libpython2.7.so.1.0
#11 0xb7f27012 in PyEval_EvalFrame_value ()
   from /usr/lib/libpython2.7.so.1.0
#12 0xb7f272f2 in PyEval_EvalFrameEx_slp ()
   from /usr/lib/libpython2.7.so.1.0
#13 0xb7f28426 in slp_eval_frame_newstack ()
   from /usr/lib/libpython2.7.so.1.0
#14 0xb7f271fb in PyEval_EvalFrameEx_slp ()
   from /usr/lib/libpython2.7.so.1.0
#15 0xb7f28b57 in slp_frame_dispatch_top ()
   from /usr/lib/libpython2.7.so.1.0
#16 0xb7f2c12e in slp_run_tasklet () from /usr/lib/libpython2.7.so.1.0
#17 0xb7f28a84 in slp_eval_frame () from /usr/lib/libpython2.7.so.1.0
#18 0xb7f28b08 in slp_eval_frame () from /usr/lib/libpython2.7.so.1.0
#19 0xb7f28a28 in slp_eval_frame () from /usr/lib/libpython2.7.so.1.0
#20 0xb7f20e24 in PyEval_EvalCodeEx () from /usr/lib/libpython2.7.so.1.0
---Type <return> to continue, or q <return> to quit---
#21 0xb7f20eb5 in PyEval_EvalCode () from /usr/lib/libpython2.7.so.1.0
#22 0xb7f4aff8 in PyErr_Display () from /usr/lib/libpython2.7.so.1.0
#23 0xb7f4c93e in PyRun_InteractiveOneFlags ()
   from /usr/lib/libpython2.7.so.1.0
#24 0xb7f4ca86 in PyRun_InteractiveLoopFlags ()
   from /usr/lib/libpython2.7.so.1.0
#25 0xb7f4cdde in PyRun_AnyFileExFlags () from /usr/lib/libpython2.7.so.1.0
#26 0xb7f59b8a in Py_Main () from /usr/lib/libpython2.7.so.1.0
#27 0x0804862a in main (argc=135157300, argv=0x80e5634)
    at ./Modules/python.c:23

EDIT2:更多信息:

所以行

  

if(PyTuple_Check(co-&gt; co_varnames))

是文件stdtypes.c中的以下函数中发生段错误的地方:

static int
frame_traverse(NyHeapTraverse *ta) {
    PyFrameObject *v = (void *)ta->obj;
    PyCodeObject *co = v->f_code;
    int nlocals = co->co_nlocals;
    **if (PyTuple_Check(co->co_varnames)) {**
        int i;
        for (i = 0; i < nlocals; i++) {
            PyObject *name = PyTuple_GET_ITEM(co->co_varnames, i);
            if (strcmp(PyString_AsString(name), "_hiding_tag_") == 0) {
                if (v->f_local://splus[i] == ta->_hiding_tag_)
                  return 0;
                else
                  break;
            }
        }
    }
    return v->ob_type->tp_traverse(ta->obj, ta->visit, ta->arg);
}

4 个答案:

答案 0 :(得分:5)

将此问题和堆栈跟踪发布到Guppy邮件列表。我会说这对于StackOverflow的一般人群来说有点太专业了,但是如果崩溃很多,开发人员可能会指出你正确的方向。

答案 1 :(得分:4)

  

我不知道如何解决这个问题。

调试任何SIGSEGV崩溃的“标准”方法是在调试器(Linux上的GDB)下运行程序(在本例中为python)并获取崩溃堆栈跟踪:

gdb python
(gdb) run
... when you get python '>>>' prompt, enter the commands which cause crash
... GDB will stop with SIGSEGV
(gdb) where

根据您在堆栈跟踪中看到的内容,您可能会对根本原因进行有根据的猜测,或者此处有人可能会帮助您。

但没有这些信息,没有人能真正帮助你。

更新:我在Linux / x86_64上构建了guppy-0.1.9并在Valgrind下运行导致崩溃的命令(对我来说没有崩溃),这显示没有错误。

很可能,问题是由Python上的确切版本,用于构建python或guppy的编译器版本或环境触发的。我建议改变这些(环境可能最容易改变),看看你是否可以解决问题和/或重新出现在另一台机器上。如果您可以缩小崩溃显示的条件范围,那么修复错误的可能性就会大大提高。

如果做不到这一点,请调试C - 你最好调试问题,因为你是唯一可以观察它的人。

答案 2 :(得分:1)

作为解决方法,请注意堆栈跟踪中的PyErr_Display。 http://www.google.com/codesearch#-2BKs-LW4I0/trunk/python/src/Python/pythonrun.c&q=function:PyErr_Display&type=cs&l=1186

发生了一些错误吗?如果段错误是其中一个软件的编码错误,也许如果你摆脱了python异常,你就可以自由了。我建议尝试使用gdb(或ddd)

找出发生了什么异常

答案 3 :(得分:-1)

为什么使用两个不同的Python(版本27-maint),它们是用两个不同的编译器构建的?构建Python并不困难,因此在两台机器上都有一致的版本,使用相同的GCC版本构建。如果机器体系结构不同,您可以根据需要进行交叉编译。

显然,其中一个版本存在错误。如果两台机器都是相同的架构,您可以使用正常工作的Python并将其复制到另一台机器上的用户目录中。

如果某个应用对您很重要,请始终构建自己的Python,以便您拥有控制力和一致性。