📄 debdebug.c
字号:
/******************************************************************************\
* This is a part of the Microsoft Source Code Samples.
* Copyright (C) 1993-1997 Microsoft Corporation.
* All rights reserved.
* This source code is only intended as a supplement to
* Microsoft Development Tools and/or WinHelp documentation.
* See these sources for detailed information regarding the
* Microsoft samples programs.
\******************************************************************************/
// ************************************************************************
// MODULE : DEBDebug.C
// PURPOSE : Debug support functions for the Debug Event Browser
// FUNCTIONS :
// DebugEventThread() - debug event processing thread
// COMMENTS :
//
// ************************************************************************
#define STRICT // enable strict typing
#include <Windows.H> // required for all Windows applications
#include <StdDef.H> // offsetof()
#include "LinkList.H" // include the linked list functions
#include "DEBMisc.H" // include the misc. support functions
#include "DEBDebug.H" // include the DEB debugging functions
// internal global data
// ------------------------------------------------------------------------
HANDLE hHeap; // local heap
PLIST pProcessList; // pointer to the process list
BOOL fFinished = FALSE; // set to TRUE if the DebugEventThread
// is no longer needed (such as the
// debuggee failed to load or the number
// of debuggee threads goes to zero
// indicating debug session termination
static TCHAR szSourceFileName[] = TEXT(__FILE__);
// internal function prototypes
// ------------------------------------------------------------------------
//-- debug event handling functions
BOOL HandleExceptionEvent( LPDEBUG_EVENT );
BOOL HandleBreakPointException( LPDEBUG_EVENT );
BOOL HandleCreateThreadEvent( LPDEBUG_EVENT );
BOOL HandleCreateProcessEvent( LPDEBUG_EVENT );
BOOL HandleExitThreadEvent( LPDEBUG_EVENT );
BOOL HandleExitProcessEvent( LPDEBUG_EVENT );
BOOL HandleLoadDllEvent( LPDEBUG_EVENT );
BOOL HandleUnloadDllEvent( LPDEBUG_EVENT );
BOOL HandleOutputDebugStringEvent( LPDEBUG_EVENT );
BOOL HandleRipEvent( LPDEBUG_EVENT );
BOOL HandleUnknownEvent( LPDEBUG_EVENT );
//-- misc debug event helper functions
BOOL DebugNewProcess( LPTSTR, LPTSTR );
BOOL GetDllFileName( LPDEBUG_EVENT, LPTSTR, DWORD );
BOOL GetDllFileNameFromList( LPDEBUG_EVENT, LPTSTR, DWORD );
BOOL GetOutputDebugString( LPDEBUG_EVENT, LPTSTR, DWORD );
DWORD GetModuleFileNameFromHeader( HANDLE, HANDLE, DWORD, LPTSTR, DWORD );
#if defined(_MIPS_) || defined(_ALPHA_) || defined(_PPC_)
BOOL SkipBreakPoint( HANDLE );
#endif
//-- linked list wrapper functions
//-- process list and node specific linked list wrapper functions
int ProcessOrderFunction( PNODE, PNODE );
BOOL CreateProcessList( PLIST* );
BOOL DestroyProcessList( PLIST );
BOOL AllocProcessNode( PNODE*, PDEB_PROCESS_NODE_INFO* );
BOOL InitProcessNodeInfo( PDEB_PROCESS_NODE_INFO*, LPDEBUG_EVENT );
BOOL InsertProcessNode( PLIST, PNODE );
BOOL SetCurrentProcessNode( PLIST, PNODE );
BOOL DeleteProcessNode( PLIST, PNODE );
BOOL FreeProcessNodeInfo( PNODE );
BOOL DestroyProcessNode( PNODE );
BOOL DeleteCurrentProcessNode( PLIST );
//-- thread list and node specific linked list wrapper functions
int ThreadOrderFunction( PNODE, PNODE );
BOOL CreateThreadList( PLIST* );
BOOL DestroyThreadList( PLIST );
BOOL AllocThreadNode( PNODE*, PDEB_THREAD_NODE_INFO* );
BOOL InitThreadNodeInfo( PDEB_THREAD_NODE_INFO*, LPDEBUG_EVENT );
BOOL InsertThreadNode( PLIST, PNODE );
BOOL SetCurrentThreadNode( PLIST, PNODE );
BOOL DeleteThreadNode( PLIST, PNODE );
BOOL FreeThreadNodeInfo( PNODE );
BOOL DestroyThreadNode( PNODE );
BOOL DeleteCurrentThreadNode( PLIST );
//-- dll list and node specific linked list wrapper functions
int DllOrderFunction( PNODE, PNODE );
BOOL CreateDllList( PLIST* );
BOOL DestroyDllList( PLIST );
BOOL AllocDllNode( PNODE*, PDEB_DLL_NODE_INFO* );
BOOL InitDllNodeInfo( PDEB_DLL_NODE_INFO*, LPDEBUG_EVENT );
BOOL InsertDllNode( PLIST, PNODE );
BOOL SetCurrentDllNode( PLIST, PNODE );
BOOL DeleteDllNode( PLIST, PNODE );
BOOL FreeDllNodeInfo( PNODE );
BOOL DestroyDllNode( PNODE );
BOOL DeleteCurrentDllNode( PLIST );
// ************************************************************************
// FUNCTION : DebugEventThread( PDEB_STARTUP_INFO )
// PURPOSE : Main debug event processing loop
// COMMENTS :
// A new debug event thread is created for each Debuggee process.
// Return TRUE (non 0) if success, else FALSE (0)
// ************************************************************************
DWORD WINAPI
DebugEventThread( PDEB_STARTUP_INFO pDebStartupInfo )
{
#define BUFFER_SIZE 256
static BOOL fFirstTime = TRUE;
static TCHAR szDebuggeeTitle[128];
DEBUG_EVENT DebugEvent;
LPTSTR lpszDebugEventBuffer;
LPTSTR lpszTempBuffer;
//-- set the minimum error level for debugging events
SetDebugErrorLevel( Profile.DebugErrorLevel );
if( fFirstTime ) {
if( !LoadString( Global.hInstance, IDS_OFN_DEBUGGEE_TITLE, szDebuggeeTitle,
sizeof(szDebuggeeTitle)/sizeof(TCHAR) ) )
ErrorMessageBox( TEXT("LoadString()"),
Global.szApiFailed, szSourceFileName, __LINE__ );
}
//-- determine if 'attach to' or 'open new' debuggee
if( pDebStartupInfo->fActive ) {
if( !DebugActiveProcess( pDebStartupInfo->dwProcessId ) )
ErrorMessageBox( TEXT("DebugActiveProcess()"),
Global.szApiFailed, szSourceFileName, __LINE__ );
}
else {
if( !DebugNewProcess( pDebStartupInfo->lpstrPathName, szDebuggeeTitle ) )
ExitThread( FALSE );
}
//-- increment active process count
Global.dwActiveDebuggees++;
//-- create a local heap
{
SYSTEM_INFO SysInfo;
GetSystemInfo( &SysInfo ); // get the system memory page size
hHeap = HeapCreate( (DWORD) NULL, SysInfo.dwPageSize, 1000*SysInfo.dwPageSize );
}
//-- create and initialize the process list
CreateProcessList( &pProcessList );
//-- alloc temporary (life of thread) string buffers
lpszDebugEventBuffer = (LPTSTR) HeapAlloc( hHeap, (DWORD) NULL, BUFFER_SIZE );
lpszTempBuffer = (LPTSTR) HeapAlloc( hHeap, (DWORD) NULL, BUFFER_SIZE );
// ----------------------------------------------------------------------
// begin debug event processing loop
// ----------------------------------------------------------------------
for(;;) {
//-- wait for debug events
if( !WaitForDebugEvent( &DebugEvent, INFINITE ) ) {
ListBoxPrintF( pDebStartupInfo->hWndListBox, TEXT( "%s" ), TEXT( "Failed to attach to Debuggee..." ) );
fFinished = TRUE;
break;
}
// --------------------------------------------------------------------
// display each debug event as it occurs and handle minimal debug
// event processing
// --------------------------------------------------------------------
MakeCommonDebugEventString( lpszDebugEventBuffer, &DebugEvent );
switch( DebugEvent.dwDebugEventCode ) {
// ------------------------------------------------------------------
// exception occured
// ------------------------------------------------------------------
case EXCEPTION_DEBUG_EVENT:
//-- figure out which type of exception
switch( DebugEvent.u.Exception.ExceptionRecord.ExceptionCode ) {
//--standard exceptions
case EXCEPTION_ACCESS_VIOLATION:
StringAppendF( lpszDebugEventBuffer, TEXT( "%s%s" ),
TEXT( "Exception: " ), TEXT( "Access Violation" ) );
break;
case EXCEPTION_DATATYPE_MISALIGNMENT:
StringAppendF( lpszDebugEventBuffer, TEXT( "%s%s" ),
TEXT( "Exception: " ), TEXT( "Datatype Misalignment" ) );
break;
case EXCEPTION_BREAKPOINT:
StringAppendF( lpszDebugEventBuffer, TEXT( "%s%s" ),
TEXT( "Exception: " ), TEXT( "Breakpoint" ) );
break;
case EXCEPTION_SINGLE_STEP:
StringAppendF( lpszDebugEventBuffer, TEXT( "%s%s" ),
TEXT( "Exception: " ), TEXT( "Single Step" ) );
break;
case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
StringAppendF( lpszDebugEventBuffer, TEXT( "%s%s" ),
TEXT( "Exception: " ), TEXT( "Array Bound Exceeded" ) );
break;
case EXCEPTION_FLT_DENORMAL_OPERAND:
StringAppendF( lpszDebugEventBuffer, TEXT( "%s%s %s" ),
TEXT( "Exception: " ), TEXT( "Floating Point" ),
TEXT( "Denormal Operand" ) );
break;
case EXCEPTION_FLT_DIVIDE_BY_ZERO:
StringAppendF( lpszDebugEventBuffer, TEXT( "%s%s %s" ),
TEXT( "Exception: " ), TEXT( "Floating Point" ),
TEXT( "Divide By Zero" ) );
break;
case EXCEPTION_FLT_INEXACT_RESULT:
StringAppendF( lpszDebugEventBuffer, TEXT( "%s%s %s" ),
TEXT( "Exception: " ), TEXT( "Floating Point" ),
TEXT( "Inexact Result" ) );
break;
case EXCEPTION_FLT_INVALID_OPERATION:
StringAppendF( lpszDebugEventBuffer, TEXT( "%s%s %s" ),
TEXT( "Exception: " ), TEXT( "Floating Point" ),
TEXT( "Invalid Operation" ) );
break;
case EXCEPTION_FLT_OVERFLOW:
StringAppendF( lpszDebugEventBuffer, TEXT( "%s%s %s" ),
TEXT( "Exception: " ), TEXT( "Floating Point" ),
TEXT( "Overflow" ) );
break;
case EXCEPTION_FLT_STACK_CHECK:
StringAppendF( lpszDebugEventBuffer, TEXT( "%s%s %s" ),
TEXT( "Exception: " ), TEXT( "Floating Point" ),
TEXT( "Stack Check" ) );
break;
case EXCEPTION_FLT_UNDERFLOW:
StringAppendF( lpszDebugEventBuffer, TEXT( "%s%s %s" ),
TEXT( "Exception: " ), TEXT( "Floating Point" ),
TEXT( "Underflow" ) );
break;
case EXCEPTION_INT_DIVIDE_BY_ZERO:
StringAppendF( lpszDebugEventBuffer, TEXT( "%s%s %s" ),
TEXT( "Exception: " ), TEXT( "Integer" ),
TEXT( "Divide By Zero" ) );
break;
case EXCEPTION_INT_OVERFLOW:
StringAppendF( lpszDebugEventBuffer, TEXT( "%s%s %s" ),
TEXT( "Exception: " ), TEXT( "Integer" ),
TEXT( "Overflow" ) );
break;
case EXCEPTION_PRIV_INSTRUCTION:
StringAppendF( lpszDebugEventBuffer, TEXT( "%s%s" ),
TEXT( "Exception: " ), TEXT( "Privileged Instruction" ) );
break;
case EXCEPTION_IN_PAGE_ERROR:
StringAppendF( lpszDebugEventBuffer, TEXT( "%s%s" ),
TEXT( "Exception: " ), TEXT( "In Page Error" ) );
break;
//-- Debug exceptions
case DBG_TERMINATE_THREAD:
StringAppendF( lpszDebugEventBuffer, TEXT( "%s%s" ),
TEXT( "Debug Exception: " ), TEXT( "Terminate Thread" ) );
break;
case DBG_TERMINATE_PROCESS:
StringAppendF( lpszDebugEventBuffer, TEXT( "%s%s" ),
TEXT( "Debug Exception: " ), TEXT( "Terminate Process" ) );
break;
case DBG_CONTROL_C:
StringAppendF( lpszDebugEventBuffer, TEXT( "%s%s" ),
TEXT( "Debug Exception: " ), TEXT( "Control+C" ) );
break;
case DBG_CONTROL_BREAK:
StringAppendF( lpszDebugEventBuffer, TEXT( "%s%s" ),
TEXT( "Debug Exception: " ), TEXT( "Control+Break" ) );
break;
//-- RPC exceptions (some)
case RPC_S_UNKNOWN_IF:
StringAppendF( lpszDebugEventBuffer, TEXT( "%s%s" ),
TEXT( "RPC Exception: " ), TEXT( "Unknown Interface" ) );
break;
case RPC_S_SERVER_UNAVAILABLE:
StringAppendF( lpszDebugEventBuffer, TEXT( "%s%s" ),
TEXT( "RPC Exception: " ), TEXT( "Server Unavailable" ) );
break;
//-- VDM exceptions (minimal information)
case EXCEPTION_VDM_EVENT: // see DEBDebug.H for definition
StringAppendF( lpszDebugEventBuffer, TEXT( "%s" ),
TEXT( "VDM Exception: " ) );
default:
StringAppendF( lpszDebugEventBuffer, TEXT( "%s%s%X%s" ),
TEXT( "Exception: " ), TEXT( "Unknown [0x" ),
DebugEvent.u.Exception.ExceptionRecord.ExceptionCode,
TEXT( "]" ) );
break;
}
if( Profile.fVerbose ) {
StringAppendF( lpszDebugEventBuffer, TEXT( "\n + %s%d" ),
TEXT( "dwFirstChance: " ), DebugEvent.u.Exception.dwFirstChance );
}
else {
if( DebugEvent.u.Exception.dwFirstChance != 0 )
StringAppendF( lpszDebugEventBuffer, TEXT( "%s" ),
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -