从python ctypes调用err()(来自err.c)的Segfault

时间:2014-05-27 12:45:22

标签: python c ctypes

我使用ctypes在libbgpdump周围编写了一个python包装器,但是当libbgpdump调用“err()”时它会段错误。这是失败的C代码:

if(count > MAX_PREFIXES) {
    err("too many prefixes (%i > %i)", count, MAX_PREFIXES);
    return MAX_PREFIXES;
}

当我用printf()替换err()时,它可以工作。

这是stacktrace:

#0  strchrnul () at ../sysdeps/x86_64/strchrnul.S:34
#1  0x00007ffff6f2ba60 in __find_specmb (format=0x3fa <Address 0x3fa out of bounds>) at printf-parse.h:99
#2  _IO_vfprintf_internal (s=0x7fffffffc660, format=0x3fa <Address 0x3fa out of bounds>, ap=0x7fffffffce68) at vfprintf.c:1335
#3  0x00007ffff6f311a4 in buffered_vfprintf (s=0x7ffff729d1a0 <_IO_2_1_stderr_>, format=<optimized out>, args=<optimized out>) at vfprintf.c:2313
#4  0x00007ffff6f2bbde in _IO_vfprintf_internal (s=0x7ffff729d1a0 <_IO_2_1_stderr_>, format=0x3fa <Address 0x3fa out of bounds>, ap=0x7fffffffce68)
    at vfprintf.c:1316
#5  0x00007ffff6fd4ef1 in __GI_vwarn (format=0x3fa <Address 0x3fa out of bounds>, ap=0x7fffffffce68) at err.c:140
#6  0x00007ffff6fd512e in __GI_verr (status=-177566080, format=<optimized out>, ap=<optimized out>) at err.c:168
#7  0x00007ffff6fd51e7 in err (status=<optimized out>, status@entry=-177566080, format=<optimized out>, 
    format@entry=0x3fa <Address 0x3fa out of bounds>) at err.c:184
#8  0x00007ffff56a4196 in read_prefix_list (s=s@entry=0x7fffffffd010, afi=afi@entry=1, prefixes=prefixes@entry=0xa4d9a4, 
    incomplete=incomplete@entry=0xa527c8) at bgpdump_lib.c:1255
#9  0x00007ffff56a5db8 in process_zebra_bgp_message_update (asn_len=4 '\004', entry=0xa48b20, s=0x7fffffffd010) at bgpdump_lib.c:741
#10 process_zebra_bgp_message (s=s@entry=0x7fffffffd0e0, entry=entry@entry=0xa48b20, asn_len=asn_len@entry=4 '\004') at bgpdump_lib.c:682
#11 0x00007ffff56a6941 in process_zebra_bgp (entry=0xa48b20, s=0x7fffffffd0e0) at bgpdump_lib.c:543
#12 bgpdump_read_next (dump=0x9c2cf0) at bgpdump_lib.c:190
#13 0x00007ffff5b7d4d8 in ffi_call_unix64 () from /usr/lib/python2.7/lib-dynload/_ctypes.so
#14 0x00007ffff5b7cee0 in ffi_call () from /usr/lib/python2.7/lib-dynload/_ctypes.so
#15 0x00007ffff5b6f311 in _ctypes_callproc () from /usr/lib/python2.7/lib-dynload/_ctypes.so
#16 0x00007ffff5b6fa82 in ?? () from /usr/lib/python2.7/lib-dynload/_ctypes.so
#17 0x000000000046005e in PyEval_EvalFrameEx ()
#18 0x0000000000467209 in PyEval_EvalCodeEx ()
#19 0x00000000004ab55a in ?? ()
#20 0x0000000000486c3d in ?? ()
#21 0x0000000000491a5d in PyEval_CallObjectWithKeywords ()
#22 0x00000000004ebdc7 in ?? ()
#23 0x000000000045fdca in PyEval_EvalFrameEx ()
#24 0x0000000000460227 in PyEval_EvalFrameEx ()
#25 0x0000000000467209 in PyEval_EvalCodeEx ()
#26 0x00000000004cfc12 in PyEval_EvalCode ()
#27 0x00000000005137db in ?? ()
#28 0x000000000044cab6 in PyRun_FileExFlags ()
#29 0x000000000044cfca in PyRun_SimpleFileExFlags ()
#30 0x000000000044dd0c in Py_Main ()
#31 0x00007ffff6f0476d in __libc_start_main (main=0x44ddcb <main>, argc=2, ubp_av=0x7fffffffe178, init=<optimized out>, fini=<optimized out>, 
    rtld_fini=<optimized out>, stack_end=0x7fffffffe168) at libc-start.c:226
#32 0x00000000004cda7d in _start ()

感谢您的帮助:)

-------------------编辑--------------------------- -

啊,现在我看到了问题。 libbgpdump正在使用它自己的err()函数,在./util.c中定义,但是当我使用来自ctypes的lib时,它会尝试使用err.h中的lib,即使它从未包含在内。

为什么会发生这种情况以及如何使其发挥作用的任何建议?

1 个答案:

答案 0 :(得分:3)

基本上,你缺少一个err函数的参数,返回值(参见err MAN pages):

if(count > MAX_PREFIXES) 
    err(MAX_PREFIXES, "too many prefixes (%i > %i)", count, MAX_PREFIXES);