../../gdb/linux-thread-db.c:288: internal-error: thread_get_info_callback: Assertion `thread_info != NULL' failed.
在Linux下用GDB调试程序,要处理的数据量太大(每秒20万左右)的时候,总会报如下段错误(Segmentation fault):
internal-error: thread_get_info_callback: Assertion `thread_info != NULL'
failed
每次出现的时间都不一样,而且数据量越大错误出现的越快。有时候报的还不是这样的错,总之都是这样一些让人摸不着头脑的错误,比如:
internal-error: handle_inferior_event: Assertion `inf' failed
或者
#0
0x0000003f7e2b7672 in __gnu_cxx::__exchange_and_add () from /usr/lib64/libstdc++.so.6
#1 0x0000003f7e29ca4b in std::string::assign () from /usr/lib64/libstdc++.so.6
#2 0x0000000000457269 in TimerFunc6 (n=<value optimized out>)
at /usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../include/c++/4.1.2/bits/basic_string.h:486
#3 <signal handler called>
#4 0x0000003f6c407953 in pthread_join () from /lib64/libpthread.so.0
等等。
在Google上搜索了很久都没有人有明确的说法,只有自己研究。
仔细研究了很久代码以后,发现了可能造成这样错误的原因:栈溢出!(注意,不是堆!)
先从基础说起。
关于变量的存储
在c/c++中有这几个存储区
1.栈 - 由编译器自动分配释放
2.堆 - 一般由程序员分配释放,若程序员不释放,程序结束时可能由OS回收
3.全局区(静态区),全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域,未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。- 程序结束释放
4.存储常量的地方。- 程序结束释放
在函数体中定义的变量通常是在栈上,用malloc, calloc, realloc等分配内存的函数分配得到的就是在堆上。在所有函数体外定义的是全局量,加了static修饰符后不管在哪里都存放在全局区(静态区),在 所有函数体外定义的static变量表示在该文件中有效,不能extern到别的文件用,在函数体内定义的static表示只在该函数体内有效。另外,函数中的"hello world"这样的字符串存放在常量区。
程序员在编程的时候都会知道malloc等分配的内存在用完以后要释放,否则很容易出现内存用光;可是很少有人考虑由编译器自动分配的栈用光的情况,因为 一般情况下不会出现,只有无限递归的时候才会出现。然而在我的程序中,一分钟有上千万的数据,每一个数据都会自动分配一个大对象,因此就像无限递归那样, 栈很快就耗光了,导致再有需要分配栈的地方就会出错。
发现了可能导致错误的地方后,我把大对象中的很长的字符串全部换成指针,malloc大对象以后再给里边的指针malloc空间存放字符串。果然,这样做以后就没有再报那样的错误。
当然,出现internal-error: handle_inferior_event: Assertion `inf' failed
或者
internal-error: thread_get_info_callback: Assertion `thread_info != NULL'
failed 等
的错误也有别的原因。之前就出现过这样的错误,通过重新加载linux的CPU内核模块解决了它,原因就是之前的CPU内核模块不是非常稳定。
#1 0x0000003f7e29ca4b in std::string::assign () from /usr/lib64/libstdc++.so.6
#2 0x0000000000457269 in TimerFunc6 (n=<value optimized out>)
at /usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../include/c++/4.1.2/bits/basic_string.h:486
#3 <signal handler called>
#4 0x0000003f6c407953 in pthread_join () from /lib64/libpthread.so.0
等等。
在Google上搜索了很久都没有人有明确的说法,只有自己研究。
仔细研究了很久代码以后,发现了可能造成这样错误的原因:栈溢出!(注意,不是堆!)
先从基础说起。
关于变量的存储
在c/c++中有这几个存储区
1.栈 - 由编译器自动分配释放
2.堆 - 一般由程序员分配释放,若程序员不释放,程序结束时可能由OS回收
3.全局区(静态区),全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域,未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。- 程序结束释放
4.存储常量的地方。- 程序结束释放
在函数体中定义的变量通常是在栈上,用malloc, calloc, realloc等分配内存的函数分配得到的就是在堆上。在所有函数体外定义的是全局量,加了static修饰符后不管在哪里都存放在全局区(静态区),在 所有函数体外定义的static变量表示在该文件中有效,不能extern到别的文件用,在函数体内定义的static表示只在该函数体内有效。另外,函数中的"hello world"这样的字符串存放在常量区。
程序员在编程的时候都会知道malloc等分配的内存在用完以后要释放,否则很容易出现内存用光;可是很少有人考虑由编译器自动分配的栈用光的情况,因为 一般情况下不会出现,只有无限递归的时候才会出现。然而在我的程序中,一分钟有上千万的数据,每一个数据都会自动分配一个大对象,因此就像无限递归那样, 栈很快就耗光了,导致再有需要分配栈的地方就会出错。
发现了可能导致错误的地方后,我把大对象中的很长的字符串全部换成指针,malloc大对象以后再给里边的指针malloc空间存放字符串。果然,这样做以后就没有再报那样的错误。
当然,出现internal-error: handle_inferior_event: Assertion `inf' failed
或者
internal-error: thread_get_info_callback: Assertion `thread_info != NULL'
failed 等
的错误也有别的原因。之前就出现过这样的错误,通过重新加载linux的CPU内核模块解决了它,原因就是之前的CPU内核模块不是非常稳定。