Debugging 在D中引发异常时,如何使调试器中断?
当调试由于未捕获异常而失败的D代码时,异常机制会将堆栈一直向后展开,然后打印堆栈跟踪,给我们留下一些不太有用的信息:Debugging 在D中引发异常时,如何使调试器中断?,debugging,gdb,d,lldb,Debugging,Gdb,D,Lldb,当调试由于未捕获异常而失败的D代码时,异常机制会将堆栈一直向后展开,然后打印堆栈跟踪,给我们留下一些不太有用的信息: (gdb) bt No stack. 堆栈跟踪为我们提供了引发异常的行,但是如果它直到几千次迭代后才抛出,那么这并没有特别大的帮助。如果能够将调试器设置为在抛出异常时中断,这将非常有用 目前,关于这一点的唯一文档似乎是dlang邮件列表上的一些帖子。我已经找到了一些适合我的设置的方法,并将它们包含在我自己的答案中,但是为了其他解决这个问题的人的利益,我希望我们能够得到一个更全面
(gdb) bt
No stack.
堆栈跟踪为我们提供了引发异常的行,但是如果它直到几千次迭代后才抛出,那么这并没有特别大的帮助。如果能够将调试器设置为在抛出异常时中断,这将非常有用
目前,关于这一点的唯一文档似乎是dlang邮件列表上的一些帖子。我已经找到了一些适合我的设置的方法,并将它们包含在我自己的答案中,但是为了其他解决这个问题的人的利益,我希望我们能够得到一个更全面的答案,其中包含{dmd,gdc,ldc}x{gdb,lldb}的任何组合的方法。所有这些都是在Linux上测试的。-g标志被传递给所有三个编译器。-d-debug标志也被传递给了ldc,尽管它做了很多好事 gdb (gdb)中断
- 适用于linux+dmd
- 在linux+gdc上不工作
- 在linux+ldc上不起作用
- 未知,但druntime的来源似乎表明这是针对win32和win64的throwdwarf。有人想用Windows系统测试一下吗
- 适用于linux+dmd
- 适用于linux+gdc
- 在linux+ldc上不起作用
- 不适用于linux+dmd或linux+gdc
- 适用于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异常。@JimInghamb\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所示或你最喜欢的符号转储程序所示),那么你应该能够打破这个损坏的名称。