Как отладить segfault в realloc ()? - PullRequest
0 голосов
/ 14 ноября 2011

Я в растерянности. Вот что происходит в GDB:

571             void *aux = realloc(cs->body, new_size);
(gdb) p cs->body
$6 = 0x627b20 "POST /upload HTTP/1.1\r\nUser-Agent: curl/7.22.0 (x86_64-unknown-linux-gnu) libcurl/7.22.0 OpenSSL/1.0.0e zlib/1.2.5 c-ares/1.7.5 libidn/1.22 libssh2/1.2.9\r\nHost: localhost:2001\r\nAccept: */*\r\nContent-Le"...
(gdb) n
*** glibc detected *** /home/pc/bin/main: realloc(): invalid pointer: 0x0000000000627b20 ***

... далеко за картой обратной трассировки и памяти (которую я не знаю, как интерпретировать):

Program received signal SIGABRT, Aborted.
0x00007ffff7660d95 in raise () from /lib64/libc.so.6

Как это возможно? Я напечатал cs->body прямо перед вызовом realloc, и это выглядит нормально, верно? Как это может быть неверный указатель, но все равно содержать символы просто отлично? Как я могу отладить этот segfault?

Ответы [ 2 ]

3 голосов
/ 14 ноября 2011

Разыменование недействительных указателей вызывает неопределенное поведение , что означает, что может произойти все, включая поведение, которое вы наблюдаете. Если бы мне пришлось угадывать, я бы сказал, что либо:

  • Ваш указатель действительно недействителен (он не был получен из malloc, или вы уже free d его, или вы случайно изменили его.
  • вы где-то переполнили буфер и удалили скрытые метаданные malloc.

Я бы предложил запустить ваше приложение в чем-то вроде Valgrind, которое разработано, чтобы помочь отследить проблемы с памятью.

1 голос
/ 14 ноября 2011

Есть несколько возможностей:

  • Память действительна, но не получена через malloc или realloc (строковый литерал, глобальная, статическая, автоматическая память, память, полученная через mmap () или через shm *)
  • память была получена с помощью malloc, но указатель не является точным указателем на начало объекта (тот, который вы получили от malloc (). Возможно, вы пропустили начальный белый цвет, или ваш указатель указывает на структуру или 2D массив и т. д.
  • вы повредили память, используя неверное смещение или указатель в любом месте программы

В вашем случае выбор между опциями (1,2) и 3 выше очень прост: вы можете визуально проверить, как указатель "cs-> body" получил свое значение. Если он действительно был получен через malloc et.al, открыт только вариант 3. Без использования valgrind единственный способ найти ложные перезаписи - это (временно) откатить последние изменения в источнике.

...