【发布时间】:2013-02-20 22:45:00
【问题描述】:
由于各种原因,我无法详细说明,但这是我正在使用的基本架构
- 我有一个 C++ 框架,它使用我构建的 C++ 目标文件来执行动态模拟。
- C++ 库调用了一个用 Ada 编写的共享 (.so) 库。
据我所知,Ada 库(包含大量重要代码)在边缘情况下生成异常,但我无法隔离生成异常的函数。
这是我正在使用的:
- CentOS 4.8(最终版)
- gcc 3.4.6 (w/ gnat)
- gdb 6.3.0.0-1.162.el4rh
这是我正常执行时遇到的错误:
terminate called without an active exception
raised PROGRAM_ERROR : unhandled signal
我可以让 gdb 在异常返回到 C++ 后立即捕获它,但我无法让它在 Ada 代码中捕获。我已确保使用-g 编译所有内容,但这似乎无助于解决问题。
当我尝试捕捉/中断gdb(礼貌地告诉我Catch of signal not yet implemented)中的信号/异常时,我得到了这个:
[Thread debugging using libthread_db enabled]
[New thread -1208371520 (LWP 14568)]
terminate called without an active exception
Program received signal SIGABRT, Aborted.
[Switching to thread -1208371520 (LWP 14568)]
0x001327a2 in _dl_sysinfo_int80 () from /lib/ld-linux.so.2
我相信terminate called [...] 行来自框架。当我尝试捕获该中断,然后运行回溯 (bt) 时,我得到如下信息:
#0 0x001327a2 in gdb makes me want to flip tables.
#1 0x00661825 in raise () from /lib/tls/libc.so.6
#2 0x00663289 in abort () from /lib/tls/libc.so.6
#3 0x0061123e in __gnu_cxx: __verbose_terminate_handler () from /usr/lib/libstdc++.so.6
#4 0x0060eed1 in __xac_call_unexpected () from /usr/lib/libstdc++.so.6
#5 0x0060ef06 in std::terminate () from /usr/lib/libstdc++.so.6
#6 0x0060f0a3 in __xax_rethrow () from /usr/lib/libstdc++.so.6
#7 0x001fe526 in cpputil::ExceptionBase::Rethrow (scope=@0xbfe67470) at ExceptionBase.cpp:140
此时,它已进入框架代码。
我已经在线阅读了一些指南、教程和手册页,但我有点不知所措。我希望这里有人可以帮助我指出正确的方向。
【问题讨论】:
-
你给 gdb 什么命令来捕获异常?
-
我试过
catch signal SIGABRT,但它回复了Catch of signal not yet implemented.,所以我用handle SIGABRT stop来尝试捕捉信号,但得到的结果与上面相似。我认为真正的问题,我不知道如何解决这个问题,是我无法打破 Ada 中未捕获的异常。当我尝试catch exception(基于我在网上找到的一些 Ada 特定的 gdb 资料)时,我收到一个错误Unknown event type specified for catch。 -
我相信您的 GDB 需要专门在 Ada 支持下构建。我在自己的工作中注意到“捕获异常”仅适用于专门针对 Ada 的 GDB 安装,例如由 AdaCore 分发的安装。
-
这是完全可能的。我使用的是系统默认包含的任何版本的 gdb。我可以在各种 Ada 函数中设置正常断点并始终停止它们,但是捕捉这个断点让我很适应。用 Ada 支持重建 gdb 是我可以在本地做的事情,还是我需要从 AdaCore 之类的东西预构建它?
-
你可以尝试在
__gnat_unhandled_exception(源在s-excdeb.ads,s-excdeb.adb)尝试破解,这是一个在异常E的传播过程中调用的“[h]ook,尽快众所周知,它未被处理”。这可能为时已晚;__gnat_debug_raise_exception在引发点被调用,但如果应用程序引发了许多它随后处理的异常,则将难以使用。