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 qgsFree(void *ptr)
Frees the memory space pointed to by ptr.
void * qgsMalloc(size_t size)
Allocates size bytes and returns a pointer to the allocated memory.