Возможно, вы перезаписываете стек или кучу.
Вы можете попробовать добавить флаг -fstack-protector-all
в свой Параметры командной строки GCC для запроса встроенных в программу отчетов о разбиении стека. Это может привести к более раннему выходу из строя.
Другая возможность - посмотреть адрес, указанный в dmesg
выводе, и посмотреть, не можете ли вы отследить функцию / память, которая была разбита:
[68303.941351] broken[13301]: segfault at 7f0061616161 ip 000000000040053d sp 00007fffd4ad3980 error 4 in broken[400000+1000]
readelf -s
сбросит таблицу символов, мы можем найти функцию, которая вызывает проблему:
$ readelf -s broken | grep 4005
40: 00000000004005e0 0 FUNC LOCAL DEFAULT 13 __do_global_ctors_aux
47: 0000000000400540 2 FUNC GLOBAL DEFAULT 13 __libc_csu_fini
57: 0000000000400550 137 FUNC GLOBAL DEFAULT 13 __libc_csu_init
63: 0000000000400515 42 FUNC GLOBAL DEFAULT 13 main
Процедура main
выполняется, когда используется неверный указатель:
#include <string.h>
void f(const char *s) {
char buf[4];
strcpy(buf, s);
return;
}
int main(int argc, char* argv[]) {
f("aaaa");
f("aaaaaaaaaaaaaaaaaaaa");
return 0;
}
Когда main
пытается вернуться в библиотеку C для выхода, он использует неверный указатель, хранящийся в кадре стека. Итак, посмотрите на функции, вызываемые main
, и (в этом тривиальном случае это довольно просто) f
, очевидно, тот жук, который нацарапал весь фрейм стека.
Если вы перезаписываете кучу, возможно, вам стоит попробовать электрический забор. Минусы довольно крутые (большое использование памяти), но это может быть именно то, что вам нужно, чтобы найти проблему.
person
sarnold
schedule
21.02.2011