首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >无限中止()在c++程序内核转储的回滚中

无限中止()在c++程序内核转储的回滚中
EN

Stack Overflow用户
提问于 2012-02-26 19:08:22
回答 2查看 1.8K关注 0票数 10

我有一个我解决不了的奇怪问题。请帮帮我!

该程序是一个多线程c++应用程序,运行在ARM Linux机器上。最近,我开始测试它的长期运行,有时它会在1-2天后崩溃,如下所示:

代码语言:javascript
运行
复制
*** glibc detected ** /root/client/my_program: free(): invalid pointer: 0x002a9408 ***

当我打开核心转储时,我看到主线程似乎有一个损坏的堆栈:我所能看到的就是无限的abort()调用。

代码语言:javascript
运行
复制
GNU gdb (GDB) 7.3 
...
This GDB was configured as "--host=i686 --target=arm-linux".
[New LWP 706]
[New LWP 700]
[New LWP 702]
[New LWP 703]
[New LWP 704]
[New LWP 705]
Core was generated by `/root/client/my_program'.
Program terminated with signal 6, Aborted.
#0  0x001c44d4 in raise ()
(gdb) bt
#0  0x001c44d4 in raise ()
#1  0x001c47e0 in abort ()
#2  0x001c47e0 in abort ()
#3  0x001c47e0 in abort ()
#4  0x001c47e0 in abort ()
#5  0x001c47e0 in abort ()
#6  0x001c47e0 in abort ()
#7  0x001c47e0 in abort ()
#8  0x001c47e0 in abort ()
#9  0x001c47e0 in abort ()
#10 0x001c47e0 in abort ()
#11 0x001c47e0 in abort ()

而且它还在不停地进行。我试图从堆栈上移动到底部:帧3000或更多,但最终核心转储耗尽了框架,我仍然不明白为什么会发生这种情况。

当我检查其他线程时,那里的一切看起来都很正常。

代码语言:javascript
运行
复制
(gdb) info threads
  Id   Target Id         Frame 
  6    LWP 705           0x00132f04 in nanosleep ()
  5    LWP 704           0x001e7a70 in select ()
  4    LWP 703           0x00132f04 in nanosleep ()
  3    LWP 702           0x00132318 in sem_wait ()
  2    LWP 700           0x00132f04 in nanosleep ()
* 1    LWP 706           0x001c44d4 in raise ()
(gdb) thread 5
[Switching to thread 5 (LWP 704)]
#0  0x001e7a70 in select ()
(gdb) bt
#0  0x001e7a70 in select ()
#1  0x00057ad4 in CSerialPort::read (this=0xbea7d98c, string_buffer=..., delimiter=..., timeout_ms=1000) at CSerialPort.cpp:202
#2  0x00070de4 in CScanner::readResponse (this=0xbea7d4cc, resp_recv=..., timeout=1000, delim=...) at PidScanner.cpp:657
#3  0x00071198 in CScanner::sendExpect (this=0xbea7d4cc, cmd=..., exp_str=..., rcv_str=..., timeout=1000) at PidScanner.cpp:604
#4  0x00071d48 in CScanner::pollPid (this=0xbea7d4cc, mode=1, pid=12, pid_str=...) at PidScanner.cpp:525
#5  0x00072ce0 in CScanner::poll1 (this=0xbea7d4cc) 
#6  0x00074c78 in CScanner::Poll (this=0xbea7d4cc) 
#7  0x00089edc in CThread5::Thread5Poll (this=0xbea7d360) 
#8  0x0008c140 in CThread5::run (this=0xbea7d360) 
#9  0x00088698 in CThread::threadFunc (p=0xbea7d360) 
#10 0x0012e6a0 in start_thread ()
#11 0x001e90e8 in clone ()
#12 0x001e90e8 in clone ()
Backtrace stopped: previous frame identical to this frame (corrupt stack?)

(类和函数名有点模糊,因为我将它们更改为-:)因此,线程#1是堆栈损坏的地方,其他(2-6)显示的回溯显示

代码语言:javascript
运行
复制
Backtrace stopped: previous frame identical to this frame (corrupt stack?).

之所以发生这种情况是因为线程2-6是在线程#1中创建的。

问题是,我不能在gdb中运行这个程序,因为它运行在嵌入式系统上。我不能使用远程gdb服务器。唯一的选择是检查不经常发生的核心转储。

你能告诉我一些能让我在这件事上向前迈进的东西吗?(也许我可以从核心转储中提取其他东西,或者在代码中做一些钩子来捕获abort()调用)。

更新:巴希尔·斯金克维奇建议使用Valgrind,但结果证明它仅用于ARMv7。我有ARM 926,它是ARMv5,所以这对我不起作用。但是,有一些工作可以编译为ARMv5:ARMv5tel的值研交叉编译在ARM9上的精研

更新2:无法使电气围栏与我的程序工作。该程序使用C++和线程。当我启动一个线程并尝试做一些或多或少复杂的事情(例如,将一个值放入一个STL向量)之后,2.1.13就会崩溃在任意的位置。我看到人们在网上提到了一些补丁,但没有时间去尝试。我在我的Linux上,而不是在ARM上尝试过这一点,其他一些工具,比如val差业或Dmalloc,都不报告代码有任何问题。因此,使用Version2.1.13版本的每个人都准备好使用p线程(或者可能是p线程+ C++ + STL,不知道)。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-03-02 00:48:26

我对“无限”中止的猜测是,无论是abort()导致一个循环(例如,中止->信号处理程序-> abort -> .),还是gdb不能正确解释堆栈上的帧。

在这两种情况下,我建议手动检查问题线程的堆栈。如果中止会导致循环,那么您应该会看到一个模式,或者至少每隔一次都会看到中止的返回地址。也许您可以通过手动跳过(重复)堆栈的大部分来更容易地找到问题的根源。

否则,您将发现没有重复模式,并且希望堆栈上某个地方有失败函数的返回地址。在最坏的情况下,这些地址由于缓冲区溢出或类似的原因而被覆盖,但是也许这样的话,您仍然可以幸运地识别被覆盖的地址。

票数 3
EN

Stack Overflow用户

发布于 2012-03-02 01:09:52

这里的一种可能是,线程中的某些东西非常非常严重地破坏了堆栈,因为它覆盖了堆栈上的数据结构,破坏了进程中堆栈上所有需要的数据。这使得死后调试非常不愉快。

如果您可以随意地重现这个问题,那么正确的做法是在gdb下运行线程,并在堆栈被核弹时准确地观察正在发生的事情。反过来,这可能需要进行某种仔细的搜索,以确定错误究竟发生在哪里。

如果您不能随意地重现这个问题,我建议的最好方法是在线程本地存储中为该线程仔细寻找线索,看看它是否暗示了线程在死前执行的位置。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9456194

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档