5

我有一个需要调试的 c++ dll。由于我使用 dll 的情况,我无法通过调用应用程序对其进行调试。

因此,我创建了一个 try -catch,其中 catch 将异常写入文件。

需要调试的行涉及从第 3 方 dll 导入的类,所以我无法知道它是什么类型的异常。当我尝试捕获(异常 e)时,没有消息写入文件。所以我尝试了 catch(...),它确实触发了一些东西:

使用 std::exception::what,写入文件的唯一内容是“1”。使用 std::exception::exception,文件收到以下代码:“0579EF90”。

有什么方法可以让我检索有关引发的异常的有意义的信息?

TIA

CG

4

5 回答 5

8

如果您不使用catch(KnownExceptionType ex)和使用有关 KnownExceptionType 的知识来提取信息,那么您不能。

当你赶上时,catch(...)你几乎迷路了,你知道你处理了一个异常,但那里没有类型信息,你无能为力。

你在更糟糕的情况下,一个来自库的异常,你没有关于异常的信息,即使你有库的标题,也不需要在那里定义异常类型。

于 2010-01-12T16:30:58.147 回答
4

如果我对您的理解正确,您已经将问题的根源缩小到对 3rd 方库的特定调用,但是您不允许实时调试应用程序(我想问为什么?),以及您的问题是“我如何在不知道异常是什么的情况下调试异常”

答案是,你不能。正如您所观察到的,您可以盲目猜测并希望抓住正确的东西。你也可以catch(...),但这不会告诉你什么。如果您可以实时调试,您可以将调试器设置为在抛出异常时中断并查看那里发生了什么。

我认为正确的答案是联系您已缩小问题来源的第 3 方图书馆并询问他们。抛出异常并允许它跨模块边界传播是非常非常糟糕的形式。这让我怀疑它是空指针 deref 或其他东西的 Windows SEH 异常,并且您正在以 catch(...) 捕获这些的方式进行编译。

于 2010-01-12T19:10:52.610 回答
3

也许尝试捕捉 std::exception & e

  1. std::cout << e.what() << endl;
  2. 看看你是否可以将它转换为 std::logic_error 和 std::runtime_error - 这应该会给你一些线索你正在处理什么
于 2010-01-12T16:34:38.573 回答
1

首先,您应该始终通过 const 引用捕获异常,换句话说:

catch( const std::exception & ex ) {
  ...
}

不这样做意味着您的异常将是您捕获的确切类型,这可能会导致异常信息丢失。

但是,您的库似乎抛出了一些不是从 std::exception 派生的东西 - 您需要找出类型(理想情况下是基本类型)是什么。

于 2010-01-12T16:56:22.380 回答
1

我有点困惑。一方面你写的catch(std::exception)没有用(你应该使用catch(const std::exception&),顺便说一句),另一方面你也写你调用std::exception::what()的。如果你一开始没有,你是怎么做到std::exception的?

无论如何,一旦你发现了任何东西...,你可以尝试记录 RTTI 信息:

#include <typeinfo>

try {
  foreign_code(my_data);
} catch(const some_type& x) {
  std::cerr << "Yikes! Caught exception of type '" 
            << typeid(x).name() 
            << "' with its hand in the cookie jar!\n";
  std::abort();
}

虽然标准没有对 的结果做出任何假设,但std::type_info::name()大多数(如果不是全部)编译器将生成代码,这些代码至少会产生一些有用的东西。

当您在 VS 调试器中时,您还可以对其进行设置,使其在抛出任何异常时停止。这为您提供了堆栈跟踪,从而可能为您提供有关传递给 DLL 的哪些数据可能导致问题的线索。

于 2010-01-12T17:06:06.917 回答