zoukankan      html  css  js  c++  java
  • 异常0xc000041d的抛出过程

    为了说明这个过程,我们必须写一个示例程序,如下:

    #include "stdafx.h"
    #include <tchar.h>
    #include <stdio.h>
    #include <Windows.h>
    
    #pragma comment(lib, "user32")
    
    WNDPROC oldproc = NULL;
    
    LRESULT CALLBACK newproc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
    {
        throw 0;
        return oldproc(hwnd, uMsg, wParam, lParam);
    }
    
    int _tmain(int argc, TCHAR *argv[])
    {
        HWND hWnd = CreateWindowEx(0, TEXT("STATIC"), TEXT("Name"),
            WS_OVERLAPPEDWINDOW | WS_VISIBLE,
            CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
            NULL, NULL, NULL, NULL);
        oldproc = (WNDPROC)SetWindowLongPtr(hWnd, GWLP_WNDPROC, (LONG_PTR)newproc);
        
            UpdateWindow(hWnd);
    
        
            system("pause");
    }

    将上面的程序在vs建立工程编译运行,得到如下结果

     退出,在vs里按下快捷建F11,程序中断后,给函数ZwRaiseException下断点

     按F5运行程序,程序中断,观察到程序停在了_NtRaiseException@12

    看下调用栈

    可以看到此时正在抛出第一个异常,也就是真正的异常 throw 0;

    按F5 继续运行程序,程序又中断了,可以看到此时又中断在_NtRaiseException@12,看下栈

    这是第二次抛出异常,也就是抛出0xc000041d,我们观察下函数ntdll.dll!_LdrpLogFatalUserCallbackException@8() 

    在这里里,填充了EXCEPTION_RECORD结构,紧接着调用了_NtRaiseException@12抛出异常。

    简单来说,当程序产生了一个异常,首先走的还是正常的异常分发流程,当没有得到处理,又是在Windows系统的用户回调里发生的,会分发给_KiUserCallbackExceptionHandler去处理,_KiUserCallbackExceptionHandler里会调用_LdrpLogFatalUserCallbackException,_LdrpLogFatalUserCallbackException里会重新填充EXCEPTION_RECORD结构抛出异常0xc000041d。

  • 相关阅读:
    svn安装教程
    六、数组类的创建
    五、顺序存储线性表分析
    四、StaticList 和 DynamicList
    三、顺序存储结构的抽象实现
    二、线性表的顺序存储结构
    一、线性表的本质和操作
    专题五:局部变量、全局变量global、导入模块变量
    专题四:文件基础知识、字符编码
    专题3-2:列表基础知识:二维list排序、获取下标和处理txt文本实例
  • 原文地址:https://www.cnblogs.com/yilang/p/12028082.html
Copyright © 2011-2022 走看看