社区
Linux/Unix社区
帖子详情
程序访问内存非法退出,调试core时,却发现#0 0x00000000 in ?? () ,奶奶的,已经加了调试信息了
wxbfly
2005-06-26 10:08:03
打where时出现
#0 0x00000000 in ?? ()
一看eip为0,堆栈也就只有这么一个,这让我怎么搞。
...全文
2134
15
打赏
收藏
程序访问内存非法退出,调试core时,却发现#0 0x00000000 in ?? () ,奶奶的,已经加了调试信息了
打where时出现 #0 0x00000000 in ?? () 一看eip为0,堆栈也就只有这么一个,这让我怎么搞。
复制链接
扫一扫
分享
转发到动态
举报
写回复
配置赞助广告
用AI写文章
15 条
回复
切换为时间正序
请发表友善的回复…
发表回复
打赏红包
wxbfly
2005-06-28
打赏
举报
回复
我也想过有这种可能,但没道理堆栈就只有一个啊
wxbfly
2005-06-28
打赏
举报
回复
OK,多谢,结贴给分。
chanteur
2005-06-28
打赏
举报
回复
客气了,大家互相探讨吧。
我的email:lichentao@datangmobile.cn。
nm是GNU命令,不是GDB命令,具体用法看man吧
wxbfly
2005-06-28
打赏
举报
回复
先说我的msn,wxbfly@hotmail.com或qq:37737098
wxbfly
2005-06-28
打赏
举报
回复
呵呵,多谢老兄指点。
我对汇编还算比较熟悉,对c语言的压栈、退栈操作也都比较清楚。确实,在堆栈被破坏时,esp的值应该还是正确的,估计也只有你所说的这个办法。不过我对gdb的操作不是很熟,符号表的获取在我的gdb版本中不知用什么命令,nm不被支持。我的linux版本是slackware 2.4.20,gdb版本是5.2。
另外,请问老兄的联系方式是什么?以后多交流,QQ或msn、email都可以
chanteur
2005-06-28
打赏
举报
回复
一般来说因为局部变量导致堆栈越界的问题比较难查,因为gdb保存的也不是第一现场。
以我的经验来说,首先应该初步估计出问题的流程,然后在该流程中大量加入打印,通过
打印信息缩小排查范围,然后结合代码走读查找BUG。
阅读代码时重点注意,局部变量中的数组大小,以及memset,memcpy类的系统调用,还有就是循环赋值语句。
如果问题无法复现的话,就要碰运气了。
假设局部变量写越界不严重的话,可以手动推导一部分堆栈中的函数调用关系,要求对C语言的压栈过程比较熟悉。
大致上的做法是:
出现SEGV时,查看寄存器esp的值,在根据esp的值打印出堆栈的信息,如果这部分数据不是全零的话,说明堆栈被写越界的太多;否则的话,还是放弃吧。
另一方面要用nm命令把调试目标的符号表取出,最好按地址排序。
接下来,就是手动对比堆栈中的现场和符号表了
wxbfly
2005-06-28
打赏
举报
回复
嗯,有道理。我试了一下,确实是这样。
那么此时该怎么办呢?如何跟踪调试?还有,出现此类情况时,gdb是否能够将没有破坏的部分堆栈显示出来?
还望 chanteur(晓涛) 老兄解答,我再加分。
chanteur
2005-06-28
打赏
举报
回复
不知道楼主说的堆栈只有一个是什么意思。
是多线程的堆栈都看不到了,只能看到一个线程的堆栈;还是指堆栈中只能看到一个函数调用。
如果是后者的话,应该是局部变量写越界吧,GDB显示堆栈调用关系也是从堆栈中读取保存的现场;
如果堆栈已被破坏了,GDB无法得到正确的解析,就只能显示一级函数调用了。
刚才做了一个试验,
#include <stdio.h>
void func()
{
int i[2];
memset(i,0,100);
}
void main()
{
func();
}
用gdb调试,当出现SegV时,堆栈显示为
#0 0x00000000 in ??()
chanteur
2005-06-27
打赏
举报
回复
有没有可能是局部变量写越界,导致堆栈中调用现场被覆盖成0;
退出当前函数调用时跳转到0,同时导致backtrace解析失败。
wxbfly
2005-06-27
打赏
举报
回复
to kaoziji(靠自己):
能不能详细讲解一下?
kaoziji
2005-06-27
打赏
举报
回复
感觉是在程序中 throw exception 后,在main中没有catch。
wxbfly
2005-06-26
打赏
举报
回复
鸡巴晕,发现这里没几人解答我的问题。
wxbfly
2005-06-26
打赏
举报
回复
就是用gdb调试的core文件,但由于程序是在一定情况下才死机的,无法再让程序从头再现一遍,因此只有分析core文件。单步跟踪等操作是实施不了的
那么,只分析core文件没法解决问题吗?
mprogrammer
2005-06-26
打赏
举报
回复
学习用 gdb吧,断点调一下,要不有时候 printf不能打出来程序就 down了
sharkhuang
2005-06-26
打赏
举报
回复
很难回答这个问题!用GDB单步吧
Linux GDB C/C++
调试
从入门到精通
这是关于Linux C/C++ gdb
调试
课程,主要介绍Linux gdb C/C++
调试
基本知识,Linux gdb C/C++
调试
基本技巧和Linux gdb C/C++高级
调试
技巧, 能够快速上手,快速实战,达到快速定位BUG,快速纠错的能力!尤其是一些高级...
gdb
调试
堆栈信息一堆问号如 #0
0x00000000
00000000 in ?? () 看这里跟踪
今日分享的内容是建立在gdb环境与编译环境都正常的情况下所做的
调试
工作。 如何安装gdb以及如何搭建可以生成
调试
信息
的编译环境可以自行百度,有很多的文章可以参考,我们重点介绍 gdb过程中产生 #0
0x00000000
00000000 in ?? () 信息的问题如何定位
调试
。 这里我使用的是printf+gdb的方式,由于堆栈信息是一堆0和问号,我们通过gdb无法直接定位,所以我们先
加
打印大致定位到死在哪个接口,假设打印跟踪到的接口我们定义为My_test()。 一、首次运行
core
dump文件 利用
0x00000000
00000000 in ??
栈溢出
gdb堆栈被破坏
时
的定位方法
gdb堆栈被破坏
时
的定位方法 前几天碰到一个崩溃问题,利用
core
dump查看崩溃堆栈信息
时
,却
发现
堆栈被破坏了 (gdb) bt #0 0x0000000f55555186 in ?? () #1
0x00000000
00000003 in ?? () #2 0x0000000e00000000 in ?? () #3
0x00000000
00000000 in ?? () 不过正好还可以利用栈帧和寄存器的信息继续去定位崩溃原因,这里简单做下分享用到的一些命令和知识 gdb的x命令 x命令是用于
Linux
程序
崩溃(segment fault)原因的
调试
主要有两种方法: 一是用gdb,二是用valgrind 1.先用 ulimit -c unlimited 设置环境 2.重新运行
程序
,等待 segment fault,应该会生成
core
文件 3.gdb
core
* 以下是gdb ./UserStatsControl
core
.12345的输出 #0
0x00000000
in ?? () (gdb) bt
Linux/Unix社区
23,118
社区成员
74,507
社区内容
发帖
与我相关
我的任务
Linux/Unix社区
Linux/Unix社区 应用程序开发区
复制链接
扫一扫
分享
社区描述
Linux/Unix社区 应用程序开发区
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
暂无公告
试试用AI创作助手写篇文章吧
+ 用AI写文章