我发现自己处于必须调试Qt应用程序而几乎没有任何调试工具的困难情况下:应用程序似乎开始使用越来越多的CPU,因为它一次又一次地运行相同的操作;几个小时后,CPU完全饱和。
该应用程序在ARM Linux嵌入式设备上运行,其中gdb似乎不起作用,可能难以发现所提供工具链的问题。 strace似乎只报告计时器活动(这是一个OpenGL应用程序所以这是预期的)。 ltrace不可用,编译它会导致一项艰巨的任务,也许是无用的。我没有编写应用程序,但源代码可用。
在消耗那么多资源时,我还能做些什么来发现应用程序忙于做什么?我必须跟踪应用程序执行的所有方法调用吗?是否还有其他技术可以用来猜测问题或在哪里集中注意力?
编辑:这是gdb:Only question marks in backtrace reported by gdb on ARM的问题之一。即使编写模拟segfault的十行应用程序也会导致这种情况。
答案 0 :(得分:4)
您可以在机器上启用核心转储吗?然后当它正在播放时,您可以发送一个SIGABRT并将核心转储复制到您的开发机器,并使用交叉调试器检查它,并提供源和未提取的可执行文件。
下次学习痛苦的教训也很重要,不要使用这种支持不当的工具链。
如果是一个选项,你可以尝试使用至少gdbserver的另一个工具链,如果不是gdb支持的话。我对CodeSourcery ARM Lite工具链非常满意。
编辑:gdb适用于您的情况有两种:
gdbserver允许您在开发主机上运行cross-gdb并连接到目标以远程调试在其上运行的内容。所以核心转储或gdbserver是两种使用cross-gdb来检查目标上的东西的方法,但是gdbserver本身对你没有多大帮助。
如果您的交叉编译器类似arm-none-linux-gnueabi-gcc
,请查看您的开发主机上是否有arm-none-linux-gnueabi-gdb
。
答案 1 :(得分:3)
您可以尝试在应用程序中放置一些调试代码。
选择一些信号,如SIGINT。为此信号添加信号处理程序。在此处理程序中打印堆栈跟踪或至少指令指针值。然后启动应用程序并多次发送SIGINT以查看应用程序正在执行的操作。
答案 2 :(得分:0)
尝试记录不同功能的执行时间。首先记录最有可能的候选人的执行时间,如果你已经删除它们,继续使用程序中其他不太可能的函数。
记录消息的最简单方法是使用std :: cout(或printf)并将out重定向到文件,以便您可以在以后查看日志。
答案 3 :(得分:0)
您可以尝试运行Zoom探查器的ARM版本 - 这应该告诉您代码在大部分时间内花费的时间 - 您可以在30天的评估许可证上免费下载。
答案 4 :(得分:0)
假设gcc有类似MSVC文件和行宏的东西,它扩展到当前文件和当前行,你可以创建自己的伪剖析功能。把它放在标题中:
void MyPseudoProfileLog(const char* file, int line, int* count);
#define MY_PSEUDO_PROFILE_LOG(file, line) { static int count = 0; MyPseudoProfileLog(file, line, &count); }
这是一个cpp文件(如果你把它放在标题中,你将获得静态变量的多个副本,每个cpp文件一个包含标题):
void MyPseudoProfileLog(const char* file, int line, int* count)
{
static FILE* f = NULL;
const int max_count = 1000;
if (++(*count) == max_count)
{
*count = 0;
if (!f)
f = fopen("/tmp/my_pseudo_profile_log.log");
fprintf(f, "file=\"%s\", line=%d was passed %d times\n", file, line, max_count);
fflush(f);
}
}
然后你可以粘贴
MY_PSEUDO_PROFILE_LOG(__FILE__, __LINE__);
到代码中的各个位置,以查看它们被调用的频率。请记住,这不是线程安全的,因此只能在主线程中使用。