Author: pluto
Date: Thu Jul 12 14:22:23 2007
New Revision: 8671

Modified:
   backtracexx/LICENSE
   backtracexx/backtracexx.cpp
   backtracexx/backtracexx.hpp
   backtracexx/example.cpp
   backtracexx/makefile
Log:
- use ::StackWalk64 on winnt instead of primitive assembly.
- add operator << for std::ostream. 
- tweak makefile and example.
- detailed note about license version. 


Modified: backtracexx/LICENSE
==============================================================================
--- backtracexx/LICENSE (original)
+++ backtracexx/LICENSE Thu Jul 12 14:22:23 2007
@@ -1 +1,2 @@
+the backtracexx library is licensed under LGPL v2.1.
 http://www.opensource.org/licenses/lgpl-license.php

Modified: backtracexx/backtracexx.cpp
==============================================================================
--- backtracexx/backtracexx.cpp (original)
+++ backtracexx/backtracexx.cpp Thu Jul 12 14:22:23 2007
@@ -1,4 +1,6 @@
 #include "backtracexx.hpp"
+#include <iomanip>
+#include <iostream>
 
 #if defined( __GNUC__ )
 #include <cxxabi.h>
@@ -155,37 +157,56 @@
 
 #elif defined( _MSC_VER ) && defined( WIN32 )
 
-               ::SymInitialize( ::GetCurrentProcess(), 0, FALSE );
+               ::HANDLE process = ::GetCurrentProcess();
+               ::SymInitialize( process, 0, FALSE );
                ::SymSetOptions( ::SymGetOptions() | SYMOPT_UNDNAME );
-               struct StackFrame
-               {
-                       StackFrame* previousFrame;
-                       unsigned long returnAddress;
-               };
-               StackFrame const* stackFrame;
-               __asm mov stackFrame, ebp;
-               //
-               //      the deepest frame pointer and return address of the 
process
-               //      call chain are zeroed by kernel32.dll during process 
startup:
-               //
-               //      BaseProcessStartThunk:
-               //              xor             ebp,ebp
-               //              push    eax
-               //              push    0x0
-               //              jmp             KERNEL32!BaseProcessStart
-               //
-               while ( stackFrame->returnAddress )
+               ::CONTEXT context = { 0 };
+               ::STACKFRAME64 stackFrame = { 0 };
+               stackFrame.AddrPC.Mode = stackFrame.AddrFrame.Mode = 
stackFrame.AddrStack.Mode = AddrModeFlat;
+               __asm
+               {
+                       call $ + 5;
+                       pop eax;
+                       mov context.Eip, eax;
+                       mov context.Esp, esp;
+                       mov context.Ebp, ebp;
+                       mov stackFrame.AddrPC, eax;
+                       mov stackFrame.AddrStack, esp;
+                       mov stackFrame.AddrFrame, ebp;
+               }
+               while ( ::StackWalk64( IMAGE_FILE_MACHINE_I386, process, 
::GetCurrentThread(),
+                       &stackFrame, &context, 0, ::SymFunctionTableAccess64, 
::SymGetModuleBase64, 0 ) )
                {
                        Frame frame;
-                       frame.address = caller( stackFrame->returnAddress );
+                       frame.address = static_cast< unsigned long >( 
stackFrame.AddrReturn.Offset );
+                       //
+                       //      the deepest frame pointer and return address of 
the process
+                       //      call chain are zeroed by kernel32.dll during 
process startup,
+                       //      so exclude such frame from trace and exit from 
loop.
+                       //
+                       if ( !frame.address )
+                               break;
                        lookupSymbol( frame );
                        trace.push_back( frame );
-                       stackFrame = stackFrame->previousFrame;
                }
-               ::SymCleanup( ::GetCurrentProcess() );
+               ::SymCleanup( process );
 
 #endif
 
                return trace;
        }
