gpt4 book ai didi

c++ - c++ 程序核心转储的回溯中的无限中止()

转载 作者:IT王子 更新时间:2023-10-29 00:07:34 24 4
gpt4 key购买 nike

我有一个奇怪的问题,我无法解决。请帮忙!

该程序是一个在 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 帧 或更多,但最终核心转储用完了帧,我仍然不明白为什么会这样。 p>

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

(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) 的回溯显示

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

这是因为线程 2-6 是在线程 #1 中创建的。

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

能否请您提出一些可以插入我前进的建议? (也许我可以从核心转储中提取其他东西,或者以某种方式在代码中创建一些 Hook 以捕获 abort() 调用)。

更新:Basile Starynkevitch建议使用 Valgrind,但事实证明它仅适用于 ARMv7。我有 ARM 926,它是 ARMv5,所以这对我不起作用。虽然有一些努力为 ARMv5 编译 valgrind:Valgrind cross compilation for ARMv5tel , valgrind on the ARM9

更新 2:无法让 Electric Fence 与我的程序一起工作。该程序使用 C++ 和 pthreads。我得到的 Efence 版本,2.1.13在我启动一个线程并尝试做一些或多或少复杂的事情(例如将一个值放入 STL vector 中)后,在任意位置崩溃。我在网上看到有人提到 Efence 的一些补丁,但没有时间去尝试。我在我的 Linux PC 上试过这个,而不是在 ARM 上,其他工具如 valgrind 或 Dmalloc 没有报告任何代码问题。因此,使用 efence 2.1.13 版的每个人都准备好遇到 pthreads 问题(或者可能是 pthread + C++ + STL,不知道)。

最佳答案

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

无论哪种情况,我都建议手动检查有问题线程的堆栈。如果中止导致循环,您应该看到一个模式或至少中止的返回地址每隔一段时间重复一次。也许您可以通过手动跳过大部分(重复)堆栈来更轻松地找到问题的根源。

否则,您应该会发现没有重复模式,而且很有可能是失败函数的返回地址在堆栈中的某处。在最坏的情况下,此类地址会由于缓冲区溢出等原因而被覆盖,但也许您仍然可以幸运地识别它被覆盖的内容。

关于c++ - c++ 程序核心转储的回溯中的无限中止(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9456194/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com