在将调试语句重定向到stderr时出现了奇怪的情况

Strange situation while redirecting debug statements to stderr

本文关键字:情况 调试 语句 重定向 stderr      更新时间:2023-10-16

我被困在一个情况。我正在研究嵌入式设备(基于linux操作系统和ARM处理器,32位)。它是一种触摸屏设备,有许多外围设备,如智能卡读卡器,GPS, GPRS。我在C编码和我的应用程序崩溃后一段时间,当我重定向我的调试语句如下所示。我有大约300个调试打印语句,我使用这个函数像宏一样打印。设备也可以通过USB线连接到系统终端。当我在系统终端中打印这些调试语句时,应用程序不会在任何地方崩溃,但是当我不使用计算机终端并在设备中运行应用程序时,它会在一段时间后崩溃:

#ifdef DEBUG_TEST
  #define DEBUG_TEST 1
  #else
  #define DEBUG_TEST 0
  #endif
  #define DEBUG_PRINT(fmt, ...) 
             do { if (DEBUG_TEST) fprintf(stderr, fmt, ##__VA_ARGS__); } while (0)

但是当我关闭这些调试语句时,应用程序不会在任何地方崩溃。我不明白为什么会这样。
根据我的猜测,由于设备没有自己的标准终端,因此打印这些调试消息正在创建一个缓冲区,由于它在一段时间后崩溃,而另一方面,当我关闭调试语句时,它工作得很好。请说明为什么会发生这种情况?

也许你的DEBUG_PRINT调用的一个参数导致fprintf的字符串插值器例程引用无效内存?例如,在你的代码中,像这样的代码会使你的应用程序在fprintf():

中崩溃。
const char * badPointer = (const char *) 0xDEADBEEF;  // deliberately pointing to invalid memory
DEBUG_PRINT("Crashing now!  %sn", badPointer);

…要么是这样,要么是系统的studio或USB实现中存在导致崩溃的错误。

为了缩小范围,您可以尝试注释掉各种DEBUG_PRINT语句,直到崩溃消失(此时您可以合理地怀疑是现在被注释掉的DEBUG_PRINT语句之一导致了崩溃,并重新注释一些,直到找出罪魁祸首是谁)……或者,如果您怀疑fprintf()中有bug,您可以执行如下的酷刑测试:

while(1) DEBUG_PRINT("I think I %s!n", "can");

…然后看看运行它是否会给您预期的输出(字符串的无限输出)或崩溃。如果它崩溃了,那就说明程序之外有bug。

您是在更改这些语句,还是从调试到发布版本?从调试版本切换到发布版本会改变诸如优化和内存填充之类的事情,所以你的崩溃可能发生在非调试中,因为这些。

如果你所改变的只是调试跟踪开关,我建议你非常仔细地检查你所有的格式参数(%s, %d等),并确保你没有传递一个错误类型的变量

如何在没有控制终端的情况下运行应用程序?您可以尝试以下操作:

在终端连接的情况下运行应用程序,但是stderr重定向

./yourapp 2>/dev/null

./yourapp 2>somefile.log

,看看它是否仍然崩溃。如果你想转储一个核心文件,不要忘记执行ulimit -c unlimited。

如果您有一个基于busybox的用户空间,您可以尝试在循环缓冲区模式下使用syslogd,并通过调用syslog来替换fprintf(stderr,…),并查看它是否仍然崩溃。

相关文章: