повреждение стека в coredump?GCC / с - PullRequest
2 голосов
/ 21 февраля 2011

Я замечаю странную проблему, когда пытаюсь использовать обработчик сигналов для выгрузки глобальных данных в текстовый файл и генерации файла ядра. Я ожидаю, что данные, выгруженные в файл, будут такими же, как и в основном файле (это те же глобальные данные)

в заголовочном файле 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 и выдаю сигнал ABRT (сигнал, которым я обрабатываю) через kill. В 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 буфер [0]

$ 2 "c0 - idx = 54 \ n", '\ 0', "main: 20 0x7ef9524"

буфер смещен на 1110 байт. Я использовал GDB, чтобы проверить, не поврежден ли буфер. Извините за путаницу.

1 Ответ

1 голос
/ 22 февраля 2011

Пожалуйста, предоставьте отдельный пример.Я могу объяснить другой адрес, когда ядро ​​создается извне 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...