免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
123下一页
最近访问板块 发新帖
查看: 8827 | 回复: 21

[书评] [大件事]gdb调试技术以及地址越界相关!·!! [复制链接]

论坛徽章:
1
2015年亚洲杯之巴林
日期:2015-02-05 20:34:47
发表于 2013-01-30 21:58 |显示全部楼层
请教大家一个关于内存地址突变的一个问题,是这样的:
我有一个类一个方法是检测条件状态的。比如这样:
  1. void test::checkstatus()
  2. {
  3.         while(true)
  4.         {
  5.                 printf("this = %0x\n", this);
  6.                 //其他代码
  7.                 if (this->need_process())
  8.                 {
  9.                         //process
  10.                 }
  11.                 //其他代码
  12. }
  13. }

  14. bool test::need_process()
  15. {
  16.         printf("this = %0x\n", this);
  17.         //检测过程
  18. }
复制代码
这个方法运行在多线程环境中,而且这个方法也是create出来的一个线程执行的(大家请忽略语法之类的错误)
  1. pthread_create(pid_t, NULL, test::checkstatus, NULL);
复制代码
问题是:
test这个对象是在堆上new出来的, 、在运行的过程中checkstatus,need_process 这两个函数里面打印出来的this指针地址是一致的。

但是有时候程序在一直在正常得运行(这里指两个this打印一致,比如都是0x6EA8975),但是某个时刻checkstatus打印还是正常的(0x6EA8975),但是掉用need_process的时候
里面的打印是一个非法的地址值了,比如是(0x123),以至于need_process函数里面需要对对象成员进行修改导致段错误。
这时候,test这个对象是没有析构的(因为在析构的最前面有打印)。
我gdb进去,
1 bt full,发现有一些值已经是一些随机值了(比如一个非常大的整数)。
2 直接print *this,直接提示 0x123这个地址不能访问,
3 执行up
4 print *this发现checkstatus这里面还是正常的,所有的变量什么的都是正常值。


我的疑问是,为什么在对象没有被析构的情况下,this指针发生了跳转(正常情况这两个打印this地址的值都是一样的,而且这个段错误不是必现的),
而且他的上一跳 执行情况都是正常的 。

这个大概可能是什么情况呢?gdb之类的我不是很熟,所以想请教一下大家。
非常感谢。

论坛徽章:
4
水瓶座
日期:2013-09-06 12:27:30摩羯座
日期:2013-09-28 14:07:46处女座
日期:2013-10-24 14:25:01酉鸡
日期:2014-04-07 11:54:15
发表于 2013-01-30 22:44 |显示全部楼层
valgrind --tool=memcheck --log-file=xxx --leak-check=full ./your_program

关注xxx里的overlap, invalide 关键字。

另外, 看是否有栈溢出问题, 一般你找不到越界的时候可能是栈溢出了。

论坛徽章:
1
2015年亚洲杯之巴林
日期:2015-02-05 20:34:47
发表于 2013-01-31 00:03 |显示全部楼层
回复 2# linux_c_py_php

我不明白的是,这个对象是我在堆上申请的,调用这个函数之前什么都是正确的,但是接下来的调用,this指针已经变为非法的了。这个中间应该没有执行任何代码吧?因为我直接./gdb up 之后的 p *this 都是正常的。


   

论坛徽章:
1
2015年亚洲杯之巴林
日期:2015-02-05 20:34:47
发表于 2013-01-31 08:46 |显示全部楼层
回复 2# linux_c_py_php


    我的疑问是:比如:
  int *p = new int; //如果这里p的地址是 0xAEF1233(反正是一个合法的地址)
*p = 100;//这里 段错误了 p的地址变成了 0x123(不是进程空间的地址 )

有什么原因 在我没有做  delete p 这个动作  ,而 p的地址发生了跳变?

或者 ,我1楼的例子中 。我得到了一个core文件,我的操作步骤为(中间没有插入任何步骤 ):
1、>bt full (在对象的这个函数 need_process里  )
2、>print *this;(在对象的这个函数 need_process里  )
       打印0x123不能访问。
