使用gdb调试断言显示了奇怪的std :: string大小

时间:2015-03-17 13:36:33

标签: c++ gdb assert core

我在C ++程序中遇到断言问题。

HA_Archive & HA_Archive::operator << (const string & str) {
    buffer[wcursor] = HA_TYPE_STRING;
    wcursor++;
    unsigned size = str.size();
    CASSERT((bufferSize > wcursor + size),"buffer exceeds the maximum");

CASSERT是一个简单的断言,存在问题。

该程序留下了我用gdb调试过的核心转储,我发现了一些奇怪的东西。

Program terminated with signal 6, Aborted.
#0  0xb7766424 in __kernel_vsyscall ()
(gdb) bt
#0  0xb7766424 in __kernel_vsyscall ()
#1  0xb6cd1cb1 in raise () from /lib/libc.so.6
#2  0xb6cd33e8 in abort () from /lib/libc.so.6
#3  0xb6ccb58c in __assert_fail () from /lib/libc.so.6
#4  0x086c6dbd in HA_Archive::operator<< (this=0xb2610fb8, str=@0xb49e1f08) at HA_Archive.cxx:94
#5  0x0849b4d3 in PortDriver::serialize (this=0xb49e1ed8, ar=@0xb2610fb8) at PortDriver.cxx:624
#6  0x0838ed80 in PortSession::serialize (this=0xb49e1630, ar=@0xb2610fb8) at PortSession/PortSession.h:71

(gdb) frame 4
#4  0x086c6dbd in HA_Archive::operator<< (this=0xb2610fb8, str=@0xb49e1f08) at HA_Archive.cxx:94
94  HA_Archive.cxx: No such file or directory.
    in HA_Archive.cxx
(gdb) print str
$1 = (const string &) @0xb49e1f08: {static npos = 4294967295, _M_dataplus = {<std::allocator<char>> = {<__gnu_cxx::new_allocator<char>> = {<No data fields>}, <No data fields>}, _M_p = 0xb322f9b4 "NOT-SET"}}
(gdb) print wcursor
$2 = 180
(gdb) print bufferSize
$3 = 4096
(gdb) print size
$4 = 171791040

打印 str 我可以看到它有&#34; NOT-SET&#34; ,这没关系,但是当我打印变量时大小 str.size()值很大!显然是导致断言失败的原因,因为bufferSize是4096而wcursor只有180.

我非常擅长gdb,所以我的第一个问题是如果我做错了。也许尺寸不是运行时的真正价值?

我的第二个问题是:如果gdb显示正确的大小值,为什么我正确看到字符串&#34; NOT-SET&#34;当我打印它,但尺寸是那么大的数字?

谢谢!

1 个答案:

答案 0 :(得分:0)

有几种方法可以实现。

字符串可能真的是那么大,但内容可能在str [7]上有一个空字符,这会导致GDB停止打印出来。

或者可能有些东西在你的堆上乱写并覆盖了存储字符串大小的内存位置,所以虽然内容仍然只有7个字节长,但是大小成员已被垃圾覆盖。

或者str可能只是一个悬空引用,_M_p指向的内存仍然包含字符串“NOT-SET”,但包含size成员的内存已被重新用于其他内容

我会尝试在valgrind下运行,以确保没有可能覆盖该成员的缓冲区溢出,或者使用后免费错误。