示例#1
0
static DWORD64 WINAPI JuliaGetModuleBase64(
        _In_  HANDLE hProcess,
        _In_  DWORD64 dwAddr)
{
    //jl_printf(JL_STDOUT, "lookup base %d\n", dwAddr);
#ifdef _CPU_X86_64_
    DWORD64 ImageBase;
    PRUNTIME_FUNCTION fn = RtlLookupFunctionEntry(dwAddr, &ImageBase, &HistoryTable);
    if (fn) return ImageBase;
    if (jl_in_stackwalk) {
        return 0;
    }
    jl_in_stackwalk = 1;
    DWORD64 fbase = SymGetModuleBase64(hProcess, dwAddr);
    jl_in_stackwalk = 0;
    return fbase;
#else
    if (dwAddr == HistoryTable.dwAddr) return HistoryTable.ImageBase;
    DWORD64 ImageBase = jl_getUnwindInfo(dwAddr);
    if (ImageBase) {
        HistoryTable.dwAddr = dwAddr;
        HistoryTable.ImageBase = ImageBase;
        return ImageBase;
    }
    return SymGetModuleBase64(hProcess, dwAddr);
#endif
}
示例#2
0
/***********************************************************************
 *		SymGetModuleBase (DBGHELP.@)
 */
DWORD WINAPI SymGetModuleBase(HANDLE hProcess, DWORD dwAddr)
{
    DWORD64     ret;

    ret = SymGetModuleBase64(hProcess, dwAddr);
    return validate_addr64(ret) ? ret : 0;
}
示例#3
0
		void StackWalker::WriteModuleName(std::ostream& os, HANDLE process, DWORD64 program_counter) 
		{
			DWORD64 module_base = SymGetModuleBase64(process, program_counter);
			if (module_base) 
			{
				std::string module_name = GetModulePath(reinterpret_cast<HMODULE>(module_base));
				if (!module_name.empty())
					os << module_name << " | ";
				else 
					os << "Unknown module | ";
			} 
			else 
			{
				os << "Unknown module | ";
			}
		}
示例#4
0
prmap_t *Paddr_to_map(struct ps_prochandle *P, uintptr_t addr)
{
    DWORD64 p;
    prmap_t *t;

    if ((p = SymGetModuleBase64(P->phandle, addr)) == 0) {
        dprintf("SymGetModuleBase64 failed (%d) at address %p: %x\n",
                P->pid, addr, GetLastError());
        return NULL;
    }
    if ((t = malloc(sizeof(prmap_t))) == NULL) {
        return NULL;
    }

    t->pr_vaddr = p;
    t->pr_mflags = MA_READ;

    return t;
}
示例#5
0
    void HEART_API InitMemTracking()
    {
#ifdef HEART_TRACK_MEMORY_ALLOCS
        InitializeCriticalSection(&g_access);
        hSysCall::hInitSystemDebugLibs();
        if (g_file == NULL)
        {
            if (g_file = fopen("mem_track.txt", "w"))
            {
                g_open = hTrue;
                hMemTrackingHeader header;
                header.baseAddress_=SymGetModuleBase64(GetCurrentProcess(), (DWORD64)&InitMemTracking);
                GetModuleFileName(0, header.moduleName_, (hUint)hArraySize(header.moduleName_));
                fwrite(&header, sizeof(hMemTrackingHeader), 1, g_file);
                fwrite("\n", 1, 1, g_file);
                atexit(memTrackExitHandle);
                //TrackPushMarker("ROOT");
            }
        }
#endif
    }
示例#6
0
文件: mgwhelp.c 项目: aijiekj/drmingw
/*
 * The GetModuleBase64 function retrieves the base address of the module that
 * contains the specified address.
 *
 * Same as SymGetModuleBase64, but that seems to often cause problems.
 */
DWORD64 WINAPI
MgwSymGetModuleBase64(HANDLE hProcess, DWORD64 dwAddress)
{
    if (hProcess == GetCurrentProcess()) {
        HMODULE hModule = NULL;
        BOOL bRet = GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS |
                                       GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
                                       (LPCSTR)(UINT_PTR)dwAddress,
                                       &hModule);
        if (bRet) {
            return (DWORD64)(UINT_PTR)hModule;
        }
    }

    MEMORY_BASIC_INFORMATION Buffer;
    if (VirtualQueryEx(hProcess, (LPCVOID)(UINT_PTR)dwAddress, &Buffer, sizeof Buffer) != 0) {
        return (DWORD64)(UINT_PTR)Buffer.AllocationBase;
    }

    return SymGetModuleBase64(hProcess, dwAddress);
}
示例#7
0
static int find_pe_symbol_by_name(Context * ctx, int frame, ContextAddress ip, char * name, Symbol * sym) {
    HANDLE process = get_context_handle(ctx->parent == NULL ? ctx : ctx->parent);
    ULONG64 buffer[(sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(TCHAR) + sizeof(ULONG64) - 1) / sizeof(ULONG64)];
    SYMBOL_INFO * info = (SYMBOL_INFO *)buffer;
    IMAGEHLP_STACK_FRAME stack_frame;
    DWORD err;

    if (set_pe_context(ctx, frame, ip, process, &stack_frame) < 0) return -1;

    memset(info, 0, sizeof(SYMBOL_INFO));
    info->SizeOfStruct = sizeof(SYMBOL_INFO);
    info->MaxNameLen = MAX_SYM_NAME;

    if (find_cache_symbol(ctx, frame, stack_frame.InstructionOffset, name, sym)) return errno ? -1 : 0;

    /* TODO: SymFromName() searches only main executable, need to search DLLs too */
    if (SymFromName(process, name, info) && info->Tag != SymTagPublicSymbol) {
        syminfo2symbol(ctx, frame, info, sym);
        add_cache_symbol(ctx, stack_frame.InstructionOffset, name, sym, 0);
        return 0;
    }
    if (stack_frame.InstructionOffset != 0) {
        DWORD64 module = SymGetModuleBase64(process, stack_frame.InstructionOffset);
        if (module != 0 && SymGetTypeFromName(process, module, name, info)) {
            syminfo2symbol(ctx, frame, info, sym);
            add_cache_symbol(ctx, stack_frame.InstructionOffset, name, sym, 0);
            return 0;
        }
    }
    set_win32_errno(err = GetLastError());
    if (err == 0 || err == ERROR_MOD_NOT_FOUND) {
        add_cache_symbol(ctx, stack_frame.InstructionOffset, name, NULL, ERR_SYM_NOT_FOUND);
        errno = ERR_SYM_NOT_FOUND;
    }
    return -1;
}
示例#8
0
void jl_getDylibFunctionInfo(const char **name, size_t *line, const char **filename, size_t pointer, int *fromC, int skipC)
{
#ifdef _OS_WINDOWS_
    DWORD fbase = SymGetModuleBase64(GetCurrentProcess(),(DWORD)pointer);
    char *fname = 0;
    if (fbase != 0) {
#else
    Dl_info dlinfo;
    const char *fname = 0;
    if ((dladdr((void*)pointer, &dlinfo) != 0) && dlinfo.dli_fname) {
        *fromC = !jl_is_sysimg(dlinfo.dli_fname);
        if (skipC && *fromC)
            return;
        // In case we fail with the debug info lookup, we at least still
        // have the function name, even if we don't have line numbers
        *name = dlinfo.dli_sname;
        *filename = dlinfo.dli_fname;
        uint64_t fbase = (uint64_t)dlinfo.dli_fbase;
#endif
        obfiletype::iterator it = objfilemap.find(fbase);
        llvm::object::ObjectFile *obj = NULL;
        DIContext *context = NULL;
        int64_t slide = 0;
#ifndef _OS_WINDOWS_
        fname = dlinfo.dli_fname;
#else
        IMAGEHLP_MODULE64 ModuleInfo;
        ModuleInfo.SizeOfStruct = sizeof(IMAGEHLP_MODULE64);
        SymGetModuleInfo64(GetCurrentProcess(), (DWORD64)pointer, &ModuleInfo);
        fname = ModuleInfo.LoadedImageName;
        *fromC = !jl_is_sysimg(fname);
        if (skipC && *fromC)
            return;
#endif
        if (it == objfilemap.end()) {
#ifdef _OS_DARWIN_
           // First find the uuid of the object file (we'll use this to make sure we find the
           // correct debug symbol file).
           uint8_t uuid[16], uuid2[16];
#ifdef LLVM36
	   std::unique_ptr<MemoryBuffer> membuf = MemoryBuffer::getMemBuffer(
                StringRef((const char *)fbase, (size_t)(((uint64_t)-1)-fbase)),"",false);
	   auto origerrorobj = llvm::object::ObjectFile::createObjectFile(
	        membuf->getMemBufferRef(), sys::fs::file_magic::unknown);
#elif LLVM35
            MemoryBuffer *membuf = MemoryBuffer::getMemBuffer(
                StringRef((const char *)fbase, (size_t)(((uint64_t)-1)-fbase)),"",false);
            std::unique_ptr<MemoryBuffer> buf(membuf);
            auto origerrorobj = llvm::object::ObjectFile::createObjectFile(
                buf, sys::fs::file_magic::unknown);
#else
            MemoryBuffer *membuf = MemoryBuffer::getMemBuffer(
	        StringRef((const char *)fbase, (size_t)(((uint64_t)-1)-fbase)),"",false);
            llvm::object::ObjectFile *origerrorobj = llvm::object::ObjectFile::createObjectFile(
                membuf);
#endif
            if (!origerrorobj) {
                objfileentry_t entry = {obj,context,slide};
                objfilemap[fbase] = entry;
                goto lookup;
            }
#ifdef LLVM36
            llvm::object::MachOObjectFile *morigobj = (llvm::object::MachOObjectFile *)origerrorobj.get().release();
#elif LLVM35
            llvm::object::MachOObjectFile *morigobj = (llvm::object::MachOObjectFile *)origerrorobj.get();
#else
            llvm::object::MachOObjectFile *morigobj = (llvm::object::MachOObjectFile *)origerrorobj;
#endif
            if (!getObjUUID(morigobj,uuid)) {
                objfileentry_t entry = {obj,context,slide};
                objfilemap[fbase] = entry;
                goto lookup;
            }

            // On OS X debug symbols are not contained in the dynamic library and that's why
            // we can't have nice things (easily). For now we only support .dSYM files in the same directory
            // as the shared library. In the future we may use DBGCopyFullDSYMURLForUUID from CoreFoundation to make
            // use of spotlight to find the .dSYM file.
            char dsympath[PATH_MAX];
            strlcpy(dsympath, dlinfo.dli_fname, sizeof(dsympath));
            strlcat(dsympath, ".dSYM/Contents/Resources/DWARF/", sizeof(dsympath));
            strlcat(dsympath, strrchr(dlinfo.dli_fname,'/')+1, sizeof(dsympath));
#ifdef LLVM35
            auto errorobj = llvm::object::ObjectFile::createObjectFile(dsympath);
#else
            llvm::object::ObjectFile *errorobj = llvm::object::ObjectFile::createObjectFile(dsympath);
#endif
#else
            // On non OS X systems we need to mmap another copy because of the permissions on the mmaped
            // shared library.
#ifdef LLVM35
            auto errorobj = llvm::object::ObjectFile::createObjectFile(fname);
#else
            llvm::object::ObjectFile *errorobj = llvm::object::ObjectFile::createObjectFile(fname);
#endif
#endif
#ifdef LLVM36
            if (errorobj) {
                obj = errorobj.get().getBinary().release();
                errorobj.get().getBuffer().release();
#elif LLVM35
            if (errorobj) {
                obj = errorobj.get();
#else
            if (errorobj != NULL) {
                obj = errorobj;
#endif
#ifdef _OS_DARWIN_
                if (getObjUUID(morigobj,uuid2) && memcmp(uuid,uuid2,sizeof(uuid)) == 0) {
#endif
#ifdef LLVM36
                    context = DIContext::getDWARFContext(*obj);
#else
                    context = DIContext::getDWARFContext(obj);
#endif
                    slide = -(uint64_t)fbase;
#ifdef _OS_DARWIN_
                }
#endif
#ifdef _OS_WINDOWS_
                assert(obj->isCOFF());
                llvm::object::COFFObjectFile *coffobj = (llvm::object::COFFObjectFile *)obj;
                const llvm::object::pe32plus_header *pe32plus;
                coffobj->getPE32PlusHeader(pe32plus);
                if (pe32plus != NULL) {
                    slide = pe32plus->ImageBase-fbase;
                }
                else {
                    const llvm::object::pe32_header *pe32;
                    coffobj->getPE32Header(pe32); 
                    if (pe32 == NULL) {
                        obj = NULL;
                        context = NULL;
                    }
                    else {
                        slide = pe32->ImageBase-fbase;
                    }
                }
#endif

            }
            objfileentry_t entry = {obj,context,slide};
            objfilemap[fbase] = entry;
        }
        else {
            obj = it->second.obj;
            context = it->second.ctx;
            slide = it->second.slide;
        }
#ifdef _OS_DARWIN_
    lookup:
#endif
        lookup_pointer(context, name, line, filename, pointer+slide, jl_is_sysimg(fname), fromC);
        return;
    }
    *fromC = 1;
    return;
}
#endif

void jl_getFunctionInfo(const char **name, size_t *line, const char **filename, size_t pointer, int *fromC, int skipC)
{
    *name = NULL;
    *line = -1;
    *filename = "no file";
    *fromC = 0;

#if USE_MCJIT
// With MCJIT we can get function information directly from the ObjectFile
    std::map<size_t, ObjectInfo, revcomp> &objmap = jl_jit_events->getObjectMap();
    std::map<size_t, ObjectInfo, revcomp>::iterator it = objmap.lower_bound(pointer);

    if (it == objmap.end())
        return jl_getDylibFunctionInfo(name,line,filename,pointer,fromC,skipC);
    if ((pointer - it->first) > it->second.size)
        return jl_getDylibFunctionInfo(name,line,filename,pointer,fromC,skipC);

#ifdef LLVM36
    DIContext *context = DIContext::getDWARFContext(*it->second.object);
#else
    DIContext *context = DIContext::getDWARFContext(it->second.object);
#endif
    lookup_pointer(context, name, line, filename, pointer, 1, fromC);

#else // !USE_MCJIT

// Without MCJIT we use the FuncInfo structure containing address maps
    std::map<size_t, FuncInfo, revcomp> &info = jl_jit_events->getMap();
    std::map<size_t, FuncInfo, revcomp>::iterator it = info.lower_bound(pointer);
    if (it != info.end() && (size_t)(*it).first + (*it).second.lengthAdr >= pointer) {
        // We do this to hide the jlcall wrappers when getting julia backtraces,
        // but it is still good to have them for regular lookup of C frames.
        if (skipC && (*it).second.lines.empty()) {
            // Technically not true, but we don't want them
            // in julia backtraces, so close enough
            *fromC = 1;
            return;
        }

        *name = (*it).second.name.c_str();
        *filename = (*it).second.filename.c_str();

        if ((*it).second.lines.empty()) {
            *fromC = 1;
            return;
        }

        std::vector<JITEvent_EmittedFunctionDetails::LineStart>::iterator vit =
            (*it).second.lines.begin();
        JITEvent_EmittedFunctionDetails::LineStart prev = *vit;

        if ((*it).second.func) {
            DISubprogram debugscope =
                DISubprogram(prev.Loc.getScope((*it).second.func->getContext()));
            *filename = debugscope.getFilename().data();
            // the DISubprogram has the un-mangled name, so use that if
            // available. However, if the scope need not be the current
            // subprogram.
            if (debugscope.getName().data() != NULL)
                *name = debugscope.getName().data();
            else
                *name = jl_demangle(*name);
        }

        vit++;

        while (vit != (*it).second.lines.end()) {
            if (pointer <= (*vit).Address) {
                *line = prev.Loc.getLine();
                break;
            }
            prev = *vit;
            vit++;
        }
        if (*line == (size_t) -1) {
            *line = prev.Loc.getLine();
        }
    }
    else {
        jl_getDylibFunctionInfo(name,line,filename,pointer,fromC,skipC);
    }
#endif // USE_MCJIT
}
示例#9
0
// This callback function is used by StackWalk64. It provides access to 
// module list stored in minidump file
DWORD64 CALLBACK GetModuleBaseProc64(
                                     HANDLE hProcess,
                                     DWORD64 Address)
{  
    return SymGetModuleBase64(hProcess, Address);
}
示例#10
0
文件: debuginfo.cpp 项目: Oddan/julia
void jl_getDylibFunctionInfo(const char **name, int *line, const char **filename, size_t pointer, int skipC)
{
#ifdef _OS_WINDOWS_
    DWORD fbase = SymGetModuleBase64(GetCurrentProcess(),(DWORD)pointer);
    if (fbase != 0) {
#else
    Dl_info dlinfo;
    if ((dladdr((void*)pointer, &dlinfo) != 0) && dlinfo.dli_fname) {
        if (skipC && !jl_is_sysimg(dlinfo.dli_fname))
            return;
        uint64_t fbase = (uint64_t)dlinfo.dli_fbase;
#endif
        obfiletype::iterator it = objfilemap.find(fbase);
        llvm::object::ObjectFile *obj = NULL;
        DIContext *context = NULL;
        int64_t slide = 0;
        if (it == objfilemap.end()) {
#ifdef _OS_DARWIN_
            // First find the uuid of the object file (we'll use this to make sure we find the
            // correct debug symbol file).
            uint8_t uuid[16], uuid2[16];
#ifdef LLVM35
            ErrorOr<llvm::object::ObjectFile*> origerrorobj = llvm::object::ObjectFile::createObjectFile(
#else
            llvm::object::ObjectFile *origerrorobj = llvm::object::ObjectFile::createObjectFile(
#endif
                    MemoryBuffer::getMemBuffer(
                    StringRef((const char *)fbase, (size_t)(((uint64_t)-1)-fbase)),"",false)
#ifdef LLVM35
                    ,false, sys::fs::file_magic::unknown
#endif
            );
            if (!origerrorobj) {
                objfileentry_t entry = {obj,context,slide};
                objfilemap[fbase] = entry;
                return;
            }
#ifdef LLVM35
            llvm::object::MachOObjectFile *morigobj = (llvm::object::MachOObjectFile *)origerrorobj.get();
#else
            llvm::object::MachOObjectFile *morigobj = (llvm::object::MachOObjectFile *)origerrorobj;
#endif
            if (!getObjUUID(morigobj,uuid)) {
                objfileentry_t entry = {obj,context,slide};
                objfilemap[fbase] = entry;
                return;
            }

            // On OS X debug symbols are not contained in the dynamic library and that's why
            // we can't have nice things (easily). For now we only support .dSYM files in the same directory
            // as the shared library. In the future we may use DBGCopyFullDSYMURLForUUID from CoreFoundation to make
            // use of spotlight to find the .dSYM file.
            char dsympath[PATH_MAX];
            strlcpy(dsympath, dlinfo.dli_fname, sizeof(dsympath));
            strlcat(dsympath, ".dSYM/Contents/Resources/DWARF/", sizeof(dsympath));
            strlcat(dsympath, strrchr(dlinfo.dli_fname,'/')+1, sizeof(dsympath));
#ifdef LLVM35
            ErrorOr<llvm::object::ObjectFile*> errorobj = llvm::object::ObjectFile::createObjectFile(dsympath);
#else
            llvm::object::ObjectFile *errorobj = llvm::object::ObjectFile::createObjectFile(dsympath);
#endif
#else
#ifndef _OS_WINDOWS_
            const char *fname = dlinfo.dli_fname;
#else
            IMAGEHLP_MODULE64 ModuleInfo;
            ModuleInfo.SizeOfStruct = sizeof(IMAGEHLP_MODULE64);
            SymGetModuleInfo64(GetCurrentProcess(), (DWORD64)pointer, &ModuleInfo);
            char *fname = ModuleInfo.LoadedImageName;
            JL_PRINTF(JL_STDOUT,fname);
#endif
            // On non OS X systems we need to mmap another copy because of the permissions on the mmaped
            // shared library.
#ifdef LLVM35
            ErrorOr<llvm::object::ObjectFile*> errorobj = llvm::object::ObjectFile::createObjectFile(fname);
#else
            llvm::object::ObjectFile *errorobj = llvm::object::ObjectFile::createObjectFile(fname);
#endif
#endif
#ifdef LLVM35
            if (errorobj) {
                obj = errorobj.get();
#else
            if (errorobj != NULL) {
                obj = errorobj;
#endif
#ifdef _OS_DARWIN_
                if (getObjUUID(morigobj,uuid2) && memcmp(uuid,uuid2,sizeof(uuid)) == 0) {
#endif
                    context = DIContext::getDWARFContext(obj);
                    slide = -(uint64_t)fbase;
#ifdef _OS_DARWIN_
                }
#endif
#ifdef _OS_WINDOWS_
                assert(obj->isCOFF());
                llvm::object::COFFObjectFile *coffobj = (llvm::object::COFFObjectFile *)obj;
                const llvm::object::pe32plus_header *pe32plus;
                coffobj->getPE32PlusHeader(pe32plus);
                if (pe32plus != NULL) {
                    slide = pe32plus->ImageBase-fbase;
                }
                else {
                    const llvm::object::pe32_header *pe32;
                    coffobj->getPE32Header(pe32); 
                    if (pe32 == NULL) {
                        obj = NULL;
                        context = NULL;
                    }
                    else {
                        slide = pe32->ImageBase-fbase;
                    }
                }
#endif

            }
            objfileentry_t entry = {obj,context,slide};
            objfilemap[fbase] = entry;
        }
        else {
            obj = it->second.obj;
            context = it->second.ctx;
            slide = it->second.slide;
        }

        lookup_pointer(context, name, line, filename, pointer+slide, jl_is_sysimg(dlinfo.dli_fname));
    }
    return;
}