3、>up
4、>print *this (在对象的这个函数 checkstatus里  )
    可以打印出 我new出来那个对象的所有正常的内容。

是不是说明 1楼的进程执行顺序是 checkstatus-->调用 need_process  中间没有执行这个进程其他部分的指令? 就像执行顺序为
int *p = new int; *p = 100;那样。

如果是这样的话,连续执行的2个指令,第一条的时候 this指针的地址还是合法的,为什么接下来的这一条就变成非法了?
在什么情况下会发生这样的事情?
而且,每次this指针变为非法的地址都是一模一模的 比如都是 :0x123。

论坛徽章:
4
天秤座
日期:2013-10-18 13:58:33金牛座
日期:2013-11-28 16:17:01辰龙
日期:2014-01-14 09:54:32戌狗
日期:2014-01-24 09:23:27
发表于 2013-01-31 09:21 |显示全部楼层
建议你再看一下二楼的回复,你要确定明白二楼想让你怎么去调试。

虽然并不一定是这个问题,但是,二楼说的是最大的可能。

论坛徽章:
1
2015年亚洲杯之巴林
日期:2015-02-05 20:34:47
发表于 2013-01-31 09:43 来自手机 |显示全部楼层
那段是编译选项?不太清楚怎么用。因为这个问题是偶尔出现的。

论坛徽章:
1
2015年亚洲杯之巴林
日期:2015-02-05 20:34:47
发表于 2013-01-31 09:55 |显示全部楼层
回复 5# liuiang


    关键是我在嵌入式系统上运行的程序,能用那个工具吗?整个系统RAM估计只有几十M。

论坛徽章:
11
未羊
日期:2013-12-16 12:45:4615-16赛季CBA联赛之青岛
日期:2016-04-11 19:17:4715-16赛季CBA联赛之广夏
日期:2016-04-06 16:34:012015亚冠之卡尔希纳萨夫
日期:2015-11-10 10:04:522015亚冠之大阪钢巴
日期:2015-07-30 18:29:402015亚冠之城南
日期:2015-06-15 17:56:392015亚冠之卡尔希纳萨夫
日期:2015-05-15 15:19:272015亚冠之山东鲁能
日期:2015-05-14 12:38:13金牛座
日期:2014-12-04 15:34:06子鼠
日期:2014-10-16 13:40:4715-16赛季CBA联赛之八一
日期:2016-07-22 09:41:40
发表于 2013-01-31 10:02 |显示全部楼层
回复 7# sublx

不管是什么样的奇技淫巧, 我觉得 pthread_create(pid_t, NULL, test::checkstatus, NULL); 这句将一个成员函数作为非成员函数作为 thread main, 是有点危险的, 而且, 这个调用好歹
pthread_create(pid_t, NULL, test::checkstatus, &test); 才更合理吧, 就算这样我也奇怪他居然能够编译过去不报错?


   

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
发表于 2013-01-31 10:05 |显示全部楼层
sublx 发表于 2013-01-31 00:03
回复 2# linux_c_py_php

我不明白的是,这个对象是我在堆上申请的,调用这个函数之前什么都是正确的,但 ...


对象是堆上申请的,对象的成员是个函数
你用了pthread_create去创建线程,线程的入口就是这个函数指针指向的地址,那么
函数里的任何自动变量都会用到栈,函数里的任何静态变量都会线程间共享
函数说白了就是个地址,存储这个地址的指针也许是堆上申请的,但是这个指针指向的内存区域机器码执行可就未必是堆上的行为

论坛徽章:
1
2015年亚洲杯之巴林
日期:2015-02-05 20:34:47
发表于 2013-01-31 10:07 |显示全部楼层
回复 8# zylthinking


    程序里面不是那样用的。我只是举个例子说明那个函数是在一个单独的线程里面运行,
实际上是用 boost::thread 创建的线程 。我在powerpc上运行的。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP