16 #include "qgsstacktrace.h"    30 QVector<QgsStackTrace::StackLine> QgsStackTrace::trace( _EXCEPTION_POINTERS *ExceptionInfo )
    37   HANDLE process = GetCurrentProcess();
    38   SymSetOptions( SYMOPT_DEFERRED_LOADS | SYMOPT_INCLUDE_32BIT_MODULES | SYMOPT_UNDNAME );
    41   if ( QgsStackTrace::mSymbolPaths.isEmpty() )
    47     paths = QgsStackTrace::mSymbolPaths.toStdString().c_str();
    50   SymInitialize( process, paths, TRUE );
    54   CONTEXT context_record;
    56     context_record = *ExceptionInfo->ContextRecord;
    58     RtlCaptureContext( &context_record );
    61   STACKFRAME64 stack_frame;
    62   memset( &stack_frame, 0, 
sizeof( stack_frame ) );
    64   int machine_type = IMAGE_FILE_MACHINE_AMD64;
    65   stack_frame.AddrPC.Offset = context_record.Rip;
    66   stack_frame.AddrFrame.Offset = context_record.Rbp;
    67   stack_frame.AddrStack.Offset = context_record.Rsp;
    69   int machine_type = IMAGE_FILE_MACHINE_I386;
    70   stack_frame.AddrPC.Offset = context_record.Eip;
    71   stack_frame.AddrFrame.Offset = context_record.Ebp;
    72   stack_frame.AddrStack.Offset = context_record.Esp;
    74   stack_frame.AddrPC.Mode = AddrModeFlat;
    75   stack_frame.AddrFrame.Mode = AddrModeFlat;
    76   stack_frame.AddrStack.Mode = AddrModeFlat;
    78   SYMBOL_INFO *symbol = ( SYMBOL_INFO * ) 
qgsMalloc( 
sizeof( SYMBOL_INFO ) + MAX_SYM_NAME );
    79   symbol->SizeOfStruct = 
sizeof( SYMBOL_INFO );
    80   symbol->MaxNameLen = MAX_SYM_NAME;
    82   IMAGEHLP_LINE *line = ( IMAGEHLP_LINE * ) 
qgsMalloc( 
sizeof( IMAGEHLP_LINE ) );
    83   line->SizeOfStruct = 
sizeof( IMAGEHLP_LINE );
    85   IMAGEHLP_MODULE *module = ( IMAGEHLP_MODULE * ) 
qgsMalloc( 
sizeof( IMAGEHLP_MODULE ) );
    86   module->SizeOfStruct = 
sizeof( IMAGEHLP_MODULE );
    88   while ( StackWalk64( machine_type,
    94                        &SymFunctionTableAccess64,
    99     DWORD64 displacement = 0;
   101     if ( SymFromAddr( process, ( DWORD64 )stack_frame.AddrPC.Offset, &displacement, symbol ) )
   103       DWORD dwDisplacement;
   105       QgsStackTrace::StackLine stackline;
   106       stackline.symbolName = QString( symbol->Name );
   108       if ( SymGetLineFromAddr( process, ( DWORD64 ) stack_frame.AddrPC.Offset, &dwDisplacement, line ) )
   110         stackline.fileName = QString( line->FileName );
   111         stackline.lineNumber = QString::number( line->LineNumber );
   115         stackline.fileName = 
"(unknown file)";
   116         stackline.lineNumber = 
"(unknown line)";
   119       if ( SymGetModuleInfo( process, ( DWORD64 ) stack_frame.AddrPC.Offset, module ) )
   121         stackline.moduleName = module->ModuleName;
   125         stackline.moduleName = 
"(unknown module)";
   128       stack.append( stackline );
   135   SymCleanup( process );
   139 QString QgsStackTrace::mSymbolPaths;
   141 void QgsStackTrace::setSymbolPath( QString symbolPaths )
   143   mSymbolPaths = symbolPaths;
   149 QVector<QgsStackTrace::StackLine> QgsStackTrace::trace( 
unsigned int maxFrames )
   151   Q_UNUSED( maxFrames )
   162 bool QgsStackTrace::StackLine::isQgisModule()
 const   164   return moduleName.contains( QLatin1String( 
"qgis" ), Qt::CaseInsensitive );
   167 bool QgsStackTrace::StackLine::isValid()
 const   169   return !( fileName.contains( QLatin1String( 
"exe_common" ), Qt::CaseInsensitive ) ||
   170             fileName.contains( QLatin1String( 
"unknown" ), Qt::CaseInsensitive ) ||
   171             lineNumber.contains( QLatin1String( 
"unknown" ), Qt::CaseInsensitive ) );
 void * qgsMalloc(size_t size)
Allocates size bytes and returns a pointer to the allocated memory. 
 
void qgsFree(void *ptr)
Frees the memory space pointed to by ptr.