Как найти место переполнения буфера и повреждения памяти? - PullRequest
6 голосов
/ 21 февраля 2011

valgrind не может найти ничего полезного. Я в замешательстве.

Symptomes:

  1. мои данные повреждены вызовом malloc ()
  2. адрес возврата моей функции заменен на что-то неправильное

PS: код НЕ работает по умолчанию

В настоящее время у меня есть некоторый прогресс в замене всех моих malloc () на mmap() + mprotect()

Ответы [ 6 ]

7 голосов
/ 21 февраля 2011

Возможно, вы перезаписываете стек или перезаписываете кучу.

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

Если вы перезаписываете кучу, то, возможно, вы можете попробовать электрический забор . Недостатки довольно крутые (обширное использование памяти), но это может быть как раз то, что вам нужно, чтобы найти проблему.

2 голосов
/ 21 февраля 2011

Вы также можете попробовать пробную версию IBM Rational Purify - довольно хорошего инструмента для обнаружения переполнения буфера, утечек памяти и любых других ошибок повреждения памяти.Перейдите по этой ссылке, чтобы загрузить http://www -01.ibm.com / программное обеспечение / awdtools / Очистить / Unix /

2 голосов
/ 21 февраля 2011

Valgrind memcheck не очень хорош в обнаружении переполнения буфера. Но вы можете попробовать патч , который может.

2 голосов
/ 21 февраля 2011
  1. Исправить все висячие указатели, все переполнения буфера
  2. Использовать указатели только там, где они действительно необходимы

см. Следующую ссылку :: Какие инструменты C / C ++можно проверить на переполнение буфера?

0 голосов
/ 09 июля 2011

Не могу помочь вам в Linux. Но вы говорите, что не используете строковые функции, что говорит о том, что ваше приложение может быть довольно переносимым. Не получается ли под Windows?

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

0 голосов
/ 21 февраля 2011

В какой среде вы разрабатываете?

Если вы разрабатываете в Windows, попробуйте эту статью http://msdn.microsoft.com/en-us/library/cc500347.aspx

...