//++ ------------------------------------------------------------------------------------ // Details: Initialize resources for *this debugger object. // Type: Method. // Args: None. // Return: MIstatus::success - Functionality succeeded. // MIstatus::failure - Functionality failed. // Throws: None. //-- bool CMICmnLLDBDebugger::Initialize( void ) { m_clientUsageRefCnt++; if( m_bInitialized ) return MIstatus::success; bool bOk = MIstatus::success; CMIUtilString errMsg; ClrErrorDescription(); if( m_pClientDriver == nullptr ) { bOk = false; errMsg = MIRSRC( IDS_LLDBDEBUGGER_ERR_CLIENTDRIVER ); } // Note initialization order is important here as some resources depend on previous MI::ModuleInit< CMICmnLog > ( IDS_MI_INIT_ERR_LOG , bOk, errMsg ); MI::ModuleInit< CMICmnResources > ( IDS_MI_INIT_ERR_RESOURCES , bOk, errMsg ); MI::ModuleInit< CMICmnThreadMgrStd > ( IDS_MI_INIT_ERR_THREADMGR , bOk, errMsg ); MI::ModuleInit< CMICmnLLDBDebuggerHandleEvents >( IDS_MI_INIT_ERR_OUTOFBANDHANDLER, bOk, errMsg ); MI::ModuleInit< CMICmnLLDBDebugSessionInfo > ( IDS_MI_INIT_ERR_DEBUGSESSIONINFO, bOk, errMsg ); // Note order is important here! if( bOk ) lldb::SBDebugger::Initialize(); if( bOk && !InitSBDebugger() ) { bOk = false; if( !errMsg.empty() ) errMsg += ", "; errMsg += GetErrorDescription().c_str(); } if( bOk && !InitSBListener() ) { bOk = false; if( !errMsg.empty() ) errMsg += ", "; errMsg += GetErrorDescription().c_str(); } bOk = bOk && InitStdStreams(); m_bInitialized = bOk; if( !bOk && !HaveErrorDescription() ) { CMIUtilString strInitError( CMIUtilString::Format( MIRSRC( IDS_MI_INIT_ERR_LLDBDEBUGGER ), errMsg.c_str() ) ); SetErrorDescription( strInitError ); } return bOk; }
//++ //------------------------------------------------------------------------------------ // Details: Release resources for *this debugger object. // Type: Method. // Args: None. // Return: MIstatus::success - Functionality succeeded. // MIstatus::failure - Functionality failed. // Throws: None. //-- bool CMICmnLLDBDebugger::Shutdown() { if (--m_clientUsageRefCnt > 0) return MIstatus::success; if (!m_bInitialized) return MIstatus::success; m_bInitialized = false; ClrErrorDescription(); bool bOk = MIstatus::success; CMIUtilString errMsg; // Explicitly delete the remote target in case MI needs to exit prematurely // otherwise // LLDB debugger may hang in its Destroy() fn waiting on events lldb::SBTarget sbTarget = CMICmnLLDBDebugSessionInfo::Instance().GetTarget(); m_lldbDebugger.DeleteTarget(sbTarget); // Debug: May need this but does seem to work without it so commented out the // fudge 19/06/2014 // It appears we need to wait as hang does not occur when hitting a debug // breakpoint here // const std::chrono::milliseconds time( 1000 ); // std::this_thread::sleep_for( time ); lldb::SBDebugger::Destroy(m_lldbDebugger); lldb::SBDebugger::Terminate(); m_pClientDriver = nullptr; m_mapBroadcastClassNameToEventMask.clear(); m_mapIdToEventMask.clear(); // Note shutdown order is important here MI::ModuleShutdown<CMICmnLLDBDebugSessionInfo>( IDS_MI_INIT_ERR_DEBUGSESSIONINFO, bOk, errMsg); MI::ModuleShutdown<CMICmnLLDBDebuggerHandleEvents>( IDS_MI_INIT_ERR_OUTOFBANDHANDLER, bOk, errMsg); MI::ModuleShutdown<CMICmnThreadMgrStd>(IDS_MI_INIT_ERR_THREADMGR, bOk, errMsg); MI::ModuleShutdown<CMICmnResources>(IDS_MI_INIT_ERR_RESOURCES, bOk, errMsg); MI::ModuleShutdown<CMICmnLog>(IDS_MI_INIT_ERR_LOG, bOk, errMsg); if (!bOk) { SetErrorDescriptionn(MIRSRC(IDS_MI_SHTDWN_ERR_LLDBDEBUGGER), errMsg.c_str()); } return MIstatus::success; }
//++ ------------------------------------------------------------------------------------ // Details: Release resources for *this stderr stream. // Type: Method. // Args: None. // Return: MIstatus::success - Functional succeeded. // MIstatus::failure - Functional failed. // Throws: None. //-- bool CMICmnStreamStderr::Shutdown( void ) { if( --m_clientUsageRefCnt > 0 ) return MIstatus::success; if( !m_bInitialized ) return MIstatus::success; ClrErrorDescription(); m_bInitialized = false; return MIstatus::success; }
//++ ------------------------------------------------------------------------------------ // Details: Release resources for *this Command Manager. // Type: Method. // Args: None. // Return: MIstatus::success - Functionality succeeded. // MIstatus::failure - Functionality failed. // Throws: None. //-- bool CMICmdMgr::Shutdown(void) { if (--m_clientUsageRefCnt > 0) return MIstatus::success; if (!m_bInitialized) return MIstatus::success; m_bInitialized = false; ClrErrorDescription(); bool bOk = MIstatus::success; CMIUtilString errMsg; // Tidy up m_setCmdDeleteCallback.clear(); // Note shutdown order is important here if (!m_invoker.Shutdown()) { bOk = false; errMsg += CMIUtilString::Format(MIRSRC(IDS_MI_SHTDWN_ERR_CMDINVOKER), m_invoker.GetErrorDescription().c_str()); } if (!m_factory.Shutdown()) { bOk = false; if (!errMsg.empty()) errMsg += ", "; errMsg += CMIUtilString::Format(MIRSRC(IDS_MI_SHTDWN_ERR_CMDFACTORY), m_factory.GetErrorDescription().c_str()); } if (!m_interpretor.Shutdown()) { bOk = false; if (!errMsg.empty()) errMsg += ", "; errMsg += CMIUtilString::Format(MIRSRC(IDS_MI_SHTDWN_ERR_CMDINTERPRETER), m_interpretor.GetErrorDescription().c_str()); } MI::ModuleShutdown<CMICmnResources>(IDS_MI_INIT_ERR_RESOURCES, bOk, errMsg); MI::ModuleShutdown<CMICmnLog>(IDS_MI_INIT_ERR_LOG, bOk, errMsg); if (!bOk) { SetErrorDescriptionn(MIRSRC(IDS_MI_SHUTDOWN_ERR), errMsg.c_str()); } return MIstatus::success; }
//++ ------------------------------------------------------------------------------------ // Details: Release resources for *this Logger. // Type: Method. // Args: None. // Return: MIstatus::success - Functional succeeded. // MIstatus::failure - Functional failed. // Throws: None. //-- bool CMICmnLog::Shutdown(void) { if (--m_clientUsageRefCnt > 0) return MIstatus::success; if (!m_bInitialized) return MIstatus::success; ClrErrorDescription(); const bool bOk = UnregisterMediumAll(); m_bInitialized = bOk; return bOk; }
//++ ------------------------------------------------------------------------------------ // Details: Initialize resources for *this Logger. // Type: Method. // Args: None. // Return: MIstatus::success - Functional succeeded. // MIstatus::failure - Functional failed. // Throws: None. //-- bool CMICmnLog::Initialize(void) { m_clientUsageRefCnt++; if (m_bInitialized) return MIstatus::success; ClrErrorDescription(); // Mediums set inside because explicitly initing in MIDriverMain.cpp causes compile errors with CAtlFile CMICmnLogMediumFile &rFileLog(CMICmnLogMediumFile::Instance()); bool bOk = RegisterMedium(rFileLog); bOk = bOk && SetEnabled(true); if (bOk) { // Set the Log trace file's header const CMIUtilString &rCR(rFileLog.GetLineReturn()); CMIUtilDateTimeStd date; CMIUtilString msg; msg = CMIUtilString::Format("%s\n", CMIDriverMgr::Instance().GetAppVersion().c_str()); CMIUtilString logHdr(msg); msg = CMIUtilString::Format(MIRSRC(IDS_LOG_MSG_CREATION_DATE), date.GetDate().c_str(), date.GetTime().c_str(), rCR.c_str()); logHdr += msg; msg = CMIUtilString::Format(MIRSRC(IDS_LOG_MSG_FILE_LOGGER_PATH), rFileLog.GetFileNamePath().c_str(), rCR.c_str()); logHdr += msg; bOk = rFileLog.SetHeaderTxt(logHdr); // Note log file medium's status is not available until we write at least once to the file (so just write the title 1st line) m_bInitializingATM = true; CMICmnLog::WriteLog("."); if (!rFileLog.IsOk()) { const CMIUtilString msg( CMIUtilString::Format(MIRSRC(IDS_LOG_ERR_FILE_LOGGER_DISABLED), rFileLog.GetErrorDescription().c_str())); CMICmnLog::WriteLog(msg); } m_bInitializingATM = false; } m_bInitialized = bOk; return bOk; }
//++ //------------------------------------------------------------------------------------ // Details: Determine and form the medium file's directory path and name. // Type: Method. // Args: None. // Return: MIstatus::success - Functional succeeded. // MIstatus::failure - Functional failed. // Throws: None. //-- bool CMICmnLogMediumFile::FileFormFileNamePath() { ClrErrorDescription(); m_fileNamePath = MIRSRC(IDS_MEDIUMFILE_ERR_INVALID_PATH); CMIUtilDateTimeStd date; m_strMediumFileName = CMIUtilString::Format(m_constMediumFileNameFormat.c_str(), date.GetDateTimeLogFilename().c_str()); #if defined(_MSC_VER) m_fileNamePath = CMIUtilString::Format( "%s\\%s", m_strMediumFileDirectory.c_str(), m_strMediumFileName.c_str()); #else m_fileNamePath = CMIUtilString::Format( "%s/%s", m_strMediumFileDirectory.c_str(), m_strMediumFileName.c_str()); #endif // defined ( _MSC_VER ) return MIstatus::success; }
//++ ------------------------------------------------------------------------------------ // Details: Initialize setup *this driver ready for use. // Type: Method. // Args: None. // Return: MIstatus::success - Functional succeeded. // MIstatus::failure - Functional failed. // Throws: None. //-- bool CMIDriver::Initialize(void) { m_eCurrentDriverState = eDriverState_Initialising; m_clientUsageRefCnt++; ClrErrorDescription(); if (m_bInitialized) return MIstatus::success; bool bOk = MIstatus::success; CMIUtilString errMsg; // Initialize all of the modules we depend on MI::ModuleInit<CMICmnLog>(IDS_MI_INIT_ERR_LOG, bOk, errMsg); MI::ModuleInit<CMICmnStreamStdout>(IDS_MI_INIT_ERR_STREAMSTDOUT, bOk, errMsg); MI::ModuleInit<CMICmnStreamStderr>(IDS_MI_INIT_ERR_STREAMSTDERR, bOk, errMsg); MI::ModuleInit<CMICmnResources>(IDS_MI_INIT_ERR_RESOURCES, bOk, errMsg); MI::ModuleInit<CMICmnThreadMgrStd>(IDS_MI_INIT_ERR_THREADMANAGER, bOk, errMsg); MI::ModuleInit<CMICmnStreamStdin>(IDS_MI_INIT_ERR_STREAMSTDIN, bOk, errMsg); MI::ModuleInit<CMICmdMgr>(IDS_MI_INIT_ERR_CMDMGR, bOk, errMsg); bOk &= m_rLldbDebugger.SetDriver(*this); MI::ModuleInit<CMICmnLLDBDebugger>(IDS_MI_INIT_ERR_LLDBDEBUGGER, bOk, errMsg); m_bExitApp = false; m_bInitialized = bOk; if (!bOk) { const CMIUtilString msg = CMIUtilString::Format(MIRSRC(IDS_MI_INIT_ERR_DRIVER), errMsg.c_str()); SetErrorDescription(msg); return MIstatus::failure; } m_eCurrentDriverState = eDriverState_RunningNotDebugging; return bOk; }
//++ ------------------------------------------------------------------------------------ // Details: Release resources for *this Stdin stream. // Type: Method. // Args: None. // Return: MIstatus::success - Functional succeeded. // MIstatus::failure - Functional failed. // Throws: None. //-- bool CMICmnStreamStdin::Shutdown(void) { if (--m_clientUsageRefCnt > 0) return MIstatus::success; if (!m_bInitialized) return MIstatus::success; m_bInitialized = false; ClrErrorDescription(); bool bOk = MIstatus::success; CMIUtilString errMsg; m_pVisitor = nullptr; m_bKeyCtrlCHit = false; // Note shutdown order is important here #ifndef _MSC_VER MI::ModuleShutdown<CMICmnStreamStdinLinux>(IDS_MI_SHTDWN_ERR_OS_STDIN_HANDLER, bOk, errMsg); #else MI::ModuleShutdown<CMICmnStreamStdinWindows>(IDS_MI_SHTDWN_ERR_OS_STDIN_HANDLER, bOk, errMsg); #endif // ( _MSC_VER ) MI::ModuleShutdown<CMICmnThreadMgrStd>(IDS_MI_SHTDWN_ERR_THREADMGR, bOk, errMsg); MI::ModuleShutdown<CMICmnResources>(IDE_MI_SHTDWN_ERR_RESOURCES, bOk, errMsg); MI::ModuleShutdown<CMICmnLog>(IDS_MI_SHTDWN_ERR_LOG, bOk, errMsg); if (!bOk) { SetErrorDescriptionn(MIRSRC(IDE_MI_SHTDWN_ERR_STREAMSTDIN), errMsg.c_str()); } return MIstatus::success; }
//++ ------------------------------------------------------------------------------------ // Details: Unbind detach or release resources used by this server in general common // functionality shared between versions of any server interfaces implemented. // Type: Method. // Args: vbAppExitOk - (R) True = No problems, false = App exiting with problems (investigate!). // Return: MIstatus::success - Functional succeeded. // MIstatus::failure - Functional failed. // Throws: None. //-- bool CMIDriverMgr::Shutdown( void ) { // Do not want a ref counter because this function needs to be called how ever this // application stops running //if( --m_clientUsageRefCnt > 0 ) // return MIstatus::success; bool vbAppExitOk = true; ClrErrorDescription(); if( !m_bInitialized ) return MIstatus::success; if( vbAppExitOk ) { // The MI Driver's log updating may have been switched off switch back on to say all is ok. CMICmnLog::Instance().SetEnabled( true ); #if _DEBUG CMICmnStreamStdout::Instance().Write( MIRSRC( IDE_MI_APP_EXIT_OK ) ); // Both stdout and Log #else CMICmnLog::WriteLog( MIRSRC( IDE_MI_APP_EXIT_OK ) ); // Just to the Log #endif // _DEBUG } else { CMICmnLog & rAppLog = CMICmnLog::Instance(); if( rAppLog.GetEnabled() ) { const CMIUtilString msg( CMIUtilString::Format( MIRSRC( IDE_MI_APP_EXIT_WITH_PROBLEM ), CMICmnLogMediumFile::Instance().GetFileName().c_str() ) ); CMICmnStreamStdout::Instance().Write( msg ); } else { // The MI Driver's log updating may have been switched off switch back on to say there has been problem. rAppLog.SetEnabled( true ); const CMIUtilString msg( CMIUtilString::Format( MIRSRC( IDE_MI_APP_EXIT_WITH_PROBLEM_NO_LOG ), CMICmnLogMediumFile::Instance().GetFileName().c_str() ) ); CMICmnStreamStdout::Instance().Write( msg ); } } m_bInitialized = false; bool bOk = MIstatus::success; CMIUtilString errMsg; // Tidy up UnregisterDriverAll(); MIUtilTermios::StdinTermiosReset(); // Note shutdown order is important here MI::ModuleShutdown< CMICmnResources >( IDE_MI_SHTDWN_ERR_RESOURCES, bOk, errMsg ); MI::ModuleShutdown< CMICmnLog > ( IDS_MI_SHTDWN_ERR_LOG , bOk, errMsg ); if( !bOk ) { SetErrorDescriptionn( MIRSRC( IDS_MI_SHTDWN_ERR_DRIVERMGR ), errMsg.c_str() ); } return bOk; }