]> de.git.xonotic.org Git - xonotic/netradiant.git/blobdiff - radiant/stacktrace.cpp
reformat code! now the code is only ugly on the *inside*
[xonotic/netradiant.git] / radiant / stacktrace.cpp
index 7c75db423597a7afd6b90dc64cc5169264ae9d86..e2d383f5d590bbe9a95b2f04ad07e148b31ff1dd 100644 (file)
@@ -1,57 +1,60 @@
 /*
-Copyright (C) 2001-2006, William Joseph.
-All Rights Reserved.
+   Copyright (C) 2001-2006, William Joseph.
+   All Rights Reserved.
 
-This file is part of GtkRadiant.
+   This file is part of GtkRadiant.
 
-GtkRadiant is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
+   GtkRadiant is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
 
-GtkRadiant is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
+   GtkRadiant is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
 
-You should have received a copy of the GNU General Public License
-along with GtkRadiant; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-*/
+   You should have received a copy of the GNU General Public License
+   along with GtkRadiant; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
 
 #include "stacktrace.h"
+#include "globaldefs.h"
+
 #include "stream/textstream.h"
 
 #include "environment.h"
 
-#ifdef __linux__
+#if GDEF_OS_LINUX
+
 #include <execinfo.h>
 
-void write_stack_trace(TextOutputStreamoutputStream)
+void write_stack_trace(TextOutputStream &outputStream)
 {
-  const unsigned int MAX_SYMBOLS = 256;
-  void* symbols[MAX_SYMBOLS];
-    
-  // get return addresses
-  int symbol_count = backtrace(symbols, MAX_SYMBOLS);
-  
-  if(!symbol_count)
-       return;
-  
-  // resolve and print names
-  char** symbol_names = backtrace_symbols(symbols, symbol_count);      
-  if(symbol_names)
-  {
-     for(int i = 0; (i < symbol_count); ++i)
-        outputStream << symbol_names[i] << "\n";
-        
-     // not a memleak, see www.gnu.org/software/libc/manual (Debugging Support, Backtraces)
-     free(symbol_names);
-  }
-}      
-#endif
+    const unsigned int MAX_SYMBOLS = 256;
+    void *symbols[MAX_SYMBOLS];
+
+    // get return addresses
+    int symbol_count = backtrace(symbols, MAX_SYMBOLS);
 
-#if defined (WIN32) && defined (_MSC_VER) && defined (DEBUG)
+    if (!symbol_count) {
+        return;
+    }
+
+    // resolve and print names
+    char **symbol_names = backtrace_symbols(symbols, symbol_count);
+    if (symbol_names) {
+        for (int i = 0; (i < symbol_count); ++i) {
+            outputStream << symbol_names[i] << "\n";
+        }
+
+        // not a memleak, see www.gnu.org/software/libc/manual (Debugging Support, Backtraces)
+        free(symbol_names);
+    }
+}
+
+#elif GDEF_COMPILER_MSVC
 
 #include "windows.h"
 #include "winnt.h"
@@ -60,259 +63,243 @@ void write_stack_trace(TextOutputStream& outputStream)
 class Address
 {
 public:
-  void* m_value;
-  Address(void* value) : m_value(value)
-  {
-  }
+void* m_value;
+Address( void* value ) : m_value( value ){
+}
 };
 
 /// \brief Writes an address \p p to \p ostream in hexadecimal form.
 template<typename TextOutputStreamType>
