首页 > 其他 > 详细

异常0xc000041d的抛出过程

时间:2019-12-12 13:20:29      阅读:103      评论:0      收藏:0      [点我收藏+]

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

#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。

异常0xc000041d的抛出过程

原文:https://www.cnblogs.com/yilang/p/12028082.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!