如何调试'Stack smashing detected'?

时间:2012-04-10 11:23:48

标签: c++ stack-smash

我有一个复杂的c ++代码。

这是一个使用http://althenia.net/fcgicc

的FastCGI程序

当我要求它提供一个looooong url时,我得到了

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

对于现实生活,这不是一个问题,因为我从来没有使用这么长的网址,但这意味着任何人都可以终止我的服务器......我不喜欢这样。

是否有工具(以及如何使用它?)来找出问题出现在哪里?

编辑:已解决

好的解决了。

我在做

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());

对于len测试看起来200太高了。 实际上它在194处失败了。

所以我做了:

if (len > 190) return 1;

现在,没关系。

2 个答案:

答案 0 :(得分:16)

如果您阅读该网站,您会发现这是一个基于C库的简单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个字符,所以剩余的字符将被写入其末尾。这是堆栈粉碎未定义的行为

运行时库或操作系统的许多实现都可能在某些情况下检测到这种情况并终止程序。

正在做错事或图书馆

要找到问题,您可以使用Valgrind或在调试器中运行程序。或者,如果您的系统允许,您可能在程序被杀死时有内存转储。您还可以在调试器中查看此内存转储。

答案 1 :(得分:0)

你可以使用像valgrind这样的东西,或者你的编译器可能有静态分析,可以找到你可能会超越缓冲区的地方。

此外,您可以审核代码以使用容易出错的函数(如strcpy),并使用strncpy等安全函数替换它们,或者更好地使用管理自己内存的对象,如std :: string。