Ejemplo n.º 1
0
//++ ------------------------------------------------------------------------------------
// Details: Set up the events from the SBDebugger's we would like to listen to.
// Type:    Method.
// Args:    None.
// Return:  MIstatus::success - Functionality succeeded.
//          MIstatus::failure - Functionality failed.
// Throws:  None.
//--
bool
CMICmnLLDBDebugger::InitSBListener()
{
    m_lldbListener = m_lldbDebugger.GetListener();
    if (!m_lldbListener.IsValid())
    {
        SetErrorDescription(MIRSRC(IDS_LLDBDEBUGGER_ERR_INVALIDLISTENER));
        return MIstatus::failure;
    }

    const CMIUtilString strDbgId("CMICmnLLDBDebugger1");
    MIuint eventMask = lldb::SBTarget::eBroadcastBitBreakpointChanged | lldb::SBTarget::eBroadcastBitModulesLoaded |
                       lldb::SBTarget::eBroadcastBitModulesUnloaded | lldb::SBTarget::eBroadcastBitWatchpointChanged |
                       lldb::SBTarget::eBroadcastBitSymbolsLoaded;
    bool bOk = RegisterForEvent(strDbgId, CMIUtilString(lldb::SBTarget::GetBroadcasterClassName()), eventMask);

    eventMask = lldb::SBThread::eBroadcastBitStackChanged;
    bOk = bOk && RegisterForEvent(strDbgId, CMIUtilString(lldb::SBThread::GetBroadcasterClassName()), eventMask);

    eventMask = lldb::SBProcess::eBroadcastBitStateChanged | lldb::SBProcess::eBroadcastBitInterrupt |
                lldb::SBProcess::eBroadcastBitSTDOUT | lldb::SBProcess::eBroadcastBitSTDERR | lldb::SBProcess::eBroadcastBitProfileData;
    bOk = bOk && RegisterForEvent(strDbgId, CMIUtilString(lldb::SBProcess::GetBroadcasterClassName()), eventMask);

    eventMask = lldb::SBCommandInterpreter::eBroadcastBitQuitCommandReceived | lldb::SBCommandInterpreter::eBroadcastBitThreadShouldExit |
                lldb::SBCommandInterpreter::eBroadcastBitAsynchronousOutputData |
                lldb::SBCommandInterpreter::eBroadcastBitAsynchronousErrorData;
    bOk = bOk && RegisterForEvent(strDbgId, m_lldbDebugger.GetCommandInterpreter().GetBroadcaster(), eventMask);

    return bOk;
}
Ejemplo n.º 2
0
//++ ------------------------------------------------------------------------------------
// Details: Does the command name entered match the criteria for a MI command format.
//          Is a recogised command present? The command name is entered into the
//          command meta data structure whether correct or not for reporting or later
//          command execution purposes. Command options is present are also put into the
//          command meta data structure.
// Type:    Method.
// Args:    vTextLine   - (R) Command information structure.
// Return:  bool  - True = yes command name present, false = command not recognised.
// Throws:  None.
//--
bool
CMICmdInterpreter::MiHasCmd(const CMIUtilString &vTextLine)
{
    MIint nPos = 0;
    if (m_miCmdData.bMIOldStyle)
    {
        char cChar = vTextLine[0];
        MIuint i = 0;
        while (::isdigit(cChar) != 0)
        {
            cChar = vTextLine[++i];
        }
        nPos = --i;
    }
    else
    {
        nPos = vTextLine.find("-", 0);
    }

    bool bFoundCmd = false;
    const MIint nLen = vTextLine.length();
    const MIint nPos2 = vTextLine.find(" ", nPos);
    if (nPos2 != (MIint)std::string::npos)
    {
        if (nPos2 == nLen)
            return false;
        const CMIUtilString cmd = CMIUtilString(vTextLine.substr(nPos + 1, nPos2 - nPos - 1).c_str());
        if (cmd.empty())
            return false;

        m_miCmdData.strMiCmd = cmd;

        if (nPos2 < nLen)
            m_miCmdData.strMiCmdOption = CMIUtilString(vTextLine.substr(nPos2 + 1, nLen - nPos2 - 1).c_str());

        bFoundCmd = true;
    }
    else
    {
        const CMIUtilString cmd = CMIUtilString(vTextLine.substr(nPos + 1, nLen - nPos - 1).c_str());
        if (cmd.empty())
            return false;
        m_miCmdData.strMiCmd = cmd;
        bFoundCmd = true;
    }

    if (bFoundCmd)
        m_miCmdData.strMiCmdAll = vTextLine;

    return bFoundCmd;
}
Ejemplo n.º 3
0
//++ ------------------------------------------------------------------------------------
// Details: The invoker requires this function. The command does work in this function.
//          The command is likely to communicate with the LLDB SBDebugger in here.
// Type:    Overridden.
// Args:    None.
// Return:  MIstatus::success - Functional succeeded.
//          MIstatus::failure - Functional failed.
// Throws:  None.
//--
bool
CMICmdCmdExecContinue::Execute()
{
    const char *pCmd = "continue";
    CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());
    const lldb::ReturnStatus rtn = rSessionInfo.GetDebugger().GetCommandInterpreter().HandleCommand(pCmd, m_lldbResult);
    MIunused(rtn);

    if (m_lldbResult.GetErrorSize() == 0)
    {
        // CODETAG_DEBUG_SESSION_RUNNING_PROG_RECEIVED_SIGINT_PAUSE_PROGRAM
        if (!CMIDriver::Instance().SetDriverStateRunningDebugging())
        {
            const CMIUtilString &rErrMsg(CMIDriver::Instance().GetErrorDescription());
            SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_SET_NEW_DRIVER_STATE), m_cmdData.strMiCmd.c_str(), rErrMsg.c_str()));
            return MIstatus::failure;
        }
    }
    else
    {
        // ToDo: Re-evaluate if this is required when application near finished as this is parsing LLDB error message
        // which seems a hack and is code brittle
        const char *pLldbErr = m_lldbResult.GetError();
        const CMIUtilString strLldbMsg(CMIUtilString(pLldbErr).StripCREndOfLine());
        if (strLldbMsg == "error: Process must be launched.")
        {
            CMIDriver::Instance().SetExitApplicationFlag(true);
        }
    }

    return MIstatus::success;
}
Ejemplo n.º 4
0
CMIUtilString
CMIUtilString::ConvertCharValueToPrintableASCII(char vChar, bool bEscapeQuotes)
{
    switch (vChar)
    {
        case '\a':
            return "\\a";
        case '\b':
            return "\\b";
        case '\t':
            return "\\t";
        case '\n':
            return "\\n";
        case '\v':
            return "\\v";
        case '\f':
            return "\\f";
        case '\r':
            return "\\r";
        case '\033':
            return "\\e";
        case '\\':
            return "\\\\";
        case '"':
            if (bEscapeQuotes)
                return "\\\"";
            // fall thru
        default:
            if (::isprint(vChar))
                return Format("%c", vChar);
            else
                return CMIUtilString();
    }
}
//++
//------------------------------------------------------------------------------------
// Details: Retrieve the value object' has a name. A value object can be valid
// but still
//          have no name which suggest it is not a variable.
// Type:    Method.
// Args:    None.
// Return:  bool    - True = valid, false = not valid.
// Throws:  None.
//--
bool CMICmnLLDBUtilSBValue::HasName() const {
  bool bHasAName = false;

  const char *pName = m_bValidSBValue ? m_rValue.GetDisplayTypeName() : nullptr;
  if (pName != nullptr) {
    bHasAName = (CMIUtilString(pName).length() > 0);
  }

  return bHasAName;
}
Ejemplo n.º 6
0
//++ ------------------------------------------------------------------------------------
// Details:	CMIUtilFileStd constructor.
// Type:	Method.
// Args:	None.
// Return:	None.
// Throws:	None.
//--
CMIUtilFileStd::CMIUtilFileStd( void )
:	m_fileNamePath( CMIUtilString() )
,	m_pFileHandle( nullptr )
#if defined( _MSC_VER )
,	m_constCharNewLine( "\r\n" )
#else
,	m_constCharNewLine( "\n" )
#endif // #if defined( _MSC_VER )
,	m_bFileError( false )
{
}
Ejemplo n.º 7
0
//++ ------------------------------------------------------------------------------------
// 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();
}
Ejemplo n.º 8
0
//++ ------------------------------------------------------------------------------------
// Details: Form MI partial response by appending more MI value type objects to the
//          tuple type object past in.
// Type:    Method.
// Args:    vCmdData        - (R) A command's information.
//          vrThread        - (R) LLDB thread object.
//          vwrMIValueTuple - (W) MI value tuple object.
// Return:  MIstatus::success - Functional succeeded.
//          MIstatus::failure - Functional failed.
// Throws:  None.
//--
bool
CMICmnLLDBDebugSessionInfo::MIResponseFormThreadInfo(const SMICmdData &vCmdData, const lldb::SBThread &vrThread,
                                                     const ThreadInfoFormat_e veThreadInfoFormat, CMICmnMIValueTuple &vwrMIValueTuple)
{
    lldb::SBThread &rThread = const_cast<lldb::SBThread &>(vrThread);

    const bool bSuspended = rThread.IsSuspended();
    const lldb::StopReason eReason = rThread.GetStopReason();
    const bool bValidReason = !((eReason == lldb::eStopReasonNone) || (eReason == lldb::eStopReasonInvalid));
    const CMIUtilString strState((bSuspended || bValidReason) ? "stopped" : "running");

    // Add "id"
    const CMIUtilString strId(CMIUtilString::Format("%d", rThread.GetIndexID()));
    const CMICmnMIValueConst miValueConst1(strId);
    const CMICmnMIValueResult miValueResult1("id", miValueConst1);
    vwrMIValueTuple.Add(miValueResult1);

    // Add "target-id"
    const char *pThreadName = rThread.GetName();
    const MIuint len = (pThreadName != nullptr) ? CMIUtilString(pThreadName).length() : 0;
    const bool bHaveName = ((pThreadName != nullptr) && (len > 0) && (len < 32) &&
                            CMIUtilString::IsAllValidAlphaAndNumeric(pThreadName)); // 32 is arbitrary number
    const char *pThrdFmt = bHaveName ? "%s" : "Thread %d";
    CMIUtilString strThread;
    if (bHaveName)
        strThread = CMIUtilString::Format(pThrdFmt, pThreadName);
    else
        strThread = CMIUtilString::Format(pThrdFmt, rThread.GetIndexID());
    const CMICmnMIValueConst miValueConst2(strThread);
    const CMICmnMIValueResult miValueResult2("target-id", miValueConst2);
    vwrMIValueTuple.Add(miValueResult2);

    // Add "frame"
    if (veThreadInfoFormat != eThreadInfoFormat_NoFrames)
    {
        CMIUtilString strFrames;
        if (!GetThreadFrames(vCmdData, rThread.GetIndexID(), eFrameInfoFormat_AllArgumentsInSimpleForm, strFrames))
            return MIstatus::failure;

        const CMICmnMIValueConst miValueConst3(strFrames, true);
        vwrMIValueTuple.Add(miValueConst3, false);
    }

    // Add "state"
    const CMICmnMIValueConst miValueConst4(strState);
    const CMICmnMIValueResult miValueResult4("state", miValueConst4);
    vwrMIValueTuple.Add(miValueResult4);

    return MIstatus::success;
}
Ejemplo n.º 9
0
//++ ------------------------------------------------------------------------------------
// Details:	Does the command entered match the criteria for a MI command format.
//			The format to validate against is 'nn-' where there can be 1 to n digits.
//			I.e. '2-gdb-exit'.
//			Is the execution token present? The command token is entered into the
//			command meta data structure whether correct or not for reporting or later
//			command execution purposes.
// Type:	Method.
// Args:	vTextLine	- (R) Text data to interpret.
// Return:	bool  - True = yes command token present, false = command not recognised.
// Throws:	None.
//--
bool CMICmdInterpreter::MiHasCmdTokenEndingHypthen( const CMIUtilString & vTextLine )
{
    // The hythen is mandatory
    const MIint nPos = vTextLine.find( "-", 0 );
    if( (nPos == (MIint) std::string::npos) )
        return false;

    if( MiHasCmdTokenPresent( vTextLine ) )
    {
        const std::string strNum = vTextLine.substr( 0, nPos );
        if( !CMIUtilString( strNum.c_str() ).IsNumber() )
            return false;

        m_miCmdData.strMiCmdToken = strNum.c_str();
    }

    m_miCmdData.bMIOldStyle = false;

    return true;
}
Ejemplo n.º 10
0
//++ ------------------------------------------------------------------------------------
// Details: The monitoring on new line data calls back to the visitor object registered
//          with *this stdin monitoring. The monitoring to stops when the visitor returns
//          true for bYesExit flag. Errors output to log file.
//          This function runs in the thread "MI stdin monitor".
// Type:    Method.
//          vrwbYesAlive    - (W) False = yes exit stdin monitoring, true = continue monitor.
// Return:  MIstatus::success - Functional succeeded.
//          MIstatus::failure - Functional failed.
// Throws:  None.
//--
bool
CMICmnStreamStdin::MonitorStdin(bool &vrwbYesAlive)
{
    if (m_bShowPrompt)
    {
        CMICmnStreamStdout &rStdoutMan = CMICmnStreamStdout::Instance();
        rStdoutMan.WriteMIResponse(m_strPromptCurrent.c_str());
        m_bRedrawPrompt = false;
    }

    // CODETAG_DEBUG_SESSION_RUNNING_PROG_RECEIVED_SIGINT_PAUSE_PROGRAM
    if (m_bKeyCtrlCHit)
    {
        CMIDriver &rMIDriver = CMIDriver::Instance();
        rMIDriver.SetExitApplicationFlag(false);
        if (rMIDriver.GetExitApplicationFlag())
        {
            vrwbYesAlive = false;
            return MIstatus::success;
        }

        // Reset - the MI Driver received SIGINT during a running debug programm session
        m_bKeyCtrlCHit = false;
    }

#if MICONFIG_POLL_FOR_STD_IN
    bool bAvail = true;
    // Check if there is stdin available
    if (InputAvailable(bAvail))
    {
        // Early exit when there is no input
        if (!bAvail)
            return MIstatus::success;
    }
    else
    {
        vrwbYesAlive = false;
        CMIDriver::Instance().SetExitApplicationFlag(true);
        return MIstatus::failure;
    }
#endif // MICONFIG_POLL_FOR_STD_IN

    // Read a line from std input
    CMIUtilString stdinErrMsg;
    const MIchar *pText = ReadLine(stdinErrMsg);

    // Did something go wrong
    const bool bHaveError(!stdinErrMsg.empty());
    if ((pText == nullptr) || bHaveError)
    {
        if (bHaveError)
        {
            CMICmnStreamStdout::Instance().Write(stdinErrMsg);
        }
        return MIstatus::failure;
    }

    // We have text so send it off to the visitor
    bool bOk = MIstatus::success;
    if (m_pVisitor != nullptr)
    {
        bool bYesExit = false;
        bOk = m_pVisitor->ReadLine(CMIUtilString(pText), bYesExit);
        m_bRedrawPrompt = true;
        vrwbYesAlive = !bYesExit;
    }

    return bOk;
}
//++ ------------------------------------------------------------------------------------
// Details: Retrieves the fully qualified path for the this application. If the function
//          fails the string is filled with the error message.
// Type:    Method.
// Args:    vrwFileNamePath	- (W) The executable's name and path or last error description.
// Return:  MIstatus::success - Functional succeeded.
//          MIstatus::failure - Functional failed.
// Throws:  None.
//--
bool
CMIUtilSystemOsx::GetExecutablesPath(CMIUtilString &vrwFileNamePath) const
{
    vrwFileNamePath = CMIUtilString(".");
    return MIstatus::success;
}
Ejemplo n.º 12
0
//++ ------------------------------------------------------------------------------------
// Details: Retrieves the fully qualified path for the Log file for this application.
//          If the function fails the string is filled with the error message.
//          Append a dummy file name on the end of the path. This will be stripped off
//          later and the real log file name replaces it.
// Type:    Method.
// Args:    vrwFileNamePath - (W) The Log file's name and path or last error description.
// Return:  MIstatus::success - Functional succeeded.
//          MIstatus::failure - Functional failed.
// Throws:  None.
//--
bool
CMIUtilSystemLinux::GetLogFilesPath(CMIUtilString &vrwFileNamePath) const
{
    vrwFileNamePath = CMIUtilString(".");
    return MIstatus::success;
}
//++
//------------------------------------------------------------------------------------
// Details: Retrieve from the LLDB SB Value object the name of the variable. If
// the name
//          is invalid (or the SBValue object invalid) then "??" is returned.
// Type:    Method.
// Args:    None.
// Return:  CMIUtilString   - Name of the variable or "??" for unknown.
// Throws:  None.
//--
CMIUtilString CMICmnLLDBUtilSBValue::GetName() const {
  const char *pName = m_bValidSBValue ? m_rValue.GetName() : nullptr;
  const CMIUtilString text((pName != nullptr) ? pName : CMIUtilString());

  return text;
}
Ejemplo n.º 14
0
//++ ------------------------------------------------------------------------------------
// Details: Clear the last error.
// Type:    None.
// Args:    None.
// Return:  None.
// Throws:  None.
//--
void
CMICmnLog::ClrErrorDescription(void) const
{
    m_strMILastErrorDescription = CMIUtilString("");
}
Ejemplo n.º 15
0
//++
// Details: CMICmnBase constructor.
// Type:    Method.
// Args:    None.
// Return:  None.
// Throws:  None.
//--
CMICmnBase::CMICmnBase()
    : m_strMILastErrorDescription(CMIUtilString()), m_bInitialized(false),
      m_pLog(&CMICmnLog::Instance()), m_clientUsageRefCnt(0) {}