【问题标题】:check used stack size using core file使用核心文件检查使用的堆栈大小
【发布时间】:2016-05-19 11:00:45
【问题描述】:

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

【问题讨论】:

  • 这在某种程度上取决于操作系统和架构。您可以将这些添加到您的问题中吗?
  • 操作系统是 Linux,64 位 x86

标签: c segmentation-fault gdb stack-trace


【解决方案1】:

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

(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

【讨论】:

  • “aarch64 GNU/Linux”怎么样?
【解决方案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.
}

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

【讨论】:

    【解决方案3】:

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

    【讨论】:

    • 首先欢迎来到 Stack Overflow。为您的问题添加标签真是个好主意。
    • 我确实找到了使用 gdb 的方法。通过检查回溯中起始帧和结束帧的sp寄存器之间的差异。似乎正确?
    猜你喜欢
    • 2010-09-16
    • 2014-12-07
    • 2014-02-23
    • 1970-01-01
    • 2011-02-23
    • 2018-02-22
    • 2020-04-27
    • 1970-01-01
    相关资源
    最近更新 更多