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

check used stack size using core file

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

你不能,但要确保你 运行 出栈 space ,你可以使用 ulimit 系统命令来确定堆栈大小:ulimit -a。 之后,您可以使用 ulimit -s 增加 is 并尝试查看您是否仍在取芯。 堆栈大小的默认值非常大,但对于 运行 程序的用户来说,堆栈大小可能会减小。

在程序中有一个获取堆栈大小的绝妙方法。

您可以将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.
}

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

如果您认为无限递归已达到您的堆栈大小限制,确定这一点的简单方法是 运行 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_environ 之间的区别,其中包含一个非常接近堆栈底部的高地址17=],当前帧的栈指针(栈顶)。

(gdb) print (char *)_environ - (char *)$sp
 = 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
 = 8384640