mirror of
https://github.com/holub/mame
synced 2025-05-22 13:48:55 +03:00
On Windows, osd_break_into_debugger() will now dump a stack crawl
if there's no debugger attached. This means that asserts should have a full crawl now, for easier debugging.
This commit is contained in:
parent
8f8981db66
commit
3d1a55e19e
@ -118,11 +118,12 @@ class stack_walker
|
||||
{
|
||||
public:
|
||||
stack_walker();
|
||||
|
||||
|
||||
FPTR ip() const { return m_stackframe.AddrPC.Offset; }
|
||||
FPTR sp() const { return m_stackframe.AddrStack.Offset; }
|
||||
FPTR frame() const { return m_stackframe.AddrFrame.Offset; }
|
||||
|
||||
bool reset();
|
||||
void reset(CONTEXT &context, HANDLE thread);
|
||||
bool unwind();
|
||||
|
||||
@ -138,6 +139,7 @@ private:
|
||||
dynamic_bind<BOOL (WINAPI *)(HANDLE, LPCTSTR, BOOL)> m_sym_initialize;
|
||||
dynamic_bind<PVOID (WINAPI *)(HANDLE, DWORD64)> m_sym_function_table_access_64;
|
||||
dynamic_bind<DWORD64 (WINAPI *)(HANDLE, DWORD64)> m_sym_get_module_base_64;
|
||||
dynamic_bind<VOID (WINAPI *)(PCONTEXT)> m_rtl_capture_context;
|
||||
|
||||
static bool s_initialized;
|
||||
};
|
||||
@ -392,11 +394,15 @@ int main(int argc, char *argv[])
|
||||
// allocate symbols
|
||||
symbol_manager local_symbols(argv[0]);
|
||||
symbols = &local_symbols;
|
||||
|
||||
|
||||
// set up exception handling
|
||||
pass_thru_filter = SetUnhandledExceptionFilter(exception_filter);
|
||||
SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX);
|
||||
|
||||
// enable stack crawls for asserts
|
||||
extern void (*s_debugger_stack_crawler)();
|
||||
s_debugger_stack_crawler = winmain_dump_stack;
|
||||
|
||||
// if we're a GUI app, out errors to message boxes
|
||||
if (win_is_gui_application() || is_double_click_start(argc))
|
||||
{
|
||||
@ -582,6 +588,23 @@ static void osd_exit(running_machine &machine)
|
||||
}
|
||||
|
||||
|
||||
//============================================================
|
||||
// winmain_dump_stack
|
||||
//============================================================
|
||||
|
||||
void winmain_dump_stack()
|
||||
{
|
||||
// set up the stack walker
|
||||
stack_walker walker;
|
||||
if (!walker.reset())
|
||||
return;
|
||||
|
||||
// walk the stack
|
||||
while (walker.unwind())
|
||||
fprintf(stderr, " %p: %p%s\n", (void *)walker.frame(), (void *)walker.ip(), (symbols == NULL) ? "" : symbols->symbol_for_address(walker.ip()));
|
||||
}
|
||||
|
||||
|
||||
//============================================================
|
||||
// check_for_double_click_start
|
||||
//============================================================
|
||||
@ -755,14 +778,13 @@ static LONG WINAPI exception_filter(struct _EXCEPTION_POINTERS *info)
|
||||
|
||||
// walk the stack
|
||||
while (walker.unwind())
|
||||
fprintf(stderr, " %p: %p%s\n", (void *)walker.frame(), (void *)walker.ip(), symbols->symbol_for_address(walker.ip()));
|
||||
fprintf(stderr, " %p: %p%s\n", (void *)walker.frame(), (void *)walker.ip(), (symbols == NULL) ? "" : symbols->symbol_for_address(walker.ip()));
|
||||
|
||||
// exit
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// STACK WALKER
|
||||
//**************************************************************************
|
||||
@ -778,7 +800,8 @@ stack_walker::stack_walker()
|
||||
m_stack_walk_64(TEXT("dbghelp.dll"), "StackWalk64"),
|
||||
m_sym_initialize(TEXT("dbghelp.dll"), "SymInitialize"),
|
||||
m_sym_function_table_access_64(TEXT("dbghelp.dll"), "SymFunctionTableAccess64"),
|
||||
m_sym_get_module_base_64(TEXT("dbghelp.dll"), "SymGetModuleBase64")
|
||||
m_sym_get_module_base_64(TEXT("dbghelp.dll"), "SymGetModuleBase64"),
|
||||
m_rtl_capture_context(TEXT("kernel32.dll"), "RtlCaptureContext")
|
||||
{
|
||||
// zap the structs
|
||||
memset(&m_stackframe, 0, sizeof(m_stackframe));
|
||||
@ -797,6 +820,34 @@ stack_walker::stack_walker()
|
||||
// reset - set up a new context
|
||||
//-------------------------------------------------
|
||||
|
||||
bool stack_walker::reset()
|
||||
{
|
||||
// set up the initial state
|
||||
if (!m_rtl_capture_context)
|
||||
return false;
|
||||
(*m_rtl_capture_context)(&m_context);
|
||||
m_thread = GetCurrentThread();
|
||||
m_first = true;
|
||||
|
||||
// initialize the stackframe
|
||||
memset(&m_stackframe, 0, sizeof(m_stackframe));
|
||||
m_stackframe.AddrPC.Mode = AddrModeFlat;
|
||||
m_stackframe.AddrFrame.Mode = AddrModeFlat;
|
||||
m_stackframe.AddrStack.Mode = AddrModeFlat;
|
||||
|
||||
// pull architecture-specific fields from the context
|
||||
#ifdef PTR64
|
||||
m_stackframe.AddrPC.Offset = m_context.Rip;
|
||||
m_stackframe.AddrFrame.Offset = m_context.Rsp;
|
||||
m_stackframe.AddrStack.Offset = m_context.Rsp;
|
||||
#else
|
||||
m_stackframe.AddrPC.Offset = m_context.Eip;
|
||||
m_stackframe.AddrFrame.Offset = m_context.Ebp;
|
||||
m_stackframe.AddrStack.Offset = m_context.Esp;
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
void stack_walker::reset(CONTEXT &initial, HANDLE thread)
|
||||
{
|
||||
// set up the initial state
|
||||
|
@ -149,3 +149,4 @@ void CLIB_DECL mame_printf_verbose(const char *text, ...) ATTR_PRINTF(1,2);
|
||||
|
||||
// use this to ping the watchdog
|
||||
void winmain_watchdog_ping(void);
|
||||
void winmain_dump_stack();
|
||||
|
@ -50,6 +50,7 @@
|
||||
// MAMEOS headers
|
||||
#include "winutf8.h"
|
||||
#include "strconv.h"
|
||||
#include "strconv.h"
|
||||
|
||||
|
||||
//============================================================
|
||||
@ -67,6 +68,14 @@
|
||||
|
||||
|
||||
|
||||
//============================================================
|
||||
// GLOBAL VARIABLES
|
||||
//============================================================
|
||||
|
||||
void (*s_debugger_stack_crawler)() = NULL;
|
||||
|
||||
|
||||
|
||||
//============================================================
|
||||
// osd_malloc
|
||||
//============================================================
|
||||
@ -167,4 +176,6 @@ void osd_break_into_debugger(const char *message)
|
||||
win_output_debug_string_utf8(message);
|
||||
DebugBreak();
|
||||
}
|
||||
else if (s_debugger_stack_crawler != NULL)
|
||||
(*s_debugger_stack_crawler)();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user