|
|
// ReadLogsDlg.cpp : implementation file
//
#include "stdafx.h"
#include "emshell.h"
#include "ReadLogsDlg.h"
#include "EmShell.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__; #endif
extern BSTR CopyBSTR( LPBYTE pb, ULONG cb );
const char* gslCarriageReturn = "\r"; const TCHAR* gtcFileOpenFlags = _T("w+b"); const TCHAR* gtcTempFilenameSeed = _T("ems"); const char* gslFirstChance = "first chance"; const char* gslCode = " - code"; const char* gslKV = "> kv"; const char* gslChildEBP = "ChildEBP"; const char* gslPrompt = ">"; const char* gslUEIP = "> u eip"; const char* gslSemiColon = ":"; const char* gslReadLogsAV = "READLOGS_AV"; const char* gslReadLogsDB = "READLOGS_DB"; const char* gslTildaStarKV = "~*kv"; const char* gslBangLocks = "!locks"; const char* gslIDColon = "id: "; const char* gslCritSecText = "CritSec "; const char gslSpace = ' '; const char* gslOwningThread = "OwningThread"; const char* gslPeriod = "."; const char* gslWaitForSingleObject = "WaitForSingleObject"; const char* gslWaitForMultipleObjects = "WaitForMultipleObjects"; const char* gslWaitForCriticalSection = "WaitForCriticalSection";
/////////////////////////////////////////////////////////////////////////////
// CReadLogsDlg dialog
CReadLogsDlg::CReadLogsDlg(PEmObject pEmObj, IEmManager *pEmMgr, CWnd* pParent /*=NULL*/) : CDialog(CReadLogsDlg::IDD, pParent) { _ASSERTE( pEmObj != NULL ); _ASSERTE( pEmMgr != NULL );
m_pEmObject = pEmObj; m_pIEmManager = pEmMgr; m_bAdvancedWindow = FALSE; m_pLogFile = NULL;
//{{AFX_DATA_INIT(CReadLogsDlg)
m_csCompleteLog = _T(""); m_strExceptionType = _T(""); m_strExceptionLocation = _T(""); m_strFailingInstruction = _T(""); //}}AFX_DATA_INIT
}
void CReadLogsDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CReadLogsDlg)
DDX_Control(pDX, IDC_STATIC_EXCEPINFO, m_ctlStaticExcepInfo); DDX_Control(pDX, IDC_STATIC_HANGINFO, m_staticHangInfo); DDX_Control(pDX, IDC_STATIC_FAILING_INSTRUCTION, m_ctlStaticFailingInstruction); DDX_Control(pDX, IDC_STATIC_EXCEPTION_LOCATION, m_ctlStaticExceptionLocation); DDX_Control(pDX, IDC_STATIC_EXCEPTION_TYPE, m_ctlStaticExceptionType); DDX_Control(pDX, IDC_STATIC_CALL_STACK, m_ctlStaticCallStack); DDX_Control(pDX, IDC_EDIT_FAILING_INSTRUCTION, m_ctlEditFailingInstruction); DDX_Control(pDX, IDC_EDIT_EXCEPTION_TYPE, m_ctlEditExceptionType); DDX_Control(pDX, IDC_EDIT_EXCEPTION_LOCATION, m_ctlEditExceptionLocation); DDX_Control(pDX, IDC_LIST_CALL_STACK, m_ctlListControl); DDX_Control(pDX, IDC_ADVANCED, m_ctrlAdvancedBtn); DDX_Control(pDX, IDC_EDIT_READLOGS, m_ctrlCompleteReadLog); DDX_Text(pDX, IDC_EDIT_READLOGS, m_csCompleteLog); DDX_Text(pDX, IDC_EDIT_EXCEPTION_TYPE, m_strExceptionType); DDX_Text(pDX, IDC_EDIT_EXCEPTION_LOCATION, m_strExceptionLocation); DDX_Text(pDX, IDC_EDIT_FAILING_INSTRUCTION, m_strFailingInstruction); //}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CReadLogsDlg, CDialog) //{{AFX_MSG_MAP(CReadLogsDlg)
ON_BN_CLICKED(IDC_ADVANCED, OnAdvanced) ON_WM_DESTROY() //}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CReadLogsDlg message handlers
BOOL CReadLogsDlg::OnInitDialog() { CDialog::OnInitDialog(); // TODO: Add extra initialization here
HRESULT hr = E_FAIL; ULONG lRead = 0L; size_t tWritten = 0; BSTR bstrEmObj = NULL; TCHAR szTempDirPath[MAX_PATH] = {0}; TCHAR szTempFileName[MAX_PATH] = {0}; char lpszLogData[ISTREAM_BUFFER_SIZE];
do { CWaitCursor wait; if( !m_pEmObject || !m_pIEmManager ) break;
bstrEmObj = CopyBSTR( (LPBYTE) m_pEmObject, sizeof EmObject );
//Load the read logs stream from the manager
hr = m_pIEmManager->GetEmFileInterface( bstrEmObj, (IStream **)&m_pIEmStream ); if( FAILED(hr) ) break;
SysFreeString( bstrEmObj );
//Get the temporary system path
if ( 0 == GetTempPath( MAX_PATH, szTempDirPath ) ) break;
//Create a temp filename
GetTempFileName( szTempDirPath, gtcTempFilenameSeed, 0, szTempFileName);
m_pTempLogFileName = szTempFileName;
//Create a temp file in the system temp directory
m_pLogFile = _tfopen( m_pTempLogFileName, gtcFileOpenFlags ); if ( m_pLogFile == NULL ) break;
//Check the second line, if it's not either READLOGS_AV OR READLOGS_DB, cancel
for (int i = 1; i < 2; i++) {
hr = m_pIEmStream->Read( (void *)lpszLogData, ISTREAM_BUFFER_SIZE, &lRead ); if ( lRead == 0 || FAILED( hr ) ) break; m_csCompleteLog += lpszLogData;
tWritten = fwrite( lpszLogData, sizeof( char ), lRead, m_pLogFile ); if ( tWritten == 0 ) { hr = E_FAIL; break; } if ( i == 1) {
//Check to see which version of the dlg we should be showing
if ( strstr( lpszLogData, gslReadLogsAV ) ) m_eReadLogType = ReadLogsType_Exception; else if ( strstr( lpszLogData, gslReadLogsDB ) ) m_eReadLogType = ReadLogsType_Hang; else m_eReadLogType = ReadLogsType_None;
} } while ( FALSE );
if ( FAILED( hr) ) break;
//Continue to read the log into the temp file
do { hr = m_pIEmStream->Read( (void *)lpszLogData, ISTREAM_BUFFER_SIZE, &lRead ); if ( lRead == 0 || FAILED( hr ) ) break; m_csCompleteLog += lpszLogData;
tWritten = fwrite( lpszLogData, sizeof( char ), lRead, m_pLogFile ); if ( tWritten == 0 ) { hr = E_FAIL; break; }
} while (TRUE);
if ( FAILED( hr ) ) break;
//Flush the data to the file.
fflush( m_pLogFile );
switch ( m_eReadLogType ) { case ReadLogsType_Exception: ParseAndInitExceptionView(); break; case ReadLogsType_Hang: ParseAndInitHangView(); break; case ReadLogsType_None: ParseAndInitNoneView(); break; default: break; } UpdateData(FALSE); } while ( FALSE );
SysFreeString( bstrEmObj );
if (m_pIEmStream) m_pIEmStream->Release();
//
// a-mando
//
ShowAppropriateControls(); ResizeAndReposControl(); // a-mando
SetDialogSize(FALSE);
if( FAILED(hr) ) { //Show msg box
((CEmshellApp*)AfxGetApp())->DisplayErrMsgFromHR(hr); return FALSE; }
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
void CReadLogsDlg::SetDialogSize(BOOL bAdvanced) { CRect rtCompleteLog, rtDlg;
GetWindowRect( &rtDlg ); m_ctrlCompleteReadLog.GetWindowRect( &rtCompleteLog );
rtDlg.bottom = rtCompleteLog.top;
if( bAdvanced ) {
rtDlg.bottom = rtCompleteLog.bottom + DLG_PIXEL_EXTEND_SIZE; m_ctrlCompleteReadLog.ShowWindow(SW_SHOW); }
MoveWindow(rtDlg); }
void CReadLogsDlg::OnAdvanced() { CString csTemp;
// TODO: Add your control notification handler code here
if( !m_bAdvancedWindow ) { SetDialogSize( TRUE ); m_bAdvancedWindow = TRUE;
csTemp.LoadString( IDS_READLOGS_ADVOPEN ); m_ctrlAdvancedBtn.SetWindowText( csTemp ); } else { SetDialogSize(FALSE); m_bAdvancedWindow = FALSE;
csTemp.LoadString( IDS_READLOGS_ADVCLOSE ); m_ctrlAdvancedBtn.SetWindowText( csTemp ); } }
CReadLogsDlg::~CReadLogsDlg() { POSITION pos = NULL; CString key; CString* pVal = NULL;
ASSERT( m_pLogFile == NULL );
}
void CReadLogsDlg::ParseAndInitHangView() { //Show the controls for this view
//Hide the controls for this view
//Build map of critical sections
BuildCriticalSectionsMap();
//Build map of thread ID's
BuildThreadIDMap();
//Set the file cursor to the beginning of the logfile
ProcessKvThreadBlocks(); }
//
// a-mando
//
void CReadLogsDlg::ShowAppropriateControls() { //Enable the controls based on what view is selected
switch ( m_eReadLogType ) { case ReadLogsType_None: case ReadLogsType_Exception: m_ctlStaticExcepInfo.ShowWindow(SW_SHOW); m_staticHangInfo.ShowWindow(SW_HIDE); m_ctlStaticFailingInstruction.ShowWindow(SW_SHOW); m_ctlStaticExceptionLocation.ShowWindow(SW_SHOW); m_ctlStaticExceptionType.ShowWindow(SW_SHOW); m_ctlStaticCallStack.ShowWindow(SW_SHOW); m_ctlEditFailingInstruction.ShowWindow(SW_SHOW); m_ctlEditExceptionType.ShowWindow(SW_SHOW); m_ctlEditExceptionLocation.ShowWindow(SW_SHOW); m_ctlListControl.ShowWindow(SW_SHOW); break; case ReadLogsType_Hang: m_staticHangInfo.ShowWindow(SW_SHOW); //Disable all the controls except for the m_ctlHangListControl
break; } } // a-mando
void CReadLogsDlg::ParseAndInitNoneView() { //Show the controls for this view
//Hide the controls for this view
}
void CReadLogsDlg::ParseAndInitExceptionView() { char szBuffer[MAX_TEMP_BUFFER_SIZE] = {0}; TCHAR szTmpBuffer[MAX_TEMP_BUFFER_SIZE] = {0}; char* pszOffset = NULL; long lLastLineOffset = 0L; char szException[MAX_TEMP_BUFFER_SIZE] = {0}; BOOL bFound = FALSE;
//Show the controls for this view
//Hide the controls for this view
do { //Set the file cursor to the beginning of the logfile
fseek( m_pLogFile, 0, SEEK_SET );
do {
//Search through each line looking for the "(first chance)" text
pszOffset = fgets( szBuffer, MAX_TEMP_BUFFER_SIZE, m_pLogFile ); if ( pszOffset == NULL ) break;
pszOffset = strstr( szBuffer, gslFirstChance ); if ( pszOffset == 0 ) continue;
//Get the current byte offset. Note this is the next line, not the first chance line
lLastLineOffset = ftell( m_pLogFile ); if ( lLastLineOffset == -1L ) break;
//Store off the line just matched
strcpy( szException, szBuffer ); bFound = TRUE;
} while ( TRUE );
if ( !bFound ) break;
//Parse the szException for the readable exception text
//Get the position of the word "code", and then only get the string up to that point
pszOffset = strstr( szException, gslCode );
if ( pszOffset != NULL ) //a-kjaw, bug ID: 296028
*pszOffset = '\0';
//Store off szException to the dialog control
m_strExceptionType = szException;
bFound = FALSE; //Reset
//Handle ~KV
//Set the file pointer back to the last exception position or break if there is a problem
do { if ( fseek( m_pLogFile, lLastLineOffset, SEEK_SET ) ) break;
do {
//Search through each line looking for the "> kv" text
pszOffset = fgets( szBuffer, MAX_TEMP_BUFFER_SIZE, m_pLogFile ); if ( pszOffset == NULL ) break;
pszOffset = strstr( szBuffer, gslKV ); if ( pszOffset == 0 ) continue;
bFound = TRUE;
break;
} while ( TRUE ); if ( !bFound ) break;
bFound = FALSE; //Reset
do {
//Search through each line looking for the "ChildEBP" text
pszOffset = fgets( szBuffer, MAX_TEMP_BUFFER_SIZE, m_pLogFile ); if ( pszOffset == NULL ) break;
pszOffset = strstr( szBuffer, gslChildEBP ); if ( pszOffset == 0 ) continue;
bFound = TRUE;
break;
} while ( TRUE );
if ( !bFound ) break; bFound = FALSE; //Reset
do {
//Search through each line getting the call stack strings and
//populating the list control with them
pszOffset = fgets( szBuffer, MAX_TEMP_BUFFER_SIZE, m_pLogFile ); if ( pszOffset == NULL ) break;
pszOffset = strstr( szBuffer, gslPrompt ); if ( pszOffset != 0 ) break;
pszOffset = strstr( szBuffer, gslCarriageReturn ); *pszOffset = 0;
//Get the string from offset 45 on and insert into list control
mbstowcs( szTmpBuffer, szBuffer + sizeof( char[45] ), MAX_TEMP_BUFFER_SIZE ); m_ctlListControl.AddString( szTmpBuffer );
} while ( TRUE );
} while ( FALSE ); //Handle u eip
do {
if ( fseek( m_pLogFile, lLastLineOffset, SEEK_SET ) ) break;
do {
//Search through each line looking for the "> u eip" text
pszOffset = fgets( szBuffer, MAX_TEMP_BUFFER_SIZE, m_pLogFile ); if ( pszOffset == NULL ) break;
pszOffset = strstr( szBuffer, gslUEIP ); if ( pszOffset == 0 ) continue;
bFound = TRUE;
break;
} while ( TRUE ); if ( !bFound ) break;
bFound = FALSE; //Reset
//Get the first item in the list control
m_ctlListControl.GetText( 0, m_strExceptionLocation );
do {
//Get the immediate next line and stuff it into the failing instruction
pszOffset = fgets( szBuffer, MAX_TEMP_BUFFER_SIZE, m_pLogFile ); if ( pszOffset == NULL ) break;
//If the line has a semicolon, skip it.
pszOffset = strstr( szBuffer, gslSemiColon ); if ( pszOffset != NULL ) { pszOffset = fgets( szBuffer, MAX_TEMP_BUFFER_SIZE, m_pLogFile ); }
pszOffset = strstr( szBuffer, gslCarriageReturn ); *pszOffset = 0;
m_strFailingInstruction = szBuffer + sizeof( char[26] ); bFound = TRUE;
break;
} while ( TRUE );
} while ( FALSE );
} while ( FALSE );
if ( !bFound ) {
//We didn't find an exception, error to the user
} }
void CReadLogsDlg::OnDestroy() { CDialog::OnDestroy(); // TODO: Add your message handler code here
//Release the handle to the file
if ( m_pLogFile ) {
fclose( m_pLogFile ); m_pLogFile = NULL; DeleteFile( m_pTempLogFileName ); } }
void CReadLogsDlg::BuildCriticalSectionsMap() { BOOL bFound = FALSE; char *pszOffset = NULL; char *pszTempOffset = NULL; char szBuffer[MAX_TEMP_BUFFER_SIZE] = {0}; CString csAddress; CString *pcsOwningThread = NULL; do { //Set the file cursor to the beginning of the logfile
fseek( m_pLogFile, 0, SEEK_SET );
do {
//Search through each line looking for the "!Locks" command
pszOffset = fgets( szBuffer, MAX_TEMP_BUFFER_SIZE, m_pLogFile ); if ( pszOffset == NULL ) break;
pszOffset = strstr( szBuffer, gslBangLocks ); if ( pszOffset == NULL ) continue;
bFound = TRUE; break; } while ( TRUE );
if ( !bFound ) break; bFound = FALSE;
//We're now at the !Locks area of the log file
do {
//We are now poised to extract the critical section address and the internal thread ID
do {
//Search through the block looking for the "CritSec" text or the "> " prompt
pszOffset = fgets( szBuffer, MAX_TEMP_BUFFER_SIZE, m_pLogFile ); if ( pszOffset == NULL ) break;
pszOffset = strstr( szBuffer, gslCritSecText );
//If "CritSec" is not in the string, look for the prompt
if ( pszOffset == NULL ) { pszOffset = strstr( szBuffer, gslPrompt ); //If the prompt is not in the string, continue
if ( pszOffset == NULL ) { continue; } else break; }
pszOffset = strstr( szBuffer, gslCarriageReturn ); if( pszOffset != NULL ) // a-mando, bug ID: 296029
*pszOffset = '\0';
//We have a "CritSec", get the address from the right most edge
pszOffset = strrchr( szBuffer, gslSpace ); if ( pszOffset == NULL ) break;
csAddress = pszOffset + 1;
csAddress.MakeLower();
bFound = TRUE; break; } while ( TRUE );
if ( !bFound ) break; bFound = FALSE; do {
//Search through the block looking for the "OwningThread" text or the "> " prompt
pszOffset = fgets( szBuffer, MAX_TEMP_BUFFER_SIZE, m_pLogFile ); if ( pszOffset == NULL ) break;
pszOffset = strstr( szBuffer, gslOwningThread );
//If "OwningThread" is not in the string, look for the prompt
if ( pszOffset == NULL ) { pszOffset = strstr( szBuffer, gslPrompt ); //If the prompt is not in the string, continue
if ( pszOffset == NULL ) { continue; } else break; }
//We have an "OwningThread", get the internal thread ID from the right most edge
pszOffset = strrchr( szBuffer, gslSpace ); if ( pszOffset == NULL ) break;
pszTempOffset = strstr( pszOffset, gslCarriageReturn ); if ( pszTempOffset != NULL ) *pszTempOffset = '\0';
CString pcsOwningThread = pszOffset + 1 ;
//Add the address and owning thread to the critical section map
m_mapCriticalSection.SetAt( csAddress, (CString&) pcsOwningThread );
bFound = TRUE; break; } while ( TRUE );
if ( !bFound ) break; bFound = FALSE; } while ( TRUE );
if ( !bFound ) break; bFound = FALSE;
} while ( FALSE ); }
void CReadLogsDlg::BuildThreadIDMap() { BOOL bFound = FALSE; char *pszStartOffset = NULL; char *pszEndOffset = NULL; char szBuffer[MAX_TEMP_BUFFER_SIZE] = {0}; CString* pcsThreadVal = NULL; CString csThreadKey;
do { //Set the file cursor to the beginning of the logfile
fseek( m_pLogFile, 0, SEEK_SET );
do {
//Search through each line looking for the "~*kv" command
pszStartOffset = fgets( szBuffer, MAX_TEMP_BUFFER_SIZE, m_pLogFile ); if ( pszStartOffset == NULL ) break;
pszStartOffset = strstr( szBuffer, gslTildaStarKV ); if ( pszStartOffset == NULL ) continue;
bFound = TRUE; break; } while ( TRUE );
if ( !bFound ) break; bFound = FALSE;
//We're now at the ~*kv area of the log file
do {
//We are now poised to extract the critical section address and the internal thread ID
do {
//Search through the block looking for the "id: " text or the "> " prompt
pszStartOffset = fgets( szBuffer, MAX_TEMP_BUFFER_SIZE, m_pLogFile ); if ( pszStartOffset == NULL ) break;
pszStartOffset = strstr( szBuffer, gslIDColon );
//If "id: " is not in the string, look for the prompt
if ( pszStartOffset == NULL ) { pszStartOffset = strstr( szBuffer, gslPrompt ); //If the prompt is not in the string, continue
if ( pszStartOffset == NULL ) { continue; } else break; }
//We have an "id: ", get the internal thread ID and ordered thread ID
CString pcsThreadVal = GetThreadID( szBuffer );
csThreadKey = GetThreadNumber( szBuffer ); csThreadKey.MakeLower();
m_mapThreadID.SetAt( csThreadKey, (CString&) pcsThreadVal );
bFound = TRUE; break; } while ( TRUE );
if ( !bFound ) break; bFound = FALSE; } while ( TRUE );
if ( !bFound ) break; bFound = FALSE;
}while ( FALSE );
}
char* CReadLogsDlg::GetThreadID( char* szBuffer ) { char *pszStartOffset = NULL; char *pszEndOffset = NULL;
do { pszStartOffset = strstr( szBuffer, gslPeriod ); if ( pszStartOffset == NULL ) break;
if ( pszStartOffset == szBuffer ) { szBuffer++; continue; }
pszStartOffset++;
//increment 1 past the period we're sitting on. Unless it's the first one we're encountering
pszEndOffset = strchr( pszStartOffset, gslSpace ); if ( pszEndOffset == NULL ) break; *pszEndOffset = '\0';
break; } while ( TRUE );
return pszStartOffset; }
char* CReadLogsDlg::GetThreadNumber( char* szBuffer ) { char *pszStartOffset = NULL; char *pszEndOffset = NULL;
//Look for the first occurance of a numeric number
pszStartOffset = szBuffer; for ( ; (!isdigit( *pszStartOffset ) || *pszStartOffset == '.') && *pszStartOffset != '\0'; ) { pszStartOffset++; } pszEndOffset = strchr( pszStartOffset, gslSpace ); *pszEndOffset = '\0';
return pszStartOffset; }
void CReadLogsDlg::GetFirstParameter( char* szBuffer, CString &str ) { char* token = NULL;
//Tokenize the buffer and get the 3rd token and set to str
token = strtok( szBuffer, &gslSpace );
for ( int i = 1; i < 3 && token != NULL; i++) { /* Get next token: */ token = strtok( NULL, &gslSpace ); }
str = token; }
void CReadLogsDlg::GetSecondParameter( char* szBuffer, CString &str ) { char* token = NULL;
//Tokenize the buffer and get the 3rd token and set to str
token = strtok( szBuffer, &gslSpace );
for ( int i = 1; i < 4 && token != NULL; i++) { /* Get next token: */ token = strtok( NULL, &gslSpace ); }
str = token; }
void CReadLogsDlg::GetThirdParameter( char* szBuffer, CString &str ) { char* token = NULL;
//Tokenize the buffer and get the 3rd token and set to str
token = strtok( szBuffer, &gslSpace );
for ( int i = 1; i < 5 && token != NULL; i++) { /* Get next token: */ token = strtok( NULL, &gslSpace ); }
str = token; }
void CReadLogsDlg::ProcessKvThreadBlocks() { BOOL bFound = FALSE; char *pszStartOffset = NULL; char *pszEndOffset = NULL; char szBuffer[MAX_TEMP_BUFFER_SIZE] = {0}; char szOriginalBuffer[MAX_TEMP_BUFFER_SIZE] = {0}; CString csThreadID; CString csThreadNumber; CString csOutput; CString csFirstParameter; CString csSecondParameter; CString csThirdParameter; CString csOwningThread;
do { //Set the file cursor to the beginning of the logfile
fseek( m_pLogFile, 0, SEEK_SET );
do {
//Search through each line looking for the "~*kv" command
pszStartOffset = fgets( szBuffer, MAX_TEMP_BUFFER_SIZE, m_pLogFile ); if ( pszStartOffset == NULL ) break; pszStartOffset = strstr( szBuffer, gslTildaStarKV ); if ( pszStartOffset == NULL ) continue;
bFound = TRUE; break; } while ( TRUE );
if ( !bFound ) break; bFound = FALSE;
//We're now at the ~*kv area of the log file
do {
//We are now poised to handle determining output string for thread states
do { //Search through the block looking for the "id: " text or the "> " prompt
pszStartOffset = fgets( szBuffer, MAX_TEMP_BUFFER_SIZE, m_pLogFile ); if ( pszStartOffset == NULL ) break;
//Let's keep a copy of the original around
strcpy( szOriginalBuffer, szBuffer );
pszStartOffset = strstr( szBuffer, gslIDColon );
//If "id: " is not in the string, look for the prompt
if ( pszStartOffset == NULL ) { pszStartOffset = strstr( szBuffer, gslPrompt ); //If the prompt is not in the string, continue
if ( pszStartOffset == NULL ) { continue; } else break; }
csThreadNumber = GetThreadNumber( szBuffer ); strcpy( szBuffer, szOriginalBuffer );
csThreadID = GetThreadID( szBuffer ); strcpy( szBuffer, szOriginalBuffer );
//Search through the block looking for the "ChildEBP" text or the "> " prompt
pszStartOffset = fgets( szBuffer, MAX_TEMP_BUFFER_SIZE, m_pLogFile ); if ( pszStartOffset == NULL ) break;
//Let's keep a copy of the original around
strcpy( szOriginalBuffer, szBuffer );
pszStartOffset = strstr( szBuffer, gslChildEBP );
//If "ChildEBP" is not in the string, look for the prompt
if ( pszStartOffset == NULL ) { pszStartOffset = strstr( szBuffer, gslPrompt ); //If the prompt is not in the string, continue
if ( pszStartOffset == NULL ) { continue; } else break; }
//We have found the "ChildEBP", so skip it! hahahahaa (what a waste)
pszStartOffset = fgets( szBuffer, MAX_TEMP_BUFFER_SIZE, m_pLogFile ); if ( pszStartOffset == NULL ) break;
//Let's keep a copy of the original around
strcpy( szOriginalBuffer, szBuffer );
if ( strstr( szBuffer, gslWaitForSingleObject ) ) { //Get the next line and look for WaitForCriticalSection
pszStartOffset = fgets( szBuffer, MAX_TEMP_BUFFER_SIZE, m_pLogFile ); if ( pszStartOffset == NULL ) break;
//Let's keep a copy of the original around
strcpy( szOriginalBuffer, szBuffer );
pszStartOffset = strstr( szBuffer, gslWaitForCriticalSection );
//If "WaitForCriticalSection" is not in the string, look for the prompt
if ( pszStartOffset == NULL ) { pszStartOffset = strstr( szBuffer, gslPrompt ); //If the prompt is not in the string, continue
if ( pszStartOffset == NULL ) { GetFirstParameter( szBuffer, csFirstParameter ); strcpy( szBuffer, szOriginalBuffer ); csOutput.Format( _T("Thread %s is in a WaitForSingleObject() call on object %s"), csThreadNumber, csFirstParameter ); bFound = TRUE; break; } else break; }
//"WaitForCriticalSection" is in the string,
//Get the 5th token (3rd parameter) and look it up in the critical section map
GetThirdParameter( szBuffer, csThirdParameter ); strcpy( szBuffer, szOriginalBuffer ); csThirdParameter.MakeLower(); BOOL bFoundInMap = m_mapCriticalSection.Lookup( csThirdParameter, (CString&) csOwningThread );
//If not found in map,
if ( !bFoundInMap ) { csOutput.Format( _T("Thread %s id: %s is in WaitForCriticalSection() call on object %s"), csThreadNumber, csThreadID, csThirdParameter ); bFound = TRUE; break; } else { csOutput.Format( _T("Thread %s id: %s is in WaitForCriticalSection() call on object %s. Thread %s is the owning thread."), csThreadNumber, csThreadID, csThirdParameter, csOwningThread); bFound = TRUE; break; }
} else if ( strstr( szBuffer, gslWaitForMultipleObjects ) ) { GetFirstParameter( szBuffer, csFirstParameter ); strcpy( szBuffer, szOriginalBuffer ); GetSecondParameter( szBuffer, csSecondParameter ); strcpy( szBuffer, szOriginalBuffer ); csOutput.Format( _T("Thread %s id: %s is in a WaitForMultipleObjects() call on %s objects at address %s"), csThreadNumber, csThreadID, csFirstParameter, csSecondParameter ); bFound = TRUE; break; } else { csOutput.Format( _T("Thread %s is not in a known wait state"), csThreadNumber ); bFound = TRUE; break; }
if ( !bFound ) break; bFound = FALSE;
} while ( TRUE );
if ( !bFound ) break; bFound = FALSE; //Output the text to the list control
m_ctlListControl.AddString( csOutput );
} while ( TRUE );
if ( !bFound ) break; bFound = FALSE;
} while ( TRUE ); }
//
// a-mando
//
void CReadLogsDlg::ResizeAndReposControl() { CRect rtListCtrl, rtHangInfo, rtDlg; GetWindowRect( &rtDlg ); m_staticHangInfo.GetWindowRect( &rtHangInfo ); m_ctlListControl.GetWindowRect( &rtListCtrl ); ScreenToClient( &rtDlg ); ScreenToClient( &rtHangInfo ); ScreenToClient( &rtListCtrl );
switch ( m_eReadLogType ) {
case ReadLogsType_Exception: break;
case ReadLogsType_Hang: m_staticHangInfo.ShowWindow(SW_SHOW); rtListCtrl.left = rtDlg.left + DLG_PIXEL_EXTEND_SIZE; rtListCtrl.top = rtHangInfo.bottom + DLG_PIXEL_EXTEND_SIZE; m_ctlListControl.MoveWindow(&rtListCtrl); m_ctlListControl.ShowWindow(SW_SHOW); break;
case ReadLogsType_None: //Disable all the controls
break; }
} // a-mando
|