分类 调试 下的文章

简介

STATUS_STOWED_EXCEPTION,值为0xC000027B。代表的意思是"发生应用程序内部异常"。它定义在 ntstatus.h头文件里,如下:

/
// MessageId: STATUS_STOWED_EXCEPTION
//
// MessageText:
//
// An application-internal exception has occurred.
//
#define STATUS_STOWED_EXCEPTION          ((NTSTATUS)0xC000027BL)

详细说明

本异常是UWP应用程序产生的异常类型。它是作为WinRT API(现在称为UWP)的一部分引入Windows 8.0的。这个异常已被故障点异常(0xC000027C)替换/增强。与POF异常一样,异常代码由WinRT框架生成。它不需要重新编译应用程序才能使用它。
当异步操作失败时,将引发这个异常。当通过RoOriginateException或RoOriginateLanguageException调用从工作线程报告异常时,将通过CaptureStackBackTrace函数调用收集当前线程的堆栈回溯(指令指针数组)。异常的堆栈回溯和HRESULT包装在一个iresteredrorinfo对象中,并通过WinRT的语言投影层路由到调用方。
如果调用方未处理异常,则会致命地抛出已装载的异常。因为抛出是延迟的,所以关联转储的当前上下文几乎没有值。原始问题的线程不再定期存在,如果存在,则已结束操作(意味着线程的堆栈内存已被覆盖)。这意味着函数参数和局部变量不可用。

异常结构信息填充

ExceptionAddress:

ExceptionCode: c000027b
ExceptionFlags: 00000001
NumberParameters: 2
Parameter[0]: 000002414ffc8680//是指向以STOWED_EXCEPTION_INFORMATION_HEADER开头的结构的指针数组的起始地址。自Windows 8.1以来,已使用的版本是STOWED_EXCEPTION_INFORMATION_V2。
Parameter[1]: 000000000000003//是数组中指针的数目


当我们提到CLR里的“异常”,要注意一个很重要的区别。有通过如C#的try/catch/finally暴露给应用程序,并由运行时提供机制全权实现的托管异常。也有运行时自己使用的异常。大部分运行时开发人员很少需要想到如何实现并暴露托管异常模型。但每个运行时开发人员都应该懂得CLR实现里是怎么使用异常的。为了保持区分,本文将托管程序抛出并捕捉的称为托管异常,而将运行时自己使用的错误处理方式称为 CLR内部异常。本文主要讨论CLR内部异常。

异常在什么地方有用?

异常几乎在所有地方都有用。最有用的地方就是抛出或捕捉异常的函数里,因为需要显式编写代码来抛出异常或者捕捉其并优雅的处理异常。即使一个函数本身不抛出异常,它也有可能调用抛出异常的函数。这样该函数必须在异常抛出的时候行为正常。明智的使用支持物(holders)可以极大简化正确编写这类代码。

为什么CLR内部异常是不同的?

CLR内部异常更像C++异常,但不完全是。CLR可以在Mac OSX、BSD还有Windows下编译。操作系统和编译器的差异使得我们不能仅使用标准C++的try/catch。另外,CLR内部异常还提供了类似托管代码的“finally”和“fault”这样的功能。

通过一些宏,编写异常处理代码就像标准C++那样简单。

捕捉异常

EX_TRY

最基本的宏是:EX_TRY / EX_CATCH / EX_END_CATCH,使用方法如下:

EX_TRY//调用一些函数,也许会抛出一个异常
Bar();
EX_CATCH
//在这里,那就有错误发生了 m_finalDisposition =terminallyHopeless;
EX_END_CATCH(RethrowTransientExceptions)

