代码之家  ›  专栏  ›  技术社区  ›  Craig Ringer

调试使用SIGINT和gdb的程序

  •  18
  • Craig Ringer  · 技术社区  · 8 年前

    我经常使用PostgreSQL进行调试,它使用 SIGINT 内部的一些后端间信令。

    因此,在运行某些后端时 gdb 执行往往会受到很多干扰。可以使用 signal 命令以确保 SIGINT(信号) 传递给程序,而不是由捕获 gdb公司 …但之后 gdb公司 不响应命令行上的control-C,因为这会发送 SIGINT(信号) .

    如果您跑步:

    handle SIGINT noprint nostop pass
    

    gdb公司 会抱怨的

    SIGINT is used by the debugger.
    Are you sure you want to change it? (y or n) y
    

    有没有办法让gdb使用不同的中断信号?或者任何其他方法 gdb公司 忽视 SIGINT(信号) ?

    (对于大多数PostgreSQL后端调试来说,这不是一个问题,但对于后台工作人员和自动真空来说,这是一个痛苦的问题)。

    3 回复  |  直到 8 年前
        1
  •  30
  •   pestophagous    7 年前

    如果读者(和我一样)在这一页上看到这个问题的一个略微不同的变体,他们可能会对这个问题更感兴趣:

    Debugging a segmentation fault when I do ctrl c

    …其答案是:

    • 从gdb本身内部发送SIGINT:

      (gdb)信号2

    (通常我会在本页OP的问题下将链接作为一个简单的评论发布,但因为已经有7条评论,所以评论被隐藏/隐藏。)

    如果你在这里阅读了OP问题的所有细节,那么很明显,我的答案对于OP来说是不正确的。

    然而,我的答案在许多情况下都是正确的,这些情况可以用相同的标题来描述:“用gdb调试使用SIGINT的程序”

        2
  •  11
  •   Mark Plotnick    8 年前

    在类UNIX系统上,可以区分tty启动的SIGINT和由 kill 通过查看 si_pid 中的元素 siginfo 结构。如果pid为0,则它来自tty。

    所以你可以这样做:

    catch signal SIGINT
    commands
      if $_siginfo._sifields._kill.si_pid == 0
        print "Received SIGINT from tty"
      else
        printf "Received SIGINT from %d; continuing\n", $_siginfo._sifields._kill.si_pid
        signal SIGINT
      end
    end
    
        3
  •  5
  •   Tom Tromey    8 年前

    gdb的这一部分有点棘手,这既是因为它的历史,也是因为它支持的各种操作模式。

    人们可能会认为,在单独的终端中运行gdb,并且只使用 attach 将有助于它做正确的事情,但我认为这并不容易。

    一种前进的方法可能是在调试时只使用异步执行,然后使用命令中断下级。类似于:

    (gdb) attach 5555
    ... attaches
    (gdb) continue &
    ... lots of stuff happens
    (gdb) interrupt -a
    

    根据您的gdb版本,您可能需要设置 target-async 这样才能奏效。