代码之家  ›  专栏  ›  技术社区  ›  alexgolec

我有一个有很多返回点的函数。有没有办法让gdb告诉我哪一个会回来?

gdb c
  •  2
  • alexgolec  · 技术社区  · 14 年前

    我有一个返回点数目荒谬的函数,我不想每一个都是穴居人,我也不想下一个通过这个函数。除了在返回语句上停止之外,还有什么方法可以做finish之类的事情吗?

    5 回复  |  直到 14 年前
        1
  •  2
  •   Community Egal    7 年前

    你可以试试 reverse debugging 找出函数实际返回的位置。完成当前帧的执行,do 反步 然后你应该停在刚才返回的语句。

    (gdb) fin
    (gdb) reverse-step
    

    已经有了 similar question

        2
  •  1
  •   nmichaels    14 年前

    我想你被困在设置断点上了。我会编写一个脚本来生成要运行的断点命令列表,并将它们粘贴到gdb中。

    示例脚本(用Python编写):

    lines = open(filename, 'r').readlines()
    break_lines = [line_num for line_num, line in enumerate(lines) if 'return' in line and
    line_num > first and line_num <= last]
    break_cmds = ['b %s:%d' % (filename, line_num) for line_num in break_lines]
    print '\n'.join(break_cmds)
    

    filename 以具有荒谬功能的文件名命名, first 到函数的第一行(这是一个快速脚本,不是一个C解析器)和 last 函数最后一行的编号。输出应该适合粘贴到gdb中。

        3
  •  1
  •   DigitalRoss    14 年前

    不如趁这个机会把这个看起来显然太大的功能拆散?

        4
  •  0
  •   Ben Jackson    14 年前

    有点紧张,但是 catch 命令可以在很多事情上停止(如分叉、退出、接收信号)。你也许可以使用 catch catch 如果您将函数打包在C++中,您就可以在C++中执行所需的操作。 try/finally . 因此,如果你在 finally 在那之后,您可能只需一步就可以完成返回(尽管这将告诉您关于它来自何处的信息在很大程度上取决于优化:常见的返回用例通常由gcc折叠)。

        5
  •  0
  •   Community Egal    7 年前

    This question's come up before on SO . 我的回答是:

    显然,你应该重构这个函数,但是在C++中,你可以用这个简单的权宜之计在五分钟内处理这个问题:

    class ReturnMarker
    {
       public:
       ReturnMarker()  {};
       ~ReturnMarker() 
       {
          dummy += 1; //<-- put your breakpoint here
       }
       static int dummy;
    }
    
    int ReturnMarker::dummy = 0;
    

    然后在函数顶部引用一个ReturnMarker。当它返回时,该实例将超出范围,您将命中析构函数。

    void LongFunction()
    {
        ReturnMarker foo;
    
        // ...
    }