如何减少非异常异常的调试开销

时间:2014-01-31 15:03:41

标签: c++ exception visual-studio-debugging

我们使用的API非常依赖异常来返回非异常结果。这个(众多)中的一个例子是,为了确定用户是否在一组人中,我们必须尝试获取该组并解释所得到的“无组”异常。此外,所有这些例外都是一种类型。

我们正在使用C ++ 11开发一个庞大而复杂的项目,这个项目是多线程的,而且我们正在研究的领域涉及网络通信,因此我们必须同时调试多个实例。

我们的问题,以及我的问题的基础,是因为非例外情况对我们工作流程的影响。我们不愿意为API抛出的单一异常类型关闭第一次机会异常报告,因为这意味着如果我们调用了编码器错过了try / catch块的API,我们将放松主要和松散呼叫的上下文。如果我们将异常留下来,那么简单的非异常行为(例如上面示例中描述的行为)可能导致多次中断(初始抛出和可能的一些重新抛出),并且我们只能验证这实际上是非异常异常通过查询堆栈(通常是非主线程)来查找导致异常的API调用。

我相信我们的用例并不是那么独特,以至于其他人不会遇到相同的工作流问题,所以我的问题是我们应该如何改变我们的调试过程,以便更好地应对非例外异常所带来的问题,如上所述。

我们目前仅限于使用Visual Studio(或可能是WinDbg)进行调试。

1 个答案:

答案 0 :(得分:1)

在非特殊用例中抛出异常是完全错误的。下一步:每个函数都是void,抛出异常会返回所有函数。

据我所知,您正在使用第三方API来显示这种奇怪的行为。这是我在处理任何类型的“Odd API”时通常会考虑的内容,包括使用愚蠢的宏污染所有内容的C-API(是的,我看着你,WinAPI):

  1. 尽量避免表现奇怪的部分。在您的情况下:如果您可以拨打非支票支票,请执行此操作,即拨打if(hasGroup) getGroup; else ...而不是try {getGroup;} catch(X) {...}
  2. 不要让奇怪的东西扼杀所有代码,而是通过编写包装器API来约束它。在您的情况下:编写一个捕获异常的包装器并将其转换为正常的返回值。这样你的程序员就不会忘记捕获正常情况异常(因为你的包装器不会抛出它们),如果你把包装器放在它自己的库中,你可能可以在包装器API中使用另一个异常策略。 getGroup问题的快速示例:

    //myAPIWrapper.h
    
    namespace myAPIWrapper {
    
      class Group;
    
      class User {
      public:
        boost::optional<Group> getGroup();
      };
    
    }
    
    
    //myAPIWrapper.cpp
    
    #include "OddAPI.h"
    
    namespace myAPIWrapper {
    
      boost::optional<Group> User::getGroup()
      {
        boost::optional<Group> theGroup;
    
        try {
          oddAPI::user& oddUser= unwrap(*this);
          oddAPI::group& oddGroup = oddUser.get_group();
          theGroup = wrap(oddGroup);
        }
        catch(oddAPI::exception&) {
        }
    
        return theGroup;
      }
    }