【问题标题】:Is there a better way to see which function caused a exception other than using catch除了使用 catch 之外,有没有更好的方法来查看哪个函数导致了异常
【发布时间】:2022-01-12 02:19:16
【问题描述】:

我在定位发生错误的地址时遇到问题,我的整个代码在“try”语句中运行,遗憾的是,每当出现问题时,我都需要使用旧的 try and fail 方法来查找错误删除我的部分代码。有没有更好的方法?

我当前的代码:

try
{
    do
    {
    if (somefunction)

    if (somefunction2)

    if (somefunction3)

    if (somefunction4)
    }
    while (false);
}
catch (...) 
{
    // todo: somehow get the address where the error occurred
    Logger::Log("Exception\n");
}

【问题讨论】:

  • 异常消息为您提供了引发异常的地址。目前,您忽略了 Exception 对象中可用的所有信息,只需将其丢弃并记录无用信息“Exception”。此外,根据您使用的 IDE,您通常可以在引发异常时查看堆栈跟踪,这样您就可以查看发生异常的确切位置。
  • 您发布的代码根本没有显示您使用异常。您只是在记录绝对无用的短语“异常”。 Exception 对象包含您可以使用的信息,但前提是您实际查看它。
  • @KenWhite "异常消息为您提供了引发异常的地址" - 对于纯 C++ 异常,情况并非如此

标签: c++ try-catch


【解决方案1】:

找出异常来自何处的一个简单解决方案是在每个函数中使用唯一的消息。捕获异常对象并打印消息。或者甚至可以使用不同类型的异常,如果您想要这样做,这将使您能够以不同的方式有效地处理每种情况。


关于获取“地址”,导致当前执行点的函数调用跟踪称为堆栈跟踪(或回溯)。堆栈跟踪将包含诸如地址之类的信息。目前还没有标准的方法来获取堆栈跟踪,尽管它已被提议用于 C++23。

但是,一旦您捕获到异常,堆栈就会“展开”,因此您无法知道异常来自何处。您可以做的是获取可能正在抛出的代码中的堆栈跟踪(它们中的每一个,因为您不知道哪个是抛出者)并将跟踪存储在异常中。执行此操作的中心位置是在自定义异常类型的构造函数中。这种模式在现代语言的标准异常处理中很常见。


最后,您不一定需要对程序进行任何更改,如果您改为在调试器中运行程序并在抛出时中断,您可以获得所有可能获得的信息。

【讨论】:

  • 如果 OP 想要在没有调试器的情况下找到错误原因(不知道为什么有人会这样做),那么 OP 应该让每个 somefunctions 抛出带有唯一消息的异常。跨度>
  • @dmedine 确实如此。这就是我在答案的第一句话中所说的。但他们也必须展示信息才能发挥作用。
  • 你确实做到了。我的错。
猜你喜欢
  • 1970-01-01
  • 2021-08-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-04
  • 2015-10-10
相关资源
最近更新 更多