windows获取程序调试信息
来源:互联网 发布:上海用友软件 编辑:程序博客网 时间:2024/05/17 19:58
windows获取程序调试信息
通常能调试的时候,可以放断点进行调试以及加日志log的方式,然后有时候无法放断点调试(比如正式版本),此时我们需要查看日志log进行分析问题。日志一般通过写文件完成,但是如果我们程序都是通过printf outputDebugString输出的调试信息,此时该如何查看这些调试信息。不知道你是否注意到VS调试程序时候,会把这些信息输出到输出窗口,这是如何实现的呢?接下来我们就去实现一个调试器
- WaitForDebugEvent
BOOL WINAPI WaitForDebugEvent( _Out_ LPDEBUG_EVENT lpDebugEvent, _In_ DWORD dwMilliseconds);
用于等待调试事件,调用此函数会阻塞当前线程,当比如prinft,创建线程等事件就会唤醒此函数。得到事件通知,然后解析DEBUG_EVENT结构,并对事件进行响应,处理完成后调试器将会调用ContinueDebugEvent,并根据参数来通知调试目标执行相应操作。
lpDebugEvent :指向接收调试事件信息的DEBUG_ ENENT结构的指针
dwMilliseconds:指定用来等待调试事件发生的毫秒数,如果 这段时间内没有调试事件发生,函数将返回调用者;如果将该参数指定为INFINITE,函数将一直等待直到调试事件发生
- ContinueDebugEvent
BOOL ContinueDebugEvent( DWORD dwProcessId, // process to continue DWORD dwThreadId, // thread to continue DWORD dwContinueStatus // continuation status);
此函数允许调试器恢复先前由于调试事件而挂起的线程。(比如我们写的调试器为进程A, 被调试的进程为B,当A的WaitForDebugEvent接收到事件的时候,B进程的发出事件的线程会被挂起,当A处理完事件后调用ContinueDebugEvent恢复B中被挂起的那个线程)
dwProcessId: 为被调试进程的进程标识符
dwThreadId : 为欲恢复线程的线程标识符
dwContinueStatus指定了该线程将以何种方式继续,包含两个定义值DBG_CONTINUE和DBG_EXCEPTION_NOT_HANDLED
- DebugActiveProcess
BOOL DebugActiveProcess( DWORD dwProcessId // process to be debugged);
此函数允许将调试器捆绑到一个正在运行的进程上(这里我们传入进程B的进程id)。
下来就是获取调试信息的主要代码
DWORD CDebugInfoDlg::GetDebugInfoProc( LPARAM lparam ){ CDebugInfoDlg* pThis = (CDebugInfoDlg*)lparam; if (pThis->m_hProcess == INVALID_HANDLE_VALUE) { return 1; } DebugActiveProcess(pThis->m_dwProcessId); while (m_bThreadLive) { DEBUG_EVENT DebugEv; // debugging event information // Wait for a debugging event to occur. The second parameter indicates // that the function does not return until a debugging event occurs. WaitForDebugEvent(&DebugEv, INFINITE); // Process the debugging event code. switch (DebugEv.dwDebugEventCode) { case EXCEPTION_DEBUG_EVENT: // Process the exception code. When handling // exceptions, remember to set the continuation // status parameter (dwContinueStatus). This value // is used by the ContinueDebugEvent function. switch (DebugEv.u.Exception.ExceptionRecord.ExceptionCode) { case EXCEPTION_ACCESS_VIOLATION: // First chance: Pass this on to the system. // Last chance: Display an appropriate error. break; case EXCEPTION_BREAKPOINT: // First chance: Display the current // instruction and register values. break; case EXCEPTION_DATATYPE_MISALIGNMENT: // First chance: Pass this on to the system. // Last chance: Display an appropriate error. break; case EXCEPTION_SINGLE_STEP: // First chance: Update the display of the // current instruction and register values. break; case DBG_CONTROL_C: // First chance: Pass this on to the system. // Last chance: Display an appropriate error. // Handle other exceptions. break; } break; case CREATE_THREAD_DEBUG_EVENT: // As needed, examine or change the thread's registers // with the GetThreadContext and SetThreadContext functions; // and suspend and resume thread execution with the // SuspendThread and ResumeThread functions. break; case CREATE_PROCESS_DEBUG_EVENT: // As needed, examine or change the registers of the // process's initial thread with the GetThreadContext and // SetThreadContext functions; read from and write to the // process's virtual memory with the ReadProcessMemory and // WriteProcessMemory functions; and suspend and resume // thread execution with the SuspendThread and ResumeThread // functions. break; case EXIT_THREAD_DEBUG_EVENT: // Display the thread's exit code. break; case EXIT_PROCESS_DEBUG_EVENT: // Display the process's exit code. break; case LOAD_DLL_DEBUG_EVENT: // Read the debugging information included in the newly // loaded DLL. break; case UNLOAD_DLL_DEBUG_EVENT: // Display a message that the DLL has been unloaded. break; case OUTPUT_DEBUG_STRING_EVENT: // Display the output debugging string. { char szbuf[1024] = {0}; DWORD dwRead = 0; //读取被调试进程调试信息 if(ReadProcessMemory(pThis->m_hProcess, DebugEv.u.DebugString.lpDebugStringData, szbuf, DebugEv.u.DebugString.nDebugStringLength, &dwRead)) { EnterCriticalSection(&g_cs); CDebugInfoDlg::m_csBuf += szbuf; LeaveCriticalSection(&g_cs); ::PostMessage(pThis->m_hWnd, WM_UPDATA_VIEW, 0, 0); } } break; } // Resume executing the thread that reported the debugging event. ContinueDebugEvent(DebugEv.dwProcessId, DebugEv.dwThreadId, DBG_CONTINUE); } return 0;}
这些api不仅仅可以读取调试信息,还能实现抓取异常崩溃的调用堆栈等功能。
- windows获取程序调试信息
- Windows程序调试系列: 使用VC++生成调试信息
- Windows程序调试系列: 使用VC++生成调试信息
- Windows程序调试系列: 使用VC++生成调试信息
- Windows程序调试系列: 使用VC++生成调试信息
- Windows程序调试系列: 使用VC++生成调试信息
- Windows程序调试系列: 使用VC++生成调试信息
- Windows程序调试系列: 使用VC++生成调试信息
- Windows程序调试系列: 使用VC++生成调试信息
- Windows程序调试系列: 使用VC++生成调试信息
- windows下使用minidump获取和调试崩溃信息
- 几个获取Windows系统信息的Delphi程序
- 几个获取Windows系统信息的Delphi程序
- 几个获取Windows系统信息的Delphi程序
- 几个获取Windows系统信息的Delphi程序
- 几个获取Windows系统信息的Delphi程序
- 几个获取Windows系统信息的Delphi程序
- 几个获取Windows系统信息的Delphi程序
- 【剑指offer】(扩展)大数相加
- C++构造顺序
- Java泛型详解
- ConsumerIrManager类
- spel表达式
- windows获取程序调试信息
- dubbo配置文件报错解决思路
- java ee 中request对象getAttribute和getParameter区别
- CONSUMING REST API WITH RETROFIT 2.0 IN ANDROID
- 9-2CSS特殊性
- 剑指offer32--找出第一个只出现一次的字符
- Python Requests快速入
- HttpServletRequest添加header
- Spring中的AOP——AspectJ的基本使用