Project

General

Profile

Feature #3875 » 0001-Add-C-level-backtrace-for-MSWIN-x86.patch

pweldon (Peter Weldon), 09/25/2010 10:06 AM

View differences:

include/ruby/win32.h
typedef uintptr_t (*asynchronous_func_t)(uintptr_t self, int argc, uintptr_t* argv);
uintptr_t rb_w32_asynchronize(asynchronous_func_t func, uintptr_t self, int argc, uintptr_t* argv, uintptr_t intrval);
/* backtrace */
void rb_w32_backtrace();
#if defined __GNUC__ && __GNUC__ >= 4
#pragma GCC visibility pop
#endif
vm_dump.c
}
fprintf(stderr, "\n");
}
#elif _WIN32
rb_w32_backtrace();
#endif
}
win32/win32.c
#ifdef __MINGW32__
#include <mswsock.h>
#endif
#if _MSC_VER && _M_IX86
#include <DbgHelp.h>
#endif
#include "ruby/win32.h"
#include "win32/dir.h"
#define isdirsep(x) ((x) == '/' || (x) == '\\')
......
return *ip < 0;
}
#endif
#if _MSC_VER && _M_IX86
static struct DumpArgs {
DWORD thread_id;
HANDLE event;
};
static void
dump_thread(void *arg)
{
struct DumpArgs* dump_args = (struct DumpArgs*)arg;
HANDLE process = GetCurrentProcess();
HANDLE thread = OpenThread(THREAD_ALL_ACCESS, 0, dump_args->thread_id);
STACKFRAME64 stackFrame;
CONTEXT context;
BOOL bool_rc;
DWORD64 dwDisplacement;
DWORD64 dwAddress;
char buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(TCHAR)];
PSYMBOL_INFO pSymbol = (PSYMBOL_INFO)buffer;
IMAGEHLP_LINE64 line;
DWORD dwLineDisplacement;
SymSetOptions(SYMOPT_UNDNAME | SYMOPT_DEFERRED_LOADS | SYMOPT_DEBUG | SYMOPT_LOAD_LINES);
if (!SymInitialize(process, NULL, TRUE)) abort();
memset(&context, 0, sizeof(CONTEXT));
context.ContextFlags = CONTEXT_FULL;
bool_rc = GetThreadContext(thread, &context);
if(!bool_rc) abort();
memset(&stackFrame,0,sizeof(STACKFRAME64));
stackFrame.AddrPC.Mode = AddrModeFlat;
stackFrame.AddrPC.Offset = context.Eip;
stackFrame.AddrFrame.Mode = AddrModeFlat;
stackFrame.AddrFrame.Offset = context.Ebp;
stackFrame.AddrStack.Mode = AddrModeFlat;
stackFrame.AddrStack.Offset = context.Esp;
fprintf(stderr, "-- C level backtrace information "
"-------------------------------------------\n");
while(1)
{
bool_rc = StackWalk64(
IMAGE_FILE_MACHINE_I386,
process,
thread,
&stackFrame,
(PVOID)&context,
NULL,
SymFunctionTableAccess64,
SymGetModuleBase64,
NULL);
if(!bool_rc) break;
dwDisplacement = 0;
dwAddress = stackFrame.AddrPC.Offset;
memset(buffer, 0, sizeof(buffer));
pSymbol->SizeOfStruct = sizeof(SYMBOL_INFO);
pSymbol->MaxNameLen = MAX_SYM_NAME;
if (SymFromAddr(process, dwAddress, &dwDisplacement, pSymbol))
{
fprintf(stderr, "(%s)", pSymbol->Name);
}
memset(&line, 0, sizeof(IMAGEHLP_LINE64));
line.SizeOfStruct = sizeof(IMAGEHLP_LINE64);
if (SymGetLineFromAddr64(process, dwAddress, &dwLineDisplacement, &line))
{
fprintf(stderr, "(%s:%lu)", line.FileName, line.LineNumber);
}
fprintf(stderr, " [0x%08I64x]\n", dwAddress);
}
fprintf(stderr, "\n");
if (!CloseHandle(thread)) abort();
if (!SymCleanup(process)) abort();
if (!SetEvent(dump_args->event)) abort();
}
void
rb_w32_backtrace() {
struct DumpArgs dump_args;
dump_args.thread_id = GetCurrentThreadId();
dump_args.event = CreateEvent(NULL, TRUE, FALSE, NULL);
if(!dump_args.event) abort();
_beginthread(dump_thread,0,&dump_args);
if (WaitForSingleObject(dump_args.event, INFINITE) != WAIT_OBJECT_0) abort();
}
#elif
void
rb_w32_backtrace() {
}
#endif
-
(1-1/3)