std::shared_ptr<StackTrace::Frame> StackTrace::Translate(void *frame) { Dl_info dlInfo; addr2line_data adata; Frame * f1 = new Frame(frame); std::shared_ptr<Frame> f(f1); if (!StackTraceBase::Translate(frame, f1, dlInfo, &adata)) { // Lookup using dladdr() failed, so this is probably a PHP symbol. // Let's check the perf map. StackTrace::TranslateFromPerfMap(frame, f1); return f; } if (adata.filename) { f->filename = adata.filename; } if (adata.functionname) { f->funcname = Demangle(adata.functionname); } if (f->filename.empty() && dlInfo.dli_fname) { f->filename = dlInfo.dli_fname; } if (f->funcname.empty() && dlInfo.dli_sname) { f->funcname = Demangle(dlInfo.dli_sname); } return f; }
DALI_EXPORT_API DaliException::DaliException( const char* location, const char* condition ) : location( location ), condition( condition ) { // Note, if a memory error has occured, then the backtrace won't work - backtrace_symbols relies on // allocating memory. // Initial dlog error message is output in DALI_ASSERT_ALWAYS macro // Also output on stderr #if defined(DEBUG_ENABLED) fprintf(stderr, "Exception: \n%s\n thrown at %s\nSee dlog for backtrace\n", condition, location); #else fprintf(stderr, "Exception: \n%s\n thrown\nSee dlog for backtrace\n", condition ); #endif DALI_LOG_ERROR_NOFN("Backtrace:\n"); void* frameArray[MAX_NUM_STACK_FRAMES]; int nSize = backtrace(frameArray, MAX_NUM_STACK_FRAMES); char** symbols = backtrace_symbols(frameArray, nSize); for(int i=1; i< nSize; i++) { std::string demangled_symbol = Demangle(symbols[i]); DALI_LOG_ERROR_NOFN("[%02d] %s\n", i, demangled_symbol.c_str() ); } free(symbols); }
CPath::CPath(const wxString& filename) { // Equivalent to the default constructor ... if (!filename) { return; } wxCharBuffer fn = filename2char(filename); if (fn) { // Filename is valid in the current locale. This means that // it either originated from a (wx)system-call, or from a // user with a properly setup system. m_filesystem = DeepCopy(filename); m_printable = Demangle(fn, filename); } else { // It's not a valid filename in the current locale, so we'll // have to do some magic. This ensures that the filename is // saved as UTF8, even if the system is not unicode enabled, // preserving the original filename till the user has fixed // his system ... fn = wxConvUTF8.cWC2MB(filename); m_filesystem = wxConvFile.cMB2WC(fn); // There's no need to try to unmangle the filename here. m_printable = DeepCopy(filename); } wxASSERT(m_filesystem.Length()); wxASSERT(m_printable.Length()); }
bool StackTraceNoHeap::Translate(int fd, void *frame, int frame_num, void *bfds, unsigned bfds_size) { // frame pointer offset in previous frame Dl_info dlInfo; addr2line_data adata; Frame f(frame); if (!StackTraceBase::Translate(frame, &f, dlInfo, &adata, bfds, bfds_size)) { return false; } const char *filename = adata.filename ? adata.filename : dlInfo.dli_fname; if (!filename) filename = "??"; const char *funcname = adata.functionname ? adata.functionname : dlInfo.dli_sname; if (!funcname) funcname = "??"; // ignore some frames that are always present for (int i = 0; i < FunctionBlacklistCount; i++) { auto ignoreFunc = FunctionBlacklist[i]; if (strncmp(funcname, ignoreFunc, strlen(ignoreFunc)) == 0) { return false; } } dprintf(fd, "# %d%s ", frame_num, frame_num < 10 ? " " : ""); Demangle(fd, funcname); dprintf(fd, " at %s:%u\n", filename, f.lineno); return true; }
bool StackTraceNoHeap::Translate(int fd, void *frame, int frame_num, void *bfds, unsigned bfds_size) { // frame pointer offset in previous frame Dl_info dlInfo; addr2line_data adata; Frame f(frame); if (!StackTraceBase::Translate(frame, &f, dlInfo, &adata, bfds, bfds_size)) { return false; } const char *filename = adata.filename ? adata.filename : dlInfo.dli_fname; if (!filename) filename = "??"; const char *funcname = adata.functionname ? adata.functionname : dlInfo.dli_sname; if (!funcname) funcname = "??"; // ignore frames in the StackTrace class if (strstr(funcname, "StackTraceNoHeap")) return false ; dprintf(fd, "# %d%s ", frame_num, frame_num < 10 ? " " : ""); Demangle(fd, funcname); dprintf(fd, " at %s:%u\n", filename, f.lineno); return true; }
// This function wraps the Demangle function to provide an interface // where the input symbol is demangled in-place. // To keep stack consumption low, we would like this function to not // get inlined. static ATTRIBUTE_NOINLINE void DemangleInplace(char *out, int out_size) { char demangled[256]; // Big enough for sane demangled symbols. if (Demangle(out, demangled, sizeof(demangled))) { // Demangling succeeded. Copy to out if the space allows. int len = strlen(demangled); if (len + 1 <= out_size) { // +1 for '\0'. SAFE_ASSERT(len < (int)sizeof(demangled)); memmove(out, demangled, len + 1); } } }
int main() { try { throw baby_jeebus {}; } catch (...) { std::cout << "Caught " << Demangle(abi::__cxa_current_exception_type()->name()) << std::endl; } }
void ShowBacktrace( std::stringstream & p_stream ) { p_stream << "CALL STACK:" << std::endl; void * backTrace[CALLS_TO_CAPTURE]; unsigned int num( ::backtrace( backTrace, CALLS_TO_CAPTURE ) ); char ** fnStrings( ::backtrace_symbols( backTrace, num ) ); for ( unsigned i = CALLS_TO_SKIP; i < num; ++i ) { p_stream << "== " << Demangle( fnStrings[i] ) << std::endl; } free( fnStrings ); }
StackTrace::FramePtr StackTrace::Translate(void *frame) { Dl_info dlInfo; addr2line_data adata; Frame * f1 = new Frame(frame); FramePtr f(f1); if (!StackTraceBase::Translate(frame, f1, dlInfo, &adata)) return f; if (adata.filename) { f->filename = adata.filename; } if (adata.functionname) { f->funcname = Demangle(adata.functionname); } if (f->filename.empty() && dlInfo.dli_fname) { f->filename = dlInfo.dli_fname; } if (f->funcname.empty() && dlInfo.dli_sname) { f->funcname = Demangle(dlInfo.dli_sname); } return f; }
int GetSymbolName(void *addr, char *output, int output_len) { Dl_info info; dladdr(addr, &info); int status; if (info.dli_sname) { /* Attempt to demangle if a C++ name */ Demangle(info.dli_sname, output, output_len); return 1; } else { return 0; } }
void SLGTerminate(void) { SLG_LOG("========================================================="); SLG_LOG("Unhandled exception"); void *array[32]; size_t size = backtrace(array, 32); char **strings = backtrace_symbols(array, size); SLG_LOG("Obtained " << size << " stack frames."); for (size_t i = 0; i < size; i++) SLG_LOG(" " << Demangle(strings[i])); free(strings); }
void SLGTerminate(void) { cerr << "=========================================================" << endl; cerr << "Unhandled exception" << endl; void *array[32]; size_t size = backtrace(array, 32); char **strings = backtrace_symbols(array, size); cerr << "Obtained " << size << " stack frames." << endl; for (size_t i = 0; i < size; i++) cerr << " " << Demangle(strings[i]) << endl; free(strings); }
template <class Type> std::string GetName(const Type &o,const int mode=0) { std::string id=Demangle(typeid(o).name()); size_t pos=id.find("METOOLS::"); if (pos<std::string::npos) id.erase(pos,9); pos=id.find("_Calculator"); if (pos<std::string::npos) id.erase(pos,11); if (mode&1) { pos=id.find('<'); if (pos<std::string::npos) { size_t epos=id.rfind('>'); if (epos<std::string::npos) id.erase(pos,epos-pos+1); } } return id; }
void SymLookup( VDDebugInfo::Context *pctx, const void *ptr, char *buf ) { if( !pctx->Loaded() ) { strcpy( buf, "error" ); return; } MEMORY_BASIC_INFORMATION meminfo; VirtualQueryEx( g_hParent, ptr, &meminfo, sizeof meminfo ); char tmp[512]; long iAddress = VDDebugInfo::VDDebugInfoLookupRVA(pctx, (unsigned int)ptr, tmp, sizeof(tmp)); if( iAddress >= 0 ) { wsprintf( buf, "%08x: %s [%08lx+%lx+%lx]", ptr, Demangle(tmp), pctx->nFirstRVA, ((unsigned int) ptr) - pctx->nFirstRVA - iAddress, iAddress ); return; } RString sName = CrashChildGetModuleBaseName( (HMODULE)meminfo.AllocationBase ); DWORD64 disp; SYMBOL_INFO *pSymbol = GetSym( (unsigned int)ptr, disp ); if( pSymbol ) { wsprintf( buf, "%08lx: %s!%s [%08lx+%lx+%lx]", (unsigned long) ptr, sName.c_str(), pSymbol->Name, (unsigned long) meminfo.AllocationBase, (unsigned long) (pSymbol->Address) - (unsigned long) (meminfo.AllocationBase), (unsigned long) disp); return; } wsprintf( buf, "%08lx: %s!%08lx", (unsigned long) ptr, sName.c_str(), (unsigned long) meminfo.AllocationBase ); }
bool dynLibImplLinux::GetExportData( const char* dynamicLibraryName, SingleMapEntryArray& ExportEntriesArr, std::string& csPath_o ) { Elf* elf; struct link_map* lm; if ( !OpenDynamicLibrary( dynamicLibraryName, elf, lm, csPath_o ) ) { return false; } if ( GetDllEntry( csPath_o ) == NULL ) { Elf_Scn* section = 0; ElfW(Shdr) *shdr; FindSection( elf, SHT_SYMTAB, section, shdr ); std::list<std::string> symbols; ExtractSymbols( elf, section, shdr, STT_FUNC, symbols ); std::list<std::string>::iterator it; for ( it = symbols.begin( ) ; it != symbols.end( ) ; it++) { SINGLE_FUNCT_ENTRY newElement; newElement.csFunction = Demangle( it->c_str( ) ); // Use dlsym because st_value sometimes is 0 //newElement.dwData = (void*) (lm->l_addr + esym->st_value); newElement.dwData = dlsym( lm, it->c_str( ) ); newElement.csSymbol = *it; ExportEntriesArr.push_back( newElement ); } } CloseDynamicLibrary( elf ); return true; }
unsigned DIGENTRY DIPImpSymName( imp_image_handle *ii, imp_sym_handle *is, location_context *lc, symbol_name sn, char *buff, unsigned max ) { unsigned len; ji_ptr sig; len = GetName( ii, is ); switch( is->kind ) { case JS_METHOD: if( sn == SN_DEMANGLED ) { sig = GetSignature( ii, is ); if( sig != 0 ) { len = Demangle( NameBuff, len, sig ); } } break; case JS_TYPE: case JS_PACKAGE: NormalizeClassName( NameBuff, len ); break; } return( NameCopy( buff, NameBuff, max, len ) ); }
std::string GetTypeName() { return Demangle(typeid(T).name()); }
void leaky::readSymbols(const char *fileName) { LDFILE *ldptr; ldptr = ldopen(fileName, nullptr); if (!ldptr) { fprintf(stderr, "%s: unable to open \"%s\"\n", applicationName, fileName); exit(-1); } if (PSYMTAB(ldptr) == 0) { fprintf(stderr, "%s: \"%s\": has no symbol table\n", applicationName, fileName); exit(-1); } long isymMax = SYMHEADER(ldptr).isymMax; long iextMax = SYMHEADER(ldptr).iextMax; long iMax = isymMax + iextMax; long alloced = 10000; Symbol* syms = (Symbol*) malloc(sizeof(Symbol) * 10000); Symbol* sp = syms; Symbol* last = syms + alloced; SYMR symr; for (long isym = 0; isym < iMax; isym++) { if (ldtbread(ldptr, isym, &symr) != SUCCESS) { fprintf(stderr, "%s: can't read symbol #%d\n", applicationName, isym); exit(-1); } if (isym < isymMax) { if ((symr.st == stStaticProc) || ((symr.st == stProc) && ((symr.sc == scText) || (symr.sc == scAbs))) || ((symr.st == stBlock) && (symr.sc == scText))) { // Text symbol. Set name field to point to the symbol name sp->name = Demangle(ldgetname(ldptr, &symr)); sp->address = symr.value; sp++; if (sp >= last) { long n = alloced + 10000; syms = (Symbol*) realloc(syms, (size_t) (sizeof(Symbol) * n)); last = syms + n; sp = syms + alloced; alloced = n; } } } } int interesting = sp - syms; if (!quiet) { printf("Total of %d symbols\n", interesting); } usefulSymbols = interesting; externalSymbols = syms; }
inline std::string Demangle(const char* mangled) { char demangled[124]; if (Demangle(mangled, demangled, sizeof(demangled))) return std::string(demangled); return std::string(mangled); }
std::string Demangle(char const * name) { int st; char * const p = abi::__cxa_demangle(name, 0, 0, &st); switch (st) { case 0: { return std::unique_ptr<char, decltype(&std::free)>(p, &std::free).get(); } case -1: throw std::runtime_error("A memory allocation failure occurred."); case -2: throw std::runtime_error("Not a valid name under the GCC C++ ABI mangling rules."); case -3: throw std::runtime_error("One of the arguments is invalid."); default: throw std::runtime_error("unexpected demangle status"); } } template<typename T> std::string GetTypeName() { return Demangle(typeid(T).name()); }