无限中止()在c程序核心转储的后退

前端之家收集整理的这篇文章主要介绍了无限中止()在c程序核心转储的后退前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有一个奇怪的问题,我无法解决.请帮忙!

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

*** glibc detected ** /root/client/my_program: free(): invalid pointer: 0x002a9408 ***

当我打开核心转储我看到主线程似乎有一个损坏的堆栈:我可以看到的是无限的abort()调用.

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或更多,但最终核心转储运行超出框架,我仍然看不到为什么发生这种情况.

当我检查其他线程时,一切似乎都是正常的.

(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?)

(类和函数名称有点wierd,因为我改变了他们:)
所以,线程#1是堆栈被破坏的地方,每隔一个(2-6)显示回溯

Backtrace stopped: prevIoUs frame identical to this frame (corrupt stack?).

它发生,因为线程2-6在线程#1中创建.

事实是,我无法在gdb中运行程序,因为它在嵌入式系统上运行.我不能使用远程gdb服务器.唯一的选择是检查不常发生的核心转储.

你能提出一些可以让我前进的东西吗? (也许我可以从核心转储中提取某些东西,或者以某种方式使代码中的一些钩子捕获abort()调用).

更新:Basile Starynkevitch建议使用Valgrind,但事实证明它只是为ARMv7移植.我有ARM 926是ARMv5,所以这对我来说不行.有一些努力来编译valgrind for ARMv5虽然:Valgrind cross compilation for ARMv5tel,valgrind on the ARM9

更新2:无法使电篱笆与我的程序一起工作.该程序使用C和pthreads.我得到的Efence版本,2.1.13在我开始一个线程之后,在任意的地方坠毁,尝试做一些或多或少的复杂(例如把一个值放入STL向量).我看到人们在网络上提到了Efence的一些补丁,但没有时间去尝试.我在我的Linux PC上尝试过,而不是在ARM上,而像valgrind或者Dmalloc这样的其他工具也没有报告代码的任何问题.所以,所有使用版本2.1.13的efence的人都准备好与pthreads有问题(或者可能是pthread C STL,不知道).

解决方法

我对“无限”中止的猜测是,abort()导致循环(例如中止 – >信号处理程序 – > abort – > …),或者gdb无法正确解释堆栈上的帧.

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

否则,你应该发现没有重复的模式,希望在堆栈上的某个地方的失败函数的返回地址.在最坏的情况下,由于缓冲区溢出等原因,这些地址会被覆盖,但是也许您仍然可以幸运地识别出被覆盖的内容.

原文链接:https://www.f2er.com/c/114363.html

猜你在找的C&C++相关文章