Как мне найти проблему переполнения стека в Linux? - PullRequest
2 голосов
/ 10 февраля 2010

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

Но когда я добавляю оператор печати после сбойной строки, приложение работает нормально. Если я удаляю оператор печати (простой cout << «напечатать что-то» << endl; оператор), приложение падает на </p>

0x00007f48f2027276 in free () from /lib64/libc.so.6

Я попытался добавить следующий массив char вместо оператора print, и это также остановило сбой, затем я попытался распечатать содержимое массива char:

char ben[8000] = {0};
memset(&ben, 0, sizeof (ben));

for (int y = 0; y < 8000; ++y)
{
if (ben[y] != 0)
  PRINT ("CHAR[%d]=%d", y, ben[y]);
}

чтобы увидеть, не повреждено ли что-либо в массиве, но этот подход не сработал. Поэтому мне было интересно, есть ли лучшие способы определить, является ли это проблемой переполнения стека?

Я перекомпилировал приложение с -fstack-protector-all (как lib, так и моим кодом), и это ничего не дало. Я также попробовал valgrind, и он не дал мне ничего подозрительного.

Похоже, что происходит сбой, потому что я пытаюсь освободить недопустимый указатель, но я понятия не имею, почему указатель недопустим, поскольку он освобождает локальную переменную (т.е. когда он выходит из области видимости). Указатель повреждается по какой-то причине, но это немного похоже на поиск иголки в стоге сена. Есть ли хорошие методы, чтобы попытаться сойтись на этом типе проблемы? Большое спасибо!

Ответы [ 5 ]

5 голосов
/ 10 февраля 2010

При компиляции с -fstack-protector-all программа сообщит вам, был ли разбит стек.

2 голосов
/ 10 февраля 2010

Вы должны попробовать инструмент Memcheck valgrind . Это отладчик памяти, который сообщит вам, если вам не нужен доступ к памяти (случай переполнения стека, двойное освобождение, доступ к свободным указателям, переполнение массива, ...)

0 голосов
/ 10 февраля 2010

Это очень подозрительная строка, я думаю, это должно было быть

memset(&ben, 0, sizeof(ben) - 1);

У вас есть memset, чтобы перейти на один массив ...

Надеюсь, это поможет, С наилучшими пожеланиями, Том.

0 голосов
/ 10 февраля 2010

Если memcheck / valgrind ничего не включает, вы всегда можете запустить gdb и посмотреть на сборку.

Некоторые другие вещи, которые нужно проверить, - это неинициализированные переменные, которые, как известно, вызывают непредвиденные ошибки. Также используйте -Wall, если вы этого еще не сделали, это может что-то поднять.

Это действительно звучит как проблема плохого указателя. См. этот сайт для некоторых хороших советов.

0 голосов
/ 10 февраля 2010

Это пахнет проблемой повреждения указателя, а не переполнением стека. Если приложение большого размера, попробуйте вставить return в верхней части основных функций, чтобы ограничить объем выполняемого кода.

Как только диапазон подозрительного кода ограничен, тщательно проверьте управление указателями. Особенно следует убедиться, что любой указатель, отправленный на free () или деструктор, не был удален заранее.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...