使用核心文件检查使用的堆栈大小

时间:2016-05-19 11:00:45

标签: c segmentation-fault gdb stack-trace

我有一个核心文件,其中应用程序以SIGSEGV终止。 我怀疑这是因为应用程序耗尽了堆栈空间。 有没有办法从核心文件中检查使用的堆栈大小?

3 个答案:

答案 0 :(得分:12)

如果您认为由于无限递归而达到了堆栈大小限制,那么确定这一点的一种简单方法是运行btinfo stack,看看是否有比预期更多的帧。这是一个示例,我在每个堆栈帧中以递归方式调用一个大约1024字节的本地数据的函数:

(gdb) info stack
#0  recurse () at loop.c:5
#1  0x0000000000400565 in recurse () at loop.c:5
...
#7939 0x0000000000400565 in recurse () at loop.c:5
#7940 0x000000000040058f in main (argc=1, argv=0x7ffe63afef48) at loop.c:10

如果帧中有大量本地数据,您也可以只使用几帧超出堆栈大小限制。

要检查堆栈的大致大小,在Linux / x86上,您可以检查_environ之间的差异,其中包含一个非常接近堆栈基址的高地址,$sp 1}},当前帧中的堆栈指针(堆栈顶部)。

(gdb) print (char *)_environ - (char *)$sp
$5 = 8384904

这看起来非常接近8MB的堆栈大小限制。

(gdb) shell ulimit -s
8192

您还可以查看堆栈顶部框架中的$ sp与堆栈底部框架中的$ sp之间的差异。

(gdb) frame 0
#0  recurse () at loop.c:5
(gdb) set $topsp=$sp
(gdb) frame 7940
#7940 0x000000000040058f in main (argc=1, argv=0x7ffe63afef48) at loop.c:10
(gdb) print (char *)$sp - (char *)$topsp
$6 = 8384640

答案 1 :(得分:2)

有一种很好的方法来获得程序中的堆栈大小。

您可以将第一个变量的地址存储在全局的main中。然后你可以创建一个函数来找出这个地址和当前堆栈地址之间的区别。这将为您提供2字节内使用的堆栈大小。

主要。

char * initaddr;
int main()
{
   char dummy;  // Note -- first variable declared.

   initaddr = &dummy;

   // Other stuff...
}

int stacksize(void)
{
   char dummy2, *lastptr;
   lastptr = &dummy2;

   return(lastptr-initaddr); // This will give the stacksize at the instant of the return function.
}

您可以调用此函数来确定到目前为止使用的堆栈大小。这可以用作调试工具。

答案 2 :(得分:0)

你不能,但为了确保你的堆栈空间不足,你可以使用ulimit system命令来确定堆栈大小:ulimit -a。 在那之后你可以增加ulimit -s并试着看看你是否还在核心。 堆栈大小的默认值非常大,但是对于运行程序的用户而言,堆栈大小可能会减小。