diff options
Diffstat (limited to 'src/plugins/dbghelpplug.c')
-rw-r--r-- | src/plugins/dbghelpplug.c | 192 |
1 files changed, 94 insertions, 98 deletions
diff --git a/src/plugins/dbghelpplug.c b/src/plugins/dbghelpplug.c index 32b30d69a..d121e9492 100644 --- a/src/plugins/dbghelpplug.c +++ b/src/plugins/dbghelpplug.c @@ -1,23 +1,29 @@ // Copyright (c) Hercules Dev Team, licensed under GNU GPL. -// Ported from eAthena Dev Team's version @ http://eathena-project.googlecode.com/svn/trunk/src/plugins/dbghelpplug.c // See the LICENSE file -// dbghelpplug.dll Hercules Plugin +// Portions Copyright (c) Athena Dev Teams + +// Ported from eAthena Dev Team's version @ http://eathena-project.googlecode.com/svn/trunk/src/plugins/dbghelpplug.c +// Currently supported dbghelp 5.1 #include <stdio.h> #include <string.h> +#include "../common/sysinfo.h" #include "../common/HPMi.h" +#include "../common/HPMDataCheck.h" + +/** + * Plugin basic information + **/ HPExport struct hplugin_info pinfo = { - "DBGHelpPlug", // Plugin name - SERVER_TYPE_MAP,// Which server types this plugin works with? - "0.3", // Plugin version - HPM_VERSION, // HPM Version (don't change, macro is automatically updated) + "Debug Help", + SERVER_TYPE_ALL, + "0.5", + HPM_VERSION, }; -#ifdef _WIN32 - ///////////////////////////////////////////////////////////////////// -// Include files +// Include files // #include <assert.h> @@ -32,13 +38,12 @@ HPExport struct hplugin_info pinfo = { #include <time.h> ///////////////////////////////////////////////////////////////////// -// Types from Cvconst.h (DIA SDK) +// Types from Cvconst.h (DIA SDK) // #ifdef _NO_CVCONST_H -typedef enum _BasicType -{ +typedef enum _BasicType { btNoType = 0, btVoid = 1, btChar = 2, @@ -66,7 +71,7 @@ typedef enum _UdtKind UdtUnion } UdtKind; /* -typedef enum _SymTag { +typedef enum _SymTag { SymTagNull = 0, SymTagExe = 1, SymTagCompiland = 2, @@ -102,6 +107,7 @@ typedef enum _SymTag { */ #endif /* _NO_CVCONST_H */ +struct sysinfo_interface *sysinfo; ///////////////////////////////////////////////////////////////////// // dbghelp function prototypes @@ -214,6 +220,10 @@ typedef struct _InternalData { "Please report the crash in the bug tracker:\n" \ "http://hercules.ws/board/tracker/\n" +// Print object children? +// WARNING: This will generate huge dump files! +//#define DBG_PRINT_CHILDREN + ///////////////////////////////////////////////////////////////////// // Global variables @@ -235,7 +245,7 @@ SYMGETMODULEBASE SymGetModuleBase_ = NULL; ///////////////////////////////////////////////////////////////////// // Code -/// Writes the minidump to file. The callback function will at the +/// Writes the minidump to file. The callback function will at the /// same time write the list of modules to the log file. /// /// @param file Filename of the minidump @@ -324,7 +334,7 @@ Dhp__PrintModuleInfoCallback( return TRUE; } -/// Prints details about the current process, platform and exception +/// Prints details about the current process, platform and exception /// information to the log file. /// /// @param exception Exception info @@ -336,25 +346,25 @@ Dhp__PrintProcessInfo( CONTEXT* context, FILE* log_file) { - OSVERSIONINFOA oi; LPSTR cmd_line; fprintf(log_file, - "\nProcess info:\n"); + "\nProcess information:\n"); // print the command line cmd_line = GetCommandLineA(); if( cmd_line ) fprintf(log_file, - "Cmd line: %s\n", + "Command line: %s\n", cmd_line); - // print information about the OS - oi.dwOSVersionInfoSize = sizeof(oi); - GetVersionExA(&oi); - fprintf(log_file, - "Platform: Windows OS version %d.%d build %d %s\n", - oi.dwMajorVersion, oi.dwMinorVersion, oi.dwBuildNumber, oi.szCSDVersion); + // Print system information + if( sysinfo ) { + fprintf(log_file, + "Platform: %s\n CPU: %s\nApplication architecture: %s\nCompiler: %s\n%s: %s\n", + sysinfo->osversion(), sysinfo->cpu(), (sysinfo->is64bit())?"x64":"x86", + sysinfo->compiler(), sysinfo->vcstype(), sysinfo->vcsrevision_src()); + } // print the exception code if( exception ) @@ -418,7 +428,7 @@ Dhp__PrintProcessInfo( { fprintf(log_file, "eip=%08x esp=%08x ebp=%08x iopl=%1x %s %s %s %s %s %s %s %s %s %s\n", - context->Eip, context->Esp, context->Ebp, + context->Eip, context->Esp, context->Ebp, (context->EFlags >> 12) & 3, // IOPL level value context->EFlags & 0x00100000 ? "vip" : " ", // VIP (virtual interrupt pending) context->EFlags & 0x00080000 ? "vif" : " ", // VIF (virtual interrupt flag) @@ -487,7 +497,7 @@ Dhp__PrintTypeName( switch( symtag ) { case SymTagEnum: - { + { WCHAR* pwszTypeName; if( SymGetTypeInfo_(hProcess, modBase, typeIndex, TI_GET_SYMNAME, &pwszTypeName) ) @@ -945,6 +955,12 @@ Dhp__PrintDataValue( BYTE b = 0; for( i = 0; i < length; ++i ) b += p[i]; // add to make sure it's not optimized out in release mode + + // Don't continue if there's no valid data + if( b == 0 ) { + fprintf(log_file, "<no data>"); + return; + } } __except( EXCEPTION_EXECUTE_HANDLER ) { @@ -1007,7 +1023,7 @@ Dhp__PrintDataValue( fprintf(log_file, "0x%p", *(void**)pVariable); if( SymGetTypeInfo_(hProcess, modBase, typeIndex, TI_GET_TYPE, &childTypeIndex) && - SymGetTypeInfo_(hProcess, modBase, childTypeIndex, TI_GET_SYMTAG, &childSymtag) && + SymGetTypeInfo_(hProcess, modBase, childTypeIndex, TI_GET_SYMTAG, &childSymtag) && childSymtag != SymTagPointerType ) { DWORD childBasetype; @@ -1047,6 +1063,7 @@ Dhp__PrintDataValue( Dhp__PrintValueBytes(log_file, (BYTE*)pVariable, length); break; } + LocalFree(&childSymtag); if( !SymGetTypeInfo_( hProcess, modBase, typeIndex, TI_GET_COUNT, &count) ) { fprintf(log_file, "<count not found>"); @@ -1066,29 +1083,30 @@ Dhp__PrintDataValue( } break; default: -#if 0 - {//## TODO show children of structs/unions - TI_FINDCHILDREN_PARAMS* children; - DWORD childCount; +#ifdef DBG_PRINT_CHILDREN + { + TI_FINDCHILDREN_PARAMS *children = NULL; + size_t childrenSize; + DWORD childCount = 0; DWORD i; // count children - if( !SymGetTypeInfo_(hProcess, modBase, typeIndex, TI_GET_CHILDRENCOUNT, &childCount) ) - { - fprintf(log_file, "<child count not found>"); + if( !SymGetTypeInfo_(hProcess, modBase, typeIndex, TI_GET_CHILDRENCOUNT, &childCount) + || !childCount ) { + fprintf(log_file, "<no children found>"); Dhp__PrintValueBytes(log_file, (BYTE*)pVariable, length); - break; + return; } // Prepare to get an array of "TypeIds", representing each of the children. // SymGetTypeInfo(TI_FINDCHILDREN) expects more memory than just a // TI_FINDCHILDREN_PARAMS struct has. Use derivation to accomplish this. - children = (TI_FINDCHILDREN_PARAMS*)LocalAlloc(LMEM_FIXED, sizeof(TI_FINDCHILDREN_PARAMS)+childCount*sizeof(ULONG)); + childrenSize = sizeof(TI_FINDCHILDREN_PARAMS)+childCount*sizeof(ULONG); + children = (TI_FINDCHILDREN_PARAMS*)LocalAlloc(LMEM_ZEROINIT, childrenSize); children->Count = childCount; - children->Start= 0; // Get the array of TypeIds, one for each child type - if( !SymGetTypeInfo_(hProcess, modBase, typeIndex, TI_FINDCHILDREN, &children) ) + if( !SymGetTypeInfo_(hProcess, modBase, typeIndex, TI_FINDCHILDREN, children) || !children ) { fprintf(log_file, "<children not found>"); Dhp__PrintValueBytes(log_file, (BYTE*)pVariable, length); @@ -1097,15 +1115,15 @@ Dhp__PrintDataValue( } // Iterate through each of the children - fprintf(log_file, "{"); + fprintf(log_file, "\n{"); for( i = 0; i < childCount; ++i ) { DWORD childOffset; - DWORD childTypeid; - WCHAR* childName; + WCHAR *childName = NULL; + DWORD childTypeId; DWORD_PTR pData; - if( i > 0 ) fprintf(log_file, ","); + fprintf(log_file, "\n\t"); // Get the offset of the child member, relative to its parent if( !SymGetTypeInfo_(hProcess, modBase, children->ChildId[i], TI_GET_OFFSET, &childOffset) ) @@ -1114,30 +1132,26 @@ Dhp__PrintDataValue( continue; } - // Get the real "TypeId" of the child. - if( !SymGetTypeInfo_(hProcess, modBase, children->ChildId[i], TI_GET_TYPEID, &childTypeid) ) - { - fprintf(log_file, "<child typeid not found>"); - continue; - } - // Calculate the address of the member pData = (DWORD_PTR)pVariable; pData += childOffset; - // print name of the child - if( !SymGetTypeInfo_(hProcess, modBase, childTypeid, TI_GET_SYMNAME, &childName) ) - { - fprintf(log_file, "<child symname not found>"); - continue; + if( !SymGetTypeInfo_(hProcess, modBase, children->ChildId[i], TI_GET_SYMNAME, &childName) ) { + fprintf(log_file, "<child symbol name not found>"); + continue; } fprintf(log_file, "%ws=", childName); LocalFree(childName); + if( !SymGetTypeInfo_(hProcess, modBase, children->ChildId[i], TI_GET_TYPEID, &childTypeId) ) { + fprintf(log_file, "<child type id not found>"); + continue; + } + // print contents of the child - Dhp__PrintDataContents(childTypeid, (PVOID)pData, interData); + Dhp__PrintDataContents(childTypeId, (PVOID)pData, pInterData); } - fprintf(log_file, "}"); + fprintf(log_file, "\n}"); LocalFree(children); } @@ -1277,9 +1291,9 @@ Dhp__PrintSymbolInfo( assert( pSymInfo != NULL ); assert( pInterData != NULL ); - switch( pSymInfo->Tag ) + switch( pSymInfo->Tag ) { - case SymTagData: Dhp__PrintDataInfo( pSymInfo, pInterData ); break; + case SymTagData: Dhp__PrintDataInfo( pSymInfo, pInterData ); break; default: /*fprintf(pInterData->log_file, "<unsupported symtag %d>", pSymInfo->Tag);*/ break; } } @@ -1431,7 +1445,8 @@ Dhp__PrintFunctionDetails( pInterData->log_locals = FALSE; pInterData->log_globals = FALSE; pInterData->nr_of_var = 0; - SymEnumSymbols_(hProcess, 0, 0, Dhp__EnumSymbolsCallback, pInterData); + if( !SymEnumSymbols_(hProcess, 0, 0, Dhp__EnumSymbolsCallback, pInterData) ) + fprintf(log_file, "<failed enumerating symbols>"); fprintf(log_file, ")"); @@ -1463,7 +1478,8 @@ Dhp__PrintFunctionDetails( pInterData->log_locals = TRUE; pInterData->log_globals = FALSE; pInterData->nr_of_var = 0; - SymEnumSymbols_(hProcess, 0, 0, Dhp__EnumSymbolsCallback, pInterData); + if( !SymEnumSymbols_(hProcess, 0, 0, Dhp__EnumSymbolsCallback, pInterData) ) + fprintf(log_file, "!!failed enumerating symbols!!"); pInterData->nr_of_frame = ++nr_of_frame; LocalFree(pSymbolInfo); @@ -1611,7 +1627,10 @@ Dhp__LoadDbghelpDll() // Initialize the dbghelp DLL with the default path and automatic // module enumeration (and loading of symbol tables) for this process. - SymInitialize_(GetCurrentProcess(), NULL, TRUE); + if( !SymInitialize_(GetCurrentProcess(), NULL, TRUE) ) { + printf("Failed to initialize symbols. Error: %u\n", GetLastError()); + return FALSE; + } return TRUE; } @@ -1630,7 +1649,8 @@ Dhp__LoadDbghelpDll() static VOID Dhp__UnloadDbghlpDll() { - SymCleanup_(GetCurrentProcess()); + if( !SymCleanup_(GetCurrentProcess()) ) + printf("Failed to cleanup symbols! Error: %u\n", GetLastError()); FreeLibrary(dbghelp_dll); dbghelp_dll = NULL; @@ -1768,49 +1788,25 @@ Dhp__UnhandledExceptionFilter(PEXCEPTION_POINTERS ptrs) return EXCEPTION_EXECUTE_HANDLER; } - ///////////////////////////////////////////////////////////////////// -// DLL stuff -#if !defined(DBG_EMBEDDED) +// Plugin /// Previous exception filter. static LPTOP_LEVEL_EXCEPTION_FILTER previousFilter; -#if defined(__GNUC__) -// GNU : define DLL load/unload functions -static void Dhp__OnStartup(void) __attribute__((constructor)); -static void Dhp__OnExit(void) __attribute__((destructor)); -#endif /* defined(__GNUC__) */ - -/// Installs as the unhandled exception handler. -void Dhp__OnStartup(void) -{ - // Install the unhandled exception filter function +/** + * Initializes plugin + * Installs a new unhandled exception filter (Dhp__UnhandledExceptionFilter) + **/ +HPExport void plugin_init (void) { previousFilter = SetUnhandledExceptionFilter(Dhp__UnhandledExceptionFilter); + sysinfo = GET_SYMBOL("sysinfo"); } -/// Uninstalls the handler. -void Dhp__OnExit(void) -{ +/** + * Finalizes plugin + * Uninstalls the handler + **/ +HPExport void plugin_final (void) { SetUnhandledExceptionFilter(previousFilter); } - -#if !defined(__GNUC__) -// Windows : invoke DLL load/unload functions -BOOL APIENTRY DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved) -{ - switch( dwReason ) - { - case DLL_PROCESS_ATTACH: Dhp__OnStartup(); break; - case DLL_PROCESS_DETACH: Dhp__OnExit(); break; - } - return TRUE; -} -#endif /* !defined(__GNUC__) */ -#endif /* !defined(DBG_EMBEDDED) */ - -HPExport void plugin_init (void) { -} - -#endif /* _WIN32 */ - |