gdb错误:回溯停止:上一帧与此帧相同(损坏的堆栈?)

时间:2018-10-25 12:35:37

标签: c++ linux multithreading gdb

我在调试ARMv7目标上的多线程C ++应用程序时遇到问题。该问题出现在两个不同的ARM目标上,我为它们使用了不同的工具链:

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

我检查了一些线程,但是(由于简约的多线程程序存在相同的问题) *没有损坏的堆栈 *虚拟函数或函数指针的任何问题

大多数情况下,我使用的是目标 Toradex Colibri iMX6 ,该目标上运行的是 Angstrom Linux 2016.12

问题

  • 我的程序构建方式有问题吗?
  • 有……。我使用gdbserver / gdb的方式有问题吗?
  • 我必须修复调试器输出的哪些选项?

我通过目标上的gdbserver和主机上的工具链的arm-linux-gnueabihf-gdb进行调试。 任何目标都没有本地gdb。 我可以为 Linux x86 构建应用程序,但是到目前为止,仍无法在PC上重现该错误。

软件问题

似乎有两个线程被卡住了,可能是由于两个互斥锁的死锁,或者是试图第二次获取一个互斥锁的线程 (尽管这似乎不太可能,但在将互斥锁配置为递归后,该错误就会出现;我必须检查该线程中使用的第二个互斥锁。)

所有其他线程似乎都能正常运行。

软件构建和调试配置

构建设置:

我使用的是Toradex提供的工具链,其中包含arm-linux-gnueabihf-g++

-std=c++11 -Wall -Werror -Wextra -Wno-unused-result -Winit-self -Wmissing-include-dirs -Wpointer-arith -Wno-format-security -Wno-implicit-fallthrough -Wl,-Map=output.map -ggdb -g3 -fno-inline -O0

我将同一程序传递给调试器(即传递给目标上的gdbserver和主机上的arm-linux-gnueabihf-gdb

$ (gdb) set sysroot </path/to/libs>
$ (gdb) file <binary>
$ (gdb) target remote IP:port

共享库:

对于共享库,我已经将/usr/lib/lib从目标复制到了主机。然后,我下载了可用于目标/发行版的调试库,并用这些库替换了原始的共享库。

(gdb) info sharedlibrary
From        To          Syms Read   Shared Object Library
0x76fcf800  0x76feaa70  Yes         /path/to/libs/lib/ld-linux-armhf.so.3
0x76fb9700  0x76fbcd2c  Yes         /path/to/libs/lib/librt.so.1
0x76f940c0  0x76fa2e0c  Yes         /path/to/libs/lib/libpthread.so.0
0x76f01630  0x76f72a10  Yes (*)     /path/to/libs/usr/lib/libstdc++.so.6
0x76e14d38  0x76e48028  Yes         /path/to/libs/lib/libm.so.6
0x76e041b0  0x76e0e7ec  Yes         /path/to/libs/lib/libgcc_s.so.1
0x76cd1000  0x76dc2b10  Yes         /path/to/libs/lib/libc.so.6
0x7449c96c  0x744a29e4  Yes         /path/to/libs/lib/libnss_files.so.2
(*): Shared library is missing debugging information.

我找不到libstdc++.so.6的调试库。

调试结果

调试简单的单线程应用程序并导致目标崩溃:

  • 有效,即不会从上方报告错误消息

在目标上调试带有或不带有死锁的简单多线程应用程序:

(gdb) bt
#0  0x76d6cd44 in uname () at ../sysdeps/unix/syscall-template.S:84
#1  0x00000000 in ?? ()
Backtrace stopped: previous frame identical to this frame (corrupt stack?)

在Linux-x86上调试相同的简单多线程应用程序(带有或不带有死锁):

  • 有效

在PC上调试错误的应用程序:

  • 似乎可以正常工作,但到目前为止我们仍无法再现该错误

在目标上调试受影响的应用程序:

Thread 1 received signal SIGINT, Interrupt.
0x76f9facc in __lll_robust_lock_wait (futex=0x257b94 <namespace1::function()::su_place+20>, private=0)
at /usr/src/debug/glibc/2.24-r0/git/nptl/lowlevelrobustlock.c:46
46    /usr/src/debug/glibc/2.24-r0/git/nptl/lowlevelrobustlock.c: No such file or directory.
(gdb) thread apply all bt

Thread 6 (Thread 6606.6630):
#0  0x76d832c8 in __setreuid (ruid=8, euid=0)
at /usr/src/debug/glibc/2.24-r0/git/sysdeps/unix/sysv/linux/i386/setreuid.c:29
#1  0x7efff06c in ?? ()
Backtrace stopped: previous frame identical to this frame (corrupt stack?)

Thread 5 (Thread 6606.6629):
#0  0x76d55d44 in uname () at ../sysdeps/unix/syscall-template.S:84
#1  0x00000000 in ?? ()
Backtrace stopped: previous frame identical to this frame (corrupt stack?)

Thread 4 (Thread 6606.6628):
#0  0x76d55d44 in uname () at ../sysdeps/unix/syscall-template.S:84
#1  0x00000000 in ?? ()
Backtrace stopped: previous frame identical to this frame (corrupt stack?)

Thread 3 (Thread 6606.6627):
#0  0x76d55d44 in uname () at ../sysdeps/unix/syscall-template.S:84
#1  0x00000000 in ?? ()
Backtrace stopped: previous frame identical to this frame (corrupt stack?)

Thread 2 (Thread 6606.6626):
#0  __lll_robust_lock_wait (
futex=0x25b950 <namespace_2::a_function()::a_static_member+152>, private=128)
at /usr/src/debug/glibc/2.24-r0/git/nptl/lowlevelrobustlock.c:31
#1  0x00000080 in ?? ()
Backtrace stopped: previous frame identical to this frame (corrupt stack?)

Thread 1 (Thread 6606.6606):
#0  0x76f9facc in __lll_robust_lock_wait (futex=0x257b94 <namespace1::function()::su_place+20>, 
private=0) at /usr/src/debug/glibc/2.24-r0/git/nptl/lowlevelrobustlock.c:46
#1  0x00000002 in ?? ()
Backtrace stopped: previous frame identical to this frame (corrupt stack?)

更新

我可以使用valgrind和SW的PC版本来发现错误(互斥锁)。

但是,这里的问题是关于gdb的问题,我还无法理解或解决。

1 个答案:

答案 0 :(得分:1)

  

然后我下载了可用于目标/发行版的调试库,并用这些库替换了原始共享库。

这可能是错误的操作(取决于“调试库”的确切含义),并且可能助长了您的问题。参见this answer

第一步,我将使用与目标服务器相同的 exact 库,并检查是否会更改GDB的行为。