-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
Commit
…broken for me right now, so this only works for libjulia-release
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,11 +3,16 @@ | |
struct FuncInfo{ | ||
const Function* func; | ||
size_t lengthAdr; | ||
#if defined(_OS_WINDOWS_) && defined(_CPU_X86_64_) | ||
PRUNTIME_FUNCTION fnentry; | ||
#endif | ||
std::vector<JITEvent_EmittedFunctionDetails::LineStart> lines; | ||
}; | ||
|
||
#ifdef _OS_WINDOWS_ | ||
#if defined(_OS_WINDOWS_) && defined(_CPU_X86_64_) | ||
#include <dbghelp.h> | ||
extern "C" EXCEPTION_DISPOSITION _seh_exception_handler(PEXCEPTION_RECORD ExceptionRecord,void *EstablisherFrame, PCONTEXT ContextRecord, void *DispatcherContext); | ||
extern volatile int jl_in_stackwalk; | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong.
ivarne
Member
|
||
#endif | ||
|
||
struct revcomp { | ||
|
@@ -26,9 +31,9 @@ class JuliaJITEventListener: public JITEventListener | |
virtual void NotifyFunctionEmitted(const Function &F, void *Code, | ||
size_t Size, const EmittedFunctionDetails &Details) | ||
{ | ||
FuncInfo tmp = {&F, Size, Details.LineStarts}; | ||
if (tmp.lines.size() != 0) info[(size_t)(Code)] = tmp; | ||
#if defined(_OS_WINDOWS_) && defined(_CPU_X86_64_) | ||
assert(!jl_in_stackwalk); | ||
jl_in_stackwalk = 1; | ||
uintptr_t catchjmp = (uintptr_t)Code+Size; | ||
*(uint8_t*)(catchjmp+0) = 0x48; | ||
*(uint8_t*)(catchjmp+1) = 0xb8; // mov RAX, QWORD PTR [...] | ||
|
@@ -48,8 +53,24 @@ class JuliaJITEventListener: public JITEventListener | |
UnwindData[6] = 1; // first instruction | ||
UnwindData[7] = 0x50; // push RBP | ||
*(DWORD*)&UnwindData[8] = (DWORD)(catchjmp-(intptr_t)Code); | ||
RtlAddFunctionTable(tbl,1,(DWORD64)Code); | ||
DWORD mod_size = (DWORD)(size_t)(&UnwindData[8]-(uint8_t*)Code); | ||
if (!SymLoadModuleEx(GetCurrentProcess(), NULL, NULL, NULL, (DWORD64)Code, mod_size, NULL, SLMFLAG_VIRTUAL)) { | ||
JL_PRINTF(JL_STDERR, "WARNING: failed to insert function info for backtrace\n"); | ||
} | ||
else { | ||
if (!SymAddSymbol(GetCurrentProcess(), (ULONG64)Code, F.getName().data(), (DWORD64)Code, mod_size, 0)) { | ||
JL_PRINTF(JL_STDERR, "WARNING: failed to insert function name into debug info\n"); | ||
} | ||
if (!RtlAddFunctionTable(tbl,1,(DWORD64)Code)) { | ||
JL_PRINTF(JL_STDERR, "WARNING: failed to insert function stack unwind info\n"); | ||
} | ||
} | ||
jl_in_stackwalk = 0; | ||
FuncInfo tmp = {&F, Size, tbl, Details.LineStarts}; | ||
#else | ||
FuncInfo tmp = {&F, Size, Details.LineStarts}; | ||
#endif | ||
if (tmp.lines.size() != 0) info[(size_t)(Code)] = tmp; | ||
} | ||
|
||
std::map<size_t, FuncInfo, revcomp>& getMap() | ||
|
@@ -60,9 +81,9 @@ class JuliaJITEventListener: public JITEventListener | |
|
||
JuliaJITEventListener *jl_jit_events; | ||
|
||
extern "C" void getFunctionInfo(const char **name, int *line, const char **filename,size_t pointer); | ||
extern "C" void jl_getFunctionInfo(const char **name, int *line, const char **filename,size_t pointer); | ||
|
||
void getFunctionInfo(const char **name, int *line, const char **filename, size_t pointer) | ||
void jl_getFunctionInfo(const char **name, int *line, const char **filename, size_t pointer) | ||
{ | ||
std::map<size_t, FuncInfo, revcomp> &info = jl_jit_events->getMap(); | ||
*name = NULL; | ||
|
@@ -107,6 +128,19 @@ void getFunctionInfo(const char **name, int *line, const char **filename, size_t | |
} | ||
|
||
#if defined(_OS_WINDOWS_) && defined(_CPU_X86_64_) | ||
|
||
extern "C" void* CALLBACK jl_getUnwindInfo(HANDLE hProcess, ULONG64 AddrBase, ULONG64 UserContext); | ||
|
||
void* CALLBACK jl_getUnwindInfo(HANDLE hProcess, ULONG64 AddrBase, ULONG64 UserContext) | ||
{ | ||
std::map<size_t, FuncInfo, revcomp> &info = jl_jit_events->getMap(); | ||
std::map<size_t, FuncInfo, revcomp>::iterator it = info.lower_bound(AddrBase); | ||
if (it != info.end() && (size_t)(*it).first + (*it).second.lengthAdr >= AddrBase) { | ||
return (void*)(*it).second.fnentry; | ||
} | ||
return NULL; | ||
} | ||
|
||
class JITMemoryManagerWin : public JITMemoryManager { | ||
private: | ||
JITMemoryManager *JMM; | ||
|
Shouldn't this also be
extern "C"
since the value is set intask.c
?