SVN: backtracexx: README backtracexx.cpp

pluto pluto at pld-linux.org
Fri Sep 21 10:36:51 CEST 2007


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 );
 


More information about the pld-cvs-commit mailing list