当我尝试使用信号处理程序将全局数据转储到文本文件并生成核心文件时,我注意到一个奇怪的问题。我希望转储到文件的数据与核心文件中存在的数据相同(它是相同的全局数据)
在头文件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);
in 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中运行时,问题不在于,问题是在生成的核心文件中,
gdb)p buffer [0]
$ 2“c0 - idx = 54 \ n”,'\ 0',“main:20 0x7ef9524”
缓冲区偏移1110个字节。我曾使用GDB来检查缓冲区是否已损坏。对此感到抱歉。
答案 0 :(得分:1)
请提供一个独立的示例。当核心是从外部GDB生成时,我可以解释不同的地址,但不是从GDB内部生成核心时。
以下是我看到的内容:
$ cat foo.c
#include <stdio.h>
#include <stdlib.h>
char buf[100][80];
int main()
{
sprintf(buf[0], "hello");
sprintf(buf[1], "hello again");
abort();
}
$ gcc -g foo.c -fPIC -pie # PIE executable so its address can be randomized
$ gdb -q a.out
Reading symbols from /tmp/a.out...done.
(gdb) r
Program received signal SIGABRT, Aborted.
0x00007ffff7a8ca75 in raise () at ../nptl/sysdeps/unix/sysv/linux/raise.c:64
(gdb) p &buf[0]
$1 = (char (*)[80]) 0x7ffff81ff060
(gdb) sig SIGABRT
Program terminated with signal SIGABRT, Aborted.
The program no longer exists.
(gdb) q
$ gdb -q a.out core
Reading symbols from /tmp/a.out...done.
[New Thread 20440]
Core was generated by `/tmp/a.out'.
Program terminated with signal 6, Aborted.
#0 0x00007ffff7a8ca75 in raise () at ../nptl/sysdeps/unix/sysv/linux/raise.c:64
(gdb) p &buf[0]
$1 = (char (*)[80]) 0x7ffff81ff060 # same address as before
(gdb) q
$ ./a.out
Aborted (core dumped)
$ gdb -q a.out core
Reading symbols from /tmp/a.out...done.
[New Thread 20448]
Core was generated by `./a.out'.
Program terminated with signal 6, Aborted.
#0 0x00007fef9dcb5a75 in raise () at ../nptl/sysdeps/unix/sysv/linux/raise.c:64
(gdb) p &buf[0]
$1 = (char (*)[80]) 0x7fef9e428060 # different address due to ASLR