将变量赋值为null(C ++)时的信号6(SIGABRT)

时间:2013-03-12 14:14:33

标签: c++ gdb

当分析在SIGABRT之后转储的核心时,gdb说我执行的最后一行代码(在输入库代码之前)是对NULL指针的char赋值,如下所示:

GDB:

(gdb) bt full
#0  0x006337a2 in _dl_sysinfo_int80 () from /lib/ld-linux.so.2
No symbol table info available.
#1  0x00674815 in raise () from /lib/tls/libc.so.6
No symbol table info available.
#2  0x00676279 in abort () from /lib/tls/libc.so.6
No symbol table info available.
#3  0x006a8cca in __libc_message () from /lib/tls/libc.so.6
No symbol table info available.
#4  0x006af55f in _int_free () from /lib/tls/libc.so.6
No symbol table info available.
#5  0x006af93a in free () from /lib/tls/libc.so.6
No symbol table info available.
#6  0x00d0b14e in __builtin_delete () from /usr/lib/libstdc++-libc6.1-1.so.2
No symbol table info available.
#7  0x0808181c in MyObject::~MyObject (this=0x84f4db0, __in_chrg=3) at ./MyObject.cpp:16
    this = (MyObject *) 0x84f4db0

MyObject.cpp:16列表:

12: ...
13: MyObject::~MyObject() {
14:   if (this->string != NULL) {
15:     delete this->string;
16:     this->string = NULL;
17:   }
18: }
19: ...

首先,我不明白为什么第16行会导致该调用堆栈。如果它是执行第15行的结果会更有意义,第15行是delete运算符(除非“第16行”表示在析构函数的代码之后执行的代码以释放为该对象分配的内存;只是在这里猜测。)

除此之外,有人能指出正确调试核心的方法吗?

3 个答案:

答案 0 :(得分:3)

this->string有哪些类型?它是一个char数组吗?然后你应该使用delete [] this->string。它是指向对象的指针吗?然后该对象已被删除且指针未被清零,或者从未创建过该对象,并且指针仍处于酉状态。

答案 1 :(得分:1)

实际崩溃发生在这一行:

15:     delete this->string;

由于在abort内拨打了__libc_message,发生了崩溃。最后一个例程向您的标准错误打印了一条消息,消息看起来像

*** glbc detected: double free or heap corruption at ...  ***

使用ValgrindAddressSanitizer:他们会直接指出您的问题。

  

我不明白为什么第16行会导致调用堆栈。

当您查看导致raise系统调用的调用堆栈时,您需要了解CALL指令将 next 指令的地址设置为在将控制转移到被调用的过程之前,在堆栈上执行,这是GDB在backtrace中显示的下一条指令(所有调试器都这样做)。下一条指令可能位于当前行,下一行或20行。

答案 2 :(得分:0)

它指向要执行 about 的下一行,在你的情况下是第16行,最后执行的语句/表达式是第15行,它在该行上崩溃。

很难从你的帖子中看出这里有什么问题。