Files
clang-p2996/lldb/tools/lldb-mi/MIDriverMgr.cpp
Ilia K 3b0494c304 MI fix allowing multiple logging instances of lldb-mi to run simultaneously.
Summary:
Currently if two instances of lldb-mi are running with logging enabled using '--log' the log file conflicts. This produces the following error 
MI: Error: File Handler. Error Permission denied opening 'C:\Users\Ewan\LLVM\build\Debug\bin\lldb-mi-log.txt'

Fixed in this patch by renaming lldb-mi-log.txt based on the date, e.g. lldb-mi-log.txt-20150316163631.log, and moving the file into the temp directory by using the --log-dir option.

Regrading previous review comments the P_tmpdir macro is defined in Windows but always points to "\", which doesn't help much. Also when using the Windows API for GetTempPath() dynamic memory seems much more messy.

Patch from ewan@codeplay.com

Reviewers: abidh, EwanCrawford

Subscribers: zturner, lldb-commits, deepak2427

Differential Revision: http://reviews.llvm.org/D9054

llvm-svn: 235589
2015-04-23 12:48:42 +00:00

742 lines
25 KiB
C++

//===-- MIDriverMgr.cpp -----------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// Third Party Headers:
#include "lldb/API/SBError.h"
// In-house headers:
#include "MIDriverMgr.h"
#include "MICmnResources.h"
#include "MICmnLog.h"
#include "MICmnLogMediumFile.h"
#include "MIDriver.h"
#include "MICmnStreamStdout.h"
#include "MIUtilSingletonHelper.h"
//++ ------------------------------------------------------------------------------------
// Details: CMIDriverMgr constructor.
// Type: Method.
// Args: None.
// Return: None.
// Throws: None.
//--
CMIDriverMgr::CMIDriverMgr(void)
: m_pDriverCurrent(nullptr)
, m_bInMi2Mode(false)
{
}
//++ ------------------------------------------------------------------------------------
// Details: CMIDriverMgr destructor.
// Type: Overridden.
// Args: None.
// Return: None.
// Throws: None.
//--
CMIDriverMgr::~CMIDriverMgr(void)
{
Shutdown();
}
//++ ------------------------------------------------------------------------------------
// Details: Initialize *this manager.
// Type: Method.
// Args: None.
// Return: MIstatus::success - Functional succeeded.
// MIstatus::failure - Functional failed.
// Throws: None.
//--
bool
CMIDriverMgr::Initialize(void)
{
m_clientUsageRefCnt++;
ClrErrorDescription();
if (m_bInitialized)
return MIstatus::success;
bool bOk = MIstatus::success;
CMIUtilString errMsg;
// Note initialisation 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);
m_bInitialized = bOk;
if (!bOk)
{
CMIUtilString strInitError(CMIUtilString::Format(MIRSRC(IDS_MI_INIT_ERR_DRIVERMGR), errMsg.c_str()));
SetErrorDescription(strInitError);
return MIstatus::failure;
}
return bOk;
}
//++ ------------------------------------------------------------------------------------
// 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;
ClrErrorDescription();
if (!m_bInitialized)
return MIstatus::success;
m_bInitialized = false;
bool bOk = MIstatus::success;
CMIUtilString errMsg;
// Tidy up
UnregisterDriverAll();
// 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;
}
//++ ------------------------------------------------------------------------------------
// Details: Unregister all the Driver registered with *this manager. The manager also
// deletes
// Type: Method.
// Args: None.
// Return: MIstatus::success - Functional succeeded.
// MIstatus::failure - Functional failed.
// Throws: None.
//--
bool
CMIDriverMgr::UnregisterDriverAll(void)
{
MapDriverIdToDriver_t::const_iterator it = m_mapDriverIdToDriver.begin();
while (it != m_mapDriverIdToDriver.end())
{
IDriver *pDriver = (*it).second;
pDriver->DoShutdown();
// Next
++it;
}
m_mapDriverIdToDriver.clear();
m_pDriverCurrent = NULL;
return MIstatus::success;
}
//++ ------------------------------------------------------------------------------------
// Details: Register a driver with *this Driver Manager. Call SetUseThisDriverToDoWork()
// inform the manager which driver is the one to the work. The manager calls
// the driver's init function which must be successful in order to complete the
// registration.
// Type: Method.
// Args: vrDriver - (R) The driver to register.
// vrDriverID - (R) The driver's ID to lookup by.
// Return: MIstatus::success - Functional succeeded.
// MIstatus::failure - Functional failed.
// Throws: None.
//--
bool
CMIDriverMgr::RegisterDriver(const IDriver &vrDriver, const CMIUtilString &vrDriverID)
{
if (HaveDriverAlready(vrDriver))
return MIstatus::success;
IDriver *pDriver = const_cast<IDriver *>(&vrDriver);
if (!pDriver->SetId(vrDriverID))
return MIstatus::failure;
if (!pDriver->DoInitialize())
{
SetErrorDescriptionn(MIRSRC(IDS_DRIVERMGR_DRIVER_ERR_INIT), pDriver->GetName().c_str(), vrDriverID.c_str(),
pDriver->GetError().c_str());
return MIstatus::failure;
}
MapPairDriverIdToDriver_t pr(vrDriverID, pDriver);
m_mapDriverIdToDriver.insert(pr);
return MIstatus::success;
}
//++ ------------------------------------------------------------------------------------
// Details: Query the Driver Manager to see if *this manager has the driver already
// registered.
// Type: Method.
// Args: vrDriver - (R) The driver to query.
// Return: True - registered.
// False - not registered.
// Throws: None.
//--
bool
CMIDriverMgr::HaveDriverAlready(const IDriver &vrDriver) const
{
MapDriverIdToDriver_t::const_iterator it = m_mapDriverIdToDriver.begin();
while (it != m_mapDriverIdToDriver.end())
{
const IDriver *pDrvr = (*it).second;
if (pDrvr == &vrDriver)
return true;
// Next
++it;
}
return false;
}
//++ ------------------------------------------------------------------------------------
// Details: Unregister a driver from the Driver Manager. Call the SetUseThisDriverToDoWork()
// function to define another driver to do work if the one being unregistered did
// the work previously.
// Type: Method.
// Args: vrDriver - (R) The driver to unregister.
// Return: MIstatus::success - Functional succeeded.
// MIstatus::failure - Functional failed.
// Throws: None.
//--
bool
CMIDriverMgr::UnregisterDriver(const IDriver &vrDriver)
{
const IDriver *pDrvr = nullptr;
MapDriverIdToDriver_t::const_iterator it = m_mapDriverIdToDriver.begin();
while (it != m_mapDriverIdToDriver.end())
{
pDrvr = (*it).second;
if (pDrvr == &vrDriver)
break;
// Next
++it;
}
m_mapDriverIdToDriver.erase(it);
if (m_pDriverCurrent == pDrvr)
m_pDriverCurrent = nullptr;
return MIstatus::success;
}
//++ ------------------------------------------------------------------------------------
// Details: Specify the driver to do work. The Driver Manager drives this driver. Any
// previous driver doing work is not called anymore (so be sure the previous
// driver is in a tidy state before stopping it working).
// Type: Method.
// Args: vrADriver - (R) A lldb::SBBroadcaster/IDriver derived object.
// Return: MIstatus::success - Functional succeeded.
// MIstatus::failure - Functional failed.
// Throws: None.
//--
bool
CMIDriverMgr::SetUseThisDriverToDoWork(const IDriver &vrADriver)
{
m_pDriverCurrent = const_cast<IDriver *>(&vrADriver);
const CMIUtilString msg(CMIUtilString::Format(MIRSRC(IDS_DRIVER_SAY_DRIVER_USING), m_pDriverCurrent->GetName().c_str()));
m_pLog->Write(msg, CMICmnLog::eLogVerbosity_Log);
m_bInMi2Mode = m_pDriverCurrent->GetDriverIsGDBMICompatibleDriver();
return MIstatus::success;
}
//++ ------------------------------------------------------------------------------------
// Details: Ask *this manager which driver is currently doing the work.
// Type: Method.
// Args: None.
// Return: IDriver * - Pointer to a driver, NULL if there is no current working driver.
// Throws: None.
//--
CMIDriverMgr::IDriver *
CMIDriverMgr::GetUseThisDriverToDoWork(void) const
{
return m_pDriverCurrent;
}
//++ ------------------------------------------------------------------------------------
// Details: Call this function puts *this driver to work.
// Type: Method.
// Args: None.
// Return: MIstatus::success - Functional succeeded.
// MIstatus::failure - Functional failed.
// Throws: None.
//--
bool
CMIDriverMgr::DriverMainLoop(void)
{
if (m_pDriverCurrent != nullptr)
{
if (!m_pDriverCurrent->DoMainLoop())
{
const CMIUtilString errMsg(CMIUtilString::Format(MIRSRC(IDS_DRIVER_ERR_MAINLOOP), m_pDriverCurrent->GetError().c_str()));
CMICmnStreamStdout::Instance().Write(errMsg, true);
return MIstatus::failure;
}
}
else
{
const CMIUtilString errMsg(CMIUtilString::Format(MIRSRC(IDS_DRIVER_ERR_CURRENT_NOT_SET)));
CMICmnStreamStdout::Instance().Write(errMsg, true);
return MIstatus::failure;
}
return MIstatus::success;
}
//++ ------------------------------------------------------------------------------------
// Details: Get the current driver to validate executable command line arguments.
// Type: Method.
// Args: argc - (R) An integer that contains the count of arguments that follow in
// argv. The argc parameter is always greater than or equal to 1.
// argv - (R) An array of null-terminated strings representing command-line
// arguments entered by the user of the program. By convention,
// argv[0] is the command with which the program is invoked.
// vpStdOut - (R) Point to a standard output stream.
// vwbExiting - (W) True = *this want to exit, false = continue to work.
// Return: MIstatus::success - Functional succeeded.
// MIstatus::failure - Functional failed.
// Throws: None.
//--
bool
CMIDriverMgr::DriverParseArgs(const int argc, const char *argv[], FILE *vpStdOut, bool &vwbExiting)
{
if (m_pDriverCurrent == nullptr)
{
const CMIUtilString errMsg(CMIUtilString::Format(MIRSRC(IDS_DRIVER_ERR_CURRENT_NOT_SET)));
CMICmnStreamStdout::Instance().Write(errMsg, true);
return MIstatus::failure;
}
const lldb::SBError error(m_pDriverCurrent->DoParseArgs(argc, argv, vpStdOut, vwbExiting));
bool bOk = !error.Fail();
if (!bOk)
{
CMIUtilString errMsg;
const MIchar *pErrorCstr = error.GetCString();
if (pErrorCstr != nullptr)
errMsg = CMIUtilString::Format(MIRSRC(IDS_DRIVER_ERR_PARSE_ARGS), m_pDriverCurrent->GetName().c_str(), pErrorCstr);
else
errMsg = CMIUtilString::Format(MIRSRC(IDS_DRIVER_ERR_PARSE_ARGS_UNKNOWN), m_pDriverCurrent->GetName().c_str());
bOk = CMICmnStreamStdout::Instance().Write(errMsg, true);
}
return bOk;
}
//++ ------------------------------------------------------------------------------------
// Details: Retrieve the current driver's last error condition.
// Type: Method.
// Args: None.
// Return: CMIUtilString - Text description.
// Throws: None.
//--
CMIUtilString
CMIDriverMgr::DriverGetError(void) const
{
if (m_pDriverCurrent != nullptr)
return m_pDriverCurrent->GetError();
else
{
const CMIUtilString errMsg(CMIUtilString::Format(MIRSRC(IDS_DRIVER_ERR_CURRENT_NOT_SET)));
CMICmnStreamStdout::Instance().Write(errMsg, true);
}
return CMIUtilString();
}
//++ ------------------------------------------------------------------------------------
// Details: Retrieve the current driver's name.
// Type: Method.
// Args: None.
// Return: CMIUtilString - Driver name.
// Empty string = no current working driver specified.
// Throws: None.
//--
CMIUtilString
CMIDriverMgr::DriverGetName(void) const
{
if (m_pDriverCurrent != nullptr)
return m_pDriverCurrent->GetName();
else
{
const CMIUtilString errMsg(CMIUtilString::Format(MIRSRC(IDS_DRIVER_ERR_CURRENT_NOT_SET)));
CMICmnStreamStdout::Instance().Write(errMsg, true);
}
return CMIUtilString();
}
//++ ------------------------------------------------------------------------------------
// Details: Retrieve the current driver's debugger object.
// Type: Method.
// Args: None.
// Return: lldb::SBDebugger * - Ptr to driver's debugger object.
// - NULL = no current working driver specified.
// Throws: None.
//--
lldb::SBDebugger *
CMIDriverMgr::DriverGetTheDebugger(void)
{
lldb::SBDebugger *pDebugger = nullptr;
if (m_pDriverCurrent != nullptr)
pDebugger = &m_pDriverCurrent->GetTheDebugger();
else
{
const CMIUtilString errMsg(CMIUtilString::Format(MIRSRC(IDS_DRIVER_ERR_CURRENT_NOT_SET)));
CMICmnStreamStdout::Instance().Write(errMsg, true);
}
return pDebugger;
}
//++ ------------------------------------------------------------------------------------
// Details: Check the arguments given on the command line. The main purpose of this
// function is to check for the presence of the --interpreter option. Having
// this option present tells *this manager to set the CMIDriver to do work. If
// not use the LLDB driver. The following are options that are only handled by
// the CMIDriverMgr are:
// --help or -h
// --interpreter
// --version
// --versionLong
// --log
// --executable
// --log-dir
// The above arguments are not handled by any driver object except for --executable.
// The options --interpreter and --executable in code act very similar. The
// --executable is necessary to differentiate whither the MI Driver is being using
// by a client i.e. Eclipse or from the command line. Eclipse issues the option
// --interpreter and also passes additional arguments which can be interpreted as an
// executable if called from the command line. Using --executable tells the MI
// Driver is being called the command line and that the executable argument is indeed
// a specified executable an so actions commands to set up the executable for a
// debug session. Using --interpreter on the commnd line does not action additional
// commands to initialise a debug session and so be able to launch the process. The directory
// where the log file is created is specified using --log-dir.
// Type: Method.
// Args: argc - (R) An integer that contains the count of arguments that follow in
// argv. The argc parameter is always greater than or equal to 1.
// argv - (R) An array of null-terminated strings representing command-line
// arguments entered by the user of the program. By convention,
// argv[0] is the command with which the program is invoked.
// vwbExiting - (W) True = *this want to exit, Reasons: help, invalid arg(s),
// version information only.
// False = Continue to work, start debugger i.e. Command
// interpreter.
// Return: lldb::SBError - LLDB current error status.
// Throws: None.
//--
bool
CMIDriverMgr::ParseArgs(const int argc, const char *argv[], bool &vwbExiting)
{
bool bOk = MIstatus::success;
vwbExiting = false;
// Print MI application path to the Log file
const CMIUtilString appPath(CMIUtilString::Format(MIRSRC(IDS_MI_APP_FILEPATHNAME), argv[0]));
bOk = m_pLog->Write(appPath, CMICmnLog::eLogVerbosity_Log);
// Print application arguments to the Log file
const bool bHaveArgs(argc >= 2);
CMIUtilString strArgs(MIRSRC(IDS_MI_APP_ARGS));
if (!bHaveArgs)
{
strArgs += MIRSRC(IDS_WORD_NONE);
bOk = bOk && m_pLog->Write(strArgs, CMICmnLog::eLogVerbosity_Log);
}
else
{
for (MIint i = 1; i < argc; i++)
{
strArgs += CMIUtilString::Format("%d:'%s' ", i, argv[i]);
}
bOk = bOk && m_pLog->Write(strArgs, CMICmnLog::eLogVerbosity_Log);
}
// Look for the command line options
bool bHaveArgInterpret = false;
bool bHaveArgVersion = false;
bool bHaveArgVersionLong = false;
bool bHaveArgLog = false;
bool bHaveArgLogDir = false;
bool bHaveArgHelp = false;
CMIUtilString strLogDir;
bHaveArgInterpret = true;
if (bHaveArgs)
{
// CODETAG_MIDRIVE_CMD_LINE_ARG_HANDLING
for (MIint i = 1; i < argc; i++)
{
// *** Add args to help in GetHelpOnCmdLineArgOptions() ***
const CMIUtilString strArg(argv[i]);
// Argument "--executable" is also check for in CMIDriver::ParseArgs()
if ((0 == strArg.compare("--interpreter")) || // Given by the client such as Eclipse
(0 == strArg.compare("--executable"))) // Used to specify that there is executable argument also on the command line
{ // See fn description.
bHaveArgInterpret = true;
}
if (0 == strArg.compare("--version"))
{
bHaveArgVersion = true;
}
if (0 == strArg.compare("--versionLong"))
{
bHaveArgVersionLong = true;
}
if (0 == strArg.compare("--log"))
{
bHaveArgLog = true;
}
if (0 == strArg.compare(0,10,"--log-dir="))
{
strLogDir = strArg.substr(10,CMIUtilString::npos);
bHaveArgLogDir = true;
}
if ((0 == strArg.compare("--help")) || (0 == strArg.compare("-h")))
{
bHaveArgHelp = true;
}
}
}
if (bHaveArgLog)
{
CMICmnLog::Instance().SetEnabled(true);
}
if (bHaveArgLogDir)
{
bOk = bOk && CMICmnLogMediumFile::Instance().SetDirectory(strLogDir);
}
// Todo: Remove this output when MI is finished. It is temporary to persuade Ecllipse plugin to work.
// Eclipse reads this literally and will not work unless it gets this exact version text.
// Handle --version option (ignore the --interpreter option if present)
if (bHaveArgVersion)
{
vwbExiting = true;
bOk = bOk && CMICmnStreamStdout::Instance().WriteMIResponse(MIRSRC(IDE_MI_VERSION_GDB));
return bOk;
}
// Todo: Make this the --version when the the above --version version is removed
// Handle --versionlong option (ignore the --interpreter option if present)
if (bHaveArgVersionLong)
{
vwbExiting = true;
bOk = bOk && CMICmnStreamStdout::Instance().WriteMIResponse(GetAppVersion());
return bOk;
}
// Both '--help' and '--intepreter' means give help for MI only. Without
// '--interpreter' help the LLDB driver is working and so help is for that.
if (bHaveArgHelp && bHaveArgInterpret)
{
vwbExiting = true;
bOk = bOk && CMICmnStreamStdout::Instance().WriteMIResponse(GetHelpOnCmdLineArgOptions());
return bOk;
}
// This makes the assumption that there is at least one MI compatible
// driver registered and one LLDB driver registerd and the CMIDriver
// is the first one found.
// ToDo: Implement a better solution that handle any order, any number
// of drivers. Or this 'feature' may be removed if deemed not required.
IDriver *pLldbDriver = GetFirstNonMIDriver();
IDriver *pMi2Driver = GetFirstMIDriver();
if (bHaveArgInterpret && (pMi2Driver != nullptr))
bOk = bOk && SetUseThisDriverToDoWork(*pMi2Driver);
else if (pLldbDriver != nullptr)
bOk = bOk && SetUseThisDriverToDoWork(*pLldbDriver);
else
{
if (bOk)
{
vwbExiting = true;
const CMIUtilString msg(MIRSRC(IDS_DRIVER_ERR_NON_REGISTERED));
bOk = bOk && CMICmnStreamStdout::Instance().WriteMIResponse(msg);
}
}
return bOk;
}
//++ ------------------------------------------------------------------------------------
// Details: Return formatted application version and name information.
// Type: Method.
// Args: None.
// Return: CMIUtilString - Text data.
// Throws: None.
//--
CMIUtilString
CMIDriverMgr::GetAppVersion(void) const
{
const CMIUtilString strProj(MIRSRC(IDS_PROJNAME));
const CMIUtilString strVsn(CMIDriver::Instance().GetVersionDescription());
const CMIUtilString strGdb(MIRSRC(IDE_MI_VERSION_GDB));
const CMIUtilString strVrsnInfo(CMIUtilString::Format("%s\n%s\n%s", strProj.c_str(), strVsn.c_str(), strGdb.c_str()));
return strVrsnInfo;
}
//++ ------------------------------------------------------------------------------------
// Details: Return formatted help information on all the MI command line options.
// Type: Method.
// Args: None.
// Return: CMIUtilString - Text data.
// Throws: None.
//--
CMIUtilString
CMIDriverMgr::GetHelpOnCmdLineArgOptions(void) const
{
const CMIUtilString pHelp[] = {
MIRSRC(IDE_MI_APP_DESCRIPTION),
MIRSRC(IDE_MI_APP_INFORMATION),
MIRSRC(IDE_MI_APP_ARG_USAGE),
MIRSRC(IDE_MI_APP_ARG_HELP),
MIRSRC(IDE_MI_APP_ARG_VERSION),
MIRSRC(IDE_MI_APP_ARG_VERSION_LONG),
MIRSRC(IDE_MI_APP_ARG_INTERPRETER),
MIRSRC(IDE_MI_APP_ARG_EXECUTEABLE),
CMIUtilString::Format(MIRSRC(IDE_MI_APP_ARG_APP_LOG), CMICmnLogMediumFile::Instance().GetFileName().c_str()),
MIRSRC(IDE_MI_APP_ARG_APP_LOG_DIR),
MIRSRC(IDE_MI_APP_ARG_EXECUTABLE),
MIRSRC(IDS_CMD_QUIT_HELP),
MIRSRC(IDE_MI_APP_ARG_EXAMPLE)};
const MIuint nHelpItems = sizeof pHelp / sizeof pHelp[0];
CMIUtilString strHelp;
for (MIuint i = 0; i < nHelpItems; i++)
{
strHelp += pHelp[i];
strHelp += "\n\n";
}
return strHelp;
}
//++ ------------------------------------------------------------------------------------
// Details: Search the registered drivers and return the first driver which says it is
// GDB/MI compatible i.e. the CMIDriver class.
// Type: Method.
// Args: None.
// Return: IDriver * - Ptr to driver, NULL = no driver found.
// Throws: None.
//--
CMIDriverMgr::IDriver *
CMIDriverMgr::GetFirstMIDriver(void) const
{
IDriver *pDriver = nullptr;
MapDriverIdToDriver_t::const_iterator it = m_mapDriverIdToDriver.begin();
while (it != m_mapDriverIdToDriver.end())
{
const CMIUtilString &rDrvId = (*it).first;
MIunused(rDrvId);
IDriver *pDvr = (*it).second;
if (pDvr->GetDriverIsGDBMICompatibleDriver())
{
pDriver = pDvr;
break;
}
// Next
++it;
}
return pDriver;
}
//++ ------------------------------------------------------------------------------------
// Details: Search the registered drivers and return the first driver which says it is
// not GDB/MI compatible i.e. the LLDB Driver class.
// Type: Method.
// Args: None.
// Return: IDriver * - Ptr to driver, NULL = no driver found.
// Throws: None.
//--
CMIDriverMgr::IDriver *
CMIDriverMgr::GetFirstNonMIDriver(void) const
{
IDriver *pDriver = nullptr;
MapDriverIdToDriver_t::const_iterator it = m_mapDriverIdToDriver.begin();
while (it != m_mapDriverIdToDriver.end())
{
const CMIUtilString &rDrvId = (*it).first;
MIunused(rDrvId);
IDriver *pDvr = (*it).second;
if (!pDvr->GetDriverIsGDBMICompatibleDriver())
{
pDriver = pDvr;
break;
}
// Next
++it;
}
return pDriver;
}
//++ ------------------------------------------------------------------------------------
// Details: Search the registered drivers and return driver with the specified ID.
// Type: Method.
// Args: vrDriverId - (R) ID of a driver.
// Return: IDriver * - Ptr to driver, NULL = no driver found.
// Throws: None.
//--
CMIDriverMgr::IDriver *
CMIDriverMgr::GetDriver(const CMIUtilString &vrDriverId) const
{
MapDriverIdToDriver_t::const_iterator it = m_mapDriverIdToDriver.find(vrDriverId);
if (it == m_mapDriverIdToDriver.end())
return nullptr;
IDriver *pDriver = (*it).second;
return pDriver;
}
//++ ------------------------------------------------------------------------------------
// Details: Gets called when lldb-mi gets a signal. Passed signal to current driver.
//
// Type: Method.
// Args: signal that was delivered
// Return: None.
// Throws: None.
//--
void
CMIDriverMgr::DeliverSignal(int signal)
{
if (m_pDriverCurrent != nullptr)
m_pDriverCurrent->DeliverSignal(signal);
}