+
+       std::ostream& operator << ( std::ostream& os, Trace const& t )
+       {
+               os << "=== backtrace ====" << std::endl;
+               for ( backtracexx::Trace::const_iterator i = t.begin(); i != 
t.end(); ++i )
+               {
+                       backtracexx::Frame const& f = *i;
+                       os      << std::showbase << std::showpoint << std::hex 
<< std::setw( 16 ) << f.address
+                               << " : " << ( f.symbol.empty() ? "<unresolved 
symbol>" : f.symbol )
+                               << "+" << f.displacement << " [" << f.module << 
"]" << std::endl;
+               }
+               os << "==================" << std::endl;
+               return os;
+       }
 }

Modified: backtracexx/backtracexx.hpp
==============================================================================
--- backtracexx/backtracexx.hpp (original)
+++ backtracexx/backtracexx.hpp Thu Jul 12 14:22:23 2007
@@ -1,12 +1,23 @@
 #ifndef backtracexx_hpp
 #define backtracexx_hpp
 
+#include <iosfwd>
 #include <string>
 #include <vector>
 
+#if defined( WIN32 ) || defined( WIN64 )
+#ifdef BACKTRACEXX_EXPORTS
+#define DEBUGTOOLS_EXPORT      __declspec( dllexport )
+#else
+#define DEBUGTOOLS_EXPORT      __declspec( dllimport )
+#endif
+#else
+#define DEBUGTOOLS_EXPORT      __attribute__(( visibility( "default" ) ))
+#endif
+
 namespace backtracexx
 {
-       struct Frame
+       struct DEBUGTOOLS_EXPORT Frame
        {
                Frame();
 
@@ -19,7 +30,8 @@
 
        typedef std::vector< Frame > Trace;
 
-       Trace scan();
+       DEBUGTOOLS_EXPORT Trace scan();
+       DEBUGTOOLS_EXPORT std::ostream& operator << ( std::ostream&, Trace 
const& );
 }
 
 #endif

Modified: backtracexx/example.cpp
==============================================================================
--- backtracexx/example.cpp     (original)
+++ backtracexx/example.cpp     Thu Jul 12 14:22:23 2007
@@ -10,14 +10,7 @@
 
 void signalHandler( int signalNumber )
 {
-       backtracexx::Trace t = backtracexx::scan();
-       for ( backtracexx::Trace::const_iterator i = t.begin(); i != t.end(); 
++i )
-       {
-               backtracexx::Frame const& f = *i;
-               std::printf( "0x%016lx : %s+0x%lx [%s]\n", f.address,
-                       ( f.symbol.empty() ? "<unresolved symbol>" : 
f.symbol.c_str() ),
-                       f.displacement, f.module.c_str() );
-       }
+       std::cerr << backtracexx::scan();
        longjmp( context, 1 );
 }
 

Modified: backtracexx/makefile
==============================================================================
--- backtracexx/makefile        (original)
+++ backtracexx/makefile        Thu Jul 12 14:22:23 2007
@@ -1,13 +1,11 @@
 CXX := g++
 CXXFLAGS := -O1 -Wall -Werror -pedantic
-LDXXFLAGS := -Wl,-export-dynamic -s -ldl -static-libgcc
 
 all: example
 
 example: example.cpp backtracexx.hpp backtracexx.cpp
-       $(CXX) $(CXXFLAGS) backtracexx.cpp -c
-       $(CXX) $(CXXFLAGS) example.cpp -c
-       $(CXX) example.o backtracexx.o -o example $(LDXXFLAGS)
+       $(CXX) $(CXXFLAGS) -fpic backtracexx.cpp -o libbacktracexx.so -shared 
-s -ldl -static-libgcc
+       $(CXX) $(CXXFLAGS) example.cpp -o example ./libbacktracexx.so -s 
-Wl,--export-dynamic
 
 clean:
-       rm -f *.o *.s *.ii example
+       rm -f *.o *.s *.ii example libbacktracexx.so
_______________________________________________
pld-cvs-commit mailing list
[email protected]
http://lists.pld-linux.org/mailman/listinfo/pld-cvs-commit

Reply via email to