由于程序栈 导致GDB退出问题的分析

来源:互联网 发布:js源码下载 编辑:程序博客网 时间:2024/05/18 05:10

../../gdb/linux-thread-db.c:288: internal-error: thread_get_info_callback: Assertion `thread_info != NULL' failed.

 

 

在Linux下用GDB调试程序,要处理的数据量太大(每秒20万左右)的时候,总会报如下段错误(Segmentationfault):

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 handlercalled>
#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表示只在该函数体内有效。另外,函数中的"helloworld"这样的字符串存放在常量区。

   程序员在编程的时候都会知道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内核模块不是非常稳定。
原创粉丝点击