Debugging 在D中引发异常时,如何使调试器中断?

Debugging 在D中引发异常时,如何使调试器中断?,debugging,gdb,d,lldb,Debugging,Gdb,D,Lldb,当调试由于未捕获异常而失败的D代码时,异常机制会将堆栈一直向后展开,然后打印堆栈跟踪,给我们留下一些不太有用的信息: (gdb) bt No stack. 堆栈跟踪为我们提供了引发异常的行,但是如果它直到几千次迭代后才抛出,那么这并没有特别大的帮助。如果能够将调试器设置为在抛出异常时中断,这将非常有用 目前,关于这一点的唯一文档似乎是dlang邮件列表上的一些帖子。我已经找到了一些适合我的设置的方法,并将它们包含在我自己的答案中,但是为了其他解决这个问题的人的利益,我希望我们能够得到一个更全面

当调试由于未捕获异常而失败的D代码时,异常机制会将堆栈一直向后展开,然后打印堆栈跟踪,给我们留下一些不太有用的信息:

(gdb) bt
No stack.
堆栈跟踪为我们提供了引发异常的行,但是如果它直到几千次迭代后才抛出,那么这并没有特别大的帮助。如果能够将调试器设置为在抛出异常时中断,这将非常有用


目前,关于这一点的唯一文档似乎是dlang邮件列表上的一些帖子。我已经找到了一些适合我的设置的方法,并将它们包含在我自己的答案中,但是为了其他解决这个问题的人的利益,我希望我们能够得到一个更全面的答案,其中包含{dmd,gdc,ldc}x{gdb,lldb}的任何组合的方法。

所有这些都是在Linux上测试的。-g标志被传递给所有三个编译器。-d-debug标志也被传递给了ldc,尽管它做了很多好事

gdb (gdb)中断
  • 适用于linux+dmd
  • 在linux+gdc上不工作
  • 在linux+ldc上不起作用
(gdb)中断
  • 未知,但druntime的来源似乎表明这是针对win32和win64的throwdwarf。有人想用Windows系统测试一下吗
(gdb)break object.Throwable.this
  • 适用于linux+dmd
  • 适用于linux+gdc
  • 在linux+ldc上不起作用
(gdb)接球投掷|接球|信号
  • 不适用于linux+dmd或linux+gdc
lldb (lldb)b_d_throwdwarf
  • 适用于linux+dmd
    • 因为这可以通过将
      --DRT trapException=0
      标志传递给您的程序来实现。Adam在评论中链接的PR因此被合并

      通过这种添加,您还可以使用比
      rt\u trapExceptions
      code:

      extern(C)uu gshared string[]rt_options=[“trapExceptions=0”];
      
      您可以在此处阅读有关配置运行时选项的更多信息:


      在此之前,您可以在自定义main中设置rt_TrapeExceptions,如中所述:

      extern-extern(C)\u gshared bool rt\u trapExceptions;
      外部外部(C)内部运行(内部,字符**,无效*);
      外部(C)内部主(内部argc,字符**argv){
      rt_trapExceptions=false;
      返回"运行"主管道(argc,argv和"主管道);;
      }
      int_main(){
      //你的代码在这里
      }
      
      真正让我恼火的是,有一个简单的解决方案可以设置内部变量,这样所有未捕获的异常都会被调试器捕获,捕获的异常正常工作,只需向运行的程序传递一个命令行参数,就能在所有调试器、所有编译器和所有操作系统上工作。。。但他们从未合并公共关系,尽管看起来没有什么问题@如果他们强制要求所有实现中的_d_throw必须与该名称一起存在,那就更好了,因为它不需要重新编译。但是如果没有别的,你的
      rt\u trapExceptions
      hack给了我们一些可以与ldc一起工作的东西。但是你实际上不想在抛出时中断,即使它存在,因为这会中断所有抛出的异常,包括在程序中捕获的异常。trapExceptions的美妙之处在于它只捕获未捕获的异常,因此您不必一直告诉它继续处理普通的已处理案例。(有时您希望它在抛出时中断,但您可以在抛出的特定行中断,而不是在所有静止的行中断)上述所有符号断点方法都应与lldb一起工作,与gdb相同(除非您使用
      b
      break set-n
      。lldb目前没有任何语言支持D,因此异常断点不支持D异常。@JimIngham
      b\u D\u throwdwarf
      如果是用dmd编译的(添加到列表中,谢谢),但是
      b对象。Throwable。这
      “所有的编译器都无法解决位置”。什么是Objut.Basabable?这个看起来不像C或C++符号名。@ JimIngham是一个在所有DMD或GDC编译时都被调用的函数。(我还尝试了
      b object::Throwable::this
      ,以防不同的语法抛出lldb,结果相同。)那么这是一个D符号吗?D是否有一些名称损坏方案?如果是这样,那么要设置断点,lldb必须知道如何将D语法名称转换为实际损坏的符号名称(目前它无法做到,因为它对D一无所知)。但是如果你能找出实际的符号名称(如nm所示或你最喜欢的符号转储程序所示),那么你应该能够打破这个损坏的名称。