我是 gdb 的新手,所以也许这个问题没有价值,但它确实让我困惑。我发现我的代码偶尔崩溃,核心转储文件显示崩溃信号是SIGABRT,回溯是
#0 __pthread_kill_implementation (no_tid=0, signo=6, threadid=140188693307392) at ./nptl/pthread_kill.c:44
#1 __pthread_kill_internal (signo=6, threadid=140188693307392) at ./nptl/pthread_kill.c:78
#2 __GI___pthread_kill (threadid=140188693307392, signo=signo@entry=6) at ./nptl/pthread_kill.c:89
#3 0x00007f8039485476 in __GI_raise (sig=sig@entry=6) at ../sysdeps/posix/raise.c:26
#4 0x00007f803946b7f3 in __GI_abort () at ./stdlib/abort.c:79
#5 0x00007f80394cc676 in __libc_message (action=action@entry=do_abort, fmt=fmt@entry=0x7f803961eb77 "%s\n") at ../sysdeps/posix/libc_fatal.c:155
#6 0x00007f80394e3cfc in malloc_printerr (str=str@entry=0x7f8039621210 "munmap_chunk(): invalid pointer") at ./malloc/malloc.c:5664
#7 0x00007f80394e3fdc in munmap_chunk (p=<optimized out>) at ./malloc/malloc.c:3060
#8 0x00007f80394e849a in __GI___libc_free (mem=<optimized out>) at ./malloc/malloc.c:3381
#9 0x00007f7fbc5dd1c5 in __gnu_cxx::new_allocator<int>::deallocate (__t=<optimized out>, __p=<optimized out>, this=0x7fff39d1adf0) at /usr/include/c++/11/ext/new_allocator.h:145
#10 std::allocator_traits<std::allocator<int> >::deallocate (__n=<optimized out>, __p=<optimized out>, __a=...) at /usr/include/c++/11/bits/alloc_traits.h:496
#11 std::_Vector_base<int, std::allocator<int> >::_M_deallocate (__n=<optimized out>, __p=<optimized out>, this=0x7fff39d1adf0) at /usr/include/c++/11/bits/stl_vector.h:354
#12 std::_Vector_base<int, std::allocator<int> >::~_Vector_base (this=0x7fff39d1adf0, __in_chrg=<optimized out>) at /usr/include/c++/11/bits/stl_vector.h:335
#13 std::vector<int, std::allocator<int> >::~vector (this=0x7fff39d1adf0, __in_chrg=<optimized out>) at /usr/include/c++/11/bits/stl_vector.h:683
#14 FS::FSBuf::~FSBuf (this=0x7fff39d1adc0, __in_chrg=<optimized out>) at /home/cmen/Projects-Code/acq_proc/src/acq_proc/cpp/include/fs/fs_basic.h:22
#15 0x00007f7fbc5dbf45 in FS::FSModule::run (this=this@entry=0x560cb230b8e0, flagPlotStatus=flagPlotStatus@entry=12...
注意,第 6 帧显示了崩溃原因“munmap_chunk():无效指针”,我们转到第 15 帧,它位于函数的最后一行
FS::FSModule::run
,通过 i locals
,我发现本地有一个变量“FSBuf buf”包含无法访问的向量。 FSBuf
是一个包含一些大向量的结构体,所有向量都将在FSBuf
构造函数中分配,以避免在计算过程运行时分配内存。当我尝试p buf.xxx
时,有些向量是可以打印的,例如
(gdb) p buf.comp
$48 = std::vector of length 1209600000, capacity 1209600000 = {6456, 7599, 6456, 0, 0, 0, 0, 280, -8, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49304, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7676, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -4, 284, -19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 134, 17232, 134, 0, 0, 149, 126, -6, -1, 134, -2, 0, 0, 0, 0, 134, -2, -1, 0, 0, -4, 130, -3, 0, -3, 0,
0, 0, 0, 0, -1, 0, 134, -4, 0, 0, -2, 0, 0, 0, 5580, 22163, 5580, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0...}
但是有些向量无法访问,例如
(gdb) p buf.conv
$49 = std::vector of length 30240000, capacity 30240000 = {Cannot access memory at address 0x7f77d3d93010
FSBuf
就像
struct FSBuf {
std::vector<int32_t> comp;
std::vector<float> conv;
FSBuf::FSBuf(size_t comp_size, size_t conv_size);
构造函数就像
FSBuf::FSBuf(size_t comp_size, size_t conv_size) :
comp(comp_size),
conv(conv_size) {}
我想知道的是,向量无法访问的可能原因是什么?我检查了代码,
free
中的向量没有mannully delete
或buf
。
或者我需要使用其他 gdb 命令获取哪些信息?
我想知道的是,向量无法访问的可能原因是什么?
某种未定义的行为是最常见的原因。
对于 malloc
实现中的
any崩溃(这是堆栈跟踪中的内容),实际上只有两个可能的原因:
malloc
实现本身的错误不用说,在 99.999% 的此类崩溃实例中,原因 2 就是原因。
堆损坏错误很难使用 GDB 进行调试,因为根本原因可能是从崩溃发生处删除了数百或数千条指令。
幸运的是,像 Valgrind 和 Address Sanitizer 这样的工具可以通常告诉您准确错误在哪里。