-inline TextOutputStreamType& ostream_write(TextOutputStreamType& ostream, const Address& p)
-{
-  const std::size_t bufferSize = (sizeof(void*) * 2) + 1;
-  char buf[bufferSize];
-  ostream.write(buf, snprintf(buf, bufferSize, "%0p", p.m_value));
-  return ostream;
+inline TextOutputStreamType& ostream_write( TextOutputStreamType& ostream, const Address& p ){
+    const std::size_t bufferSize = ( sizeof( void* ) * 2 ) + 1;
+    char buf[bufferSize];
+    ostream.write( buf, snprintf( buf, bufferSize, "%0p", p.m_value ) );
+    return ostream;
 }
 
 class Offset
 {
 public:
-  void* m_value;
-  Offset(void* value) : m_value(value)
-  {
-  }
+void* m_value;
+Offset( void* value ) : m_value( value ){
+}
 };
 
 /// \brief Writes an address \p p to \p ostream in hexadecimal form.
 template<typename TextOutputStreamType>
-inline TextOutputStreamType& ostream_write(TextOutputStreamType& ostream, const Offset& p)
-{
-  const std::size_t bufferSize = (sizeof(void*) * 2) + 1;
-  char buf[bufferSize];
-  ostream.write(buf, snprintf(buf, bufferSize, "%X", p.m_value));
-  return ostream;
+inline TextOutputStreamType& ostream_write( TextOutputStreamType& ostream, const Offset& p ){
+    const std::size_t bufferSize = ( sizeof( void* ) * 2 ) + 1;
+    char buf[bufferSize];
+    ostream.write( buf, snprintf( buf, bufferSize, "%X", p.m_value ) );
+    return ostream;
 }
 
 /// \brief Writes a WCHAR string \p s to \p ostream.
 template<typename TextOutputStreamType>
-inline TextOutputStreamType& ostream_write(TextOutputStreamType& ostream, const WCHAR* s)
-{
-  const std::size_t bufferSize = 1024;
-  char buf[bufferSize];
-  ostream.write(buf, snprintf(buf, bufferSize, "%ls", s));
-  return ostream;
+inline TextOutputStreamType& ostream_write( TextOutputStreamType& ostream, const WCHAR* s ){
+    const std::size_t bufferSize = 1024;
+    char buf[bufferSize];
+    ostream.write( buf, snprintf( buf, bufferSize, "%ls", s ) );
+    return ostream;
 }
 
 struct EnumerateSymbolsContext
 {
-  STACKFRAME64& sf;
-  TextOutputStream& outputStream;
-  std::size_t count;
-  EnumerateSymbolsContext(STACKFRAME64& sf, TextOutputStream& outputStream) : sf(sf), outputStream(outputStream), count(0)
-  {
-  }
+    STACKFRAME64& sf;
+    TextOutputStream& outputStream;
+    std::size_t count;
+    EnumerateSymbolsContext( STACKFRAME64& sf, TextOutputStream& outputStream ) : sf( sf ), outputStream( outputStream ), count( 0 ){
+    }
 };
 
-void write_symbol(PSYMBOL_INFO pSym, STACKFRAME64& sf, TextOutputStream& outputStream, std::size_t& count)
-{
+void write_symbol( PSYMBOL_INFO pSym, STACKFRAME64& sf, TextOutputStream& outputStream, std::size_t& count ){
 #if 0
- if ( pSym->Flags & SYMFLAG_PARAMETER )
- {
+    if ( pSym->Flags & SYMFLAG_PARAMETER ) {
 
-    DWORD basicType;
-    if ( SymGetTypeInfo( GetCurrentProcess(), pSym->ModBase, pSym->TypeIndex,
-                        TI_GET_BASETYPE, &basicType ) )
-    {
-      int bleh = 0;
-    }
-    else
-    {
-      DWORD typeId;
-      if(SymGetTypeInfo( GetCurrentProcess(), pSym->ModBase, pSym->TypeIndex,
-                      TI_GET_TYPEID, &typeId ))
-      {
+        DWORD basicType;
         if ( SymGetTypeInfo( GetCurrentProcess(), pSym->ModBase, pSym->TypeIndex,
-                            TI_GET_BASETYPE, &basicType ) )
-        {
-          int bleh = 0;
+                             TI_GET_BASETYPE, &basicType ) ) {
+            int bleh = 0;
         }
         else
         {
-          const char* FormatGetLastError();
-          const char* error = FormatGetLastError();
-          int bleh = 0;
-
-          WCHAR* name;
-          if(SymGetTypeInfo( GetCurrentProcess(), pSym->ModBase, typeId,
-                          TI_GET_SYMNAME, &name ))
-          {
-            outputStream << name << " ";
-            LocalFree(name);
-            int bleh = 0;
-          }
-          else
-          {
-            const char* FormatGetLastError();
-            const char* error = FormatGetLastError();
-            int bleh = 0;
-          }
+            DWORD typeId;
+            if ( SymGetTypeInfo( GetCurrentProcess(), pSym->ModBase, pSym->TypeIndex,
+                                 TI_GET_TYPEID, &typeId ) ) {
+                if ( SymGetTypeInfo( GetCurrentProcess(), pSym->ModBase, pSym->TypeIndex,
+                                     TI_GET_BASETYPE, &basicType ) ) {
+                    int bleh = 0;
+                }
+                else
+                {
+                    const char* FormatGetLastError();
+                    const char* error = FormatGetLastError();
+                    int bleh = 0;
+
+                    WCHAR* name;
+                    if ( SymGetTypeInfo( GetCurrentProcess(), pSym->ModBase, typeId,
+                                         TI_GET_SYMNAME, &name ) ) {
+                        outputStream << name << " ";
+                        LocalFree( name );
+                        int bleh = 0;
+                    }
+                    else
+                    {
+                        const char* FormatGetLastError();
+                        const char* error = FormatGetLastError();
+                        int bleh = 0;
+                    }
+                }
+            }
+            else
+            {
+                const char* FormatGetLastError();
+                const char* error = FormatGetLastError();
+                int bleh = 0;
+            }
         }
-      }
-      else
-      {
-        const char* FormatGetLastError();
-        const char* error = FormatGetLastError();
-        int bleh = 0;
-      }
-    }
-    if(count != 0)
-    {
-      outputStream << ", ";
+        if ( count != 0 ) {
+            outputStream << ", ";
+        }
+        outputStream << pSym->Name;
+        ++count;
     }
-    outputStream << pSym->Name;
-    ++count;
-  }
 #endif
 }
 
 BOOL CALLBACK
 EnumerateSymbolsCallback(
-    PSYMBOL_INFO  pSymInfo,
-    ULONG         SymbolSize,
-    PVOID         UserContext )
-{
-  write_symbol( pSymInfo, ((EnumerateSymbolsContext*)UserContext)->sf, ((EnumerateSymbolsContext*)UserContext)->outputStream, ((EnumerateSymbolsContext*)UserContext)->count);
+    PSYMBOL_INFO pSymInfo,
+    ULONG SymbolSize,
+    PVOID UserContext ){
+    write_symbol( pSymInfo, ( (EnumerateSymbolsContext*)UserContext )->sf, ( (EnumerateSymbolsContext*)UserContext )->outputStream, ( (EnumerateSymbolsContext*)UserContext )->count );
 
 
-  return TRUE;
+    return TRUE;
 }
 
-void write_stack_trace(PCONTEXT pContext, TextOutputStream& outputStream)
-{
-  HANDLE m_hProcess = GetCurrentProcess();
-  DWORD dwMachineType = 0;
+void write_stack_trace( PCONTEXT pContext, TextOutputStream& outputStream ){
+    HANDLE m_hProcess = GetCurrentProcess();
+    DWORD dwMachineType = 0;
 
-  CONTEXT context = *pContext;
+    CONTEXT context = *pContext;
+
+    // Could use SymSetOptions here to add the SYMOPT_DEFERRED_LOADS flag
+    if ( !SymInitialize( m_hProcess, (PSTR)environment_get_app_path(), TRUE ) ) {
+        return;
+    }
+
+    STACKFRAME64 sf;
+    memset( &sf, 0, sizeof( sf ) );
+    sf.AddrPC.Mode         = AddrModeFlat;
+    sf.AddrStack.Mode      = AddrModeFlat;
+    sf.AddrFrame.Mode      = AddrModeFlat;
 
-  // Could use SymSetOptions here to add the SYMOPT_DEFERRED_LOADS flag
-  if ( !SymInitialize( m_hProcess, (PSTR)environment_get_app_path(), TRUE ) )
-  {
-    return;
-  }
-
-  STACKFRAME64 sf;
-  memset( &sf, 0, sizeof(sf) );
-  sf.AddrPC.Mode         = AddrModeFlat;
-  sf.AddrStack.Mode      = AddrModeFlat;
-  sf.AddrFrame.Mode      = AddrModeFlat;
-  
 #ifdef _M_IX86
-  // Initialize the STACKFRAME structure for the first call.  This is only
-  // necessary for Intel CPUs, and isn't mentioned in the documentation.
-  sf.AddrPC.Offset       = context.Eip;
-  sf.AddrStack.Offset    = context.Esp;
-  sf.AddrFrame.Offset    = context.Ebp;
-  
-  dwMachineType = IMAGE_FILE_MACHINE_I386;
-#elif _M_X64
-  sf.AddrPC.Offset       = context.Rip;
-  sf.AddrStack.Offset    = context.Rsp;
-  
-  // MSDN: x64:  The frame pointer is RBP or RDI. This value is not always used.
-  // very funny, we'll try Rdi for now
-  sf.AddrFrame.Offset    = context.Rdi;
-  
-  dwMachineType = IMAGE_FILE_MACHINE_AMD64;
-#endif
+    // Initialize the STACKFRAME structure for the first call.  This is only
+    // necessary for Intel CPUs, and isn't mentioned in the documentation.
+    sf.AddrPC.Offset       = context.Eip;
+    sf.AddrStack.Offset    = context.Esp;
+    sf.AddrFrame.Offset    = context.Ebp;
 
-  const unsigned int max_sym_name = 1024;// should be enough
-
-  while ( 1 )
-  {
-    // Get the next stack frame
-    if ( ! StackWalk64( dwMachineType,
-                        m_hProcess,
-                        GetCurrentThread(),
-                        &sf,
-                        &context,
-                        0,
-                        SymFunctionTableAccess64,
-                        SymGetModuleBase64,
-                        0 ) )
-        break;
-
-    if ( 0 == sf.AddrFrame.Offset ) // Basic sanity check to make sure
-      break;                      // the frame is OK.  Bail if not.
-
-    // Get the name of the function for this stack frame entry
-    BYTE symbolBuffer[ sizeof(SYMBOL_INFO) + max_sym_name ];
-    PSYMBOL_INFO pSymbol = (PSYMBOL_INFO)symbolBuffer;
-    pSymbol->SizeOfStruct = sizeof(SYMBOL_INFO);
-    pSymbol->MaxNameLen = max_sym_name;
-                    
-    DWORD64 symDisplacement = 0;    // Displacement of the input address,
-                                    // relative to the start of the symbol
-
-    IMAGEHLP_MODULE64 module = { sizeof(IMAGEHLP_MODULE64) };
-    if(SymGetModuleInfo64(m_hProcess, sf.AddrPC.Offset, &module))
-    {
-      outputStream << module.ModuleName << "!";
+    dwMachineType = IMAGE_FILE_MACHINE_I386;
+#elif _M_X64
+    sf.AddrPC.Offset       = context.Rip;
+    sf.AddrStack.Offset    = context.Rsp;
 
-      if ( SymFromAddr(m_hProcess, sf.AddrPC.Offset, &symDisplacement, pSymbol))
-      {
-        char undecoratedName[max_sym_name];
-        UnDecorateSymbolName(pSymbol->Name, undecoratedName, max_sym_name, UNDNAME_COMPLETE);
+    // MSDN: x64:  The frame pointer is RBP or RDI. This value is not always used.
+    // very funny, we'll try Rdi for now
+    sf.AddrFrame.Offset    = context.Rdi;
 
-        outputStream << undecoratedName;
+    dwMachineType = IMAGE_FILE_MACHINE_AMD64;
+#endif
 
-        outputStream << "(";
-        // Use SymSetContext to get just the locals/params for this frame
-        IMAGEHLP_STACK_FRAME imagehlpStackFrame;
-        imagehlpStackFrame.InstructionOffset = sf.AddrPC.Offset;
-        SymSetContext( m_hProcess, &imagehlpStackFrame, 0 );
+    const unsigned int max_sym_name = 1024; // should be enough
 
-        // Enumerate the locals/parameters
-        EnumerateSymbolsContext context(sf, outputStream);
-        SymEnumSymbols( m_hProcess, 0, 0, EnumerateSymbolsCallback, &context );
-        outputStream << ")";
+    while ( 1 )
+    {
+        // Get the next stack frame
+        if ( !StackWalk64( dwMachineType,
+                           m_hProcess,
+                           GetCurrentThread(),
+                           &sf,
+                           &context,
+                           0,
+                           SymFunctionTableAccess64,
+                           SymGetModuleBase64,
+                           0 ) ) {
+            break;
+        }
 
-        outputStream << " + " << Offset(reinterpret_cast<void*>(symDisplacement));
+        if ( 0 == sf.AddrFrame.Offset ) { // Basic sanity check to make sure
+            break;                // the frame is OK.  Bail if not.
 
-        // Get the source line for this stack frame entry
-        IMAGEHLP_LINE64 lineInfo = { sizeof(IMAGEHLP_LINE64) };
-        DWORD dwLineDisplacement;
-        if ( SymGetLineFromAddr64( m_hProcess, sf.AddrPC.Offset,
-                                &dwLineDisplacement, &lineInfo ) )
-        {
-          outputStream << " " << lineInfo.FileName << " line " << Unsigned(lineInfo.LineNumber); 
         }
-      }
-      else
-      {
-        outputStream << Address(reinterpret_cast<void*>(sf.AddrPC.Offset));
-      }
-    }
+        // Get the name of the function for this stack frame entry
+        BYTE symbolBuffer[ sizeof( SYMBOL_INFO ) + max_sym_name ];
+        PSYMBOL_INFO pSymbol = (PSYMBOL_INFO)symbolBuffer;
+        pSymbol->SizeOfStruct = sizeof( SYMBOL_INFO );
+        pSymbol->MaxNameLen = max_sym_name;
+
+        DWORD64 symDisplacement = 0; // Displacement of the input address,
+                                     // relative to the start of the symbol
+
+        IMAGEHLP_MODULE64 module = { sizeof( IMAGEHLP_MODULE64 ) };
+        if ( SymGetModuleInfo64( m_hProcess, sf.AddrPC.Offset, &module ) ) {
+            outputStream << module.ModuleName << "!";
+
+            if ( SymFromAddr( m_hProcess, sf.AddrPC.Offset, &symDisplacement, pSymbol ) ) {
+                char undecoratedName[max_sym_name];
+                UnDecorateSymbolName( pSymbol->Name, undecoratedName, max_sym_name, UNDNAME_COMPLETE );
+
+                outputStream << undecoratedName;
+
+                outputStream << "(";
+                // Use SymSetContext to get just the locals/params for this frame
+                IMAGEHLP_STACK_FRAME imagehlpStackFrame;
+                imagehlpStackFrame.InstructionOffset = sf.AddrPC.Offset;
+                SymSetContext( m_hProcess, &imagehlpStackFrame, 0 );
+
+                // Enumerate the locals/parameters
+                EnumerateSymbolsContext context( sf, outputStream );
+                SymEnumSymbols( m_hProcess, 0, 0, EnumerateSymbolsCallback, &context );
+                outputStream << ")";
+
+                outputStream << " + " << Offset( reinterpret_cast<void*>( symDisplacement ) );
+
+                // Get the source line for this stack frame entry
+                IMAGEHLP_LINE64 lineInfo = { sizeof( IMAGEHLP_LINE64 ) };
+                DWORD dwLineDisplacement;
+                if ( SymGetLineFromAddr64( m_hProcess, sf.AddrPC.Offset,
+                                           &dwLineDisplacement, &lineInfo ) ) {
+                    outputStream << " " << lineInfo.FileName << " line " << Unsigned( lineInfo.LineNumber );
+                }
+            }
+            else
+            {
+                outputStream << Address( reinterpret_cast<void*>( sf.AddrPC.Offset ) );
+            }
+        }
 
-    outputStream << "\n";
-  }
+        outputStream << "\n";
+    }
 
-  SymCleanup(m_hProcess);
+    SymCleanup( m_hProcess );
 
-  return;
+    return;
 }
 
-void write_stack_trace(TextOutputStream& outputStream)
-{
-  __try{ RaiseException(0,0,0,0); } __except(write_stack_trace((GetExceptionInformation())->ContextRecord, outputStream), EXCEPTION_CONTINUE_EXECUTION) {}
+void write_stack_trace( TextOutputStream& outputStream ){
+    __try { RaiseException( 0,0,0,0 ); } __except( write_stack_trace( ( GetExceptionInformation() )->ContextRecord, outputStream ), EXCEPTION_CONTINUE_EXECUTION ) {
+    }
 }
 
+#elif GDEF_OS_WINDOWS
+void write_stack_trace( TextOutputStream& outputStream ){
+    outputStream << "\nStacktrace is disabled on this compiler\n";
+}
 #else
-#if defined (WIN32)
-void write_stack_trace(TextOutputStream& outputStream)
-{
-       outputStream << "\nStacktrace is disabled in release-builds\n";
+void write_stack_trace( TextOutputStream& outputStream ){
+    outputStream << "\nStacktrace is disabled on this platform\n";
 }
 #endif
-#endif