嵌入式Linux的轻量级调试

5
我正在开发一个运行在小型 Linux 嵌入式设备上的应用程序(约32MB RAM)。不幸的是,我的应用程序最近变得太大了,无法在 GDB 下运行。有没有人知道任何好的、轻量级的调试方法,可以在嵌入式 Linux 中使用?即使能够查看线程的堆栈跟踪,也会非常有帮助。需要注意的是,这个应用程序是用 C++ 编写的,并且运行多个线程,所以 gdbserver 不适用于多线程应用程序。谢谢提前!Maha

1
你确定gdbserver对于多线程应用程序无效吗?这个页面表明它是有效的:http://www.kegel.com/linux/gdbserver.html。 - Brooks Moses
5个回答

4
绝对可以与多线程应用程序一起使用,我现在正在从事一个嵌入式项目,其中有 25 多个线程,我们一直在使用 gdbserver。
info threads 

列出系统中的所有线程。
thread <thread number from info threads>  

切换到该执行线程。

thread apply XXX <command>  

运行在由XXX指定的线程上,也可以是“all”。因此,如果您想要所有正在运行的线程的回溯,请执行以下操作:

thread apply all bt

一旦您进入给定线程的执行流程中,所有典型的命令都会像在单线程进程中一样工作。


你必须使用特殊参数运行gdb/gdbserver吗?我正在ARM处理器上运行。当我运行'gdbserver localhost:12345 myapp',然后在主机上运行相同版本的gdb并输入命令'target remote 10.0.150.92:12345'时,调试器会混淆,因为它认为只有一个线程在运行(每次上下文切换都会中断,并且'info threads'报告只有1个运行线程)。 - Jason Machacek
我在调试时不需要使用特殊参数,我们的项目也在ARM上。我的远程调试过程听起来和你的一样。目标端:gdbserver localhost:10000 myapp 主机端:arm_v5t-le-gdb myapp 主机端gdb命令行:target remote <target ip>:<port> 你所说的相同版本的gdb是指ARM构建版本,对吗? 你的应用程序是否会在上下文切换期间收到诸如SIGUSR1/2之类的信号?这将导致调试器停止。 目标端和主机端的应用程序都必须使用调试符号进行构建,我们通过NFS挂载主机来实现。 - asm
我的主机是x86系统,目标系统运行ARM处理器。你的主机也是ARM系统吗?如果不是,那么可能我在GDB构建中漏掉了一些东西(我为ARM构建了GDB 7.0,然后单独为x86构建)。我的应用程序绝对没有生成SIGUSR1/2 - 我已经验证它在上下文切换时中断,因为调试器认为只有一个线程在运行。 - Jason Machacek
我的主机也是x86。您需要像您所做的那样构建gdbserver作为arm-linux应用程序,但是您不能在主机上使用普通的gdb构建来远程调试应用程序。主机端必须构建为在x86上运行但加载和调试ARM二进制文件的混合应用程序。老实说,我不确定完整的构建过程是什么,我们公司从Montavista购买了我们的工具链。通过谷歌搜索,我发现http://www.gnuarm.com/home.html可能有您要寻找的预编译二进制文件,但我现在无法下载它。 - asm
谢谢你的帮助。我会尝试使用主机-目标调试功能构建GDB - 我已经尝试了一些configure选项,但是还没有得到可用的配置。当我成功后,我会发布我的配置选项。 - Jason Machacek
也许从http://www.codesourcery.com/sgpp/lite/arm提供的预建版本值得一试——即使您没有使用其中的编译器,我非常确定其中的GDB也可以正常工作。(声明:我在这家公司工作。) - Brooks Moses

2

我听说有人使用模拟器(例如QEMU)运行应用程序,然后在其中运行GDB(或类似valgrind的工具)进行调试。虽然听起来很痛苦,但如果能够成功....

您可以尝试使用libunwind(获取堆栈跟踪信息)和printf风格的日志记录,是否能够解决问题呢?


感谢指点。我看了一下在模拟器上运行的方式,但那绝对是一种痛苦的方式,可能需要耗费更多的时间而我无法承受。目前我正在使用printf式日志记录,但这是一个相当复杂的应用程序,有时候很难确定具体是哪个组件首先引起了问题。Libunwind 明显看起来是一个有用的工具,我将尝试使用它。 - Jason Machacek

1

串口打印是我能想到的最轻量级的方式~~~ 在主机PC上很容易看到,并且应用程序内部的代码也非常简单和轻巧~~

如果您没有串口,我们曾经使用GPIO端口并模拟了一个串口。它完美地工作,但速度有点慢 :-( ~~~


0

你为什么要自己构建调试器呢?我正在开发一个使用ARM处理器(AT91SAM926x)的Linux系统,我们正在使用CodeSourcery提供的编译器和调试器。我认为他们还没有发布带有GDB 7版本的工具,但是我正在使用gdbserver工具调试多线程C++应用程序,而且没有遇到任何问题。


我们正在使用由我们的SBC制造商提供的工具链。不幸的是,他们没有提供预构建的GDB,所以我只能自己动手了。 - Jason Machacek
2
你可以尝试构建旧版本的GDB。GDB 7非常新,我读到了一些关于主要错误的报告(虽然不是与ARM相关)。我们正在运行6.7版本。 - Anders Holmberg

0

Gdbserver确实可以与多线程应用程序一起使用。但是,您需要为您的主机编译一个交叉目标调试器,以便将其与目标gdb配合使用。

请参阅本文,了解如何详细描述:

使用GDB和GDBserver进行远程交叉目标调试


谢谢提供链接。我按照那里的说明操作了,但是它们对我没有用。试图使用他的方法构建arm-native二进制文件失败了——make命令停止运行,并抱怨C编译器无法生成可执行文件。我不知道为什么会这样,因为GDB的构建过程通常足够聪明,不会在交叉编译时测试它生成的可执行文件。 - Jason Machacek

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接