summaryrefslogtreecommitdiff
path: root/src/plugins/dbghelpplug.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/dbghelpplug.c')
-rw-r--r--src/plugins/dbghelpplug.c192
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 */
-