在本文中,我们将不解释为什么会提示“纯虚拟函数调用”和如何提示“纯虚拟函数调用”,而是详细解释在win32平台的构造函数/析构函数中直接/间接调用纯虚拟函数时程序本身。在开始时,将显示一个经典示例,在这个示例中,它将提示一个带有“纯虚拟函数调用”的消息框。

    /** 
     * "pure virtual function call" on win32 platform 
     * filename: testWin32PVFC.cpp 
     */  
    #include <iostream>  
     
    #define PI 3.1415926  
    using namespace std;  
      
    class Shape  
    {  
    private:  
        double ValuePerSquareUnit;  
      
    protected:  
        Shape(double valuePerSquareUnit):  
            ValuePerSquareUnit(valuePerSquareUnit)  
        {  
            //error LNK2001: unresolved external symbol "public: virtual double __thiscall Shape::area(void)const " (?area@Shape@@UBENXZ)  
            //std::cout << "creating shape, area = " << area() << std::endl;  
            std::cout << "creating shape, value = " << value() << std::endl;  //indirectly call pure virtual function in constructor  
        }  
      
    public:  
        virtual double area() const = 0;  
      
        double value() const  
        {  
            return ValuePerSquareUnit * area();  
        }  
      
        virtual ~Shape()  
        {  
            printf("Shape::~Shape() is called");  
        }  
      
        double getPerSquareUnit()  
        {  
            return ValuePerSquareUnit;  
        }  
    };  
      
    class Rectangle : public Shape  
    {  
    private:  
        double Width;  
        double Height;  
      
    public:  
        Rectangle(double width, double height, double valuePerSquareUnit):  
            Shape(valuePerSquareUnit),Width(width),Height(height)  
        {  
        }  
      
        virtual ~Rectangle()  //can be removed  
        {  
        }  
      
        virtual double area() const  
        {  
            return Width * Height;  
        }  
      
    };  
      
    class Circle: public Shape  
    {  
        double Radius;  
      
    public:  
        Circle(double radius, double valuePerSquareUnit):  
            Shape(valuePerSquareUnit),Radius(radius)  
        {  
        }  
      
        virtual ~Circle()  //can be removed  
        {  
        }  
      
        virtual double area() const  
        {  
            return PI * Radius * Radius;  
        }  
    };  
      
      
    int main()  
    {  
        Rectangle* pr = new Rectangle(30, 20, 10);  
        Circle* pc = new Circle(15, 10);  
      
        //invoke Rectangle::area()  
        printf("rectangle: area = %.2f, PerSquareUnit = %.2f, value = %.2f/n", pr->area(), pr->getPerSquareUnit(), pr->value());  
        //invoke Circle::area()  
        printf("circle   : area = %.2f, PerSquareUnit = %.2f, value = %.2f/n", pc->area(), pc->getPerSquareUnit(), pc->value());  
      
        Shape* shape;  
        shape = pr;  
        printf("rectangle: area = %.2f, PerSquareUnit = %.2f, value = %.2f/n", shape->area(), shape->getPerSquareUnit(), shape->value());  
      
        shape = pc;  
        printf("circle   : area = %.2f, PerSquareUnit = %.2f, value = %.2f/n", shape->area(), shape->getPerSquareUnit(), shape->value());  
      
        return 0;  
    }  

简介

STATUS_NO_MEMORY,值为0xC0000017。代表的意思是"没有足够的虚拟内存或分页文件配额来完成指定的操作。"。它定义在 ntstatus.h头文件里,如下:

/
// MessageId: STATUS_NO_MEMORY
//
// MessageText:
//
// {Not Enough Quota}
// Not enough virtual memory or paging file quota is available to complete the specified operation.
//
#define STATUS_NO_MEMORY                 ((NTSTATUS)0xC0000017L)    // winnt

 

异常结构填充

ExceptionAddress: 7706a44c (ntdll!RtlpAllocateHeapRaiseException+0x0000003b)
ExceptionCode: c0000017
ExceptionFlags: 00000000
NumberParameters: 1
Parameter[0]: 00000010//这个值暂时没整明白代表的意思,望知道的同仁告知