在gdb中没有明显原因调试段错误?

时间:2014-03-28 20:06:24

标签: c debugging gdb segmentation-fault electric-fence

gdb报告说我的C代码在malloc()的某个地方崩溃了,所以我将我的代码与Electric Fence联系起来,以确定内存错误的实际来源。现在我的代码更早出现了segfaulting,但gdb的输出更令人困惑:

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x30026b00 (LWP 4003)]
0x10007c30 in simulated_status (axis=1, F=0x300e7fa8, B=0x1003a520, A=0x3013b000, p=0x1003b258, XS=0x3013b000)
    at ccp_gch.c:799

编辑:完整的回溯:

(gdb) bt
#0  0x10007c30 in simulated_status (axis=1, F=0x300e7fa8, B=0x1003a520, A=0x3013b000, p=0x1003b258, XS=0x3013b000)
    at ccp_gch.c:799
#1  0x10007df8 in execute_QUERY (F=0x300e7fa8, B=0x1003a520, iData=0x7fb615c0) at ccp_gch.c:836
#2  0x10009680 in execute_DATA_cmd (P=0x300e7fa8, B=0x7fb615cc, R_type=0x7fb615d0, iData=0x7fb615c0)
    at ccp_gch.c:1581
#3  0x10015bd8 in do_volley (client=13) at session.c:76
#4  0x10015ef4 in do_dialogue (v=12, port=2007) at session.c:149
#5  0x10016350 in do_session (starting_port=2007, ports=1) at session.c:245
#6  0x100056e4 in main (argc=2, argv=0x7fb618f4) at main.c:271

相关代码(因原因略有修改):

796  static uint32_t simulated_status(
797      unsigned axis, struct foo *F, struct bar *B, struct Axis *A, BAZ *p, uint64_t *XS)
798  {
799      uint32_t result = A->status;
800      *XS = get_status(axis);
801      if (!some_function(p)) {
802          ...

要检查的显而易见的事情是A->status是否是有效的内存,但确实如此。删除分配会将segfault推送到第800行,并删除 分配会导致if-block中的某些其他分配发生段错误。看起来访问传递给函数的参数或写入局部变量是导致段错误的原因,但是根据gdb,所有内容都指向有效内存。

我怎么解释这个?我之前从未见过这样的事情,所以任何正确方向的建议/指示都会受到赞赏。我使用GNU gdb 6.8-debian,Electric Fence 2.1,并在PowerPC 405上运行(uname报告Linux powerpmac 2.6.30.3 #24 [...] ppc GNU/Linux)。

1 个答案:

答案 0 :(得分:0)

我猜,但你的症状类似于堆栈溢出情况下可能发生的情况。评论中的-fstack-protector建议在此处正确。我建议您同时添加-fstack-check选项。

如果由于写入保护堆栈的保护页面而发生SEGV,那么gdb中的info registersinfo frame将有助于确认是否是这种情况。