【发布时间】:2015-05-19 23:10:55
【问题描述】:
我对 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 我可以看到它有 "NOT-SET" 没关系,但是当我打印变量 size即 str.size() 价值巨大!显然是断言失败的原因,因为 bufferSize 是 4096 而 wcursor 只有 180。
我在 gdb 方面的成就和专家地位还很遥远,所以我的第一个问题是我是否做错了什么。也许大小不是运行时的真正价值?
我的第二个问题是:如果 gdb 显示正确的大小值,为什么我在打印时正确看到字符串“NOT-SET”,但大小是那么大的数字?
谢谢!
【问题讨论】:
-
你得到的大小可能是
(unsigned long)-1或类似的东西。这意味着大小已损坏,因为内存已损坏。 -
你在编译时使用的是什么优化级别?
-
你应该发布 MCVE,否则我们只是在这里猜测,问题可能出在调用上下文中。
-
尝试直接从 gdb 提示符调用
str.size(),如下所示:(gdb) print str.size()。 -
ForceBru 我无法将该数字与任何有意义的东西(如-1)匹配,因为大小并不总是相同,也许我错了..我不知道。 Vaughn Cato 我正在使用 2 级。Slava 我无法发布 MCVE,因为我无法重现该错误,它有时会发生,但我无法定义何时。 ks1322,我不能打印 str.size() 因为 gdb 说我需要一个正在运行的进程来调试。