26

我有一个复杂的 C++ 代码。它是一个 FastCGI 程序,使用FastCGI C++ 类库

当我要求它提供一个非常长的网址时,我得到:

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

对于现实生活中的应用程序,这不是问题,因为我从不使用这么长的 URL,但这意味着任何人都可以终止我的服务器……我不喜欢这样。

有没有工具可以找出这个问题出现在哪里?我该如何使用它?

编辑:已解决

我正在这样做:

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;

现在,很好。

4

2 回答 2

25

如果您阅读该网站,您会意识到这是对 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 或在调试器中运行您的程序。或者,如果您的系统允许,您可能会在程序被终止时进行内存转储。您还可以在调试器中查看此内存转储。

于 2012-04-10T11:43:16.737 回答
2

你可以使用类似 valgrind 的东西,或者你的编译器可能有静态分析,可以找到你可能超出缓冲区的地方。

Also you can just audit your code for uses of error prone functions like strcpy and replace them with safe functions like strncpy, or better yet just use objects that manage their own memory like std::string.

于 2012-04-10T12:11:51.187 回答