Подтвердить что ты не робот

Как отлаживать "обнаружение разбитого стека"?

У меня есть сложный код С++.

Это программа FastCGI, используя http://althenia.net/fcgicc

Когда я прошу его использовать looooong url, я получаю

*** stack smashing detected ***: ./tileserve terminated
Erreur de segmentation

Для реальной жизни это не проблема, так как я никогда не использую такие длинные URL-адреса, но это означает, что любой может прекратить мой сервер... Мне это не нравится.

Есть ли инструмент (и как его использовать?), чтобы узнать, где возникает проблема?

EDIT: SOLVED

Хорошо.

Я делал

int len;
char uri[200];

len = strlen(request.params[std::string("REQUEST_URI")].c_str());
printf("%d\n", len);

if (len > 200) return 1;

strcpy(uri, request.params[std::string("REQUEST_URI")].c_str());

Похоже, что 200 был слишком высоким для теста len. Это на самом деле не удается на 194.

Итак, я сделал:

if (len > 190) return 1;

Теперь это нормально.

4b9b3361

Ответ 1

Если вы читаете веб-сайт, вы поймете, что это простая С++-оболочка над библиотекой C.

Типичная проблема с библиотекой C - это переполнение буфера:

#include <cstring>
#include <cstdio>

int main(int argc, char* argv[]) {
  char buffer[16]; // ought to be sufficient

  strcpy(buffer, argv[1]);
  printf("%s", buffer);
}

Попробуйте эту программу:

> ./test "a"
a
> ./test "abcdefghijklmnoprqstuvwxyz"
???

Поскольку буфер может содержать только 16 символов, остальные символы будут записаны за его конец. Это разбиение стека и поведение undefined.

Ряд реализаций библиотеки времени выполнения или вашей ОС может обнаружить эту ситуацию в некоторых условиях и завершить работу программы.

Либо вы делаете что-то неправильно, либо библиотеку.

Чтобы найти проблему, вы можете использовать Valgrind или запустить свою программу в отладчике. В качестве альтернативы, если ваша система позволяет это, у вас может быть дамп памяти в момент, когда программа была убита. Вы также можете просмотреть этот дамп памяти в отладчике.

Ответ 2

Вы можете использовать что-то наподобие valgrind, или ваш компилятор может иметь статический анализ, который может находить места, где вы могли бы перехватывать буферы.

Также вы можете просто проверить свой код на использование функций, подверженных ошибкам, таких как strcpy, и заменить их на безопасные функции, такие как strncpy, или, еще лучше, просто использовать объекты, которые управляют своей собственной памятью, например std::string.