如何在VisualC+中每次抛出异常时运行某些代码+;节目? 如果在C++程序中抛出异常,则将控件转移到异常处理程序或终止()>代码>。

如何在VisualC+中每次抛出异常时运行某些代码+;节目? 如果在C++程序中抛出异常,则将控件转移到异常处理程序或终止()>代码>。,c++,visual-c++,exception,exception-handling,C++,Visual C++,Exception,Exception Handling,即使程序从处理程序内部(或从terminate()handler)发出一些可能太晚的诊断,最大的值还是在抛出异常的调用堆栈中,而不是在处理程序中 在Windows上,可以使用[StackWalk64()]函数获取调用堆栈。关键是如何在适当的时候调用该函数 是否有一种方法,让VisualC++程序在每次出现异常(或者设置了没有处理程序的异常)时执行一些用户代码?在Windows上使用< /P> < P>,生成一个MINIDUMP。 非常有用。如果在SEH异常被抛出时,如在发生访问冲突时,想做一些事

即使程序从处理程序内部(或从
terminate()
handler)发出一些可能太晚的诊断,最大的值还是在抛出异常的调用堆栈中,而不是在处理程序中

在Windows上,可以使用
[StackWalk64()
]函数获取调用堆栈。关键是如何在适当的时候调用该函数


是否有一种方法,让VisualC++程序在每次出现异常(或者设置了没有处理程序的异常)时执行一些用户代码?在Windows上使用< /P> < P>,生成一个MINIDUMP。

非常有用。如果在SEH异常被抛出时,如在发生访问冲突时,想做一些事情,则

< P>然后,您可以简单地捕捉SEH异常(或者用最后一个,或者转换为C++异常(参见)),并访问异常中的上下文,该异常是在抛出异常时的上下文。然后,您可以使用StackWalker或mini dump生成调用堆栈。我想最好是建一个小型垃圾场


如果你想在它们被抛出的地方捕获C++异常,而你没有访问C++异常类的来源,那么你需要得到一点狡猾。我通过在自定义调试器下运行目标进程来处理此问题—使用调试API(请参阅),它可以在抛出异常时获取通知。此时,您可以创建目标进程的小型转储或调用堆栈

当语言不支持它时,如果没有它你就活不下去了,那就用hack…:-/

#include <iostream>
#include <stdexcept>

namespace Throw_From
{
    struct Line
    {
        Line& set(int x) { x_ = x; return *this; }
        int x_;

        template <typename T>
        void operator=(const T& t) const
        {                                                                       
            throw t;
        }                                                                       
    };                                                                          
    Line line;                                                                  
}                                                                               

#define throw Throw_From::line.set(__LINE__) =                                  

void fn2()                                                                      
{                                                                               
    throw std::runtime_error("abc");                                            
}                                                                               

void fn1()                                                                      
{                                                                               
    fn2();                                                                      
}                                                                               

int main()                                                                      
{                                                                               
    try
    {
        fn1();
    }
    catch (const std::runtime_error& x)
    {
        std::cout << Throw_From::line.x_ << '\n';
    }
}
#包括
#包括
命名空间从
{
结构线
{
行集合(int x){x_ux=x;返回*this;}
int x_2;;
模板
void运算符=(常量T&T)常量
{                                                                       
掷t;
}                                                                       
};                                                                          
线条;
}                                                                               
#定义throw-From::line.set(u-line)=
无效fn2()
{                                                                               
抛出std::运行时_错误(“abc”);
}                                                                               
无效fn1()
{                                                                               
fn2();
}                                                                               
int main()
{                                                                               
尝试
{
fn1();
}
捕获(const std::runtime_error&x)
{
标准::cout

有没有一种方法,让VisualC++程序在每次抛出异常(或者设置了没有处理程序的异常)时执行一些用户代码?< /P>

将代码放入异常基类的构造函数中。

是一篇关于如何在VisualC++中捕获所有不同类型异常的伟大文章。


它还为您提供了一个对调试有用的崩溃转储。

这不会像编写的那样工作,因为
抛出的优先级高于
;您最终抛出的
抛出的是::line
,而不是
“哎哟”
。实际上,这还有一个更大的问题,即如果包含任何标准库标题,则不允许定义与关键字在词汇上相同的宏,因此
#define throw which
是不可能的。@James:通常当人们开始考虑在异常情况下调用特定于平台的堆栈转储时例如,他们不关心可移植性或标准,会检查他们的头文件,看看它是否有效。邪恶和所有这些都是次要的。(嗯…不能重载运算符,-太晚了)
#定义THROW(E)(do_stuff(),(THROW E))
@Tony:这些人通过未检测到的UB使情况变得更糟,从而加剧了糟糕的情况。这是个好主意,但如果抛出了一些无关的异常,则不会有帮助。@sharptooth:您可以执行异常转换。对我来说,包装库异常(例如来自Boost)一直是个好主意在我自己的异常类型中。@Daniel Lidström:是的,异常翻译很棒,但知道原始异常的来源通常很有用。