C++ 如何调试“检测到堆栈粉碎”?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10087804/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 13:37:05  来源:igfitidea点击:

How to debug 'Stack smashing detected'?

c++stack-smash

提问by user1219721

I have a complex c++ code.

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

It's a FastCGI program, using http://althenia.net/fcgicc

这是一个 FastCGI 程序,使用http://althenia.net/fcgicc

When I ask it for a looooong url, I get

当我向它索要 looooong 网址时,我得到

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

For real life, it's not an issue since I never use so long urls, but it mean that anyone could terminate my server.... I don't like that.

在现实生活中,这不是问题,因为我从不使用这么长的 url,但这意味着任何人都可以终止我的服务器......我不喜欢那样。

Is there a tool (and how to use it?) to findout where does the problem appear ?

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

EDIT : SOLVED

编辑:已解决

Ok solved.

好的解决了。

I was doing

我在做

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

Looks like that 200 was too hight for the len test. It actually fails at 194.

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

So I did :

所以我做了 :

if (len > 190) return 1;

Now, it's fine.

现在,没事了。

采纳答案by Matthieu M.

If you read the website you will realize that this is a simple C++ wrapper over a C library.

如果您阅读该网站,您会意识到这是一个简单的 C++ 包装器,它覆盖了 C 库。

A typical issue with C library are buffer overruns:

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

Try this program:

试试这个程序:

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

Because the buffer can only contain 16 characters, the remaining characters will be written past its end. This is stack smashing, and undefined behavior.

因为缓冲区只能包含 16 个字符,所以剩余的字符将被写入到它的末尾。这是堆栈粉碎未定义的行为

A number of implementations of either the runtime library or your OS may detect this situation in some conditions and terminate the program.

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

Either youare doing something wrong or the libraryis.

要么做错了什么,要么图书馆做错

To locate the issue, you could use Valgrind or run your program in a debugger. Alternatively, if your system allows it, you might have a memory dump at the moment the program was killed. You can also view this memory dump in a debugger.

要定位问题,您可以使用 Valgrind 或在调试器中运行您的程序。或者,如果您的系统允许,您可能会在程序被终止时进行内存转储。您还可以在调试器中查看此内存转储。

回答by bames53

You can use something like valgrind, or your compiler may have static analysis that can find places you might be overrunning buffers.

您可以使用 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.

此外,您还可以审计代码以使用诸如 strcpy 之类的容易出错的函数,并用诸如 strncpy 之类的安全函数替换它们,或者更好的是,只需使用管理自己内存的对象,如 std::string。