由于程序栈 导致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内核模块不是非常稳定。
#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内核模块不是非常稳定。
- 由于程序栈 导致GDB退出问题的分析
- SIGPIPE导致的程序退出
- SIGPIPE导致的程序退出
- SIGPIPE导致的程序退出
- ARM程序由于字节对齐引起的问题深入分析
- ARM程序由于字节对齐引起的问题深入分析
- ARM程序由于字节对齐引起的问题深入分析
- 一个rac问题分析过程由于进程资源不足导致的问题
- 由于JDK版本问题导致的错误
- 由于ADT升级后导致的问题
- 一个由于位数导致的问题
- Db2由于取sequence 的 next value 导致的性能问题案例分析
- 关于SIGPIPE导致的程序退出
- 关于SIGPIPE导致的程序退出
- 转载: 关于SIGPIPE导致的程序退出
- 关于SIGPIPE导致的程序退出
- 关于SIGPIPE导致的程序退出
- 关于SIGPIPE导致的程序退出
- android 文本中使用超链接
- Android Gallery组件实现循环显示图像
- ---------------常见HTTP状态码-------------强悍!
- C#网络编程(异步传输字符串) - Part.3
- C#网络编程(订立协议和发送文件) - Part.4
- 由于程序栈 导致GDB退出问题的分析
- PHP cookie和session的分析
- [转]Linux内核访问外设I/O资源的方式--待整理
- linux嵌入式系统中mdev的配置
- 好的程序员
- 小波处理
- vi命令一览表
- 分形艺术网发布:分形软件Apophysis视频教程第一讲
- U盘装iso镜像系统