【问题标题】:reduce stack size in debug session to catch endless recursion减少调试会话中的堆栈大小以捕获无限递归
【发布时间】:2016-06-02 01:34:50
【问题描述】:

我有一个“有时”没有破坏递归并最终导致堆栈溢出的算法。现在我想调试这种情况。 gdb 将我直接指向我覆盖堆栈边界的行,但无法获得堆栈跟踪,因为 gdb 需要无穷无尽的时间来展开堆栈并将其显示在 ddd 中。

我现在只想减少堆栈大小以更早地获得损坏。所以我需要一种方法来减少我正在运行的任务的堆栈。没有涉及线程,所以应该没什么大不了的。

但我不知道 gdb 本身是否有一个选项来操作堆栈(大小)本身,或者我需要在我的 prog 开始时以编程方式更改大小,或者我可以从 os 命令行( linux )减小大小启动调试会话后。

如果gdb有这样的选项,如果调用树达到最大深度,也许也可以停止。

【问题讨论】:

    标签: c++ linux recursion gdb stack-overflow


    【解决方案1】:

    尝试在运行程序的 shell 中使用 ulimit -s (stack_size),或者您可以以编程方式执行 Change stack size for a C++ application in Linux during compilation with GNU compiler

    编辑:

    我们可以编写简单的类似 nohup 的程序,将SIGSTOP 发送给它自己,然后执行它的参数。我们把它命名为 runpaused

    //runpaused.c
    #include <signal.h>
    #include <unistd.h>
    
    int main(int argc, char **argv)
    {
        raise(SIGSTOP);
        return execvp(argv[1], argv+1);
    }
    

    然后,我们可以做接下来的事情: 编译运行暂停

    $ gcc runpaused.c -o runpaused
    

    当前 shell 的限制堆栈

    $ ulimit -s 32
    

    通过runpaused运行我们的程序,以sh为例

    $ ./runpaused sh -c "echo Hello"
    

    从其他终端: 找到它是PID

    $ ps -ef | grep -v grep | grep runpaused
    

    用我们的程序加载 gdb

    $ gdb $(which sh)
    

    附加到PID

    (gdb) attach PID
    

    gdb发送信号SIGCONT

    (gdb) signal SIGCONT
    

    gdb继续执行程序

    (gdb) continue
    

    经过多次继续,我们得到了我们想要的。

    【讨论】:

    • 使用 ulimit -s 无济于事,因为这会影响调试会话,而不仅仅是应该调试的程序。是否有机会从 gdb 设置 ulimit -s?但是您以编程方式减少堆栈大小的链接适合我的问题。也许您可以为其他用户更改您的答案。
    • 要仅在目标中设置 ulimit,请尝试 (gdb) set exec-wrapper sh -c 'ulimit -s 32;exec "$0" "$@"' 。更多关于 exec-wrapper here 的语义。
    猜你喜欢
    • 2016-08-20
    • 2020-04-24
    • 2018-10-16
    • 2011-11-24
    • 2011-01-30
    • 1970-01-01
    • 2016-04-06
    • 1970-01-01
    • 2021-12-15
    相关资源
    最近更新 更多