Возможно, вы перезаписываете стек или перезаписываете кучу.
Вы можете попробовать добавить флаг -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
- это, очевидно, баггер, нацарапанный по всему кадру стека.
Если вы перезаписываете кучу, то, возможно, вы можете попробовать электрический забор . Недостатки довольно крутые (обширное использование памяти), но это может быть как раз то, что вам нужно, чтобы найти проблему.