【发布时间】:2011-02-21 19:19:26
【问题描述】:
当我尝试使用信号处理程序将全局数据转储到文本文件并生成核心文件时,我注意到一个奇怪的问题。我希望转储到文件中的数据与核心文件中的数据相同(它是相同的全局数据)
在头文件 foo.h 中
extern char buffer[100][80] ; // Hundred records each of length 80 characters
在 foo.c 中
char buffer[100][80];
.. in a loop ..
snprintf(buffer[i],80,"%s:%d recorded idx = %d\n",__FUNCTION__,__LINE__,i);
在 signal_handler.c 中
.. in a loop ..
fprintf(..dump data to text file..)
数据已经转储到文本文件了。我在 gdb 中运行程序,然后通过 kill 发出 ABRT 信号(我正在处理的信号)。在 gdb 中我看到了
gdb) p &buffer[0]
$3 = (char (*)[80]) 0x1002c8970
我继续并生成核心文件。在核心转储中,我看到了
(gdb) p &buffer[0]
$2 = (char (*)[80]) 0x1002c9a80
两个位置相差1110。
我的问题是为什么我会在核心文件中看到这种差异?任何线索将不胜感激!
谢谢 约翰
编辑澄清一下,问题不在于通过 GDB 生成核心 没有信号处理程序的完整代码来隔离问题。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 100
char buffer[100][80];
int main()
{
int i = 0;
int idx = 0;
FILE *fp = NULL;
fp = fopen("test.txt","w");
if (!fp)
exit(1);
for (i=0; i < 5500; i++) {
snprintf(buffer[idx],80,"%s:%d idx = %d\n",__FUNCTION__, __LINE__, i);
idx = ((idx + 1)% MAX);
}
for (i = 0 ; i < MAX; i++)
fprintf(fp,"%s",buffer[i]);
fclose(fp);
abort();
return 0;
}
问题不是我在GDB中运行的时候,问题是在生成的core文件中,
gdb) p 缓冲区[0]
$2 "c0 - idx = 54\n", '\0' , "main:20 0x7ef9524"
缓冲区偏移了 1110 个字节。我曾使用 GDB 检查缓冲区是否已损坏。很抱歉造成混乱。
【问题讨论】:
-
不是您问题的答案,而是您正在做的事情滥用了信号机制。 POSIX 定义了一长串它认为“不安全”的函数,并且该列表几乎包括所有进行 I/O 的函数。它继续说,如果信号中断了不安全函数的执行并且处理程序调用了不安全函数,则行为未定义。您应该在信号处理程序中做的最多的事情是设置一个标志以指示您的转储到文件操作需要发生然后返回。主程序中的某些东西应该处理它。
-
上面的源码不可编译(缺少MAX)。如果我添加'#define MAX 100',它会产生预期的结果:'(gdb) p buffer[0] $1 = "main:18 idx = 5400\n", '\000'
'。跨度> -
将 gdb 更新到下一个版本似乎可以解决问题。我想知道为什么。