处理关键的调试事件
来源:互联网 发布:数据库系统教程答案 编辑:程序博客网 时间:2024/06/10 05:59
必知
可以先阅读一下[Win32]一个调试器的实现(三)异常,写得非常好!
当程序中发生异常时,我们的调试器是会接收到EXCEPTION_DEBUG_EVENT调试事件的。但是这时候到底要不要处理这个调试事件,我们还必须斟酌一下。因为很可能程序里有相应的异常处理代码,而这时我们的调试器就没有什么必要接管这个异常。异常的分发过程如图:
这里是我的代码,可以拿去把玩一下,感受一下Windows的异常机制:
①myDEBUG.cpp
#include "stdafx.h"#include <iostream>#include <Windows.h>using namespace std;DWORD continue_status = DBG_EXCEPTION_NOT_HANDLED;//异常调试事件处理函数void OnException(const EXCEPTION_DEBUG_INFO* excpt_debug_info){ cout<<"\tAn exception occured at "<<hex<<excpt_debug_info->ExceptionRecord.ExceptionAddress<<endl <<"\tException code: "<<excpt_debug_info->ExceptionRecord.ExceptionCode<<dec<<endl; if(excpt_debug_info->dwFirstChance){ cout<<"\tfirst chance"<<endl; continue_status = DBG_EXCEPTION_NOT_HANDLED; }else{ cout<<"\tsecond chance"<<endl; continue_status = DBG_EXCEPTION_NOT_HANDLED; }}void main(){ PROCESS_INFORMATION process_info; STARTUPINFO startup_info; memset(&process_info, 0, sizeof(process_info)); memset(&startup_info, 0, sizeof(startup_info)); startup_info.cb = sizeof(STARTUPINFO); if(CreateProcess(TEXT("E:\\myCode\\dividedByZero\\Debug\\dividedByZero.exe"),NULL, NULL, NULL, FALSE, DEBUG_ONLY_THIS_PROCESS | CREATE_NEW_CONSOLE,NULL, NULL, &startup_info, &process_info)){ //ResumeThread(process_info.hThread); while(true){ DEBUG_EVENT debug_info; if(!WaitForDebugEvent(&debug_info, INFINITE)) break; switch (debug_info.dwDebugEventCode) { case CREATE_PROCESS_DEBUG_EVENT://创建进程 cout<<"CREATE_PROCESS_DEBUG_EVENT"<<endl; break; case CREATE_THREAD_DEBUG_EVENT://创建线程 cout<<"CREATE_THREAD_DEBUG_EVENT"<<endl; break; case EXIT_THREAD_DEBUG_EVENT://退出线程 cout<<"EXIT_THREAD_DEBUG_EVENT"<<endl; break; case EXIT_PROCESS_DEBUG_EVENT://退出进程 cout<<"EXIT_PROCESS_DEBUG_EVENT"<<endl; break; case EXCEPTION_DEBUG_EVENT://发生异常 cout<<"EXCEPTION_DEBUG_EVENT"<<endl; OnException(&debug_info.u.Exception); break; case OUTPUT_DEBUG_STRING_EVENT://调用OutputDebugString函数 cout<<"OUTPUT_DEBUG_STRING_EVENT"<<endl; break; case RIP_EVENT://发生系统调试错误 cout<<"RIP_EVENT"<<endl; break; case LOAD_DLL_DEBUG_EVENT://加载dll cout<<"LOAD_DLL_DEBUG_EVENT"<<endl; break; case UNLOAD_DLL_DEBUG_EVENT://卸载dll cout<<"UNLOAD_DLL_DEBUG_EVENT"<<endl; break; } if(debug_info.dwDebugEventCode == EXIT_PROCESS_DEBUG_EVENT) break; ContinueDebugEvent(debug_info.dwProcessId, debug_info.dwThreadId, continue_status); } CloseHandle(process_info.hThread); CloseHandle(process_info.hProcess); }else{ cout<<"Can't create process."<<endl; }}
②dividedByZero.cpp
#include "stdafx.h"#include <Windows.h>int _tmain(int argc, _TCHAR* argv[]){ OutputDebugString(TEXT("Warning! An exception will be thrown!")); __try { int a = 0; int b = 10 / a; getchar(); } __except(EXCEPTION_EXECUTE_HANDLER) { OutputDebugString(TEXT("Entered exception handler.")); } return 0;}
以上两段代码结合起来的效果如图:
思路
现在可以知道,EXCEPTION_DEBUG_EVENT调试事件是调试器和debugee交互的重要手段,通过处理EXCEPTION_DEBUG_EVENT调试事件可以完成常规的断点、单步执行等操作。而ContinueDebugEvent函数的第三个参数非常重要,我们可以使用DBG_CONTINUE或DBG_EXCEPTION_NOT_HANDLED来影响调试器的行为。
所以,若我们希望调试器仅仅在程序没有异常处理器时才对接管异常,就可以在第一次接收到异常调试事件时以DBG_EXCEPTION_NOT_HANDLED继续执行,在第二次接收到异常调试事件时才对其进行处理。
0 0
- 处理关键的调试事件
- 处理倒计时问题的关键
- [Win32]一个调试器的实现(二)调试事件的处理
- [Win32]一个调试器的实现(二)调试事件的处理
- [Win32]一个调试器的实现(二)调试事件的处理
- VC++调试OCCI程序的关键设置
- VC++调试OCCI程序的关键设置
- 事件模型的关键是delegate
- FMS视频流的关键处理
- 处理HTTP Servlet的关键方法
- 调试状态下Windows Service与Timer处理事件的问题
- 处理继承的事件
- java的事件处理
- java的事件处理
- java的事件处理
- java的事件处理
- java的事件处理
- 事件的处理
- mysql 异常处理
- 数据结构与算法(十一)二叉树结点的插入/查找
- 算法---选择-堆排序
- Base 7
- 指针练习
- 处理关键的调试事件
- 终止alphatrader脚本
- SimpleDateFormat严格限制日期转换setLenient(false)
- 安装rpm包,卸载已经安装的rpm包
- CNN FOR LICENSE PLATE MOTION DEBLURRING--阅读笔记
- Linux下Elasticsearch安装、配置及示例
- Android所有版本对应的API Level(2.1--7.1.1)
- android 关于adb以及截屏,录屏 ,关机 ,重启,查看进程 ,看内核,查看应用使用的内存信息
- 分布式系统的架构思路