Author: pluto Date: Fri Sep 21 10:36:51 2007 New Revision: 8735 Modified: backtracexx/README backtracexx/backtracexx.cpp Log: C - drop extracting caller's address from callee's return point
Modified: backtracexx/README ============================================================================== --- backtracexx/README (original) +++ backtracexx/README Fri Sep 21 10:36:51 2007 @@ -1,7 +1,4 @@ -A backtrace is a summary of how your program got where it is. -Unfortunately glibc's backtrace() and gdb's (bt) produce an unwind -path instead of true backtrace. This small library uses unwind -information and produces true backtrace with optionally demangled symbols. -it allows you to embed backtracing facility into your application. +This small library uses unwind information and produces backtrace +with optionally demangled symbols. Sources available at: http://svn.pld-linux.org/cgi-bin/viewsvn/backtracexx/ Modified: backtracexx/backtracexx.cpp ============================================================================== --- backtracexx/backtracexx.cpp (original) +++ backtracexx/backtracexx.cpp Fri Sep 21 10:36:51 2007 @@ -34,44 +34,10 @@ { namespace { - // - // extract caller's address from callee's return point. - // - unsigned long caller( unsigned long ret ) - { - unsigned char const* ip = reinterpret_cast< unsigned char const* >( ret ); -#if defined( __powerpc__ ) && !defined( __powerpc64__ ) - // powerpc64 not tested. - ip -= 4; -#elif defined( __sparc__ ) - // the same for sparc v7/8/9. - ip -= 8; -#elif defined( __alpha__ ) - ip -= 4; -#elif defined( __i386__ ) || defined( __x86_64__ ) || defined( WIN32 ) - // - // TODO: - // analysis of complex addressing forms (see intel/24319102.pdf). - // rework code to cover all cases. - // - // call, near, relative - if ( ip[ -5 ] == 0xe8 ) - return ( ret - 5 ); - // call, near, absolute indirect - if ( ip[ -2 ] == 0xff ) - { - if ( ( ip[ -1 ] & 0xf8 ) == 0xd0 ) // call *%reg - return ( ret - 2 ); - if ( ( ip[ -1 ] & 0xf8 ) == 0x10 ) // call *(%reg) - return ( ret - 2 ); - } -#endif - return ret; - } #if defined( __GNUC__ ) - void lookupSymbol( Frame& frame ) + bool lookupSymbol( Frame& frame ) { Dl_info info; if ( ::dladdr( reinterpret_cast< void* >( frame.address ), &info ) ) @@ -95,7 +61,9 @@ frame.symbol = info.dli_sname; } } + return true; } + return false; } _Unwind_Reason_Code helper( struct _Unwind_Context* ctx, Trace* trace ) @@ -107,7 +75,7 @@ if ( beforeInsn ) frame.signalTrampoline = true; else - frame.address = caller( frame.address ); + frame.address = frame.address; lookupSymbol( frame ); trace->push_back( frame ); return _URC_NO_REASON; @@ -115,12 +83,15 @@ #elif defined( _MSC_VER ) && defined( WIN32 ) - void lookupSymbol( Frame& frame ) + bool lookupSymbol( Frame& frame ) { ::MEMORY_BASIC_INFORMATION mbi; - ::VirtualQuery( reinterpret_cast< ::LPCVOID >( frame.address ), &mbi, sizeof( mbi ) ); + if ( !::VirtualQuery( reinterpret_cast< ::LPCVOID >( frame.address ), &mbi, sizeof( mbi ) ) ) + return false; ::CHAR moduleName[ MAX_PATH ]; ::GetModuleFileNameA( reinterpret_cast< ::HMODULE >( mbi.AllocationBase ), moduleName, sizeof( moduleName ) ); + if ( mbi.Protect & PAGE_NOACCESS ) + return false; frame.moduleBaseAddress = reinterpret_cast< unsigned long >( mbi.AllocationBase ); frame.moduleName = moduleName; int const MaxSymbolNameLength = 8192; @@ -148,6 +119,7 @@ } ::SymUnloadModule64( ::GetCurrentProcess(), reinterpret_cast< ::DWORD64 >( mbi.AllocationBase ) ); } + return true; } #endif @@ -203,7 +175,6 @@ while ( ::StackWalk64( IMAGE_FILE_MACHINE_I386, process, ::GetCurrentThread(), &stackFrame, &context, 0, ::SymFunctionTableAccess64, ::SymGetModuleBase64, 0 ) ) { - Frame frame; unsigned long offset = static_cast< unsigned long >( stackFrame.AddrReturn.Offset ); // // the deepest frame pointer and return address of the process @@ -212,9 +183,10 @@ // if ( !offset ) break; - frame.address = caller( offset ); - lookupSymbol( frame ); - trace.push_back( frame ); + Frame frame; + frame.address = offset; + if ( lookupSymbol( frame ) ) + trace.push_back( frame ); } ::SymCleanup( process ); _______________________________________________ pld-cvs-commit mailing list [email protected] http://lists.pld-linux.org/mailman/listinfo/pld-cvs-commit
