// PD_TRACE_DECLARE_FUNCTION ( SDB_OSSSTKTRA, "ossStackTrace" ) void ossStackTrace( LPEXCEPTION_POINTERS lpEP, const CHAR * dumpDir ) { PD_TRACE_ENTRY ( SDB_OSSSTKTRA ); SYMBOL_INFO * pSymbol = NULL ; HANDLE hProcess ; void * stack[ OSS_MAX_BACKTRACE_FRAMES_SUPPORTED + 1 ] = { 0 } ; CHAR pName[ OSS_FUNC_NAME_LEN_MAX + 1 ] ; UINT32 frames = 0 ; SYSTEM_INFO sysInfo = { 0 } ; OSVERSIONINFOEX OSVerInfo={ 0 } ; ossPrimitiveFileOp trapFile ; CHAR fileName[ OSS_MAX_PATHSIZE + 1 ] = { 0 } ; UINT32 StrLen = 0 ; ossSnprintf ( fileName, OSS_MAX_PATHSIZE, "%d.%d.trap", ossGetCurrentProcessID(), ossGetCurrentThreadID() ) ; if ( OSS_MAX_PATHSIZE < ossStrlen ( dumpDir ) + ossStrlen ( OSS_PRIMITIVE_FILE_SEP ) + ossStrlen ( fileName ) ) { pdLog ( PDERROR, __FUNC__, __FILE__, __LINE__, "path + file name is too long" ) ; goto error ; } ossMemset( fileName, 0, sizeof( fileName ) ) ; StrLen += ossSnprintf( fileName, sizeof( fileName ), "%s%s", dumpDir, OSS_PRIMITIVE_FILE_SEP ) ; ossSnprintf( fileName + StrLen, sizeof(fileName) - StrLen, "%d.%d.trap", ossGetCurrentProcessID(), ossGetCurrentThreadID() ) ; trapFile.Open( fileName ) ; if ( trapFile.isValid() ) { trapFile.seekToEnd () ; trapFile.Write(" -------- System Information --------\n" ) ; ossDumpSystemTime ( &trapFile ) ; ossDumpDatabaseInfo ( &trapFile ) ; GetSystemInfo( &sysInfo ) ; switch( sysInfo.wProcessorArchitecture ) { case PROCESSOR_ARCHITECTURE_INTEL: trapFile.Write( "Processor : Intel x86\n" ) ; break ; case PROCESSOR_ARCHITECTURE_IA64: trapFile.Write( "Processor : Intel IA64\n" ) ; break ; case PROCESSOR_ARCHITECTURE_AMD64: trapFile.Write( "Processor : AMD 64\n") ; break ; default: trapFile.Write( "Unknown processor architecture ") ; } trapFile.fWrite( " Number of processors: %u Page size: %u\n" " Min application address: %lx" " Max application address: %lx\n" " Active processor mask: %u\n", sysInfo.dwNumberOfProcessors, sysInfo.dwPageSize, sysInfo.lpMinimumApplicationAddress, sysInfo.lpMaximumApplicationAddress, sysInfo.dwActiveProcessorMask ) ; OSVerInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); GetVersionEx ( (OSVERSIONINFO*) &OSVerInfo ) ; if ( OSVerInfo.dwMajorVersion == 6 ) { if ( OSVerInfo.dwMinorVersion == 0 ) { if ( OSVerInfo.wProductType == VER_NT_WORKSTATION ) { trapFile.Write( "Windows Vista " ) ; } else { trapFile.Write( "Windows Server 2008 " ) ; } } if ( OSVerInfo.dwMinorVersion == 1 ) { if ( OSVerInfo.wProductType == VER_NT_WORKSTATION ) { trapFile.Write( "Windows 7 " ) ; } else { trapFile.Write( "Windows Server 2008 " ) ; } } } if ( OSVerInfo.dwMajorVersion == 5 && OSVerInfo.dwMinorVersion == 2 ) { if ( OSVerInfo.wProductType == VER_NT_WORKSTATION ) { trapFile.Write( "Windows XP " ) ; } else { trapFile.Write( "Windows Server 2003 " ) ; } } if ( OSVerInfo.dwMajorVersion == 5 && OSVerInfo.dwMinorVersion == 1 ) { trapFile.Write("Windows XP ") ; } if ( OSVerInfo.dwMajorVersion == 5 && OSVerInfo.dwMinorVersion == 0 ) { trapFile.Write("Windows 2000 ") ; } trapFile.fWrite( "%s ( %d.%d) Build:%d\n", OSVerInfo.szCSDVersion, OSVerInfo.dwMajorVersion, OSVerInfo.dwMinorVersion, OSVerInfo.dwBuildNumber ) ; hProcess = GetCurrentProcess() ; pSymbol = ( SYMBOL_INFO * )SDB_OSS_MALLOC( sizeof( SYMBOL_INFO ) + OSS_FUNC_NAME_LEN_MAX * sizeof( char ) ) ; if ( NULL != pSymbol ) { ossMemset( pSymbol, 0, sizeof( SYMBOL_INFO ) + OSS_FUNC_NAME_LEN_MAX * sizeof(char) ) ; pSymbol->MaxNameLen = OSS_FUNC_NAME_LEN_MAX ; pSymbol->SizeOfStruct = sizeof( SYMBOL_INFO ) ; ossSymInitialize( hProcess, NULL, TRUE ) ; if ( NULL != lpEP ) { trapFile.Write( "-------- Registers --------\n" ) ; #ifndef _WIN64 trapFile.fWrite( SEGREG, lpEP->ContextRecord->SegGs, lpEP->ContextRecord->SegFs, lpEP->ContextRecord->SegEs, lpEP->ContextRecord->SegDs ) ; trapFile.fWrite( INTREG, (void*)lpEP->ContextRecord->Edi, (void*)lpEP->ContextRecord->Esi, (void*)lpEP->ContextRecord->Eax, (void*)lpEP->ContextRecord->Ebx, (void*)lpEP->ContextRecord->Ecx, (void*)lpEP->ContextRecord->Edx ) ; trapFile.fWrite( CTXREG, (void*)lpEP->ContextRecord->Ebp, (void*)lpEP->ContextRecord->Eip, (void*)lpEP->ContextRecord->Esp, (void*)lpEP->ContextRecord->EFlags, lpEP->ContextRecord->SegCs, lpEP->ContextRecord->SegSs ) ; #elif defined(_M_AMD64) trapFile.fWrite( SEGREG, lpEP->ContextRecord->SegGs, lpEP->ContextRecord->SegFs, lpEP->ContextRecord->SegEs, lpEP->ContextRecord->SegDs ) ; trapFile.fWrite( INTREG, (void*)lpEP->ContextRecord->Rdi, (void*)lpEP->ContextRecord->Rsi, (void*)lpEP->ContextRecord->Rax, (void*)lpEP->ContextRecord->Rbx, (void*)lpEP->ContextRecord->Rcx, (void*)lpEP->ContextRecord->Rdx, (void*)lpEP->ContextRecord->R8, (void*)lpEP->ContextRecord->R9, (void*)lpEP->ContextRecord->R10, (void*)lpEP->ContextRecord->R11, (void*)lpEP->ContextRecord->R12, (void*)lpEP->ContextRecord->R13, (void*)lpEP->ContextRecord->R14, (void*)lpEP->ContextRecord->R15 ) ; trapFile.fWrite( CTXREG, (void*)lpEP->ContextRecord->Rbp, (void*)lpEP->ContextRecord->Rip, (void*)lpEP->ContextRecord->Rsp, (void*)lpEP->ContextRecord->EFlags, lpEP->ContextRecord->SegCs, lpEP->ContextRecord->SegSs ) ; #endif trapFile.fWrite( "-------- Point of failure --------\n" ) ; ossMemset( pName, 0, sizeof( pName ) ) ; ossGetSymbolNameFromAddress( hProcess, (UINT64)lpEP->ExceptionRecord->ExceptionAddress, pSymbol, pName, sizeof( pName ) ) ; trapFile.fWrite( "%s\n", pName ) ; } // if NULL != lpEP trapFile.fWrite( "\n-------- Stack frames --------\n" ) ; #ifndef _WIN64 if ( NULL != lpEP ) { frames = ossWalkStackEx( lpEP, 0, OSS_MAX_BACKTRACE_FRAMES_SUPPORTED, stack ) ; } else { #endif frames = ossWalkStack( 0, OSS_MAX_BACKTRACE_FRAMES_SUPPORTED, stack ) ; #ifndef _WIN64 } #endif for ( UINT32 i = 0; i < frames; i++ ) { ossMemset( pName, 0, sizeof( pName ) ) ; ossGetSymbolNameFromAddress( hProcess, (UINT64)stack[i], pSymbol, pName, sizeof( pName ) ) ; trapFile.fWrite( "%3i: %s\n", i, pName ) ; } SDB_OSS_FREE( pSymbol ) ; } // if NULL != pSymbol } error : trapFile.Close() ; PD_TRACE_EXIT ( SDB_OSSSTKTRA ); return ; }
// PD_TRACE_DECLARE_FUNCTION ( SDB_OSSDUMPST3, "ossDumpStackTrace" ) void ossDumpStackTrace( OSS_HANDPARMS, ossPrimitiveFileOp * trapFile ) { PD_TRACE_ENTRY ( SDB_OSSDUMPST3 ); void * syms[ OSS_MAX_BACKTRACE_FRAMES_SUPPORTED ] ; CHAR mCode[ OSS_MCODE_LEN ] ; greg_t * r = ( ( ossSignalContext)scp )->uc_mcontext.gp_regs ; UINT8 * const rip = (UINT8 *)r[REG_NIP] ; UINT32_64 * const rsp = (UINT32_64 *)r[REG_R1] ; Dl_info dlip ; INT32 cnt, i ; if ( ( NULL != trapFile ) && trapFile->isValid() ) { ossDumpSystemTime ( trapFile ) ; ossDumpDatabaseInfo ( trapFile ) ; ossDumpSystemInfo( trapFile ) ; ossDumpSigInfo( sigcode, trapFile ) ; ossDumpRegistersInfo( ( ossSignalContext )scp, trapFile ) ; trapFile->Write( OSS_NEWLINE "Point of failure:"OSS_NEWLINE ) ; if ( NULL == sigcode ) { trapFile->Write( "Unable to provide disassembly information for " "the point of faliure due to signal info pointer " "is NULL"OSS_NEWLINE ) ; } else { if ( sigcode->si_addr != rip ) { trapFile->fWrite( "0x"OSS_PRIXPTR " ", (UINT32_64)rip ) ; ossFuncAddrToName( (void *)rip, trapFile ) ; trapFile->fWrite( OSS_NEWLINE"0x"OSS_PRIXPTR " : %s", rip, ossMachineCode( *((UINT32*)rip), mCode ) ); trapFile->fWrite( "%s"OSS_NEWLINE, ossMachineCode( *((UINT32*)( rip+4 )), mCode ) ) ; trapFile->Write( OSS_NEWLINE"StackTrace:"OSS_NEWLINE "-----Address----- ----Function name + Offset---"OSS_NEWLINE); cnt = backtrace( syms, OSS_MAX_BACKTRACE_FRAMES_SUPPORTED ) ; for ( i = 0 ; i < cnt ; i++ ) { trapFile->fWrite( "0x"OSS_PRIXPTR " ", (UINT32_64)syms[i] ) ; ossFuncAddrToName( syms[i], trapFile ) ; } } else { if ( dladdr( (void *)rsp, &dlip ) ) { trapFile->fWrite( OSS_NEWLINE"0x"OSS_PRIXPTR " : %s", rsp, ossMachineCode( *((UINT32*)rsp), mCode ) ) ; trapFile->fWrite( "%s"OSS_NEWLINE, ossMachineCode( *((UINT32*)(rsp+4)), mCode ) ) ; trapFile->Write( OSS_NEWLINE"StackTrace:"OSS_NEWLINE "-----Address----- ----Function name + Offset---"OSS_NEWLINE); trapFile->fWrite( "0x"OSS_PRIXPTR " [RSP]", rsp ) ; ossFuncAddrToName( (void *)rsp, trapFile ) ; } else { trapFile->Write( "Signal address is equal to " "instruction pointer( rip )and the valid " "return address could not be determined."OSS_NEWLINE ) ; trapFile->Write( OSS_NEWLINE"StackTrace:"OSS_NEWLINE "Unable to provide stack trace info due to " "above reason"OSS_NEWLINE ) ; } } } } PD_TRACE_EXIT ( SDB_OSSDUMPST3 ); }