简体   繁体   English

linux会告诉我是否存在堆栈溢出?

[英]Would linux tell me if there was a stack overflow?

Bear in mind I'm relatively new to C and linux. 请记住,我对C和Linux比较陌生。

For one of my classes I have a project in which we are supposed to find which cities are located in a certain geographical box, we have to use binary search trees though the implementation is up to us. 对于我的一个课程,我有一个项目,我们应该找到哪个城市位于某个地理区域,我们必须使用二叉搜索树,尽管实施取决于我们。 In my particular implementation, when inserting a new element into the tree, I recursively call the insertion function on the appropriate sub-tree. 在我的特定实现中,当将新元素插入树中时,我递归地在适当的子树上调用插入函数。

We've also been told to check our programs using Valgrind, as any memory leaks or errors it would throw would negatively impact our grade. 我们也被告知要使用Valgrind检查我们的程序,因为任何内存泄漏或错误会对我们的等级产生负面影响。 My program runs fine with the cities files we've been given up to 100,000, but at 1,000,000 cities Valgrind throws me over a million errors caused by invalid read/writes, the stack has overflown. 我的程序运行得很好,我们已经给了100,000个城市文件,但在1,000,000个城市,Valgrind引发了我因读取/写入无效而导致的一百多万个错误,堆栈已经溢出。 It doesn't happen if I run Valgrind with a higher stack size. 如果我运行具有更高堆栈大小的Valgrind,则不会发生这种情况。

When I run the program directly without Valgrind however I get no errors. 当我在没有Valgrind的情况下直接运行程序时,我没有错误。 Would linux tell me if there was a stack overflow? linux会告诉我是否存在堆栈溢出? What would be the consequences of such an overflow? 这种溢出会带来什么后果?

Why not test it? 为什么不试试呢? With the following Program, i get sometimes a SIGSEGV and sometimes not: 通过以下程序,我有时会得到一个SIGSEGV ,有时不会:

#include <stdint.h>

uint64_t pos=261950;

int main(void)
  {
    volatile int a; //just some variables to use the stack
    volatile int b; //and avoid too much optimizations
    a=b; b=a;       
    if(pos) 
      {   
        pos--;
        main();
      }   
    return 0;
  }

Valgrind shows a error in all my tests. Valgrind在我的所有测试中都显示错误。 The value 261950 was found with testing, and should most likely be different on a other installation. 在测试中发现了值261950,并且在其他安装中很可能是不同的。

This was tested on GNU/Linux AMD64, Debian 8, without any special settings (i did not disable anything like ASLR or stack smashing protection). 这是在GNU / Linux AMD64,Debian 8上测试的,没有任何特殊设置(我没有禁用任何类似ASLR或堆栈粉碎保护)。 The build command was: 构建命令是:

gcc -Wall -Wextra 001.c

When the variable pos is bigger, i see always a SIGSEGV -message. 当变量pos更大时,我总是看到一个SIGSEGV -message。

Of course, here nothing bad happen, but you can not be sure how it end up in a more complex program, so avoid a uncontrolled recursion deep. 当然,这里没有什么不好的事情发生,但你不能确定它是如何最终在一个更复杂的程序中,所以避免一个不受控制的递归深入。

Would linux tell me if there was a stack overflow? linux会告诉我是否存在堆栈溢出?

No, Linux doesn't care if you overflow your stack. 不,Linux并不关心你是否溢出堆栈。 However, it does make some attempt to ensure that the memory addresses beyond the end of the stack are unmapped memory, so that a stock overflow will probably segfault. 但是,它确实尝试确保超出堆栈末尾的内存地址是未映射的内存,因此库存溢出可能会出现段错误。 (That depends on the size of each function's stack frame; allocating large arrays on the stack can produce other as symptoms if you are unlucky.) (这取决于每个函数的堆栈帧的大小;如果你运气不好,在堆栈上分配大型数组会产生其他的症状。)

The C runtime environment probably won't tell you, either, because it would require inserting extra code, which would slow down execution, and then programmers who had taken care to ensure that their stacks won't overflow would complain about having to pay the cost of protecting your code against your bugs. C运行时环境可能也不会告诉你,因为它需要插入额外的代码,这会减慢执行速度,然后那些注意确保堆栈不会溢出的程序员会抱怨不得不支付保护您的代码免受错误的成本。 That might sound harsh, but it is basically the C design philosophy; 这可能听起来很苛刻,但它基本上是C设计理念; if you don't like it, there are other languages. 如果你不喜欢它,还有其他语言。 However, some compilers do allow you to request that extra code be inserted (with GCC, see the -fstack-check option; also see -fstack-limit-* and -fsplit-stack .) 但是,有些编译器允许您请求插入额外的代码(使用GCC,请参阅-fstack-check选项;另请参阅-fstack-limit-* -fsplit-stack -fstack-limit-*-fsplit-stack 。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM