void Func5() { void *stack[1024]; unsigned short frames; SYMBOL_INFO * symbol; HANDLE process; process = GetCurrentProcess(); SymInitialize(process, NULL, TRUE); frames = CaptureStackBackTrace(0, 100, stack, NULL); symbol = (SYMBOL_INFO *)calloc(sizeof(SYMBOL_INFO) + 256 * sizeof(char), 1); symbol->MaxNameLen = 255; symbol->SizeOfStruct = sizeof(SYMBOL_INFO); std::string result; char tempStr[255]; for (int i = 0; i < frames; i++) { SymFromAddr(process, (DWORD64)(stack[i]), 0, symbol); sprintf(tempStr, "%i: %s - 0x%0X\n", frames - i - 1, symbol->Name, symbol->Address); result += tempStr; } free(symbol); std::cout << result << std::endl; }
BOOL GetSymFromAddr(HANDLE hProcess, DWORD64 dwAddress, LPSTR lpSymName, DWORD nSize) { PSYMBOL_INFO pSymbol = (PSYMBOL_INFO)malloc(sizeof(SYMBOL_INFO) + nSize * sizeof(char)); DWORD64 dwDisplacement = 0; // Displacement of the input address, relative to the start of the symbol BOOL bRet; pSymbol->SizeOfStruct = sizeof(SYMBOL_INFO); pSymbol->MaxNameLen = nSize; DWORD dwOptions = SymGetOptions(); bRet = SymFromAddr(hProcess, dwAddress, &dwDisplacement, pSymbol); if (bRet) { // Demangle if not done already if ((dwOptions & SYMOPT_UNDNAME) || UnDecorateSymbolName(pSymbol->Name, lpSymName, nSize, UNDNAME_NAME_ONLY) == 0) { strncpy(lpSymName, pSymbol->Name, nSize); } } free(pSymbol); return bRet; }
void printStacktrace() { // http://stackoverflow.com/questions/5693192/win32-backtrace-from-c-code // https://msdn.microsoft.com/en-us/library/windows/desktop/bb204633(v=vs.85).aspx unsigned int i; void * stack[ 100 ]; unsigned short frames; SYMBOL_INFO * symbol; HANDLE process; process = GetCurrentProcess(); SymInitialize( process, NULL, TRUE ); frames = CaptureStackBackTrace( 0, 100, stack, NULL ); symbol = ( SYMBOL_INFO * )calloc( sizeof( SYMBOL_INFO ) + 256 * sizeof( char ), 1 ); symbol->MaxNameLen = 255; symbol->SizeOfStruct = sizeof( SYMBOL_INFO ); printf("\nStacktrace\n"); for( i = 0; i < frames; i++ ) { SymFromAddr( process, ( DWORD64 )( stack[ i ] ), 0, symbol ); printf( "%i: %s - 0x%0X\n", frames - i - 1, symbol->Name, symbol->Address ); } free( symbol ); }
int Plookup_by_addr(struct ps_prochandle *P, uintptr_t addr, char *buf, size_t size, GElf_Sym *symp) { SYMBOL_INFO *s; s = (SYMBOL_INFO *) malloc(sizeof(SYMBOL_INFO) + size-1); if (s == NULL) return -1; s->SizeOfStruct = sizeof(SYMBOL_INFO); s->MaxNameLen = size; if (SymFromAddr(P->phandle, addr, 0, s) == TRUE) { isfunction(P, s); symp->st_name = 0; symp->st_info = GELF_ST_INFO((STB_GLOBAL), (STT_FUNC)); symp->st_other = 0; symp->st_shndx = 1; symp->st_value = s->Address; symp->st_size = s->Size; strncpy(buf, s->Name, size); return 0; } return dw_lookup_by_addr(P, addr, buf, size, symp); }
std::string win_stacktrace() { void *stack[100]; unsigned short frames = CaptureStackBackTrace(0, 100, stack, NULL); SYMBOL_INFO *symbol = (SYMBOL_INFO*)calloc(sizeof(SYMBOL_INFO) + 256 * sizeof(char), 1); symbol->MaxNameLen = 255; symbol->SizeOfStruct = sizeof(SYMBOL_INFO); HANDLE process = GetCurrentProcess(); std::string result; result.reserve(128); { muduo::MutexLockGuard guard( muduo::Singleton<win::SymManager>::instance().getMutex()); SymRefreshModuleList(process); char buf[512]; int count = 0; for(unsigned int i = 0; i < frames; i++) { SymFromAddr(process, (DWORD64)(stack[i]), 0, symbol); count = snprintf(buf, sizeof(buf)-1, "%i: %s - 0x%0X\n", frames-i-1, symbol->Name, symbol->Address); if (count != -1) result.append(buf); } } free(symbol); return result; }
/* static */ BOOL wxDbgHelpDLL::CallSymFromAddr(HANDLE hProcess, DWORD64 Address, size_t* offset, wxString* name) { DWORD64 dwDisplacement; #ifdef UNICODE if ( SymFromAddrW ) { VarSizedStruct<SYMBOL_INFOW> infoW; if ( SymFromAddrW(hProcess, Address, &dwDisplacement, infoW) ) { *offset = dwDisplacement; *name = infoW->Name; return TRUE; } } #endif // UNICODE if ( SymFromAddr ) { VarSizedStruct<SYMBOL_INFO> info; if ( SymFromAddr(hProcess, Address, &dwDisplacement, info) ) { *offset = dwDisplacement; *name = info->Name; return TRUE; } } return FALSE; }
std::string get_symbol(void *ptr) { if(ptr==0) return std::string(); init(); std::ostringstream ss; ss << ptr; if(syms_ready) { DWORD64 dwDisplacement = 0; DWORD64 dwAddress = (DWORD64)ptr; std::vector<char> buffer(sizeof(SYMBOL_INFO) + MAX_SYM_NAME); PSYMBOL_INFO pSymbol = (PSYMBOL_INFO)&buffer.front(); pSymbol->SizeOfStruct = sizeof(SYMBOL_INFO); pSymbol->MaxNameLen = MAX_SYM_NAME; if (SymFromAddr(hProcess, dwAddress, &dwDisplacement, pSymbol)) { ss <<": " << pSymbol->Name << std::hex << " +0x" << dwDisplacement; } else { ss << ": ???"; } } return ss.str(); }
std::string formatStackTrace(StackTrace *trace) { auto process = GetCurrentProcess(); static bool symInitialise = false; if (!symInitialise) { SymInitialize(process, NULL, TRUE); symInitialise = true; } auto symbol = new MySymbol(); symbol->MaxNameLen = 256; symbol->SizeOfStruct = sizeof(SYMBOL_INFO); fmt::MemoryWriter out; for (auto i = 0u; i < trace->frames; ++i) { SymFromAddr(process, (DWORD64)trace->data[i], 0, symbol); out.write("{}: {} - 0x{:X}x\n", trace->frames - i - 1, (const char*)symbol->Name, symbol->Address); } delete symbol; return out.str(); }
/*********************************************************************** * print_address * * Print an 16- or 32-bit address, with the nearest symbol if any. */ void print_address(const ADDRESS64* addr, BOOLEAN with_line) { char buffer[sizeof(SYMBOL_INFO) + 256]; SYMBOL_INFO* si = (SYMBOL_INFO*)buffer; void* lin = memory_to_linear_addr(addr); DWORD64 disp64; DWORD disp; print_bare_address(addr); si->SizeOfStruct = sizeof(*si); si->MaxNameLen = 256; if (!SymFromAddr(dbg_curr_process->handle, (DWORD_PTR)lin, &disp64, si)) return; dbg_printf(" %s", si->Name); if (disp64) dbg_printf("+0x%lx", (DWORD_PTR)disp64); if (with_line) { IMAGEHLP_LINE il; IMAGEHLP_MODULE im; il.SizeOfStruct = sizeof(il); if (SymGetLineFromAddr(dbg_curr_process->handle, (DWORD_PTR)lin, &disp, &il)) dbg_printf(" [%s:%lu]", il.FileName, il.LineNumber); im.SizeOfStruct = sizeof(im); if (SymGetModuleInfo(dbg_curr_process->handle, (DWORD_PTR)lin, &im)) dbg_printf(" in %s", im.ModuleName); } }
/* * PrintBacktrace * Prints a call backtrace into the logging buffer */ void ExceptionTracer::PrintBacktrace() { StackTracer tracer(this->context); char module_name[MAX_PATH]; char sym_buffer[sizeof(SYMBOL_INFO) + symbol_max]; int backtrace_count = 0; // Num of frames traced bool has_symbol_api = false; // True if we have the symbol API available for use DWORD old_options; // Saves old symbol API options SYMBOL_INFO& symbol = *(SYMBOL_INFO*)sym_buffer; symbol.SizeOfStruct = sizeof(SYMBOL_INFO); symbol.MaxNameLen = symbol_max; // Tries to get the symbol api if (SymInitialize(GetCurrentProcess(), 0, TRUE)) { has_symbol_api = true; old_options = SymSetOptions(SYMOPT_DEFERRED_LOADS | SYMOPT_LOAD_LINES | SYMOPT_NO_PROMPTS | SYMOPT_FAIL_CRITICAL_ERRORS); } Print("Backtrace (may be wrong):"); EnterScope(); { // Walks on the stack until there's no frame to trace or we traced 'max_backtrace' frames while (auto trace = tracer.Walk()) { if (++backtrace_count >= max_backtrace) break; bool has_sym = false; // This EIP has a symbol associated with it? DWORD64 displacement; // EIP displacement relative to symbol // If we have access to the symbol api, try to get symbol name from pc (eip) if (has_symbol_api) has_sym = trace->pc ? !!SymFromAddr(GetCurrentProcess(), (DWORD64)trace->pc, &displacement, &symbol) : false; // Print everything up, this.... Ew, this looks awful! Print(backtrace_count == 1 ? "=>" : " "); // First line should have '=>' to specify where it crashed Print("0x%p ", trace->pc); // Print EIP at frame if (has_sym) Print("%s+0x%x ", symbol.Name, (DWORD)displacement); // Print frame func symbol Print("in %s (+0x%x) ", // Print module trace->module ? FindModuleName(trace->module, module_name, sizeof(module_name)) : "unknown", (uintptr_t)(trace->pc) - (uintptr_t)(trace->module) // Module displacement ); if (trace->frame) Print("(0x%p) ", trace->frame); // Print frame pointer NewLine(); } } LeaveScope(); // Cleanup the symbol api if (has_symbol_api) { SymSetOptions(old_options); SymCleanup(GetCurrentProcess()); } }
void printStack(void) { unsigned int i; void * stack[100]; unsigned short frames; SYMBOL_INFO * symbol; HANDLE process; process = GetCurrentProcess(); SymInitialize(process, NULL, TRUE); frames = CaptureStackBackTrace(0, 100, stack, NULL); symbol = (SYMBOL_INFO *)calloc(sizeof(SYMBOL_INFO) + 256 * sizeof(char), 1); symbol->MaxNameLen = 255; symbol->SizeOfStruct = sizeof(SYMBOL_INFO); IMAGEHLP_LINE64 *line = (IMAGEHLP_LINE64 *)malloc(sizeof(IMAGEHLP_LINE64)); line->SizeOfStruct = sizeof(IMAGEHLP_LINE64); DWORD displacement; for (i = 0; i < frames; i++) { SymFromAddr(process, (DWORD64)(stack[i]), 0, symbol); SymGetLineFromAddr64(process, (DWORD64)stack[i], &displacement, line); printf("%s %s:%i\n", symbol->Name, line->FileName, line->LineNumber); } free(symbol); }
static void blender_crash_handler_backtrace(FILE *fp) { (void)fp; #if 0 #define MAXSYMBOL 256 unsigned short i; void *stack[SIZE]; unsigned short nframes; SYMBOL_INFO *symbolinfo; HANDLE process; process = GetCurrentProcess(); SymInitialize(process, NULL, TRUE); nframes = CaptureStackBackTrace(0, SIZE, stack, NULL); symbolinfo = MEM_callocN(sizeof(SYMBOL_INFO) + MAXSYMBOL * sizeof( char ), "crash Symbol table"); symbolinfo->MaxNameLen = MAXSYMBOL - 1; symbolinfo->SizeOfStruct = sizeof(SYMBOL_INFO); for (i = 0; i < nframes; i++) { SymFromAddr(process, ( DWORD64 )( stack[ i ] ), 0, symbolinfo); fprintf(fp, "%u: %s - 0x%0X\n", nframes - i - 1, symbolinfo->Name, symbolinfo->Address); } MEM_freeN(symbolinfo); #endif }
void dumpBacktrace(int dumpFile, CrashData crash) { #ifdef Q_OS_UNIX // Variables for storing crash info. void* trace[BT_SIZE]; // Backtrace frames size_t size; // The backtrace size // Get the backtrace. size = backtrace(trace, BT_SIZE); // Dump the backtrace dprintf(dumpFile, "---- BEGIN BACKTRACE ----\n"); backtrace_symbols_fd(trace, size, dumpFile); dprintf(dumpFile, "---- END BACKTRACE ----\n"); #elif defined Q_OS_WIN32 dprintf(dumpFile, "---- BEGIN BACKTRACE ----\n"); StackFrame stack[BT_SIZE]; size_t size; SYMBOL_INFO *symbol; HANDLE process; size = getBacktrace(stack, BT_SIZE, *crash.context); // FIXME: Accessing heap memory is supposedly "dangerous", // but I can't find another way of doing this. // Initialize process = GetCurrentProcess(); if (!SymInitialize(process, NULL, true)) { dprintf(dumpFile, "Failed to initialize symbol handler. Can't print stack trace.\n"); dprintf(dumpFile, "Here's a list of addresses in the call stack instead:\n"); for(int i = 0; i < size; i++) { dprintf(dumpFile, "0x%0X\n", (DWORD64)stack[i].address); } } else { // Allocate memory... ._. symbol = (SYMBOL_INFO *) calloc(sizeof(SYMBOL_INFO) + 256 * sizeof(char), 1); symbol->MaxNameLen = 255; symbol->SizeOfStruct = sizeof(SYMBOL_INFO); // Dump stacktrace for(int i = 0; i < size; i++) { DWORD64 addr = (DWORD64)stack[i].address; if (!SymFromAddr(process, (DWORD64)(addr), 0, symbol)) dprintf(dumpFile, "?? - 0x%0X\n", addr); else dprintf(dumpFile, "%s - 0x%0X\n", symbol->Name, symbol->Address); } free(symbol); } dprintf(dumpFile, "---- END BACKTRACE ----\n"); #endif }
bool CSymbolEngine::FindSymbolByAddress( DWORD64 Address, TString& Name, DWORD64& Displacement ) { // Check preconditions if( m_hProcess == NULL ) { _ASSERTE( !_T("Symbol engine is not yet initialized.") ); m_LastError = ERROR_INVALID_FUNCTION; return false; } // Look up the symbol CSymbolInfoPackage sip; // it contains SYMBOL_INFO structure plus additional // space for the name of the symbol DWORD64 Disp = 0; if( !SymFromAddr( m_hProcess, Address, &Disp, &sip.si ) ) { // Failed, but do not assert here - it is usually normal when a symbol is not found //m_LastError = GetLastError(); //return false; Name = L"unknown"; Displacement = 0; return true; } Name = sip.si.Name; Displacement = Disp; return true; }
std::string FunctionResolver::getMethodSymbolFromAddress(const ULONG64& funcAddress) { SymbolInfoHelper* pSymbolInfoHelper = new SymbolInfoHelper(); //PSYMBOL_INFO symbol = pSymbolInfoHelper->AllocSymbol(256); const size_t array_size = 256; const size_t size = sizeof(SYMBOL_INFO) + (array_size - 1) * sizeof(TCHAR); SYMBOL_INFO* symbol = (SYMBOL_INFO*)calloc(1, size); if (!symbol) { //deal with it } symbol->SizeOfStruct = sizeof(*symbol); //both values must symbol->MaxNameLen = array_size; //be set by user DWORD64 dwDisplacement = 0; if (SymFromAddr(this->m_hProcess, funcAddress, &dwDisplacement, symbol) == FALSE) { return ""; } std::string functionSymName(symbol->Name, symbol->NameLen); delete pSymbolInfoHelper; pSymbolInfoHelper = NULL; return functionSymName; }
void printStackTrace() { # ifdef _DEBUG void *stack[TRACE_MAX_STACK_FRAMES]; HANDLE process = GetCurrentProcess(); SymInitialize(process, NULL, TRUE); WORD numberOfFrames = CaptureStackBackTrace(0, TRACE_MAX_STACK_FRAMES, stack, NULL); SYMBOL_INFO *symbol = (SYMBOL_INFO *)malloc(sizeof(SYMBOL_INFO) + (TRACE_MAX_FUNCTION_NAME_LENGTH - 1) * sizeof(TCHAR)); symbol->MaxNameLen = TRACE_MAX_FUNCTION_NAME_LENGTH; symbol->SizeOfStruct = sizeof(SYMBOL_INFO); DWORD displacement; IMAGEHLP_LINE64 *line = (IMAGEHLP_LINE64 *)malloc(sizeof(IMAGEHLP_LINE64)); line->SizeOfStruct = sizeof(IMAGEHLP_LINE64); for (int i = 0; i < numberOfFrames; i++) { DWORD64 address = (DWORD64)(stack[i]); SymFromAddr(process, address, NULL, symbol); if (SymGetLineFromAddr64(process, address, &displacement, line)) { printf("\tat [Function: "); consoleWarningYellow(); printf("%s", symbol->Name); consoleDefaultWhite(); printf("][Source file: %s][Line: %lu]\n", line->FileName, line->LineNumber); } } free(symbol); free(line); # else printf("Callstack not available during release build on Visual Studio platform.\n"); # endif }
void printStack(void) { unsigned int i; void * stack[100]; unsigned short frames; SYMBOL_INFO * symbol; HANDLE process; char buffer[100]; char stackBuffer[3000]; process = GetCurrentProcess(); SymInitialize(process, NULL, TRUE); frames = CaptureStackBackTrace(0, 100, stack, NULL); symbol = (SYMBOL_INFO *)calloc(sizeof(SYMBOL_INFO) + 256 * sizeof(char), 1); symbol->MaxNameLen = 255; symbol->SizeOfStruct = sizeof(SYMBOL_INFO); for (i = 0; i < frames; i++) { SymFromAddr(process, (DWORD64)(stack[i]), 0, symbol); sprintf_s(buffer, "%i: %s - 0x%0X\n", frames - i - 1, symbol->Name, symbol->Address); strcat_s(stackBuffer, buffer); } MessageBoxA(NULL, stackBuffer, "Stack Trace", MB_OK); free(symbol); }
static void PrintSymbolForAddress(DWORD64 addr) { /* * Code adapted from Chromium's stack_trace_win.cc, in turn adapted * from an MSDN example: * http://msdn.microsoft.com/en-us/library/ms680578(VS.85).aspx */ ULONG64 buffer[(sizeof(SYMBOL_INFO) + MAX_SYMBOL_NAME_LENGTH * sizeof(wchar_t) + sizeof(ULONG64) - 1) / sizeof(ULONG64)]; DWORD64 sym_displacement = 0; PSYMBOL_INFO symbol = (PSYMBOL_INFO) buffer; BOOL has_symbol; memset(buffer, 0, sizeof(buffer)); SymInitialize(GetCurrentProcess(), NULL, TRUE); symbol->SizeOfStruct = sizeof(SYMBOL_INFO); symbol->MaxNameLen = MAX_SYMBOL_NAME_LENGTH - 1; has_symbol = SymFromAddr(GetCurrentProcess(), addr, &sym_displacement, symbol); if (has_symbol) { fprintf(stderr, "%s + 0x%x\n", symbol->Name, sym_displacement); } else { fprintf(stderr, "<no symbol>\n"); } }
CallStack::History CallStack::trace(std::uint32_t size) { poco_assert(0 < size); auto process = GetCurrentProcess(); if (FALSE == SymInitialize(process, nullptr, TRUE)) { return std::move(History()); } std::unique_ptr<void*[]> stack(new void*[size]); auto frames = CaptureStackBackTrace(0, size, stack.get(), nullptr); const int max_name_length = 255; std::unique_ptr<char[]> symbol_buffer(new char[sizeof(SYMBOL_INFO) + ((max_name_length + 1) * sizeof(char))]); auto symbol = reinterpret_cast<SYMBOL_INFO*>(symbol_buffer.get()); symbol->MaxNameLen = max_name_length; symbol->SizeOfStruct = sizeof(SYMBOL_INFO); History ret; for (decltype(frames) i = 0; i < frames; i++) { if (FALSE != SymFromAddr(process, (DWORD64)(stack[i]), 0, symbol)) { ret.insert(std::make_pair(symbol->Name, Poco::NumberFormatter::formatHex(symbol->Address, true))); } } return std::move(ret); }
int callstack_symbols( void** addresses, callstack_symbol_t* out_syms, int num_addresses, char* memory, int mem_size ) { HANDLE process; DWORD64 offset; DWORD line_dis; BOOL res; IMAGEHLP_LINE64 line; PSYMBOL_INFO sym_info; char buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(TCHAR)]; int num_translated = 0; callstack_string_buffer_t outbuf = { memory, memory + mem_size }; memset( out_syms, 0x0, (size_t)num_addresses * sizeof(callstack_symbol_t) ); process = GetCurrentProcess(); res = SymInitialize( process, NULL, TRUE ); // TODO: Only initialize once! if( res == 0 ) { DWORD err = GetLastError(); // ERROR_INVALID_PARAMETER seems to be returned IF symbols for a specific module could not be loaded. // However the lookup will still work for all other symbols so let us ignore this error! if (err != ERROR_INVALID_PARAMETER) return 0; } sym_info = (PSYMBOL_INFO)buffer; sym_info->SizeOfStruct = sizeof(SYMBOL_INFO); sym_info->MaxNameLen = MAX_SYM_NAME; line.SizeOfStruct = sizeof(IMAGEHLP_LINE64); for( int i = 0; i < num_addresses; ++i ) { res = SymFromAddr( process, (DWORD64)addresses[i], &offset, sym_info ); if( res == 0 ) out_syms[i].function = "failed to lookup symbol"; else out_syms[i].function = alloc_string( &outbuf, sym_info->Name, sym_info->NameLen ); res = SymGetLineFromAddr64( process, (DWORD64)addresses[i], &line_dis, &line ); if( res == 0 ) { out_syms[i].offset = 0; out_syms[i].file = "failed to lookup file"; out_syms[i].line = 0; } else { out_syms[i].offset = (unsigned int)line_dis; out_syms[i].file = alloc_string( &outbuf, line.FileName, strlen( line.FileName ) ); out_syms[i].line = (unsigned int)line.LineNumber; } ++num_translated; } return num_translated; }
std::string format_address_win32(const void* addr) const { if (!dbghelp.initialized()) return format_address_fallback(addr); DWORD64 symbol_info_buf[sizeof(SYMBOL_INFO) + MAX_SYM_NAME]; const auto symbol_info = reinterpret_cast<SYMBOL_INFO*>(symbol_info_buf); symbol_info->SizeOfStruct = sizeof(SYMBOL_INFO); symbol_info->MaxNameLen = MAX_SYM_NAME; IMAGEHLP_MODULE64 module_info; module_info.SizeOfStruct = sizeof(IMAGEHLP_MODULE64); DWORD64 symbol_offset; const auto symbol_resolved = SymFromAddr( GetCurrentProcess(), reinterpret_cast<DWORD64>(addr), &symbol_offset, symbol_info); if (symbol_resolved) { const auto module_resolved = SymGetModuleInfo64( GetCurrentProcess(), symbol_info->ModBase, &module_info); if (module_resolved) { return format_symbol( module_info.ModuleName, symbol_info->Name, reinterpret_cast<const void*>(symbol_offset)); } else { return format_symbol(symbol_info->Name, addr); } } else { const auto module_resolved = SymGetModuleInfo64( GetCurrentProcess(), reinterpret_cast<DWORD64>(addr), &module_info); if (module_resolved) { const auto module_offset = reinterpret_cast<const char*>(addr) - module_info.BaseOfImage; return format_module(module_info.ModuleName, module_offset); } else { return format_address_fallback(addr); } } }
void InsertInfo(DWORD dwExceptionAddr,DWORD dwThreadID,PTCHAR tcTemp) { if(dwLastOffset != dwExceptionAddr) { dwLastOffset = dwExceptionAddr; IMAGEHLP_MODULEW64 imgMod = {0}; imgMod.SizeOfStruct = sizeof(imgMod); SymGetModuleInfoW64(piProcInfo.hProcess,dwLastOffset,&imgMod); DWORD dwBytesWritten; if(bDisableNTDLLLogging) { if(wcsstr(imgMod.ModuleName,L"ntdll") == NULL) { memset(pSymbol,0,sizeof(SYMBOL_INFO) + MAX_SYM_NAME); pSymbol->SizeOfStruct = sizeof(SYMBOL_INFO); pSymbol->MaxNameLen = MAX_SYM_NAME; SymFromAddr(piProcInfo.hProcess,dwLastOffset,NULL,pSymbol); if(!(bCutDownLog && strstr(szTempSym,pSymbol->Name) != NULL)) { memcpy(szTempSym,pSymbol->Name,strlen(pSymbol->Name)); swprintf_s(tcTemp,255,L"%08d\t%08X\t%08X\t%s.%S\r\n",dwStepCount,dwThreadID,dwLastOffset,imgMod.ModuleName,pSymbol->Name); WriteFile(hLogFile,tcTemp,wcslen(tcTemp) * sizeof(TCHAR),&dwBytesWritten,NULL); } } } else { ZeroMemory(pSymbol,sizeof(SYMBOL_INFO) + MAX_SYM_NAME); pSymbol->SizeOfStruct = sizeof(SYMBOL_INFO); pSymbol->MaxNameLen = MAX_SYM_NAME; SymFromAddr(piProcInfo.hProcess,dwLastOffset,NULL,pSymbol); if(!(bCutDownLog && strstr(szTempSym,pSymbol->Name) != NULL)) { memcpy(szTempSym,pSymbol->Name,strlen(pSymbol->Name)); swprintf_s(tcTemp,255,L"%08d\t%08X\t%08X\t%s.%S\r\n",dwStepCount,dwThreadID,dwLastOffset,imgMod.ModuleName,pSymbol->Name); WriteFile(hLogFile,tcTemp,wcslen(tcTemp) * sizeof(TCHAR),&dwBytesWritten,NULL); } } } dwStepCount++; }
void write_function_name(std::ostream & os, HANDLE process, DWORD64 program_counter) { SYMBOL_INFO_PACKAGE sym = { sizeof(SYMBOL_INFO) }; sym.si.MaxNameLen = MAX_SYM_NAME; if (SymFromAddr(process, program_counter, 0, &sym.si)) { os << sym.si.Name << "()"; } else { os << "Unknown function(" << GetLastError() << ")"; } }
/****************************************************************** * stack_get_current_symbol * * Retrieves the symbol information for the current frame element */ BOOL stack_get_current_symbol(SYMBOL_INFO* symbol) { IMAGEHLP_STACK_FRAME ihsf; DWORD64 disp; if (!stack_get_current_frame(&ihsf)) return FALSE; return SymFromAddr(dbg_curr_process->handle, ihsf.InstructionOffset, &disp, symbol); }
/*********************************************************************** * symbol_get_function_line_status * * Find the symbol nearest to a given address. */ enum dbg_line_status symbol_get_function_line_status(const ADDRESS64* addr) { IMAGEHLP_LINE64 il; DWORD disp; ULONG64 disp64, start; DWORD_PTR lin = (DWORD_PTR)memory_to_linear_addr(addr); char buffer[sizeof(SYMBOL_INFO) + 256]; SYMBOL_INFO* sym = (SYMBOL_INFO*)buffer; struct dbg_type func; il.SizeOfStruct = sizeof(il); sym->SizeOfStruct = sizeof(SYMBOL_INFO); sym->MaxNameLen = sizeof(buffer) - sizeof(SYMBOL_INFO); /* do we have some info for lin address ? */ if (!SymFromAddr(dbg_curr_process->handle, lin, &disp64, sym)) { ADDRESS64 jumpee; /* some compilers insert thunks in their code without debug info associated * take care of this situation */ if (be_cpu->is_jump((void*)lin, &jumpee)) return symbol_get_function_line_status(&jumpee); return dbg_no_line_info; } switch (sym->Tag) { case SymTagThunk: /* FIXME: so far dbghelp doesn't return the 16 <=> 32 thunks * and furthermore, we no longer take care of them !!! */ return dbg_in_a_thunk; case SymTagFunction: case SymTagPublicSymbol: break; default: WINE_FIXME("Unexpected sym-tag 0x%08x\n", sym->Tag); case SymTagData: return dbg_no_line_info; } /* we should have a function now */ if (!SymGetLineFromAddr64(dbg_curr_process->handle, lin, &disp, &il)) return dbg_no_line_info; func.module = sym->ModBase; func.id = sym->info; if (symbol_get_debug_start(&func, &start) && lin < start) return dbg_not_on_a_line_number; if (!sym->Size) sym->Size = 0x100000; if (il.FileName && il.FileName[0] && disp < sym->Size) return (disp == 0) ? dbg_on_a_line_number : dbg_not_on_a_line_number; return dbg_no_line_info; }
void StackWalker::WriteFunctionName(std::ostream& os, HANDLE process, DWORD64 program_counter) { SYMBOL_INFO_PACKAGE sym = {}; sym.si.SizeOfStruct = sizeof(SYMBOL_INFO); sym.si.MaxNameLen = MAX_SYM_NAME; if (SymFromAddr(process, program_counter, 0, &sym.si)) { os << sym.si.Name << "()"; } else { os << "Unknown function"; } }
void P_APIENTRY pDebugPrintStack(pint32 skip) { typedef USHORT (WINAPI *CaptureStackBackTraceType)(__in ULONG, __in ULONG, __out PVOID*, __out_opt PULONG); CaptureStackBackTraceType func = (CaptureStackBackTraceType)(GetProcAddress(LoadLibrary(TEXT("kernel32.dll")), "RtlCaptureStackBackTrace")); if (func == NULL) { return ; } // Quote from Microsoft Documentation: // ## Windows Server 2003 and Windows XP: // ## The sum of the FramesToSkip and FramesToCapture parameters must be less than 63. const int kMaxCallers = 62; HANDLE hProcess = GetCurrentProcess(); SymInitialize(hProcess, NULL, TRUE); PSYMBOL_INFO pSymbol = (PSYMBOL_INFO)malloc(sizeof(SYMBOL_INFO) + 256); pSymbol->SizeOfStruct = sizeof(SYMBOL_INFO); pSymbol->MaxNameLen = 255; void* callers[kMaxCallers]; int count = (func)(0, kMaxCallers, callers, NULL); // To skip the pDebugPrintStack function frame, we start from 1 instead of 0. for(int i = skip; i < count; i++) { //PLOG_INFO("*** %d called from %016I64LX\n", i, callers[i]); DWORD addr = (DWORD)(callers[i]); DWORD64 symDisplacement = 0; if (SymFromAddr(hProcess, addr, 0, pSymbol)) { IMAGEHLP_LINE lineInfo = {sizeof(IMAGEHLP_LINE)}; DWORD dwLineDisplacement; if (SymGetLineFromAddr(hProcess, addr, &dwLineDisplacement, &lineInfo)) { PLOG_INFO("%s:%s(),Line %u", lineInfo.FileName, pSymbol->Name, lineInfo.LineNumber); } // Stop the walk at main function. if (pstrcmp(pSymbol->Name, "main") == 0) { break; } } } SymCleanup(GetCurrentProcess()); }
VOID InstrumentationCHook ( _In_ DWORD64 Function, _In_ DWORD64 ReturnValue ) { static BOOLEAN g_Recurse = 0; // // Don't recurse, since we may be doing indirect calls here // if (g_Recurse == 0) { BOOL bRes; DWORD64 dwDisplacement = 0; DWORD64 dwAddress = Function; CHAR buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME] = { 0 }; PSYMBOL_INFO pSymbol = (PSYMBOL_INFO)buffer; // // In the recurse path now // g_Recurse = 1; // // The return address may be in some known symbol -- look it up // pSymbol->SizeOfStruct = sizeof(SYMBOL_INFO); pSymbol->MaxNameLen = MAX_SYM_NAME; bRes = SymFromAddr(GetCurrentProcess(), dwAddress, &dwDisplacement, pSymbol); if (!bRes) { // // Arbitrary memory // printf("CFG Hook to: %p\n", Function); } else { // // Some symbol and displacement. Print return address too // printf("Instrumentation Hook from: %p (%s+%lx) [EAX = %08lX]\n", Function, pSymbol->Name, dwDisplacement, ReturnValue); } // // Recursion ended // g_Recurse = 0; } }
//============================================================================== String SystemStats::getStackBacktrace() { String result; #if JUCE_ANDROID || JUCE_MINGW || JUCE_HAIKU jassertfalse; // sorry, not implemented yet! #elif JUCE_WINDOWS HANDLE process = GetCurrentProcess(); SymInitialize (process, nullptr, TRUE); void* stack[128]; int frames = (int) CaptureStackBackTrace (0, numElementsInArray (stack), stack, nullptr); HeapBlock<SYMBOL_INFO> symbol; symbol.calloc (sizeof (SYMBOL_INFO) + 256, 1); symbol->MaxNameLen = 255; symbol->SizeOfStruct = sizeof (SYMBOL_INFO); for (int i = 0; i < frames; ++i) { DWORD64 displacement = 0; if (SymFromAddr (process, (DWORD64) stack[i], &displacement, symbol)) { result << i << ": "; IMAGEHLP_MODULE64 moduleInfo; zerostruct (moduleInfo); moduleInfo.SizeOfStruct = sizeof (moduleInfo); if (::SymGetModuleInfo64 (process, symbol->ModBase, &moduleInfo)) result << moduleInfo.ModuleName << ": "; result << symbol->Name << " + 0x" << String::toHexString ((int64) displacement) << newLine; } } #else void* stack[128]; int frames = backtrace (stack, numElementsInArray (stack)); char** frameStrings = backtrace_symbols (stack, frames); for (int i = 0; i < frames; ++i) result << frameStrings[i] << newLine; ::free (frameStrings); #endif return result; }
TORRENT_EXPORT void print_backtrace(char* out, int len, int max_depth) { typedef USHORT (*RtlCaptureStackBackTrace_t)( __in ULONG FramesToSkip, __in ULONG FramesToCapture, __out PVOID *BackTrace, __out_opt PULONG BackTraceHash); static RtlCaptureStackBackTrace_t RtlCaptureStackBackTrace = 0; if (RtlCaptureStackBackTrace == 0) { // we don't actually have to free this library, everyone has it loaded HMODULE lib = LoadLibrary(TEXT("kernel32.dll")); RtlCaptureStackBackTrace = (RtlCaptureStackBackTrace_t)GetProcAddress(lib, "RtlCaptureStackBackTrace"); if (RtlCaptureStackBackTrace == 0) { out[0] = 0; return; } } int i; void* stack[50]; int size = CaptureStackBackTrace(0, 50, stack, 0); SYMBOL_INFO* symbol = (SYMBOL_INFO*)calloc(sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(TCHAR), 1); symbol->MaxNameLen = MAX_SYM_NAME; symbol->SizeOfStruct = sizeof(SYMBOL_INFO); HANDLE p = GetCurrentProcess(); static bool sym_initialized = false; if (!sym_initialized) { sym_initialized = true; SymInitialize(p, NULL, true); } for (i = 0; i < size && len > 0; ++i) { int ret; if (SymFromAddr(p, uintptr_t(stack[i]), 0, symbol)) ret = snprintf(out, len, "%d: %s\n", i, symbol->Name); else ret = snprintf(out, len, "%d: <unknown>\n", i); out += ret; len -= ret; if (i == max_depth && max_depth > 0) break; } free(symbol); }