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

时间:2012-01-02 19:11:40

标签: c++ c linux embedded

我陷入了困境。我正在研究嵌入式设备(基于Linux OS和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)

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

3 个答案:

答案 0 :(得分:3)

也许你的一个DEBUG_PRINT调用的一个参数是导致fprintf的string-interpolator例程引用无效的内存?例如,代码中的类似内容会使您的应用程序在fprintf()中崩溃:

const char * badPointer = (const char *) 0xDEADBEEF;  // deliberately pointing to invalid memory
DEBUG_PRINT("Crashing now!  %s\n", badPointer);

...或者是,或者系统的stdio或USB实现中可能存在导致崩溃的错误。

为了缩小范围,您可以尝试注释掉各种DEBUG_PRINT语句,直到崩溃消失(此时您可以合理地怀疑它是导致崩溃的现已注释掉的DEBUG_PRINT语句之一,并且评论一些,直到你弄清楚谁是罪魁祸首)...或者如果你怀疑fprintf()中有一个错误,你可以做这样的折磨测试:

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

...并查看是否正在运行,为您提供预期的输出(字符串的无限输出)或崩溃。如果它崩溃,那么这表明你的程序之外的错误。

答案 1 :(得分:1)

您唯一要更改这些语句,还是从调试到发布版本?从调试到发布版本的切换将改变优化和内存填充等内容,因此可能因为这些而导致崩溃发生在非调试中。

如果您要更改的是打开和关闭调试跟踪,我建议您仔细检查所有格式参数(%s,%d等),并确保您没有将变量作为错误类型传递

答案 2 :(得分:0)

如果没有控制终端,您如何运行应用程序? 您可以尝试以下方法:

使用已连接的终端运行您的应用程序,但stderr已重定向

./yourapp 2>/dev/null

./yourapp 2>somefile.log

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

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