使用名为guppy(heapy)的Python工具时C代码中出现段错误

2 投票
4 回答
852 浏览
提问于 2025-04-16 22:06

我在两台机器上使用Python Stackless和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的回溯信息:

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

编辑2:更多信息:

出问题的那一行是:

if (PyTuple_Check(co->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 个回答

1

作为一种解决方法,可以注意到堆栈跟踪中的 PyErr_Display。

可能发生了一些错误吗?如果这个段错误是某个软件中的编码错误,或许如果你去掉了 Python 的异常,你就能解决问题。我建议你用 gdb(或者 ddd)来找出到底是什么异常发生了。

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的编译器版本,或者环境引起的。我建议你尝试改变这些(环境可能是最容易改变的),看看能否让问题消失,或者在另一台机器上重新出现。如果你能缩小崩溃出现的条件,你解决这个bug的机会就会大大增加。

如果还是不行,那就动手调试 C 吧——因为你是唯一能观察到这个问题的人,所以你在调试这个问题时处于最佳位置。

5

把这个问题和错误信息发到Guppy的邮件列表上。我觉得这个问题对StackOverflow上大多数人来说有点太专业了,可能帮不上忙。不过,如果崩溃是出现在heapy这个地方,开发者们可能能给你一些有用的建议。

撰写回答