void BPBinderCallback::AddBoundBP( UINT64 address, Module* mod, ModuleBinding* binding ) { HRESULT hr = S_OK; RefPtr<CodeContext> code; RefPtr<BreakpointResolution> res; CComPtr<IDebugBreakpointResolution2> breakpointResolution; CComPtr<IDebugCodeContext2> codeContext; BpResolutionLocation resLoc; RefPtr<BoundBreakpoint> boundBP; ArchData* archData = NULL; hr = MakeCComObject( code ); if ( FAILED( hr ) ) return; // TODO: maybe we should be able to customize the code context with things like function and module archData = mCurProg->GetCoreProcess()->GetArchData(); hr = code->Init( (Address64) address, mod, mDocContextInterface, archData->GetPointerSize() ); if ( FAILED( hr ) ) return; hr = code->QueryInterface( __uuidof( IDebugCodeContext2 ), (void**) &codeContext ); _ASSERT( hr == S_OK ); hr = MakeCComObject( res ); if ( FAILED( hr ) ) return; hr = BpResolutionLocation::InitCode( resLoc, codeContext ); if ( FAILED( hr ) ) return; hr = res->Init( resLoc, mCurProgInterface, NULL ); if ( FAILED( hr ) ) return; hr = res->QueryInterface( __uuidof( IDebugBreakpointResolution2 ), (void**) &breakpointResolution ); _ASSERT( hr == S_OK ); hr = MakeCComObject( boundBP ); if ( FAILED( hr ) ) return; const DWORD Id = mPendingBP->GetNextBPId(); boundBP->Init( Id, (Address64) address, mPendingBP, breakpointResolution, mCurProg.Get() ); binding->BoundBPs.push_back( boundBP ); }
HRESULT EnumDebugPropertyInfo2::MakeErrorProperty( HRESULT hrErr, const wchar_t* name, const wchar_t* fullName, IDebugProperty2** ppResult ) { HRESULT hr = S_OK; std::wstring errStr; hr = MagoEE::GetErrorString( hrErr, errStr ); // use a general error, if original error couldn't be found if ( hr == S_FALSE ) hr = MagoEE::GetErrorString( E_MAGOEE_BASE, errStr ); if ( hr == S_OK ) { RefPtr<ErrorProperty> errProp; hr = MakeCComObject( errProp ); if ( SUCCEEDED( hr ) ) { hr = errProp->Init( name, fullName, errStr.c_str() ); if ( hr == S_OK ) { *ppResult = errProp.Detach(); return S_OK; } } } return hrErr; }
HRESULT PendingBreakpoint::SendUnboundEvent( BoundBreakpoint* boundBP, Program* prog ) { HRESULT hr = S_OK; RefPtr<BreakpointUnboundEvent> event; CComPtr<IDebugBoundBreakpoint2> ad7BP; CComPtr<IDebugProgram2> ad7Prog; CComPtr<IDebugEngine2> engine; if ( prog != NULL ) { hr = prog->QueryInterface( __uuidof( IDebugProgram2 ), (void**) &ad7Prog ); _ASSERT( hr == S_OK ); } hr = mEngine->QueryInterface( __uuidof( IDebugEngine2 ), (void**) &engine ); _ASSERT( hr == S_OK ); hr = boundBP->QueryInterface( __uuidof( IDebugBoundBreakpoint2 ), (void**) &ad7BP ); _ASSERT( hr == S_OK ); hr = MakeCComObject( event ); if ( FAILED( hr ) ) return hr; event->Init( ad7BP, BPUR_CODE_UNLOADED ); return event->Send( mCallback, engine, ad7Prog, NULL ); }
void EventCallback::OnThreadExit( DWORD uniquePid, DWORD threadId, DWORD exitCode ) { OutputDebugStringA( "EventCallback::OnThreadExit\n" ); HRESULT hr = S_OK; RefPtr<ThreadDestroyEvent> event; RefPtr<Program> prog; RefPtr<Thread> thread; if ( !mEngine->FindProgram( uniquePid, prog ) ) return; if ( !prog->FindThread( threadId, thread ) ) return; prog->DeleteThread( thread.Get() ); hr = MakeCComObject( event ); if ( FAILED( hr ) ) return; event->Init( exitCode ); SendEvent( event.Get(), prog.Get(), thread.Get() ); }
void EventCallback::OnThreadStart( DWORD uniquePid, ICoreThread* coreThread ) { OutputDebugStringA( "EventCallback::OnThreadStart\n" ); HRESULT hr = S_OK; RefPtr<ThreadCreateEvent> event; RefPtr<Program> prog; RefPtr<Thread> thread; if ( !mEngine->FindProgram( uniquePid, prog ) ) return; hr = prog->CreateThread( coreThread, thread ); if ( FAILED( hr ) ) return; hr = prog->AddThread( thread.Get() ); if ( FAILED( hr ) ) return; hr = MakeCComObject( event ); if ( FAILED( hr ) ) return; SendEvent( event.Get(), prog.Get(), thread.Get() ); }
HRESULT StackFrame::MakeExprContext() { HRESULT hr = S_OK; // ignore any error, because we don't have to have symbols for expression eval hr = FindFunction(); if ( mExprContext == NULL ) { GuardedArea guard( mExprContextGuard ); if ( mExprContext == NULL ) { RefPtr<ExprContext> exprContext; hr = MakeCComObject( exprContext ); if ( FAILED( hr ) ) return hr; hr = exprContext->Init( mModule, mThread, mFuncSH, mBlockSH, mPC, mRegSet ); if ( FAILED( hr ) ) return hr; mExprContext = exprContext; } } return S_OK; }
HRESULT StackFrame::GetDebugProperty( IDebugProperty2** ppDebugProp ) { OutputDebugStringA( "StackFrame::GetDebugProperty\n" ); if ( ppDebugProp == NULL ) return E_INVALIDARG; HRESULT hr = S_OK; RefPtr<FrameProperty> frameProp; hr = MakeExprContext(); if ( FAILED( hr ) ) return hr; hr = MakeCComObject( frameProp ); if ( FAILED( hr ) ) return hr; hr = frameProp->Init( mRegSet, mExprContext ); if ( FAILED( hr ) ) return hr; *ppDebugProp = frameProp.Detach(); return S_OK; }
void EventCallback::OnModuleUnload( IProcess* process, Address baseAddr ) { OutputDebugStringA( "EventCallback::OnModuleUnload\n" ); HRESULT hr = S_OK; RefPtr<ModuleLoadEvent> event; RefPtr<Program> prog; RefPtr<Module> mod; CComPtr<IDebugModule2> mod2; if ( !mEngine->FindProgram( process->GetId(), prog ) ) return; if ( !prog->FindModule( baseAddr, mod ) ) return; prog->DeleteModule( mod.Get() ); mEngine->UnbindPendingBPsFromModule( mod.Get(), prog.Get() ); hr = MakeCComObject( event ); if ( FAILED( hr ) ) return; hr = mod->QueryInterface( __uuidof( IDebugModule2 ), (void**) &mod2 ); if ( FAILED( hr ) ) return; // TODO: message event->Init( mod2, NULL, false ); SendEvent( event.Get(), prog.Get(), NULL ); }
HRESULT Property::EnumChildren( DEBUGPROP_INFO_FLAGS dwFields, DWORD dwRadix, REFGUID guidFilter, DBG_ATTRIB_FLAGS dwAttribFilter, LPCOLESTR pszNameFilter, DWORD dwTimeout, IEnumDebugPropertyInfo2** ppEnum ) { HRESULT hr = S_OK; RefPtr<EnumDebugPropertyInfo2> enumProps; RefPtr<MagoEE::IEEDEnumValues> enumVals; hr = MagoEE::EnumValueChildren( mExprContext, mFullExprText, mObjVal.ObjVal, mExprContext->GetTypeEnv(), mExprContext->GetStringTable(), mFormatOpts, enumVals.Ref() ); if ( FAILED( hr ) ) return hr; hr = MakeCComObject( enumProps ); if ( FAILED( hr ) ) return hr; MagoEE::FormatOptions fmtopts (dwRadix); hr = enumProps->Init( enumVals, mExprContext, dwFields, fmtopts ); if ( FAILED( hr ) ) return hr; return enumProps->QueryInterface( __uuidof( IEnumDebugPropertyInfo2 ), (void**) ppEnum ); }
HRESULT BPBinderCallback::MakeDocContext( MagoST::ISession* session, uint16_t compIx, uint16_t fileIx, const MagoST::LineNumber& lineNumber ) { _ASSERT( session != NULL ); _ASSERT( compIx != 0 ); HRESULT hr = S_OK; CComBSTR filename; CComBSTR langName; GUID langGuid; TEXT_POSITION posBegin = { 0 }; TEXT_POSITION posEnd = { 0 }; RefPtr<BPDocumentContext> docCtx; // already exists; don't need to make a new one if ( mDocContext.Get() != NULL ) return S_FALSE; MagoST::FileInfo fileInfo = { 0 }; hr = session->GetFileInfo( compIx, fileIx, fileInfo ); if ( FAILED( hr ) ) return hr; hr = Utf8To16( fileInfo.Name.ptr, fileInfo.Name.length, filename.m_str ); if ( FAILED( hr ) ) return hr; // TODO: //compiland->get_language(); posBegin.dwLine = lineNumber.Number; posEnd.dwLine = lineNumber.Number; // NumberEnd;? // AD7 lines are 0-based, DIA ones are 1-based posBegin.dwLine--; posEnd.dwLine--; hr = MakeCComObject( docCtx ); if ( FAILED( hr ) ) return hr; hr = docCtx->Init( mPendingBP, filename, posBegin, posEnd, langName, langGuid ); if ( FAILED( hr ) ) return hr; hr = docCtx->QueryInterface( __uuidof( IDebugDocumentContext2 ), (void**) &mDocContextInterface ); _ASSERT( hr == S_OK ); mDocContext = docCtx; return hr; }
HRESULT BPBinderCallback::MakeErrorBP( Error& errDesc, RefPtr<ErrorBreakpoint>& errorBP ) { HRESULT hr = S_OK; const wchar_t* msg = NULL; BP_ERROR_TYPE errType = errDesc.Type | errDesc.Sev; RefPtr<ErrorBreakpoint> errBP; RefPtr<ErrorBreakpointResolution> errBPRes; BpResolutionLocation bpResLoc; CComPtr<IDebugErrorBreakpointResolution2> errBPResInterface; CComPtr<IDebugPendingBreakpoint2> pendBPInterface; hr = mPendingBP->QueryInterface( __uuidof( IDebugPendingBreakpoint2 ), (void**) &pendBPInterface ); _ASSERT( hr == S_OK ); hr = MakeCComObject( errBPRes ); if ( FAILED( hr ) ) return true; msg = GetString( errDesc.StrId ); hr = errBPRes->Init( bpResLoc, mCurProgInterface, NULL, msg, errType ); if ( FAILED( hr ) ) return hr; hr = errBPRes->QueryInterface( __uuidof( IDebugErrorBreakpointResolution2 ), (void**) &errBPResInterface ); _ASSERT( hr == S_OK ); hr = MakeCComObject( errBP ); if ( FAILED( hr ) ) return hr; errBP->Init( pendBPInterface, errBPResInterface ); errorBP = errBP; return hr; }
HRESULT SingleDocumentContext::Clone( DocumentContext** ppDocContext ) { HRESULT hr = S_OK; RefPtr<SingleDocumentContext> docContext; hr = MakeCComObject( docContext ); if ( FAILED( hr ) ) return hr; hr = docContext->Init( mFilename, mStatementBegin, mStatementEnd, mLangName, mLangGuid ); if ( FAILED( hr ) ) return hr; *ppDocContext = docContext.Detach(); return S_OK; }
void EventCallback::OnOutputString( DWORD uniquePid, const wchar_t* outputString ) { OutputDebugStringA( "EventCallback::OnOutputString\n" ); HRESULT hr = S_OK; RefPtr<OutputStringEvent> event; RefPtr<Program> prog; if ( !mEngine->FindProgram( uniquePid, prog ) ) return; hr = MakeCComObject( event ); if ( FAILED( hr ) ) return; event->Init( outputString ); hr = SendEvent( event.Get(), prog.Get(), NULL ); }
HRESULT Property::GetMemoryContext( IDebugMemoryContext2** ppMemory ) { OutputDebugStringA( "Property::GetMemoryContext\n" ); if ( ppMemory == NULL ) return E_INVALIDARG; HRESULT hr = S_OK; RefPtr<CodeContext> codeCxt; Address64 addr = 0; // TODO: let the EE figure this out if ( mObjVal.ObjVal._Type->IsPointer() ) { addr = (Address64) mObjVal.ObjVal.Value.Addr; } else if ( mObjVal.ObjVal._Type->IsIntegral() ) { addr = (Address64) mObjVal.ObjVal.Value.UInt64Value; } else if ( mObjVal.ObjVal._Type->IsSArray() ) { addr = (Address64) mObjVal.ObjVal.Addr; } else if ( mObjVal.ObjVal._Type->IsDArray() ) { addr = (Address64) mObjVal.ObjVal.Value.Array.Addr; } else return S_GETMEMORYCONTEXT_NO_MEMORY_CONTEXT; hr = MakeCComObject( codeCxt ); if ( FAILED( hr ) ) return hr; hr = codeCxt->Init( addr, NULL, NULL, mPtrSize ); if ( FAILED( hr ) ) return hr; return codeCxt->QueryInterface( __uuidof( IDebugMemoryContext2 ), (void**) ppMemory ); }
void EventCallback::OnLoadComplete( DWORD uniquePid, DWORD threadId ) { OutputDebugStringA( "EventCallback::OnLoadComplete\n" ); HRESULT hr = S_OK; RefPtr<LoadCompleteEvent> event; RefPtr<Program> prog; RefPtr<Thread> thread; if ( !mEngine->FindProgram( uniquePid, prog ) ) return; if ( !prog->FindThread( threadId, thread ) ) return; hr = MakeCComObject( event ); if ( FAILED( hr ) ) return; hr = SendEvent( event.Get(), prog.Get(), thread.Get() ); Address64 entryPoint = prog->FindEntryPoint(); if ( entryPoint != 0 ) { RefPtr<Module> mod; if ( prog->FindModuleContainingAddress( entryPoint, mod ) ) { Address64 userEntryPoint = 0; if ( FindUserEntryPoint( mod, userEntryPoint ) ) entryPoint = userEntryPoint; } hr = prog->SetInternalBreakpoint( entryPoint, EntryPointCookie ); // if we couldn't set the BP, then don't expect it later if ( FAILED( hr ) ) entryPoint = 0; prog->SetEntryPoint( entryPoint ); } }
HRESULT EnumDebugPropertyInfo2::Clone( IEnumDebugPropertyInfo2** ppEnum ) { HRESULT hr = S_OK; RefPtr<MagoEE::IEEDEnumValues> eeEnumCopy; RefPtr<EnumDebugPropertyInfo2> enumCopy; hr = mEEEnum->Clone( eeEnumCopy.Ref() ); if ( FAILED( hr ) ) return hr; hr = MakeCComObject( enumCopy ); if ( FAILED( hr ) ) return hr; hr = enumCopy->Init( eeEnumCopy, mExprContext, mFields, mFormatOpt ); if ( FAILED( hr ) ) return hr; return S_OK; }
void EventCallback::OnProcessExit( DWORD uniquePid, DWORD exitCode ) { OutputDebugStringA( "EventCallback::OnProcessExit\n" ); HRESULT hr = S_OK; RefPtr<ProgramDestroyEvent> event; RefPtr<Program> prog; if ( !mEngine->FindProgram( uniquePid, prog ) ) return; mEngine->DeleteProgram( prog.Get() ); hr = MakeCComObject( event ); if ( FAILED( hr ) ) return; event->Init( exitCode ); SendEvent( event.Get(), prog.Get(), NULL ); }
void EventCallback::OnStepComplete( DWORD uniquePid, uint32_t threadId ) { OutputDebugStringA( "EventCallback::OnStepComplete\n" ); HRESULT hr = S_OK; RefPtr<StepCompleteEvent> event; RefPtr<Program> prog; RefPtr<Thread> thread; if ( !mEngine->FindProgram( uniquePid, prog ) ) return; if ( !prog->FindThread( threadId, thread ) ) return; hr = MakeCComObject( event ); if ( FAILED( hr ) ) return; hr = SendEvent( event.Get(), prog.Get(), thread.Get() ); }
HRESULT PendingBreakpoint::SendErrorEvent( ErrorBreakpoint* errorBP ) { HRESULT hr = S_OK; CComPtr<IDebugEngine2> engine; CComPtr<IDebugErrorBreakpoint2> ad7ErrorBP; RefPtr<BreakpointErrorEvent> event; hr = errorBP->QueryInterface( __uuidof( IDebugErrorBreakpoint2 ), (void**) &ad7ErrorBP ); _ASSERT( hr == S_OK ); hr = mEngine->QueryInterface( __uuidof( IDebugEngine2 ), (void**) &engine ); _ASSERT( hr == S_OK ); hr = MakeCComObject( event ); if ( FAILED( hr ) ) return hr; event->Init( ad7ErrorBP ); return event->Send( mCallback, engine, NULL, NULL ); }
HRESULT PendingBreakpoint::SendBoundEvent( IEnumDebugBoundBreakpoints2* enumBPs ) { HRESULT hr = S_OK; CComPtr<IDebugPendingBreakpoint2> pendBP; CComPtr<IDebugEngine2> engine; RefPtr<BreakpointBoundEvent> event; hr = QueryInterface( __uuidof( IDebugPendingBreakpoint2 ), (void**) &pendBP ); _ASSERT( hr == S_OK ); hr = mEngine->QueryInterface( __uuidof( IDebugEngine2 ), (void**) &engine ); _ASSERT( hr == S_OK ); hr = MakeCComObject( event ); if ( FAILED( hr ) ) return hr; event->Init( enumBPs, pendBP ); return event->Send( mCallback, engine, NULL, NULL ); }
HRESULT StackFrame::GetCodeContext( IDebugCodeContext2** ppCodeCxt ) { if ( ppCodeCxt == NULL ) return E_INVALIDARG; HRESULT hr = S_OK; RefPtr<CodeContext> codeContext; hr = MakeCComObject( codeContext ); if ( FAILED( hr ) ) return hr; CComPtr<IDebugDocumentContext2> docContext; hr = GetDocumentContext( &docContext ); // there doesn't have to be a document context hr = codeContext->Init( mPC, mModule, docContext, mPtrSize ); if ( FAILED( hr ) ) return hr; return codeContext->QueryInterface( __uuidof( IDebugCodeContext2 ), (void**) ppCodeCxt ); }
HRESULT StackFrame::GetDocumentContext( IDebugDocumentContext2** ppCxt ) { if ( ppCxt == NULL ) return E_INVALIDARG; HRESULT hr = S_OK; RefPtr<SingleDocumentContext> docContext; LineInfo line; hr = MakeCComObject( docContext ); if ( FAILED( hr ) ) return hr; hr = GetLineInfo( line ); if ( FAILED( hr ) ) return hr; hr = docContext->Init( line.Filename, line.LineBegin, line.LineEnd, line.LangName, line.LangGuid ); if ( FAILED( hr ) ) return hr; return docContext->QueryInterface( __uuidof( IDebugDocumentContext2 ), (void**) ppCxt ); }
void EventCallback::OnModuleUnloadInternal( DWORD uniquePid, Address64 baseAddr ) { OutputDebugStringA( "EventCallback::OnModuleUnload\n" ); HRESULT hr = S_OK; RefPtr<ModuleLoadEvent> event; RefPtr<Program> prog; RefPtr<Module> mod; CComPtr<IDebugModule2> mod2; CComBSTR msg; if ( !mEngine->FindProgram( uniquePid, prog ) ) return; if ( !prog->FindModule( baseAddr, mod ) ) return; prog->DeleteModule( mod.Get() ); mEngine->UnbindPendingBPsFromModule( mod.Get(), prog.Get() ); hr = MakeCComObject( event ); if ( FAILED( hr ) ) return; hr = mod->QueryInterface( __uuidof( IDebugModule2 ), (void**) &mod2 ); if ( FAILED( hr ) ) return; mod->GetPath( msg ); msg.Append( L" unloaded."); event->Init( mod2, msg.m_str, false ); SendEvent( event.Get(), prog.Get(), NULL ); }
RunMode EventCallback::OnBreakpointInternal( Program* prog, Thread* thread, Address64 address, bool embedded ) { HRESULT hr = S_OK; if ( embedded ) { RefPtr<EmbeddedBreakpointEvent> event; hr = MakeCComObject( event ); if ( FAILED( hr ) ) return RunMode_Run; event->Init( prog ); hr = SendEvent( event, prog, thread ); if ( FAILED( hr ) ) return RunMode_Run; return RunMode_Break; } else { std::vector< BPCookie > iter; int stoppingBPs = 0; hr = prog->EnumBPCookies( address, iter ); if ( FAILED( hr ) ) return RunMode_Run; for ( std::vector< BPCookie >::iterator it = iter.begin(); it != iter.end(); it++ ) { if ( *it != EntryPointCookie ) { stoppingBPs++; } } if ( stoppingBPs > 0 ) { RefPtr<BreakpointEvent> event; CComPtr<IEnumDebugBoundBreakpoints2> enumBPs; hr = MakeCComObject( event ); if ( FAILED( hr ) ) return RunMode_Run; InterfaceArray<IDebugBoundBreakpoint2> array( stoppingBPs ); if ( array.Get() == NULL ) return RunMode_Run; int i = 0; for ( std::vector< BPCookie >::iterator it = iter.begin(); it != iter.end(); it++ ) { if ( *it != EntryPointCookie ) { IDebugBoundBreakpoint2* bp = (IDebugBoundBreakpoint2*) *it; _ASSERT( i < stoppingBPs ); array[i] = bp; array[i]->AddRef(); i++; } } hr = MakeEnumWithCount<EnumDebugBoundBreakpoints>( array, &enumBPs ); if ( FAILED( hr ) ) return RunMode_Run; event->Init( enumBPs ); hr = SendEvent( event, prog, thread ); if ( FAILED( hr ) ) return RunMode_Run; return RunMode_Break; } else if ( (prog->GetEntryPoint() != 0) && (address == prog->GetEntryPoint()) ) { RefPtr<EntryPointEvent> entryPointEvent; hr = MakeCComObject( entryPointEvent ); if ( FAILED( hr ) ) return RunMode_Run; hr = SendEvent( entryPointEvent, prog, thread ); if ( FAILED( hr ) ) return RunMode_Run; return RunMode_Break; } } return RunMode_Run; }
void EventCallback::OnModuleLoad( IProcess* process, IModule* coreModule ) { OutputDebugStringA( "EventCallback::OnModuleLoad\n" ); HRESULT hr = S_OK; RefPtr<ModuleLoadEvent> event; RefPtr<Program> prog; RefPtr<Module> mod; CComPtr<IDebugModule2> mod2; if ( !mEngine->FindProgram( process->GetId(), prog ) ) return; hr = prog->CreateModule( coreModule, mod ); if ( FAILED( hr ) ) return; hr = prog->AddModule( mod.Get() ); if ( FAILED( hr ) ) return; hr = mod->LoadSymbols( false ); // later we'll check if symbols were loaded hr = mEngine->BindPendingBPsToModule( mod.Get(), prog.Get() ); hr = MakeCComObject( event ); if ( FAILED( hr ) ) return; hr = mod->QueryInterface( __uuidof( IDebugModule2 ), (void**) &mod2 ); if ( FAILED( hr ) ) return; // TODO: message event->Init( mod2, NULL, true ); SendEvent( event.Get(), prog.Get(), NULL ); //------------------------- RefPtr<SymbolSearchEvent> symEvent; CComPtr<IDebugModule3> mod3; MODULE_INFO_FLAGS flags = 0; RefPtr<MagoST::ISession> session; CComBSTR name; mod->GetName( name ); hr = mod->QueryInterface( __uuidof( IDebugModule3 ), (void**) &mod3 ); if ( FAILED( hr ) ) return; hr = MakeCComObject( symEvent ); if ( FAILED( hr ) ) return; if ( mod->GetSymbolSession( session ) ) flags |= MIF_SYMBOLS_LOADED; symEvent->Init( mod3, name.m_str, flags ); hr = SendEvent( symEvent.Get(), prog.Get(), NULL ); }
bool EventCallback::OnException( IProcess* process, DWORD threadId, bool firstChance, const EXCEPTION_RECORD* exceptRec ) { const DWORD DefaultState = EXCEPTION_STOP_SECOND_CHANCE; OutputDebugStringA( "EventCallback::OnException\n" ); HRESULT hr = S_OK; RefPtr<ExceptionEvent> event; RefPtr<Program> prog; RefPtr<Thread> thread; if ( !mEngine->FindProgram( process->GetId(), prog ) ) return false; if ( !prog->FindThread( threadId, thread ) ) return false; prog->NotifyException( firstChance, exceptRec ); hr = MakeCComObject( event ); if ( FAILED( hr ) ) return false; event->Init( prog.Get(), firstChance, exceptRec, prog->CanPassExceptionToDebuggee() ); DWORD state = DefaultState; ExceptionInfo info; bool found = false; if ( event->GetSearchKey() == ExceptionEvent::Name ) { found = mEngine->FindExceptionInfo( event->GetGUID(), event->GetExceptionName(), info ); } else // search by code { found = mEngine->FindExceptionInfo( event->GetGUID(), event->GetCode(), info ); } // if not found, then check against the catch-all entry if ( !found ) found = mEngine->FindExceptionInfo( event->GetGUID(), event->GetRootExceptionName(), info ); if ( found ) { if ( event->GetSearchKey() == ExceptionEvent::Code ) event->SetExceptionName( info.bstrExceptionName ); state = info.dwState; } if ( ( firstChance && ( state & EXCEPTION_STOP_FIRST_CHANCE ) ) || ( !firstChance && ( state & EXCEPTION_STOP_SECOND_CHANCE ) ) ) { hr = SendEvent( event.Get(), prog.Get(), thread.Get() ); return false; } else { RefPtr<MessageTextEvent> msgEvent; CComBSTR desc; hr = MakeCComObject( msgEvent ); if ( FAILED( hr ) ) return true; hr = event->GetExceptionDescription( &desc ); if ( FAILED( hr ) ) return true; desc.Append( L"\n" ); msgEvent->Init( MT_REASON_EXCEPTION, desc ); hr = SendEvent( msgEvent.Get(), prog.Get(), thread.Get() ); return true; // wants to continue } }
bool EventCallback::OnBreakpointInternal( Program* prog, Thread* thread, Address address, Enumerator< BPCookie >* iter ) { HRESULT hr = S_OK; int stoppingBPs = 0; while ( iter->MoveNext() ) { if ( iter->GetCurrent() != EntryPointCookie ) { stoppingBPs++; } } iter->Reset(); if ( stoppingBPs > 0 ) { RefPtr<BreakpointEvent> event; CComPtr<IEnumDebugBoundBreakpoints2> enumBPs; hr = MakeCComObject( event ); if ( FAILED( hr ) ) return true; InterfaceArray<IDebugBoundBreakpoint2> array( stoppingBPs ); if ( array.Get() == NULL ) return true; int i = 0; while ( iter->MoveNext() ) { if ( iter->GetCurrent() != EntryPointCookie ) { IDebugBoundBreakpoint2* bp = (IDebugBoundBreakpoint2*) iter->GetCurrent(); _ASSERT( i < stoppingBPs ); array[i] = bp; array[i]->AddRef(); i++; } } hr = MakeEnumWithCount<EnumDebugBoundBreakpoints>( array, &enumBPs ); if ( FAILED( hr ) ) return true; event->Init( enumBPs ); hr = SendEvent( event, prog, thread ); if ( FAILED( hr ) ) return true; return false; } else if ( iter->GetCount() == 0 ) { RefPtr<EmbeddedBreakpointEvent> event; hr = MakeCComObject( event ); if ( FAILED( hr ) ) return true; event->Init( prog ); hr = SendEvent( event, prog, thread ); if ( FAILED( hr ) ) return true; return false; } else if ( (mEntryPoint != 0) && (address == mEntryPoint) ) { RefPtr<EntryPointEvent> entryPointEvent; hr = MakeCComObject( entryPointEvent ); if ( FAILED( hr ) ) return true; hr = SendEvent( entryPointEvent, prog, thread ); if ( FAILED( hr ) ) return true; return false; } return true; }
void EventCallback::OnModuleLoadInternal( DWORD uniquePid, ICoreModule* coreModule ) { OutputDebugStringA( "EventCallback::OnModuleLoad\n" ); HRESULT hr = S_OK; RefPtr<ModuleLoadEvent> event; RefPtr<Program> prog; RefPtr<Module> mod; CComPtr<IDebugModule2> mod2; if ( !mEngine->FindProgram( uniquePid, prog ) ) return; hr = prog->CreateModule( coreModule, mod ); if ( FAILED( hr ) ) return; hr = prog->AddModule( mod.Get() ); if ( FAILED( hr ) ) return; hr = mod->LoadSymbols( false ); // later we'll check if symbols were loaded prog->UpdateAAVersion( mod.Get() ); hr = mEngine->BindPendingBPsToModule( mod.Get(), prog.Get() ); hr = MakeCComObject( event ); if ( FAILED( hr ) ) return; hr = mod->QueryInterface( __uuidof( IDebugModule2 ), (void**) &mod2 ); if ( FAILED( hr ) ) return; // TODO: message event->Init( mod2, NULL, true ); SendEvent( event.Get(), prog.Get(), NULL ); //------------------------- RefPtr<SymbolSearchEvent> symEvent; CComPtr<IDebugModule3> mod3; MODULE_INFO_FLAGS flags = 0; RefPtr<MagoST::ISession> session; CComBSTR msg; hr = mod->QueryInterface( __uuidof( IDebugModule3 ), (void**) &mod3 ); if ( FAILED( hr ) ) return; hr = MakeCComObject( symEvent ); if ( FAILED( hr ) ) return; if ( mod->GetSymbolSession( session ) ) flags |= MIF_SYMBOLS_LOADED; mod->GetPath( msg ); if( flags & MIF_SYMBOLS_LOADED ) msg.Append( L" loaded, symbols found."); else msg.Append( L" loaded, no symbols."); symEvent->Init( mod3, msg.m_str, flags ); hr = SendEvent( symEvent.Get(), prog.Get(), NULL ); }
RunMode EventCallback::OnException( DWORD uniquePid, DWORD threadId, bool firstChance, const EXCEPTION_RECORD64* exceptRec ) { const DWORD DefaultState = EXCEPTION_STOP_SECOND_CHANCE; OutputDebugStringA( "EventCallback::OnException\n" ); HRESULT hr = S_OK; RefPtr<ExceptionEvent> event; RefPtr<Program> prog; RefPtr<Thread> thread; if ( !mEngine->FindProgram( uniquePid, prog ) ) return RunMode_Break; if ( !prog->FindThread( threadId, thread ) ) return RunMode_Break; prog->NotifyException( firstChance, exceptRec ); hr = MakeCComObject( event ); if ( FAILED( hr ) ) return RunMode_Break; event->Init( prog.Get(), firstChance, exceptRec, prog->CanPassExceptionToDebuggee() ); DWORD state = DefaultState; ExceptionInfo info; bool found = false; if ( event->GetSearchKey() == ExceptionEvent::Name ) { found = mEngine->FindExceptionInfo( event->GetGUID(), event->GetExceptionName(), info ); } else // search by code { found = mEngine->FindExceptionInfo( event->GetGUID(), event->GetCode(), info ); } // if not found, then check against the catch-all entry if ( !found ) found = mEngine->FindExceptionInfo( event->GetGUID(), event->GetRootExceptionName(), info ); if ( found ) { if ( event->GetSearchKey() == ExceptionEvent::Code ) { wchar_t name[256] = L""; _swprintf_p( name, _countof( name ), L"0x%08x: %s", event->GetCode(), (BSTR) info.bstrExceptionName ); event->SetExceptionName( name ); } state = info.dwState; } if ( ( firstChance && ( state & EXCEPTION_STOP_FIRST_CHANCE ) ) || ( !firstChance && ( state & EXCEPTION_STOP_SECOND_CHANCE ) ) ) { hr = SendEvent( event.Get(), prog.Get(), thread.Get() ); return RunMode_Break; } else { RefPtr<MessageTextEvent> msgEvent; CComBSTR desc; hr = MakeCComObject( msgEvent ); if ( FAILED( hr ) ) return RunMode_Run; hr = event->GetExceptionDescription( &desc ); if ( FAILED( hr ) ) return RunMode_Run; desc.Append( L"\n" ); msgEvent->Init( MT_REASON_EXCEPTION, desc ); hr = SendEvent( msgEvent.Get(), prog.Get(), thread.Get() ); return RunMode_Run; } }
HRESULT EnumDebugPropertyInfo2::GetPropertyInfo( const MagoEE::EvalResult& result, const wchar_t* name, const wchar_t* fullName, DEBUG_PROPERTY_INFO& info ) { HRESULT hr = S_OK; info.dwFields = 0; if ( (mFields & DEBUGPROP_INFO_NAME) != 0 ) { info.bstrName = SysAllocString( name ); info.dwFields |= DEBUGPROP_INFO_NAME; } if ( (mFields & DEBUGPROP_INFO_FULLNAME) != 0 ) { info.bstrFullName = SysAllocString( fullName ); info.dwFields |= DEBUGPROP_INFO_FULLNAME; } if ( (mFields & DEBUGPROP_INFO_VALUE) != 0 ) { MagoEE::EED::FormatValue( mExprContext, result.ObjVal, mFormatOpt, info.bstrValue ); info.dwFields |= DEBUGPROP_INFO_VALUE; } if ( (mFields & DEBUGPROP_INFO_TYPE) != 0 ) { if ( result.ObjVal._Type != NULL ) { std::wstring typeStr; result.ObjVal._Type->ToString( typeStr ); info.bstrType = SysAllocString( typeStr.c_str() ); info.dwFields |= DEBUGPROP_INFO_TYPE; } } if ( (mFields & DEBUGPROP_INFO_PROP) != 0 ) { RefPtr<Property> prop; hr = MakeCComObject( prop ); if ( SUCCEEDED( hr ) ) { hr = prop->Init( name, fullName, result, mExprContext, mFormatOpt ); if ( SUCCEEDED( hr ) ) { prop->QueryInterface( __uuidof( IDebugProperty2 ), (void**) &info.pProperty ); info.dwFields |= DEBUGPROP_INFO_PROP; } } } if ( (mFields & DEBUGPROP_INFO_ATTRIB) != 0 ) { info.dwAttrib = 0; if ( result.HasString ) info.dwAttrib |= DBG_ATTRIB_VALUE_RAW_STRING; if ( result.ReadOnly ) info.dwAttrib |= DBG_ATTRIB_VALUE_READONLY; if ( mFormatOpt.specifier != MagoEE::FormatSpecRaw && result.HasChildren ) info.dwAttrib |= DBG_ATTRIB_OBJ_IS_EXPANDABLE; if ( mFormatOpt.specifier == MagoEE::FormatSpecRaw && result.HasRawChildren ) info.dwAttrib |= DBG_ATTRIB_OBJ_IS_EXPANDABLE; info.dwFields |= DEBUGPROP_INFO_ATTRIB; } return S_OK; }