Added support for new MI commands and bug fixes. More details in MIReadme.txt.

llvm-svn: 211607
This commit is contained in:
Deepak Panickal 2014-06-24 16:35:50 +00:00
parent f93ef4e450
commit 877569c2b8
113 changed files with 7734 additions and 1497 deletions

View File

@ -6,6 +6,7 @@ add_lldb_executable(lldb-mi
MICmdArgContext.cpp
MICmdArgSet.cpp
MICmdArgValBase.cpp
MICmdArgValConsume.cpp
MICmdArgValFile.cpp
MICmdArgValListBase.cpp
MICmdArgValListOfN.cpp
@ -22,6 +23,9 @@ add_lldb_executable(lldb-mi
MICmdCmdEnviro.cpp
MICmdCmdExec.cpp
MICmdCmdFile.cpp
MICmdCmdGdbInfo.cpp
MICmdCmdGdbSet.cpp
MICmdCmdGdbThread.cpp
MICmdCmdMiscellanous.cpp
MICmdCmdStack.cpp
MICmdCmdSupportInfo.cpp
@ -55,6 +59,8 @@ add_lldb_executable(lldb-mi
MICmnResources.cpp
MICmnStreamStderr.cpp
MICmnStreamStdin.cpp
MICmnStreamStdinLinux.cpp
MICmnStreamStdinWindows.cpp
MICmnStreamStdout.cpp
MICmnThreadMgrStd.cpp
MIDriver.cpp
@ -64,13 +70,14 @@ add_lldb_executable(lldb-mi
MIUtilDateTimeStd.cpp
MIUtilDebug.cpp
MIUtilFileStd.cpp
MIUtilSetID.cpp
MIUtilMapIdToVariant.cpp
MIUtilString.cpp
MIUtilSystemLinux.cpp
MIUtilSystemOsx.cpp
MIUtilSystemWindows.cpp
MIUtilTermios.cpp
MIUtilThreadBaseStd.cpp
MIUtilVariant.cpp
Platform.cpp
)
else ()
@ -79,6 +86,7 @@ add_lldb_executable(lldb-mi
MICmdArgContext.cpp
MICmdArgSet.cpp
MICmdArgValBase.cpp
MICmdArgValConsume.cpp
MICmdArgValFile.cpp
MICmdArgValListBase.cpp
MICmdArgValListOfN.cpp
@ -95,6 +103,9 @@ add_lldb_executable(lldb-mi
MICmdCmdEnviro.cpp
MICmdCmdExec.cpp
MICmdCmdFile.cpp
MICmdCmdGdbInfo.cpp
MICmdCmdGdbSet.cpp
MICmdCmdGdbThread.cpp
MICmdCmdMiscellanous.cpp
MICmdCmdStack.cpp
MICmdCmdSupportInfo.cpp
@ -128,6 +139,8 @@ add_lldb_executable(lldb-mi
MICmnResources.cpp
MICmnStreamStderr.cpp
MICmnStreamStdin.cpp
MICmnStreamStdinLinux.cpp
MICmnStreamStdinWindows.cpp
MICmnStreamStdout.cpp
MICmnThreadMgrStd.cpp
MIDriver.cpp
@ -137,13 +150,14 @@ add_lldb_executable(lldb-mi
MIUtilDateTimeStd.cpp
MIUtilDebug.cpp
MIUtilFileStd.cpp
MIUtilSetID.cpp
MIUtilMapIdToVariant.cpp
MIUtilString.cpp
MIUtilSystemLinux.cpp
MIUtilSystemOsx.cpp
MIUtilSystemWindows.cpp
MIUtilTermios.cpp
MIUtilThreadBaseStd.cpp
MIUtilVariant.cpp
Platform.cpp
)
endif ()

View File

@ -9,12 +9,24 @@
// In-house headers:
#include "MICmnConfig.h"
#if MICONFIG_COMPILE_MIDRIVER_WITH_LLDBDRIVER
#ifndef _MSC_VER
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <limits.h>
#include <fcntl.h>
#include <string>
#endif // _MSC_VER
#include "Platform.h" // CODETAG_IOR_SIGNALS
#include "Driver.h"
#include <lldb\Host\windows\getopt\GetOptInc.h>
#ifdef _MSC_VER
#include <lldb\Host\windows\getopt\GetOptInc.h>
#endif // _MSC_VER
#include <lldb/API/SBBreakpoint.h>
#include <lldb/API/SBCommandInterpreter.h>
#include <lldb/API/SBCommandReturnObject.h>
@ -978,10 +990,10 @@ Driver::ResizeWindow (unsigned short col)
// Details: Setup *this driver so it works as pass through (child) driver for the MI
// driver. Called by the parent (MI driver) driver.
// This driver has setup code in two places. The original in MainLoop() and
// in int main() (if MICONFIG_COMPILE_MIDRIVER_VERSION == 0) so that code can remain
// as much near to the original code as possible. If MI driver is the main
// driver then this function is used to set up the Driver to work with the
// MI driver.
// in int main() (when MICONFIG_COMPILE_MIDRIVER_VERSION == 0) so that code can
// remain as much near to the original code as possible. If MI driver is the main
// driver (when MICONFIG_COMPILE_MIDRIVER_VERSION == 1) then this function is
// used to set up the Driver to work with the MI driver.
// Type: Method.
// Args: vwErrMsg - (W) On failure current error discription.
// Return: MIstatus::success - Functional succeeded.
@ -1181,10 +1193,11 @@ bool Driver::DoFallThruToAnotherDriver( const CMIUtilString & vCmd, CMIUtilStrin
bool bOk = MIstatus::success;
vwErrMsg.empty();
// ToDo: implement do work on other driver after other driver said "Give up you try"
// ToDo: Implement do work on other driver after this driver said "Give up you try"
// This may nto be required if the feature to 'fall through' is not required
SBCommandReturnObject returnObj = lldb::SBCommandReturnObject();
SBCommandInterpreter cmdIntrp = m_debugger.GetCommandInterpreter();
const lldb::ReturnStatus cmdResult = cmdIntrp.HandleCommand( vCmd.c_str(), returnObj );
const lldb::ReturnStatus cmdResult = cmdIntrp.HandleCommand( vCmd.c_str(), returnObj ); MIunused( cmdResult );
if( returnObj.Succeeded() == false )
{
bOk = MIstatus::failure;
@ -1282,4 +1295,4 @@ const CMIUtilString & Driver::GetDriverId( void ) const
return GetId();
}
#endif // MICONFIG_COMPILE_MIDRIVER_WITH_LLDBDRIVER
#endif // MICONFIG_COMPILE_MIDRIVER_WITH_LLDBDRIVER

View File

@ -149,6 +149,67 @@ bool CMICmdArgContext::RemoveArg( const CMIUtilString & vArg )
return MIstatus::success;
}
//++ ------------------------------------------------------------------------------------
// Details: Remove the argument at the Nth word position along in the context string.
// Any space after the argument is removed if applicable. A search is not
// performed as there may be more than one vArg with the same 'name' in the
// context string.
// Type: Method.
// Args: vArg - (R) The name of the argument.
// nArgIndex - (R) The word count position to which to remove the vArg word.
// Return: MIstatus::success - Functional succeeded.
// MIstatus::failure - Functional failed.
// Throws: None.
//--
bool CMICmdArgContext::RemoveArgAtPos( const CMIUtilString & vArg, const MIuint nArgIndex )
{
MIuint nWordIndex = 0;
CMIUtilString strBuildContextUp;
const CMIUtilString::VecString_t vecWords( GetArgs() );
const bool bSpaceRequired( GetNumberArgsPresent() > 2 );
CMIUtilString::VecString_t::const_iterator it = vecWords.begin();
const CMIUtilString::VecString_t::const_iterator itEnd = vecWords.end();
while( it != itEnd )
{
const CMIUtilString & rWord( *it );
if( nWordIndex++ != nArgIndex )
{
// Single words
strBuildContextUp += rWord;
if( bSpaceRequired )
strBuildContextUp += m_constStrSpace;
}
else
{
// If quoted loose quoted text
if( ++it != itEnd )
{
CMIUtilString words = rWord;
while( vArg != words )
{
if( bSpaceRequired )
words += m_constStrSpace;
words += *it;
if( ++it == itEnd )
break;
}
if( it != itEnd )
--it;
}
}
// Next
if( it != itEnd )
++it;
}
m_strCmdArgsAndOptions = strBuildContextUp;
m_strCmdArgsAndOptions = m_strCmdArgsAndOptions.Trim();
return MIstatus::success;
}
//++ ------------------------------------------------------------------------------------
// Details: Retrieve number of arguments or options present in the command's option text.
// Type: Method.

View File

@ -44,6 +44,7 @@ public:
CMIUtilString::VecString_t GetArgs( void ) const;
bool IsEmpty( void ) const;
bool RemoveArg( const CMIUtilString & vArg );
bool RemoveArgAtPos( const CMIUtilString & vArg, const MIuint nArgIndex );
//
CMICmdArgContext & operator= ( const CMICmdArgContext & vOther );

View File

@ -181,6 +181,7 @@ bool CMICmdArgSet::Validate( const CMIUtilString & vStrMiCmd, CMICmdArgContext &
while( it != m_setCmdArgs.end() )
{
const CMICmdArgValBase * pArg( *it );
const CMIUtilString & rArgName( pArg->GetName() ); MIunused( rArgName );
if( pArg->GetIsMandatory() )
nArgsMandatoryCnt++;
if( !const_cast< CMICmdArgValBase * >( pArg )->Validate( vwCmdArgsText ) )

View File

@ -0,0 +1,119 @@
//===-- MICmdArgValConsume.cpp -------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//++
// File: MICmdArgValConsume.cpp
//
// Overview: CMICmdArgValConsume implementation.
//
// Environment: Compilers: Visual C++ 12.
// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
// Libraries: See MIReadmetxt.
//
// Copyright: None.
//--
// In-house headers:
#include "MICmdArgValConsume.h"
#include "MICmdArgContext.h"
//++ ------------------------------------------------------------------------------------
// Details: CMICmdArgValConsume constructor.
// Type: Method.
// Args: None.
// Return: None.
// Throws: None.
//--
CMICmdArgValConsume::CMICmdArgValConsume( void )
{
}
//++ ------------------------------------------------------------------------------------
// Details: CMICmdArgValConsume constructor.
// Type: Method.
// Args: vrArgName - (R) Argument's name to search by.
// vbMandatory - (R) True = Yes must be present, false = optional argument.
// Return: None.
// Throws: None.
//--
CMICmdArgValConsume::CMICmdArgValConsume( const CMIUtilString & vrArgName, const bool vbMandatory )
: CMICmdArgValBaseTemplate( vrArgName, vbMandatory, true )
{
}
//++ ------------------------------------------------------------------------------------
// Details: CMICmdArgValConsume destructor.
// Type: Overidden.
// Args: None.
// Return: None.
// Throws: None.
//--
CMICmdArgValConsume::~CMICmdArgValConsume( void )
{
}
//++ ------------------------------------------------------------------------------------
// Details: Parse the command's argument options string and try to extract the value *this
// argument is looking for.
// Type: Overridden.
// Args: vwArgContext - (R) The command's argument options string.
// Return: MIstatus::success - Functional succeeded.
// MIstatus::failure - Functional failed.
// Throws: None.
//--
bool CMICmdArgValConsume::Validate( CMICmdArgContext & vwArgContext )
{
if( vwArgContext.IsEmpty() )
return MIstatus::success;
if( vwArgContext.GetNumberArgsPresent() == 1 )
{
const CMIUtilString & rArg( vwArgContext.GetArgsLeftToParse() );
m_bFound = true;
m_bValid = true;
vwArgContext.RemoveArg( rArg );
return MIstatus::success;
}
// In reality there are more than one option, if so the file option
// is the last one (don't handle that here - find the best looking one)
const CMIUtilString::VecString_t vecOptions( vwArgContext.GetArgs() );
CMIUtilString::VecString_t::const_iterator it = vecOptions.begin();
while( it != vecOptions.end() )
{
const CMIUtilString & rTxt( *it );
m_bFound = true;
if( vwArgContext.RemoveArg( rTxt ) )
{
m_bValid = true;
return MIstatus::success;
}
else
return MIstatus::success;
// Next
++it;
}
return MIstatus::failure;
}
//++ ------------------------------------------------------------------------------------
// Details: Nothing to examine as we just want to consume the argument or option (ignore
// it).
// Type: Method.
// Args: None.
// Return: bool - True = yes ok, false = not ok.
// Throws: None.
//--
bool CMICmdArgValConsume::IsOk( void ) const
{
return true;
}

View File

@ -0,0 +1,63 @@
//===-- MICmdArgValConsume.h ---------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//++
// File: MICmdArgValConsume.h
//
// Overview: CMICmdArgValConsume interface.
//
// Environment: Compilers: Visual C++ 12.
// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
// Libraries: See MIReadmetxt.
//
// Copyright: None.
//--
#pragma once
// In-house headers:
#include "MICmdArgValBase.h"
// Declarations:
class CMICmdArgContext;
//++ ============================================================================
// Details: MI common code class. Command argument class. Arguments object
// needing specialization derived from the CMICmdArgValBase class.
// An argument knows what type of argument it is and how it is to
// interpret the options (context) string to find and validate a matching
// argument. This type having recognised its argument name just consumes
// that argument or option (ignores it). This is the so the validation
// process can then ask if all arguments or options have been recognised
// other an error will occurred "argument not recognised". For example
// this can be used to consume the "--" text which is not an argument in
// itself. Normally the GetValue() function (in base class) would return
// a value for the argument but is not the case for *this argument type
// object.
// Based on the Interpreter pattern.
// Gotchas: None.
// Authors: Illya Rudkin 20/05/2014.
// Changes: None.
//--
class CMICmdArgValConsume : public CMICmdArgValBaseTemplate< CMIUtilString >
{
// Methods:
public:
/* ctor */ CMICmdArgValConsume( void );
/* ctor */ CMICmdArgValConsume( const CMIUtilString & vrArgName, const bool vbMandatory );
//
bool IsOk( void ) const;
// Overridden:
public:
// From CMICmdArgValBase
/* dtor */ virtual ~CMICmdArgValConsume( void );
// From CMICmdArgSet::IArg
virtual bool Validate( CMICmdArgContext & vwArgContext );
};

View File

@ -28,6 +28,7 @@
#include "MICmdArgValOptionShort.h"
#include "MICmdArgValString.h"
#include "MICmdArgValThreadGrp.h"
#include "MICmdArgValConsume.h"
//++ ------------------------------------------------------------------------------------
// Details: CMICmdArgValListBase constructor.
@ -125,6 +126,9 @@ CMICmdArgValBase * CMICmdArgValListBase::CreationObj( const CMIUtilString & vrTx
case eArgValType_File:
pOptionObj = new CMICmdArgValFile();
break;
case eArgValType_Consume:
pOptionObj = new CMICmdArgValConsume();
break;
case eArgValType_Number:
pOptionObj = new CMICmdArgValNumber();
break;
@ -137,6 +141,15 @@ CMICmdArgValBase * CMICmdArgValListBase::CreationObj( const CMIUtilString & vrTx
case eArgValType_String:
pOptionObj = new CMICmdArgValString();
break;
case eArgValType_StringQuoted:
pOptionObj = new CMICmdArgValString( true, false, false );
break;
case eArgValType_StringQuotedNumber:
pOptionObj = new CMICmdArgValString( true, true, false );
break;
case eArgValType_StringQuotedNumberPath:
pOptionObj = new CMICmdArgValString( true, true, true );
break;
case eArgValType_ThreadGrp:
pOptionObj = new CMICmdArgValThreadGrp();
break;
@ -167,6 +180,9 @@ bool CMICmdArgValListBase::IsExpectedCorrectType( const CMIUtilString & vrTxt, c
case eArgValType_File:
bValid = CMICmdArgValFile().IsFilePath( vrTxt );
break;
case eArgValType_Consume:
bValid = CMICmdArgValConsume().IsOk();
break;
case eArgValType_Number:
bValid = CMICmdArgValNumber().IsArgNumber( vrTxt );
break;
@ -179,6 +195,15 @@ bool CMICmdArgValListBase::IsExpectedCorrectType( const CMIUtilString & vrTxt, c
case eArgValType_String:
bValid = CMICmdArgValString().IsStringArg( vrTxt );
break;
case eArgValType_StringQuoted:
bValid = CMICmdArgValString( true, false, false ).IsStringArg( vrTxt );
break;
case eArgValType_StringQuotedNumber:
bValid = CMICmdArgValString( true, true, false ).IsStringArg( vrTxt );
break;
case eArgValType_StringQuotedNumberPath:
bValid = CMICmdArgValString( true, true, true ).IsStringArg( vrTxt );
break;
case eArgValType_ThreadGrp:
bValid = CMICmdArgValThreadGrp().IsArgThreadGrp( vrTxt );
break;

View File

@ -63,10 +63,14 @@ public:
enum ArgValType_e
{
eArgValType_File = 0,
eArgValType_Consume,
eArgValType_Number,
eArgValType_OptionLong,
eArgValType_OptionShort,
eArgValType_String,
eArgValType_StringQuoted,
eArgValType_StringQuotedNumber,
eArgValType_StringQuotedNumberPath,
eArgValType_ThreadGrp,
eArgValType_count, // Always the last one
eArgValType_invalid

View File

@ -109,7 +109,17 @@ bool CMICmdArgValListOfN::Validate( CMICmdArgContext & vwArgContext )
bool CMICmdArgValListOfN::CreateList( const CMIUtilString & vrTxt )
{
CMIUtilString::VecString_t vecOptions;
vrTxt.Split( " ", vecOptions );
if( (m_eArgType == eArgValType_StringQuoted) ||
(m_eArgType == eArgValType_StringQuotedNumber) ||
(m_eArgType == eArgValType_StringQuotedNumberPath) )
{
if( vrTxt.SplitConsiderQuotes( " ", vecOptions ) == 0 )
return MIstatus::failure;
}
else
if( vrTxt.Split( " ", vecOptions ) == 0 )
return MIstatus::failure;
CMIUtilString::VecString_t::const_iterator it = vecOptions.begin();
while( it != vecOptions.end() )
{
@ -137,8 +147,16 @@ bool CMICmdArgValListOfN::CreateList( const CMIUtilString & vrTxt )
bool CMICmdArgValListOfN::IsListOfN( const CMIUtilString & vrTxt ) const
{
CMIUtilString::VecString_t vecOptions;
if( vrTxt.Split( " ", vecOptions ) == 0 )
return false;
if ( m_eArgType == eArgValType_StringQuoted ||
m_eArgType == eArgValType_StringQuotedNumber ||
m_eArgType == eArgValType_StringQuotedNumberPath )
{
if( vrTxt.SplitConsiderQuotes( " ", vecOptions ) == 0 )
return false;
}
else
if( vrTxt.Split( " ", vecOptions ) == 0 )
return false;
CMIUtilString::VecString_t::const_iterator it = vecOptions.begin();
while( it != vecOptions.end() )

View File

@ -40,7 +40,7 @@ class CMICmdArgContext;
// to this container and will be deleted when *this object goes out of
// scope.
// To parse arguments like 'thread-id ...' i.e. 1 10 12 13 ...
// If vbMandatory argument is true it takes on the (...)+ specfication
// If vbMandatory argument is true it takes on the (...)+ specification
// otherwise assumed to be (...)* specification.
// Based on the Interpreter pattern.
// Gotchas: None.
@ -76,6 +76,8 @@ private:
// parsed from the command's options string.
// Type: Template method.
// Args: vrwValue - (W) Templated type return value.
// T1 - The argument value's class type of the data hold in the list of options.
// T2 - The type pf the variable which holds the value wanted.
// Return: MIstatus::success - Functional succeeded.
// MIstatus::failure - Functional failed. List of object was empty.
// Throws: None.

View File

@ -126,6 +126,10 @@ bool CMICmdArgValNumber::Validate( CMICmdArgContext & vwArgContext )
//--
bool CMICmdArgValNumber::IsArgNumber( const CMIUtilString & vrTxt ) const
{
// Look for --someLongOption
if( std::string::npos != vrTxt.find( "--" ) )
return false;
return vrTxt.IsNumber();
}

View File

@ -143,6 +143,7 @@ bool CMICmdArgValOptionLong::Validate( CMICmdArgContext & vwArgContext )
}
// More than one option...
MIuint nArgIndex = 0;
const CMIUtilString::VecString_t vecOptions( vwArgContext.GetArgs() );
CMIUtilString::VecString_t::const_iterator it = vecOptions.begin();
while( it != vecOptions.end() )
@ -157,7 +158,7 @@ bool CMICmdArgValOptionLong::Validate( CMICmdArgContext & vwArgContext )
if( m_nExpectingNOptions != 0 )
{
if( ExtractExpectedOptions( vwArgContext ) )
if( ExtractExpectedOptions( vwArgContext, nArgIndex ) )
{
m_bValid = true;
return MIstatus::success;
@ -175,6 +176,7 @@ bool CMICmdArgValOptionLong::Validate( CMICmdArgContext & vwArgContext )
// Next
++it;
++nArgIndex;
}
return MIstatus::failure;
@ -185,43 +187,56 @@ bool CMICmdArgValOptionLong::Validate( CMICmdArgContext & vwArgContext )
// CMICmdArgValListBase::m_eArgType forming argument objects for each of those
// options extracted.
// Type: Method.
// Args: vrwTxt - (RW) The command's argument options string.
// Args: vrwTxt - (RW) The command's argument options string.
// nArgIndex - (R) The Nth arg position in argument context from the left.
// Return: MIstatus::success - Functional succeeded.
// MIstatus::failure - Functional failed.
// Throws: None.
//--
bool CMICmdArgValOptionLong::ExtractExpectedOptions( CMICmdArgContext & vrwTxt )
bool CMICmdArgValOptionLong::ExtractExpectedOptions( CMICmdArgContext & vrwTxt, const MIuint nArgIndex )
{
CMIUtilString::VecString_t vecOptions;
const MIuint nOptionsPresent = vrwTxt.GetArgsLeftToParse().Split( " ", vecOptions );
MIuint nOptionsPresent = 0;
if( (m_eExpectingOptionType != eArgValType_StringQuoted) &&
(m_eExpectingOptionType != eArgValType_StringQuotedNumber) &&
(m_eExpectingOptionType != eArgValType_StringQuotedNumberPath) )
nOptionsPresent = vrwTxt.GetArgsLeftToParse().Split( " ", vecOptions );
else
nOptionsPresent = vrwTxt.GetArgsLeftToParse().SplitConsiderQuotes( " ", vecOptions );
if( nOptionsPresent == 0 )
return MIstatus::failure;
MIuint nArgIndexCnt = 0;
MIuint nTypeCnt = 0;
MIuint nTypeCnt2 = 0;
MIuint nFoundNOptionsCnt = 0;
CMIUtilString::VecString_t::const_iterator it = vecOptions.begin();
while( it != vecOptions.end() )
{
nTypeCnt++;
const CMIUtilString & rOption( *it );
if( IsExpectedCorrectType( rOption, m_eExpectingOptionType ) )
// Move to the Nth argument position from left before do validation/checking
if( nArgIndexCnt++ == nArgIndex )
{
nTypeCnt2++;
CMICmdArgValBase * pOptionObj = CreationObj( rOption, m_eExpectingOptionType );
if( (pOptionObj != nullptr) && vrwTxt.RemoveArg( rOption ) )
nTypeCnt++;
const CMIUtilString & rOption( *it );
if( IsExpectedCorrectType( rOption, m_eExpectingOptionType ) )
{
nFoundNOptionsCnt++;
m_vecArgsExpected.push_back( pOptionObj );
nTypeCnt2++;
CMICmdArgValBase * pOptionObj = CreationObj( rOption, m_eExpectingOptionType );
if( (pOptionObj != nullptr) && vrwTxt.RemoveArgAtPos( rOption, nArgIndex ) )
{
nFoundNOptionsCnt++;
m_vecArgsExpected.push_back( pOptionObj );
}
}
}
// Is the sequence 'options' of same type broken. Expecting the same type until the
// next argument.
if( nTypeCnt != nTypeCnt2 )
return MIstatus::failure;
if( nFoundNOptionsCnt == m_nExpectingNOptions )
return MIstatus::success;
// Is the sequence 'options' of same type broken. Expecting the same type until the
// next argument.
if( nTypeCnt != nTypeCnt2 )
return MIstatus::failure;
if( nFoundNOptionsCnt == m_nExpectingNOptions )
return MIstatus::success;
}
// Next
++it;

View File

@ -64,7 +64,7 @@ public:
// Methods:
protected:
bool ExtractExpectedOptions( CMICmdArgContext & vrwTxt );
bool ExtractExpectedOptions( CMICmdArgContext & vrwTxt, const MIuint nArgIndex );
// Overrideable:
protected:
@ -87,6 +87,8 @@ private:
// parsed from the command's options string.
// Type: Template method.
// Args: vrwValue - (W) Templated type return value.
// T1 - The argument value's class type of the data hold in the list of options.
// T2 - The type pf the variable which holds the value wanted.
// Return: MIstatus::success - Functional succeeded.
// MIstatus::failure - Functional failed. List of object was empty.
// Throws: None.

View File

@ -31,6 +31,25 @@
// Throws: None.
//--
CMICmdArgValString::CMICmdArgValString( void )
: m_bHandleQuotedString( false )
, m_bAcceptNumbers( false )
, m_bHandleDirPaths( false )
{
}
//++ ------------------------------------------------------------------------------------
// Details: CMICmdArgValString constructor.
// Type: Method.
// Args: vbHandleQuotes - (R) True = Parse a string surrounded by quotes spaces are not delimitors, false = only text up to next delimiting space character.
// vbAcceptNumbers - (R) True = Parse a string and accept as a number if number, false = numbers not recognised as string types.
// vbHandleDirPaths - (R) True = Parse a string and accept as a file path if a path, false = file paths are not recognised as string types.
// Return: None.
// Throws: None.
//--
CMICmdArgValString::CMICmdArgValString( const bool vbHandleQuotes, const bool vbAcceptNumbers, const bool vbHandleDirPaths )
: m_bHandleQuotedString( vbHandleQuotes )
, m_bAcceptNumbers( vbAcceptNumbers )
, m_bHandleDirPaths( vbHandleDirPaths )
{
}
@ -41,12 +60,15 @@ CMICmdArgValString::CMICmdArgValString( void )
// vbMandatory - (R) True = Yes must be present, false = optional argument.
// vbHandleByCmd - (R) True = Command processes *this option, false = not handled.
// vbHandleQuotes - (R) True = Parse a string surrounded by quotes spaces are not delimitors, false = only text up to next delimiting space character. (Dflt = false)
// vbAcceptNumbers - (R) True = Parse a string and accept as a number if number, false = numbers not recognised as string types. (Dflt = false)
// Return: None.
// Throws: None.
//--
CMICmdArgValString::CMICmdArgValString( const CMIUtilString & vrArgName, const bool vbMandatory, const bool vbHandleByCmd, const bool vbHandleQuotes /* = false */ )
CMICmdArgValString::CMICmdArgValString( const CMIUtilString & vrArgName, const bool vbMandatory, const bool vbHandleByCmd, const bool vbHandleQuotes /* = false */, const bool vbAcceptNumbers /* = false */ )
: CMICmdArgValBaseTemplate( vrArgName, vbMandatory, vbHandleByCmd )
, m_bHandleQuotedString( vbHandleQuotes )
, m_bAcceptNumbers( vbAcceptNumbers )
, m_bHandleDirPaths( false )
{
}
@ -145,8 +167,10 @@ bool CMICmdArgValString::ValidateSingleText( CMICmdArgContext & vrwArgContext )
//--
bool CMICmdArgValString::ValidateQuotedText( CMICmdArgContext & vrwArgContext )
{
// CODETAG_QUOTEDTEXT_SIMILAR_CODE
const CMIUtilString strOptions = vrwArgContext.GetArgsLeftToParse();
const MIint nPos = strOptions.find( '"' );
const MIchar cQuote = '"';
const MIint nPos = strOptions.find( cQuote );
if( nPos == (MIint) std::string::npos )
return ValidateSingleText( vrwArgContext );
@ -159,7 +183,7 @@ bool CMICmdArgValString::ValidateQuotedText( CMICmdArgContext & vrwArgContext )
return MIstatus::failure;
// Need to find the other quote
const MIint nPos2 = strOptions.find( '"', nPos + 1 );
const MIint nPos2 = strOptions.find( cQuote, nPos + 1 );
if( nPos2 == (MIint) std::string::npos )
return MIstatus::failure;
@ -185,34 +209,78 @@ bool CMICmdArgValString::ValidateQuotedText( CMICmdArgContext & vrwArgContext )
//--
bool CMICmdArgValString::IsStringArg( const CMIUtilString & vrTxt ) const
{
const bool bHavePosSlash = (vrTxt.find_first_of( "/" ) != std::string::npos);
const bool bHaveBckSlash = (vrTxt.find_first_of( "\\" ) != std::string::npos);
if( bHavePosSlash || bHaveBckSlash )
return false;
if( m_bHandleQuotedString )
return IsStringArgQuotedText( vrTxt );
return IsStringArgSingleText( vrTxt );
}
// Look for --someLongOption
if( std::string::npos != vrTxt.find( "--" ) )
return false;
// Look for -f type short parameters
const MIint nPos2 = vrTxt.find( "-" );
if( (MIint) std::string::npos != nPos2 )
//++ ------------------------------------------------------------------------------------
// Details: Examine the string and determine if it is a valid string type argument or
// option value. If the string looks like a long option, short option, a thread
// group ID or just a number it is rejected as a string type value. There is an
// option to allow the string to accept a number as a string type.
// Type: Method.
// Args: vrTxt - (R) Some text.
// Return: bool - True = yes valid argument value, false = something else.
// Throws: None.
//--
bool CMICmdArgValString::IsStringArgSingleText( const CMIUtilString & vrTxt ) const
{
if( !m_bHandleDirPaths )
{
if( (MIint) vrTxt.length() > (nPos2 + 1) )
{
const CMIUtilString s = vrTxt.substr( 1 ).c_str();
if( s.IsNumber() )
return false;
}
// Look for directory file paths, if found reject
const bool bHavePosSlash = (vrTxt.find_first_of( "/" ) != std::string::npos);
const bool bHaveBckSlash = (vrTxt.find_first_of( "\\" ) != std::string::npos);
if( bHavePosSlash || bHaveBckSlash )
return false;
}
// Look for i1 i2 i3....
const MIint nPos = vrTxt.find_first_of( "i" );
const bool bFoundI1 = ((nPos == 0) && (::isdigit( vrTxt[ 1 ] )) );
if( bFoundI1 )
// Look for --someLongOption, if found reject
if( 0 == vrTxt.find( "--" ) )
return false;
if( vrTxt.IsNumber() )
// Look for -f type short options, if found reject
if( (0 == vrTxt.find( "-" )) && (vrTxt.length() == 2 ) )
return false;
// Look for thread group i1 i2 i3...., if found reject
if( (vrTxt.find( "i" ) == 0) && (::isdigit( vrTxt[ 1 ] )) )
return false;
// Look for numbers, if found reject
if( !m_bAcceptNumbers && vrTxt.IsNumber() )
return false;
return true;
}
//++ ------------------------------------------------------------------------------------
// Details: Examine the string and determine if it is a valid string type argument.
// Type: Method.
// Args: vrTxt - (R) Some text.
// Return: bool - True = yes valid arg, false = no.
// Throws: None.
//--
bool CMICmdArgValString::IsStringArgQuotedText( const CMIUtilString & vrTxt ) const
{
// CODETAG_QUOTEDTEXT_SIMILAR_CODE
const MIchar cQuote = '"';
const MIint nPos = vrTxt.find( cQuote );
if( nPos == (MIint) std::string::npos )
return IsStringArgSingleText( vrTxt );
// Is one and only quote at end of the string
if( nPos == (MIint)(vrTxt.length() - 1) )
return false;
// Quote must be the first character in the string or be preceeded by a space
if( (nPos > 0) && (vrTxt[ nPos - 1 ] != ' ' ) )
return false;
// Need to find the other quote
const MIint nPos2 = vrTxt.find( cQuote, nPos + 1 );
if( nPos2 == (MIint) std::string::npos )
return false;
return true;

View File

@ -43,7 +43,8 @@ class CMICmdArgValString : public CMICmdArgValBaseTemplate< CMIUtilString >
// Methods:
public:
/* ctor */ CMICmdArgValString( void );
/* ctor */ CMICmdArgValString( const CMIUtilString & vrArgName, const bool vbMandatory, const bool vbHandleByCmd, const bool vbHandleQuotes = false );
/* ctor */ CMICmdArgValString( const bool vbHandleQuotes, const bool vbAcceptNumbers, const bool vbHandleDirPaths );
/* ctor */ CMICmdArgValString( const CMIUtilString & vrArgName, const bool vbMandatory, const bool vbHandleByCmd, const bool vbHandleQuotes = false, const bool vbAcceptNumbers = false );
//
bool IsStringArg( const CMIUtilString & vrTxt ) const;
@ -58,8 +59,12 @@ public:
private:
bool ValidateSingleText( CMICmdArgContext & vrwArgContext );
bool ValidateQuotedText( CMICmdArgContext & vrwArgContext );
bool IsStringArgSingleText( const CMIUtilString & vrTxt ) const;
bool IsStringArgQuotedText( const CMIUtilString & vrTxt ) const;
// Attribute:
private:
bool m_bHandleQuotedString; // True = Parse a string surrounded by quotes spaces are not delimitors, false = only text up to next delimiting space character
bool m_bAcceptNumbers; // True = Parse a string and accept as a number if number, false = numbers not recognised as string types
bool m_bHandleDirPaths; // True = Parse a string and accept directory file style string if present, false = directory file path not accepted
};

View File

@ -169,5 +169,4 @@ bool CMICmdArgValThreadGrp::ExtractNumber( const CMIUtilString & vrTxt )
MIuint CMICmdArgValThreadGrp::GetNumber( void ) const
{
return m_nThreadGrp;
}
}

View File

@ -187,7 +187,7 @@ void CMICmdBase::SetError( const CMIUtilString & rErrMsg )
m_cmdData.bCmdExecutedSuccessfully = false;
const CMICmnMIValueResult valueResult( "msg", CMICmnMIValueConst( rErrMsg ) );
const CMICmnMIResultRecord miResultRecord( m_cmdData.nMiCmdNumber, CMICmnMIResultRecord::eResultClass_Error, valueResult );
const CMICmnMIResultRecord miResultRecord( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, valueResult );
m_miResultRecord = miResultRecord;
m_cmdData.strMiCmdResultRecord = miResultRecord.GetString();
}
@ -223,4 +223,4 @@ bool CMICmdBase::ParseArgs( void )
return MIstatus::success;
}

View File

@ -46,7 +46,7 @@ class CMICmnLLDBDebugSessionInfo;
// does some work then wakes up again when called back, does more work
// perhaps, ends, then the Invoker calls the command's Acknowledge
// function. The other type of command is one that just does some work,
// ends, then the Invoker calls the commmand's Acknowledge function. No
// ends, then the Invoker calls the command's Acknowledge function. No
// events set up.
// A command's Execute(), Acknowledge() and event callback functions are
// carried out in the main thread.
@ -100,7 +100,7 @@ protected:
CMIUtilString m_strCurrentErrDescription; // Reason for Execute or Acknowledge function failure
SMICmdData m_cmdData; // Holds information/status of *this command. Used by other MI code to report or determine state of a command.
bool m_bWaitForEventFromSBDebugger; // True = yes event type command wait, false = command calls Acknowledge() straight after Execute() no waiting
CMIUtilString m_strMiCmd; // The MI text identifying *this commmand i.e. 'break-insert'
CMIUtilString m_strMiCmd; // The MI text identifying *this command i.e. 'break-insert'
CMICmnMIResultRecord m_miResultRecord; // This is completed in the Acknowledge() function and returned to the Command Invoker to proceed stdout output. Each command forms 1 response to its input.
CMIUtilString m_miResultRecordExtra; // This is completed in the Acknowledge() function and returned to the Command Invoker to proceed stdout output. Hack command produce more response text to help the client because of using LLDB
CMICmnLLDBDebugSessionInfo & m_rLLDBDebugSessionInfo; // Access to command sharing information or data across any and all command based derived classes.

View File

@ -63,7 +63,7 @@ CMICmdCmdEnablePrettyPrinting::CMICmdCmdEnablePrettyPrinting( void )
// Command factory matches this name with that received from the stdin stream
m_strMiCmd = "enable-pretty-printing";
// Required by the CMICmdFactory when registering *this commmand
// Required by the CMICmdFactory when registering *this command
m_pSelfCreatorFn = &CMICmdCmdEnablePrettyPrinting::CreateSelf;
}
@ -106,14 +106,14 @@ bool CMICmdCmdEnablePrettyPrinting::Acknowledge( void )
{
const CMICmnMIValueConst miValueConst( "0" );
const CMICmnMIValueResult miValueResult( "supported", miValueConst );
const CMICmnMIResultRecord miRecordResult( m_cmdData.nMiCmdNumber, CMICmnMIResultRecord::eResultClass_Done, miValueResult );
const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult );
m_miResultRecord = miRecordResult;
return MIstatus::success;
}
//++ ------------------------------------------------------------------------------------
// Details: Required by the CMICmdFactory when registering *this commmand. The factory
// Details: Required by the CMICmdFactory when registering *this command. The factory
// calls this function to create an instance of *this command.
// Type: Static method.
// Args: None.
@ -141,7 +141,7 @@ CMICmdCmdSource::CMICmdCmdSource( void )
// Command factory matches this name with that received from the stdin stream
m_strMiCmd = "source";
// Required by the CMICmdFactory when registering *this commmand
// Required by the CMICmdFactory when registering *this command
m_pSelfCreatorFn = &CMICmdCmdSource::CreateSelf;
}
@ -182,14 +182,14 @@ bool CMICmdCmdSource::Execute( void )
//--
bool CMICmdCmdSource::Acknowledge( void )
{
const CMICmnMIResultRecord miRecordResult( m_cmdData.nMiCmdNumber, CMICmnMIResultRecord::eResultClass_Done );
const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done );
m_miResultRecord = miRecordResult;
return MIstatus::success;
}
//++ ------------------------------------------------------------------------------------
// Details: Required by the CMICmdFactory when registering *this commmand. The factory
// Details: Required by the CMICmdFactory when registering *this command. The factory
// calls this function to create an instance of *this command.
// Type: Static method.
// Args: None.
@ -199,4 +199,4 @@ bool CMICmdCmdSource::Acknowledge( void )
CMICmdBase * CMICmdCmdSource::CreateSelf( void )
{
return new CMICmdCmdSource();
}
}

View File

@ -59,7 +59,7 @@ class CMICmdCmdEnablePrettyPrinting : public CMICmdBase
{
// Statics:
public:
// Required by the CMICmdFactory when registering *this commmand
// Required by the CMICmdFactory when registering *this command
static CMICmdBase * CreateSelf( void );
// Methods:
@ -71,9 +71,6 @@ public:
// From CMICmdInvoker::ICmd
virtual bool Execute( void );
virtual bool Acknowledge( void );
// Overridden:
public:
// From CMICmnBase
/* dtor */ virtual ~CMICmdCmdEnablePrettyPrinting( void );
};
@ -90,7 +87,7 @@ class CMICmdCmdSource
{
// Statics:
public:
// Required by the CMICmdFactory when registering *this commmand
// Required by the CMICmdFactory when registering *this command
static CMICmdBase * CreateSelf( void );
// Methods:
@ -102,9 +99,6 @@ public:
// From CMICmdInvoker::ICmd
virtual bool Execute( void );
virtual bool Acknowledge( void );
// Overridden:
public:
// From CMICmnBase
/* dtor */ virtual ~CMICmdCmdSource( void );
};

View File

@ -12,6 +12,10 @@
//
// Overview: CMICmdCmdBreakInsert implementation.
// CMICmdCmdBreakDelete implementation.
// CMICmdCmdBreakDisable implementation.
// CMICmdCmdBreakEnable implementation.
// CMICmdCmdBreakAfter implementation.
// CMICmdCmdBreakCondition implementation.
//
// Environment: Compilers: Visual C++ 12.
// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
@ -28,6 +32,7 @@
#include "MICmdCmdBreak.h"
#include "MICmnMIResultRecord.h"
#include "MICmnMIValueConst.h"
#include "MICmnMIOutOfBandRecord.h"
#include "MICmnLLDBDebugger.h"
#include "MICmnLLDBDebugSessionInfo.h"
#include "MICmdArgContext.h"
@ -38,6 +43,7 @@
#include "MICmdArgValOptionLong.h"
#include "MICmdArgValOptionShort.h"
#include "MICmdArgValListOfN.h"
#include "MICmnStreamStdout.h"
//++ ------------------------------------------------------------------------------------
// Details: CMICmdCmdBreakInsert constructor.
@ -48,7 +54,12 @@
//--
CMICmdCmdBreakInsert::CMICmdCmdBreakInsert( void )
: m_bBrkPtIsTemp( false )
, m_brkName()
, m_bBrkPtIsPending( false )
, m_nBrkPtIgnoreCount( 0 )
, m_bBrkPtEnabled( false )
, m_bBrkPtCondition( false )
, m_bBrkPtThreadId( false )
, m_nBrkPtThreadId( 0 )
, m_constStrArgNamedTempBrkPt( "t" )
, m_constStrArgNamedHWBrkPt( "h" )
, m_constStrArgNamedPendinfBrkPt( "f" )
@ -63,7 +74,7 @@ CMICmdCmdBreakInsert::CMICmdCmdBreakInsert( void )
// Command factory matches this name with that received from the stdin stream
m_strMiCmd = "break-insert";
// Required by the CMICmdFactory when registering *this commmand
// Required by the CMICmdFactory when registering *this command
m_pSelfCreatorFn = &CMICmdCmdBreakInsert::CreateSelf;
}
@ -90,13 +101,13 @@ CMICmdCmdBreakInsert::~CMICmdCmdBreakInsert( void )
bool CMICmdCmdBreakInsert::ParseArgs( void )
{
bool bOk = m_setCmdArgs.Add( *(new CMICmdArgValOptionShort( m_constStrArgNamedTempBrkPt, false, true )) );
bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValOptionShort( m_constStrArgNamedHWBrkPt, false, false ) ) );
bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValOptionShort( m_constStrArgNamedPendinfBrkPt, false, false ) ) );
//Not implemented bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValOptionShort( m_constStrArgNamedHWBrkPt, false, false ) ) );
bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValOptionShort( m_constStrArgNamedPendinfBrkPt, false, true, CMICmdArgValListBase::eArgValType_String, 1 ) ) );
bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValOptionShort( m_constStrArgNamedDisableBrkPt, false, false ) ) );
bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValOptionShort( m_constStrArgNamedTracePt, false, false ) ) );
bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValOptionShort( m_constStrArgNamedConditionalBrkPt, false, false ) ) );
bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValOptionShort( m_constStrArgNamedInoreCnt, false, false ) ) );
bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValOptionShort( m_constStrArgNamedRestrictBrkPtToThreadId, false, false ) ) );
//Not implemented bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValOptionShort( m_constStrArgNamedTracePt, false, false ) ) );
bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValOptionShort( m_constStrArgNamedConditionalBrkPt, false, true, CMICmdArgValListBase::eArgValType_StringQuoted, 1 ) ) );
bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValOptionShort( m_constStrArgNamedInoreCnt, false, true, CMICmdArgValListBase::eArgValType_Number, 1 ) ) );
bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValOptionShort( m_constStrArgNamedRestrictBrkPtToThreadId, false, true, CMICmdArgValListBase::eArgValType_Number, 1 ) ) );
bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValString( m_constStrArgNamedLocation, false, true ) ) );
bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValOptionLong( m_constStrArgNamedThreadGroup, false, true, CMICmdArgValListBase::eArgValType_ThreadGrp, 1 ) ) );
CMICmdArgContext argCntxt( m_cmdData.strMiCmdOption );
@ -120,27 +131,49 @@ bool CMICmdCmdBreakInsert::ParseArgs( void )
//--
bool CMICmdCmdBreakInsert::Execute( void )
{
// Note not all arguments required ATM based on C's version off the code
CMICMDBASE_GETOPTION( pArgTempBrkPt, OptionShort, m_constStrArgNamedTempBrkPt );
CMICMDBASE_GETOPTION( pArgThreadGroup, OptionLong, m_constStrArgNamedThreadGroup );
CMICMDBASE_GETOPTION( pArgLocation, String, m_constStrArgNamedLocation );
CMICMDBASE_GETOPTION( pArgIgnoreCnt, OptionShort, m_constStrArgNamedInoreCnt );
CMICMDBASE_GETOPTION( pArgPendingBrkPt, OptionShort, m_constStrArgNamedPendinfBrkPt );
CMICMDBASE_GETOPTION( pArgDisableBrkPt, OptionShort, m_constStrArgNamedDisableBrkPt );
CMICMDBASE_GETOPTION( pArgConditionalBrkPt, OptionShort, m_constStrArgNamedConditionalBrkPt );
CMICMDBASE_GETOPTION( pArgRestrictBrkPtToThreadId, OptionShort, m_constStrArgNamedRestrictBrkPtToThreadId );
m_bBrkPtEnabled = !pArgDisableBrkPt->GetFound();
m_bBrkPtIsTemp = pArgTempBrkPt->GetFound();
m_bHaveArgOptionThreadGrp = pArgThreadGroup->GetFound();
if( m_bHaveArgOptionThreadGrp )
{
const CMICmdArgValOptionLong::VecArgObjPtr_t & rVecOptions( pArgThreadGroup->GetExpectedOptions() );
const CMICmdArgValThreadGrp * pThreadGrp = (rVecOptions.size() > 0) ? static_cast< CMICmdArgValThreadGrp * >( rVecOptions[ 0 ] ) : nullptr;
const MIuint nThreadGrp = (pThreadGrp != nullptr) ? pThreadGrp->GetValue() : 0;
m_strArgOptionThreadGrp = CMIUtilString::Format( "%d", nThreadGrp );
MIuint nThreadGrp = 0;
pArgThreadGroup->GetExpectedOption< CMICmdArgValThreadGrp, MIuint >( nThreadGrp );
m_strArgOptionThreadGrp = CMIUtilString::Format( "i%d", nThreadGrp );
}
m_brkName = pArgLocation->GetFound() ? pArgLocation->GetValue() : "";
m_bBrkPtIsPending = pArgPendingBrkPt->GetFound();
if( pArgLocation->GetFound() )
m_brkName = pArgLocation->GetValue();
else if( m_bBrkPtIsPending )
{
pArgPendingBrkPt->GetExpectedOption< CMICmdArgValString, CMIUtilString >( m_brkName );
}
if( pArgIgnoreCnt->GetFound() )
{
pArgIgnoreCnt->GetExpectedOption< CMICmdArgValNumber, MIuint >( m_nBrkPtIgnoreCount );
}
m_bBrkPtCondition = pArgConditionalBrkPt->GetFound();
if( m_bBrkPtCondition )
{
pArgConditionalBrkPt->GetExpectedOption< CMICmdArgValString, CMIUtilString >( m_brkPtCondition );
}
m_bBrkPtThreadId = pArgRestrictBrkPtToThreadId->GetFound();
if( m_bBrkPtCondition )
{
pArgRestrictBrkPtToThreadId->GetExpectedOption< CMICmdArgValNumber, MIuint >( m_nBrkPtThreadId );
}
// Determine if break on a file line or at a function
BreakPoint_e eBrkPtType = eBreakPoint_NotDefineYet;
const CMIUtilString cColon = ":";
bool bIsFileLine = false;
bool bIsFileFn = false;
CMIUtilString fileName;
MIuint nFileLine = 0;
CMIUtilString strFileFn;
@ -148,7 +181,7 @@ bool CMICmdCmdBreakInsert::Execute( void )
if( nPosColon != (MIint) std::string::npos )
{
CMIUtilString::VecString_t vecFileAndLocation;
const MIuint nSplits = m_brkName.Split( cColon, vecFileAndLocation );
const MIuint nSplits = m_brkName.Split( cColon, vecFileAndLocation ); MIunused( nSplits );
if( vecFileAndLocation.size() != 2 )
{
SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_BRKPT_LOCATION_FORMAT ), m_cmdData.strMiCmd.c_str(), m_brkName.c_str() ) );
@ -216,7 +249,38 @@ bool CMICmdCmdBreakInsert::Execute( void )
bOk = MIstatus::failure;
break;
}
if( !m_brkPt.IsValid() || !bOk )
if( bOk )
{
m_brkPt.SetEnabled( m_bBrkPtEnabled );
m_brkPt.SetIgnoreCount( m_nBrkPtIgnoreCount );
if( m_bBrkPtCondition )
m_brkPt.SetCondition( m_brkPtCondition.c_str() );
if( m_bBrkPtThreadId )
m_brkPt.SetThreadID( m_nBrkPtThreadId );
if( !m_brkPt.IsValid() )
m_bBrkPtIsPending = pArgPendingBrkPt->GetFound();
}
// CODETAG_LLDB_BREAKPOINT_CREATION
// This is in the main thread
// Record break point information to be by LLDB event handler function
CMICmnLLDBDebugSessionInfo::SBrkPtInfo sBrkPtInfo;
sBrkPtInfo.m_id = m_brkPt.GetID();
sBrkPtInfo.m_bDisp = m_bBrkPtIsTemp;
sBrkPtInfo.m_bEnabled = m_bBrkPtEnabled;
sBrkPtInfo.m_bHaveArgOptionThreadGrp = m_bHaveArgOptionThreadGrp;
sBrkPtInfo.m_strOptThrdGrp = m_strArgOptionThreadGrp;
sBrkPtInfo.m_strOrigLoc = m_brkName;
sBrkPtInfo.m_nIgnore = m_nBrkPtIgnoreCount;
sBrkPtInfo.m_bPending = m_bBrkPtIsPending;
sBrkPtInfo.m_bCondition = m_bBrkPtCondition;
sBrkPtInfo.m_strCondition = m_brkPtCondition;
sBrkPtInfo.m_bBrkPtThreadId = m_bBrkPtThreadId;
sBrkPtInfo.m_nBrkPtThreadId = m_nBrkPtThreadId;
bOk = bOk && rSessionInfo.RecordBrkPtInfo( m_brkPt.GetID(), sBrkPtInfo );
if( !bOk )
{
SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_BRKPT_INVALID ), m_cmdData.strMiCmd.c_str(), m_brkName.c_str() ) );
return MIstatus::failure;
@ -243,63 +307,43 @@ bool CMICmdCmdBreakInsert::Acknowledge( void )
{
// Get breakpoint information
CMICmnLLDBDebugSessionInfo & rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance() );
lldb::SBTarget & rTarget = rSessionInfo.m_lldbTarget;
lldb::SBBreakpointLocation brkPtLoc = m_brkPt.GetLocationAtIndex( 0 );
lldb::SBAddress brkPtAddr = brkPtLoc.GetAddress();
lldb::SBSymbolContext symbolCntxt = brkPtAddr.GetSymbolContext( lldb::eSymbolContextEverything );
const char * pUnkwn = "??";
lldb::SBModule rModule = symbolCntxt.GetModule();
const char * pModule = rModule.IsValid() ? rModule.GetFileSpec().GetFilename() : pUnkwn;
const char * pFile = pUnkwn;
const char * pFn = pUnkwn;
const char * pFilePath = pUnkwn;
size_t nLine = 0;
const size_t nAddr = brkPtAddr.GetLoadAddress( rTarget );
lldb::SBCompileUnit rCmplUnit = symbolCntxt.GetCompileUnit();
if( rCmplUnit.IsValid() )
CMICmnLLDBDebugSessionInfo::SBrkPtInfo sBrkPtInfo;
if( !rSessionInfo.GetBrkPtInfo( m_brkPt, sBrkPtInfo ) )
{
lldb::SBFileSpec rFileSpec = rCmplUnit.GetFileSpec();
pFile = rFileSpec.GetFilename();
pFilePath = rFileSpec.GetDirectory();
lldb::SBFunction rFn = symbolCntxt.GetFunction();
if( rFn.IsValid() )
pFn = rFn.GetName();
lldb::SBLineEntry rLnEntry = symbolCntxt.GetLineEntry();
if( rLnEntry.GetLine() > 0 )
nLine = rLnEntry.GetLine();
return MIstatus::failure;
}
// CODETAG_LLDB_BREAKPOINT_CREATION
// Add more breakpoint information or overwrite existing information
sBrkPtInfo.m_bDisp = m_bBrkPtIsTemp;
sBrkPtInfo.m_bEnabled = m_bBrkPtEnabled;
sBrkPtInfo.m_bHaveArgOptionThreadGrp = m_bHaveArgOptionThreadGrp;
sBrkPtInfo.m_strOptThrdGrp = m_strArgOptionThreadGrp;
sBrkPtInfo.m_nTimes = m_brkPt.GetNumLocations();
sBrkPtInfo.m_strOrigLoc = m_brkName;
sBrkPtInfo.m_nIgnore = m_nBrkPtIgnoreCount;
sBrkPtInfo.m_bPending = m_bBrkPtIsPending;
sBrkPtInfo.m_bCondition = m_bBrkPtCondition;
sBrkPtInfo.m_strCondition = m_brkPtCondition;
sBrkPtInfo.m_bBrkPtThreadId = m_bBrkPtThreadId;
sBrkPtInfo.m_nBrkPtThreadId = m_nBrkPtThreadId;
// Form MI result record example
// MI print "=breakpoint-modified,bkpt={number=\"%d\",type=\"breakpoint\",disp=\"%s\",enabled=\"%c\",addr=\"0x%08x\", func=\"%s\",file=\"%s\",fullname=\"%s/%s\",line=\"%d\",times=\"%d\",original-location=\"%s\"}"
// MI print "^done,bkpt={number=\"%d\",type=\"breakpoint\",disp=\"%s\",enabled=\"%c\",addr=\"0x%08x\",func=\"%s\",file=\"%s\",fullname=\"%s/%s\",line=\"%d\",thread-groups=[\"%s\"],times=\"%d\",original-location=\"%s\"}"
CMICmnMIValueTuple miValueTuple;
if( !CMICmnLLDBDebugSessionInfo::Instance().MIResponseFormBrkPtInfo( m_brkPt.GetID(), // "number="
"breakpoint", // "type="
m_bBrkPtIsTemp, // "disp="
m_brkPt.IsEnabled(), // "enabled="
nAddr, // "addr="
pFn, // "func="
pFile, // "file="
pFilePath, // "fullname="
nLine, // "line="
m_bHaveArgOptionThreadGrp, //
m_strArgOptionThreadGrp, // "thread-groups="
m_brkPt.GetNumLocations(), // "times="
m_brkName, // "original-location="
miValueTuple ))
if( !rSessionInfo.MIResponseFormBrkPtInfo( sBrkPtInfo, miValueTuple ) )
{
return MIstatus::failure;
}
const CMICmnMIValueResult miValueResultD( "bkpt", miValueTuple );
const CMICmnMIResultRecord miRecordResult( m_cmdData.nMiCmdNumber, CMICmnMIResultRecord::eResultClass_Done, miValueResultD );
const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResultD );
m_miResultRecord = miRecordResult;
return MIstatus::success;
}
//++ ------------------------------------------------------------------------------------
// Details: Required by the CMICmdFactory when registering *this commmand. The factory
// Details: Required by the CMICmdFactory when registering *this command. The factory
// calls this function to create an instance of *this command.
// Type: Static method.
// Args: None.
@ -324,12 +368,12 @@ CMICmdBase * CMICmdCmdBreakInsert::CreateSelf( void )
//--
CMICmdCmdBreakDelete::CMICmdCmdBreakDelete( void )
: m_constStrArgNamedBrkPt( "breakpoint" )
, m_constStrArgNamedThreadGrp( "thread-group")
, m_constStrArgNamedThreadGrp( "thread-group" )
{
// Command factory matches this name with that received from the stdin stream
m_strMiCmd = "break-delete";
// Required by the CMICmdFactory when registering *this commmand
// Required by the CMICmdFactory when registering *this command
m_pSelfCreatorFn = &CMICmdCmdBreakDelete::CreateSelf;
}
@ -384,16 +428,15 @@ bool CMICmdCmdBreakDelete::Execute( void )
MIuint64 nBrk = UINT64_MAX;
if( !pArgBrkPt->GetExpectedOption< CMICmdArgValNumber, MIuint64 >( nBrk ) )
{
const CMIUtilString errMsg( CMIUtilString::Format( MIRSRC( IDS_CMD_ARGS_ERR_N_OPTIONS_REQUIRED ), 1 ) );
SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_BRKPT_INVALID ), m_cmdData.strMiCmd.c_str(), errMsg.c_str() ) );
SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_BRKPT_INVALID ), m_cmdData.strMiCmd.c_str(), m_constStrArgNamedBrkPt.c_str() ) );
return MIstatus::failure;
}
const CMIUtilString strBrkNum( CMIUtilString::Format( "%d", nBrk ) );
CMICmnLLDBDebugSessionInfo & rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance() );
const bool bBrkPt = rSessionInfo.m_lldbTarget.BreakpointDelete( static_cast< lldb::break_id_t >( nBrk ) );
if( !bBrkPt )
{
const CMIUtilString strBrkNum( CMIUtilString::Format( "%d", nBrk ) );
SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_BRKPT_INVALID ), m_cmdData.strMiCmd.c_str(), strBrkNum.c_str() ) );
return MIstatus::failure;
}
@ -412,14 +455,14 @@ bool CMICmdCmdBreakDelete::Execute( void )
//--
bool CMICmdCmdBreakDelete::Acknowledge( void )
{
const CMICmnMIResultRecord miRecordResult( m_cmdData.nMiCmdNumber, CMICmnMIResultRecord::eResultClass_Done );
const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done );
m_miResultRecord = miRecordResult;
return MIstatus::success;
}
//++ ------------------------------------------------------------------------------------
// Details: Required by the CMICmdFactory when registering *this commmand. The factory
// Details: Required by the CMICmdFactory when registering *this command. The factory
// calls this function to create an instance of *this command.
// Type: Static method.
// Args: None.
@ -430,3 +473,596 @@ CMICmdBase * CMICmdCmdBreakDelete::CreateSelf( void )
{
return new CMICmdCmdBreakDelete();
}
//---------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------
//++ ------------------------------------------------------------------------------------
// Details: CMICmdCmdBreakDisable constructor.
// Type: Method.
// Args: None.
// Return: None.
// Throws: None.
//--
CMICmdCmdBreakDisable::CMICmdCmdBreakDisable( void )
: m_constStrArgNamedThreadGrp( "thread-group" )
, m_constStrArgNamedBrkPt( "breakpoint" )
, m_bBrkPtDisabledOk( false )
, m_nBrkPtId( 0 )
{
// Command factory matches this name with that received from the stdin stream
m_strMiCmd = "break-disable";
// Required by the CMICmdFactory when registering *this command
m_pSelfCreatorFn = &CMICmdCmdBreakDisable::CreateSelf;
}
//++ ------------------------------------------------------------------------------------
// Details: CMICmdCmdBreakDisable destructor.
// Type: Overrideable.
// Args: None.
// Return: None.
// Throws: None.
//--
CMICmdCmdBreakDisable::~CMICmdCmdBreakDisable( void )
{
}
//++ ------------------------------------------------------------------------------------
// Details: The invoker requires this function. The parses the command line options
// arguments to extract values for each of those arguments.
// Type: Overridden.
// Args: None.
// Return: MIstatus::success - Functional succeeded.
// MIstatus::failure - Functional failed.
// Throws: None.
//--
bool CMICmdCmdBreakDisable::ParseArgs( void )
{
bool bOk = m_setCmdArgs.Add( *(new CMICmdArgValOptionLong( m_constStrArgNamedThreadGrp, false, false, CMICmdArgValListBase::eArgValType_ThreadGrp, 1 ) ) );
bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValListOfN( m_constStrArgNamedBrkPt, true, true, CMICmdArgValListBase::eArgValType_Number ) ) );
CMICmdArgContext argCntxt( m_cmdData.strMiCmdOption );
if( bOk && !m_setCmdArgs.Validate( m_cmdData.strMiCmd, argCntxt ) )
{
SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_ARGS ), m_cmdData.strMiCmd.c_str(), m_setCmdArgs.GetErrorDescription().c_str() ) );
return MIstatus::failure;
}
return bOk;
}
//++ ------------------------------------------------------------------------------------
// 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 CMICmdCmdBreakDisable::Execute( void )
{
CMICMDBASE_GETOPTION( pArgBrkPt, ListOfN, m_constStrArgNamedBrkPt );
// ATM we only handle one break point ID
MIuint64 nBrk = UINT64_MAX;
if( !pArgBrkPt->GetExpectedOption< CMICmdArgValNumber, MIuint64 >( nBrk ) )
{
SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_BRKPT_INVALID ), m_cmdData.strMiCmd.c_str(), m_constStrArgNamedBrkPt.c_str() ) );
return MIstatus::failure;
}
CMICmnLLDBDebugSessionInfo & rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance() );
lldb::SBBreakpoint brkPt = rSessionInfo.m_lldbTarget.FindBreakpointByID( static_cast< lldb::break_id_t >( nBrk ) );
if( brkPt.IsValid() )
{
m_bBrkPtDisabledOk = true;
brkPt.SetEnabled( false );
m_nBrkPtId = nBrk;
}
return MIstatus::success;
}
//++ ------------------------------------------------------------------------------------
// Details: The invoker requires this function. The command prepares a MI Record Result
// for the work carried out in the Execute().
// Type: Overridden.
// Args: None.
// Return: MIstatus::success - Functional succeeded.
// MIstatus::failure - Functional failed.
// Throws: None.
//--
bool CMICmdCmdBreakDisable::Acknowledge( void )
{
if( m_bBrkPtDisabledOk )
{
const CMICmnMIValueConst miValueConst( CMIUtilString::Format( "%d", m_nBrkPtId ) );
const CMICmnMIValueResult miValueResult( "number", miValueConst );
CMICmnMIValueTuple miValueTuple( miValueResult );
const CMICmnMIValueConst miValueConst2( "n" );
const CMICmnMIValueResult miValueResult2( "enabled", miValueConst2 );
bool bOk = miValueTuple.Add( miValueResult2 );
const CMICmnMIValueResult miValueResult3( "bkpt", miValueTuple );
const CMICmnMIOutOfBandRecord miOutOfBandRecord( CMICmnMIOutOfBandRecord::eOutOfBand_BreakPointModified, miValueResult3 );
bOk = bOk && CMICmnStreamStdout::TextToStdout( miOutOfBandRecord.GetString() );
const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done );
m_miResultRecord = miRecordResult;
return bOk;
}
const CMIUtilString strBrkPtId( CMIUtilString::Format( "%d", m_nBrkPtId ) );
const CMICmnMIValueConst miValueConst( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_BRKPT_INVALID ), strBrkPtId.c_str() ) );
const CMICmnMIValueResult miValueResult( "msg", miValueConst );
const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, miValueResult );
m_miResultRecord = miRecordResult;
return MIstatus::success;
}
//++ ------------------------------------------------------------------------------------
// Details: Required by the CMICmdFactory when registering *this command. The factory
// calls this function to create an instance of *this command.
// Type: Static method.
// Args: None.
// Return: CMICmdBase * - Pointer to a new command.
// Throws: None.
//--
CMICmdBase * CMICmdCmdBreakDisable::CreateSelf( void )
{
return new CMICmdCmdBreakDisable();
}
//---------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------
//++ ------------------------------------------------------------------------------------
// Details: CMICmdCmdBreakEnable constructor.
// Type: Method.
// Args: None.
// Return: None.
// Throws: None.
//--
CMICmdCmdBreakEnable::CMICmdCmdBreakEnable( void )
: m_constStrArgNamedThreadGrp( "thread-group" )
, m_constStrArgNamedBrkPt( "breakpoint" )
, m_bBrkPtEnabledOk( false )
, m_nBrkPtId( 0 )
{
// Command factory matches this name with that received from the stdin stream
m_strMiCmd = "break-enable";
// Required by the CMICmdFactory when registering *this command
m_pSelfCreatorFn = &CMICmdCmdBreakEnable::CreateSelf;
}
//++ ------------------------------------------------------------------------------------
// Details: CMICmdCmdBreakEnable destructor.
// Type: Overrideable.
// Args: None.
// Return: None.
// Throws: None.
//--
CMICmdCmdBreakEnable::~CMICmdCmdBreakEnable( void )
{
}
//++ ------------------------------------------------------------------------------------
// Details: The invoker requires this function. The parses the command line options
// arguments to extract values for each of those arguments.
// Type: Overridden.
// Args: None.
// Return: MIstatus::success - Functional succeeded.
// MIstatus::failure - Functional failed.
// Throws: None.
//--
bool CMICmdCmdBreakEnable::ParseArgs( void )
{
bool bOk = m_setCmdArgs.Add( *(new CMICmdArgValOptionLong( m_constStrArgNamedThreadGrp, false, false, CMICmdArgValListBase::eArgValType_ThreadGrp, 1 ) ) );
bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValListOfN( m_constStrArgNamedBrkPt, true, true, CMICmdArgValListBase::eArgValType_Number ) ) );
CMICmdArgContext argCntxt( m_cmdData.strMiCmdOption );
if( bOk && !m_setCmdArgs.Validate( m_cmdData.strMiCmd, argCntxt ) )
{
SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_ARGS ), m_cmdData.strMiCmd.c_str(), m_setCmdArgs.GetErrorDescription().c_str() ) );
return MIstatus::failure;
}
return bOk;
}
//++ ------------------------------------------------------------------------------------
// 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 CMICmdCmdBreakEnable::Execute( void )
{
CMICMDBASE_GETOPTION( pArgBrkPt, ListOfN, m_constStrArgNamedBrkPt );
// ATM we only handle one break point ID
MIuint64 nBrk = UINT64_MAX;
if( !pArgBrkPt->GetExpectedOption< CMICmdArgValNumber, MIuint64 >( nBrk ) )
{
SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_BRKPT_INVALID ), m_cmdData.strMiCmd.c_str(), m_constStrArgNamedBrkPt.c_str() ) );
return MIstatus::failure;
}
CMICmnLLDBDebugSessionInfo & rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance() );
lldb::SBBreakpoint brkPt = rSessionInfo.m_lldbTarget.FindBreakpointByID( static_cast< lldb::break_id_t >( nBrk ) );
if( brkPt.IsValid() )
{
m_bBrkPtEnabledOk = true;
brkPt.SetEnabled( false );
m_nBrkPtId = nBrk;
}
return MIstatus::success;
}
//++ ------------------------------------------------------------------------------------
// Details: The invoker requires this function. The command prepares a MI Record Result
// for the work carried out in the Execute().
// Type: Overridden.
// Args: None.
// Return: MIstatus::success - Functional succeeded.
// MIstatus::failure - Functional failed.
// Throws: None.
//--
bool CMICmdCmdBreakEnable::Acknowledge( void )
{
if( m_bBrkPtEnabledOk )
{
const CMICmnMIValueConst miValueConst( CMIUtilString::Format( "%d", m_nBrkPtId ) );
const CMICmnMIValueResult miValueResult( "number", miValueConst );
CMICmnMIValueTuple miValueTuple( miValueResult );
const CMICmnMIValueConst miValueConst2( "y" );
const CMICmnMIValueResult miValueResult2( "enabled", miValueConst2 );
bool bOk = miValueTuple.Add( miValueResult2 );
const CMICmnMIValueResult miValueResult3( "bkpt", miValueTuple );
const CMICmnMIOutOfBandRecord miOutOfBandRecord( CMICmnMIOutOfBandRecord::eOutOfBand_BreakPointModified, miValueResult3 );
bOk = bOk && CMICmnStreamStdout::TextToStdout( miOutOfBandRecord.GetString() );
const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done );
m_miResultRecord = miRecordResult;
return bOk;
}
const CMIUtilString strBrkPtId( CMIUtilString::Format( "%d", m_nBrkPtId ) );
const CMICmnMIValueConst miValueConst( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_BRKPT_INVALID ), strBrkPtId.c_str() ) );
const CMICmnMIValueResult miValueResult( "msg", miValueConst );
const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, miValueResult );
m_miResultRecord = miRecordResult;
return MIstatus::success;
}
//++ ------------------------------------------------------------------------------------
// Details: Required by the CMICmdFactory when registering *this command. The factory
// calls this function to create an instance of *this command.
// Type: Static method.
// Args: None.
// Return: CMICmdBase * - Pointer to a new command.
// Throws: None.
//--
CMICmdBase * CMICmdCmdBreakEnable::CreateSelf( void )
{
return new CMICmdCmdBreakEnable();
}
//---------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------
//++ ------------------------------------------------------------------------------------
// Details: CMICmdCmdBreakAfter constructor.
// Type: Method.
// Args: None.
// Return: None.
// Throws: None.
//--
CMICmdCmdBreakAfter::CMICmdCmdBreakAfter( void )
: m_constStrArgNamedThreadGrp( "thread-group" )
, m_constStrArgNamedNumber( "number" )
, m_constStrArgNamedCount( "count" )
, m_nBrkPtId( 0 )
, m_nBrkPtCount( 0 )
{
// Command factory matches this name with that received from the stdin stream
m_strMiCmd = "break-after";
// Required by the CMICmdFactory when registering *this command
m_pSelfCreatorFn = &CMICmdCmdBreakAfter::CreateSelf;
}
//++ ------------------------------------------------------------------------------------
// Details: CMICmdCmdBreakAfter destructor.
// Type: Overrideable.
// Args: None.
// Return: None.
// Throws: None.
//--
CMICmdCmdBreakAfter::~CMICmdCmdBreakAfter( void )
{
}
//++ ------------------------------------------------------------------------------------
// Details: The invoker requires this function. The parses the command line options
// arguments to extract values for each of those arguments.
// Type: Overridden.
// Args: None.
// Return: MIstatus::success - Functional succeeded.
// MIstatus::failure - Functional failed.
// Throws: None.
//--
bool CMICmdCmdBreakAfter::ParseArgs( void )
{
bool bOk = m_setCmdArgs.Add( *(new CMICmdArgValOptionLong( m_constStrArgNamedThreadGrp, false, false, CMICmdArgValListBase::eArgValType_ThreadGrp, 1 ) ) );
bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValNumber( m_constStrArgNamedNumber, true, true ) ) );
bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValNumber( m_constStrArgNamedCount, true, true ) ) );
CMICmdArgContext argCntxt( m_cmdData.strMiCmdOption );
if( bOk && !m_setCmdArgs.Validate( m_cmdData.strMiCmd, argCntxt ) )
{
SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_ARGS ), m_cmdData.strMiCmd.c_str(), m_setCmdArgs.GetErrorDescription().c_str() ) );
return MIstatus::failure;
}
return bOk;
}
//++ ------------------------------------------------------------------------------------
// 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 CMICmdCmdBreakAfter::Execute( void )
{
CMICMDBASE_GETOPTION( pArgNumber, Number, m_constStrArgNamedNumber );
CMICMDBASE_GETOPTION( pArgCount, Number, m_constStrArgNamedCount );
m_nBrkPtId = pArgNumber->GetValue();
m_nBrkPtCount = pArgCount->GetValue();
CMICmnLLDBDebugSessionInfo & rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance() );
lldb::SBBreakpoint brkPt = rSessionInfo.m_lldbTarget.FindBreakpointByID( static_cast< lldb::break_id_t >( m_nBrkPtId ) );
if( brkPt.IsValid() )
{
brkPt.SetIgnoreCount( m_nBrkPtCount );
CMICmnLLDBDebugSessionInfo::SBrkPtInfo sBrkPtInfo;
if( !rSessionInfo.RecordBrkPtInfoGet( m_nBrkPtId, sBrkPtInfo ) )
{
SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_BRKPT_INFO_OBJ_NOT_FOUND ), m_cmdData.strMiCmd.c_str(), m_nBrkPtId ) );
return MIstatus::failure;
}
sBrkPtInfo.m_nIgnore = m_nBrkPtCount;
rSessionInfo.RecordBrkPtInfo( m_nBrkPtId, sBrkPtInfo );
}
else
{
const CMIUtilString strBrkPtId( CMIUtilString::Format( "%d", m_nBrkPtId ) );
SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_BRKPT_INVALID ), m_cmdData.strMiCmd.c_str(), strBrkPtId.c_str() ) );
return MIstatus::failure;
}
return MIstatus::success;
}
//++ ------------------------------------------------------------------------------------
// Details: The invoker requires this function. The command prepares a MI Record Result
// for the work carried out in the Execute().
// Type: Overridden.
// Args: None.
// Return: MIstatus::success - Functional succeeded.
// MIstatus::failure - Functional failed.
// Throws: None.
//--
bool CMICmdCmdBreakAfter::Acknowledge( void )
{
const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done );
m_miResultRecord = miRecordResult;
return MIstatus::success;
}
//++ ------------------------------------------------------------------------------------
// Details: Required by the CMICmdFactory when registering *this command. The factory
// calls this function to create an instance of *this command.
// Type: Static method.
// Args: None.
// Return: CMICmdBase * - Pointer to a new command.
// Throws: None.
//--
CMICmdBase * CMICmdCmdBreakAfter::CreateSelf( void )
{
return new CMICmdCmdBreakAfter();
}
//---------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------
//++ ------------------------------------------------------------------------------------
// Details: CMICmdCmdBreakCondition constructor.
// Type: Method.
// Args: None.
// Return: None.
// Throws: None.
//--
CMICmdCmdBreakCondition::CMICmdCmdBreakCondition( void )
: m_constStrArgNamedThreadGrp( "thread-group" )
, m_constStrArgNamedNumber( "number" )
, m_constStrArgNamedExpr( "expr" )
, m_constStrArgNamedExprNoQuotes( "expression not surround by quotes" ) // Not specified in MI spec, we need to handle expressions not surrounded by quotes
, m_nBrkPtId( 0 )
{
// Command factory matches this name with that received from the stdin stream
m_strMiCmd = "break-condition";
// Required by the CMICmdFactory when registering *this command
m_pSelfCreatorFn = &CMICmdCmdBreakCondition::CreateSelf;
}
//++ ------------------------------------------------------------------------------------
// Details: CMICmdCmdBreakCondition destructor.
// Type: Overrideable.
// Args: None.
// Return: None.
// Throws: None.
//--
CMICmdCmdBreakCondition::~CMICmdCmdBreakCondition( void )
{
}
//++ ------------------------------------------------------------------------------------
// Details: The invoker requires this function. The parses the command line options
// arguments to extract values for each of those arguments.
// Type: Overridden.
// Args: None.
// Return: MIstatus::success - Functional succeeded.
// MIstatus::failure - Functional failed.
// Throws: None.
//--
bool CMICmdCmdBreakCondition::ParseArgs( void )
{
bool bOk = m_setCmdArgs.Add( *(new CMICmdArgValOptionLong( m_constStrArgNamedThreadGrp, false, false, CMICmdArgValListBase::eArgValType_ThreadGrp, 1 ) ) );
bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValNumber( m_constStrArgNamedNumber, true, true ) ) );
bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValString( m_constStrArgNamedExpr, true, true, true, true ) ) );
bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValListOfN( m_constStrArgNamedExprNoQuotes, true, false, CMICmdArgValListBase::eArgValType_StringQuotedNumber ) ) );
CMICmdArgContext argCntxt( m_cmdData.strMiCmdOption );
if( bOk && !m_setCmdArgs.Validate( m_cmdData.strMiCmd, argCntxt ) )
{
SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_ARGS ), m_cmdData.strMiCmd.c_str(), m_setCmdArgs.GetErrorDescription().c_str() ) );
return MIstatus::failure;
}
return bOk;
}
//++ ------------------------------------------------------------------------------------
// 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 CMICmdCmdBreakCondition::Execute( void )
{
CMICMDBASE_GETOPTION( pArgNumber, Number, m_constStrArgNamedNumber );
CMICMDBASE_GETOPTION( pArgExpr, String, m_constStrArgNamedExpr );
m_nBrkPtId = pArgNumber->GetValue();
m_strBrkPtExpr = pArgExpr->GetValue();
m_strBrkPtExpr += GetRestOfExpressionNotSurroundedInQuotes();
CMICmnLLDBDebugSessionInfo & rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance() );
lldb::SBBreakpoint brkPt = rSessionInfo.m_lldbTarget.FindBreakpointByID( static_cast< lldb::break_id_t >( m_nBrkPtId ) );
if( brkPt.IsValid() )
{
brkPt.SetCondition( m_strBrkPtExpr.c_str() );
CMICmnLLDBDebugSessionInfo::SBrkPtInfo sBrkPtInfo;
if( !rSessionInfo.RecordBrkPtInfoGet( m_nBrkPtId, sBrkPtInfo ) )
{
SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_BRKPT_INFO_OBJ_NOT_FOUND ), m_cmdData.strMiCmd.c_str(), m_nBrkPtId ) );
return MIstatus::failure;
}
sBrkPtInfo.m_strCondition = m_strBrkPtExpr;
rSessionInfo.RecordBrkPtInfo( m_nBrkPtId, sBrkPtInfo );
}
else
{
const CMIUtilString strBrkPtId( CMIUtilString::Format( "%d", m_nBrkPtId ) );
SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_BRKPT_INVALID ), m_cmdData.strMiCmd.c_str(), strBrkPtId.c_str() ) );
return MIstatus::failure;
}
return MIstatus::success;
}
//++ ------------------------------------------------------------------------------------
// Details: The invoker requires this function. The command prepares a MI Record Result
// for the work carried out in the Execute().
// Type: Overridden.
// Args: None.
// Return: MIstatus::success - Functional succeeded.
// MIstatus::failure - Functional failed.
// Throws: None.
//--
bool CMICmdCmdBreakCondition::Acknowledge( void )
{
const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done );
m_miResultRecord = miRecordResult;
return MIstatus::success;
}
//++ ------------------------------------------------------------------------------------
// Details: Required by the CMICmdFactory when registering *this command. The factory
// calls this function to create an instance of *this command.
// Type: Static method.
// Args: None.
// Return: CMICmdBase * - Pointer to a new command.
// Throws: None.
//--
CMICmdBase * CMICmdCmdBreakCondition::CreateSelf( void )
{
return new CMICmdCmdBreakCondition();
}
//++ ------------------------------------------------------------------------------------
// Details: A breakpoint expression can be passed to *this command as:
// a single string i.e. '2' -> ok.
// a quoted string i.e. "a > 100" -> ok
// a non quoted string i.e. 'a > 100' -> not ok
// CMICmdArgValString only extracts the first space seperated string, the "a".
// This function using the optional argument type CMICmdArgValListOfN collects
// the rest of the expression so that is may be added to the 'a' part to form a
// complete expression string i.e. "a > 100".
// If the expression value was guaranteed to be surrounded by quotes them this
// function would not be necessary.
// Type: Method.
// Args: None.
// Return: CMIUtilString - Rest of the breakpoint expression.
// Throws: None.
//--
CMIUtilString CMICmdCmdBreakCondition::GetRestOfExpressionNotSurroundedInQuotes( void )
{
CMIUtilString strExpression;
CMICmdArgValListOfN * pArgExprNoQuotes = CMICmdBase::GetOption< CMICmdArgValListOfN >( m_constStrArgNamedExprNoQuotes );
if( pArgExprNoQuotes != nullptr )
{
CMIUtilString strExpression;
const CMICmdArgValListBase::VecArgObjPtr_t & rVecExprParts( pArgExprNoQuotes->GetExpectedOptions() );
if( !rVecExprParts.empty() )
{
CMICmdArgValListBase::VecArgObjPtr_t::const_iterator it = rVecExprParts.begin();
while( it != rVecExprParts.end() )
{
const CMICmdArgValString * pPartExpr = static_cast< CMICmdArgValString * >( *it );
const CMIUtilString & rPartExpr = pPartExpr->GetValue();
strExpression += " ";
strExpression += rPartExpr;
// Next
++it;
}
strExpression = strExpression.Trim();
}
}
return strExpression;
}

View File

@ -12,6 +12,10 @@
//
// Overview: CMICmdCmdBreakInsert interface.
// CMICmdCmdBreakDelete interface.
// CMICmdCmdBreakDisable interface.
// CMICmdCmdBreakEnable interface.
// CMICmdCmdBreakAfter interface.
// CMICmdCmdBreakCondition interface.
//
// To implement new MI commands derive a new command class from the command base
// class. To enable the new command for interpretation add the new command class
@ -49,7 +53,7 @@ class CMICmdCmdBreakInsert : public CMICmdBase
{
// Statics:
public:
// Required by the CMICmdFactory when registering *this commmand
// Required by the CMICmdFactory when registering *this command
static CMICmdBase * CreateSelf( void );
// Methods:
@ -62,9 +66,6 @@ public:
virtual bool Execute( void );
virtual bool Acknowledge( void );
virtual bool ParseArgs( void );
// Overridden:
public:
// From CMICmnBase
/* dtor */ virtual ~CMICmdCmdBreakInsert( void );
@ -91,14 +92,21 @@ private:
CMIUtilString m_brkName;
CMIUtilString m_strArgOptionThreadGrp;
lldb::SBBreakpoint m_brkPt;
bool m_bBrkPtIsPending;
MIuint m_nBrkPtIgnoreCount;
bool m_bBrkPtEnabled;
bool m_bBrkPtCondition;
CMIUtilString m_brkPtCondition;
bool m_bBrkPtThreadId;
MIuint m_nBrkPtThreadId;
const CMIUtilString m_constStrArgNamedTempBrkPt;
const CMIUtilString m_constStrArgNamedHWBrkPt; // Not handled by *this command
const CMIUtilString m_constStrArgNamedPendinfBrkPt; // Not handled by *this command
const CMIUtilString m_constStrArgNamedDisableBrkPt; // Not handled by *this command
const CMIUtilString m_constStrArgNamedPendinfBrkPt;
const CMIUtilString m_constStrArgNamedDisableBrkPt;
const CMIUtilString m_constStrArgNamedTracePt; // Not handled by *this command
const CMIUtilString m_constStrArgNamedConditionalBrkPt; // Not handled by *this command
const CMIUtilString m_constStrArgNamedInoreCnt; // Not handled by *this command
const CMIUtilString m_constStrArgNamedRestrictBrkPtToThreadId; // Not handled by *this command
const CMIUtilString m_constStrArgNamedConditionalBrkPt;
const CMIUtilString m_constStrArgNamedInoreCnt;
const CMIUtilString m_constStrArgNamedRestrictBrkPtToThreadId;
const CMIUtilString m_constStrArgNamedLocation;
const CMIUtilString m_constStrArgNamedThreadGroup; // Not specified in MI spec but Eclipse gives this option sometimes
};
@ -114,7 +122,7 @@ class CMICmdCmdBreakDelete : public CMICmdBase
{
// Statics:
public:
// Required by the CMICmdFactory when registering *this commmand
// Required by the CMICmdFactory when registering *this command
static CMICmdBase * CreateSelf( void );
// Methods:
@ -127,9 +135,6 @@ public:
virtual bool Execute( void );
virtual bool Acknowledge( void );
virtual bool ParseArgs( void );
// Overridden:
public:
// From CMICmnBase
/* dtor */ virtual ~CMICmdCmdBreakDelete( void );
@ -138,3 +143,150 @@ private:
const CMIUtilString m_constStrArgNamedBrkPt;
const CMIUtilString m_constStrArgNamedThreadGrp; // Not specified in MI spec but Eclipse gives this option
};
//++ ============================================================================
// Details: MI command class. MI commands derived from the command base class.
// *this class implements MI command "break-disable".
// Gotchas: None.
// Authors: Illya Rudkin 19/05/2014.
// Changes: None.
//--
class CMICmdCmdBreakDisable : public CMICmdBase
{
// Statics:
public:
// Required by the CMICmdFactory when registering *this command
static CMICmdBase * CreateSelf( void );
// Methods:
public:
/* ctor */ CMICmdCmdBreakDisable( void );
// Overridden:
public:
// From CMICmdInvoker::ICmd
virtual bool Execute( void );
virtual bool Acknowledge( void );
virtual bool ParseArgs( void );
// From CMICmnBase
/* dtor */ virtual ~CMICmdCmdBreakDisable( void );
// Attributes:
private:
const CMIUtilString m_constStrArgNamedThreadGrp; // Not specified in MI spec but Eclipse gives this option
const CMIUtilString m_constStrArgNamedBrkPt;
bool m_bBrkPtDisabledOk;
MIuint m_nBrkPtId;
};
//++ ============================================================================
// Details: MI command class. MI commands derived from the command base class.
// *this class implements MI command "break-enable".
// Gotchas: None.
// Authors: Illya Rudkin 19/05/2014.
// Changes: None.
//--
class CMICmdCmdBreakEnable : public CMICmdBase
{
// Statics:
public:
// Required by the CMICmdFactory when registering *this command
static CMICmdBase * CreateSelf( void );
// Methods:
public:
/* ctor */ CMICmdCmdBreakEnable( void );
// Overridden:
public:
// From CMICmdInvoker::ICmd
virtual bool Execute( void );
virtual bool Acknowledge( void );
virtual bool ParseArgs( void );
// From CMICmnBase
/* dtor */ virtual ~CMICmdCmdBreakEnable( void );
// Attributes:
private:
const CMIUtilString m_constStrArgNamedThreadGrp; // Not specified in MI spec but Eclipse gives this option
const CMIUtilString m_constStrArgNamedBrkPt;
bool m_bBrkPtEnabledOk;
MIuint m_nBrkPtId;
};
//++ ============================================================================
// Details: MI command class. MI commands derived from the command base class.
// *this class implements MI command "break-after".
// Gotchas: None.
// Authors: Illya Rudkin 29/05/2014.
// Changes: None.
//--
class CMICmdCmdBreakAfter : public CMICmdBase
{
// Statics:
public:
// Required by the CMICmdFactory when registering *this command
static CMICmdBase * CreateSelf( void );
// Methods:
public:
/* ctor */ CMICmdCmdBreakAfter( void );
// Overridden:
public:
// From CMICmdInvoker::ICmd
virtual bool Execute( void );
virtual bool Acknowledge( void );
virtual bool ParseArgs( void );
// From CMICmnBase
/* dtor */ virtual ~CMICmdCmdBreakAfter( void );
// Attributes:
private:
const CMIUtilString m_constStrArgNamedThreadGrp; // Not specified in MI spec but Eclipse gives this option
const CMIUtilString m_constStrArgNamedNumber;
const CMIUtilString m_constStrArgNamedCount;
MIuint m_nBrkPtId;
MIuint m_nBrkPtCount;
};
//++ ============================================================================
// Details: MI command class. MI commands derived from the command base class.
// *this class implements MI command "break-condition".
// Gotchas: None.
// Authors: Illya Rudkin 29/05/2014.
// Changes: None.
//--
class CMICmdCmdBreakCondition : public CMICmdBase
{
// Statics:
public:
// Required by the CMICmdFactory when registering *this command
static CMICmdBase * CreateSelf( void );
// Methods:
public:
/* ctor */ CMICmdCmdBreakCondition( void );
// Overridden:
public:
// From CMICmdInvoker::ICmd
virtual bool Execute( void );
virtual bool Acknowledge( void );
virtual bool ParseArgs( void );
// From CMICmnBase
/* dtor */ virtual ~CMICmdCmdBreakCondition( void );
// Methods:
private:
CMIUtilString GetRestOfExpressionNotSurroundedInQuotes( void );
// Attributes:
private:
const CMIUtilString m_constStrArgNamedThreadGrp; // Not specified in MI spec but Eclipse gives this option
const CMIUtilString m_constStrArgNamedNumber;
const CMIUtilString m_constStrArgNamedExpr;
const CMIUtilString m_constStrArgNamedExprNoQuotes; // Not specified in MI spec, we need to handle expressions not surrounded by quotes
MIuint m_nBrkPtId;
CMIUtilString m_strBrkPtExpr;
};

File diff suppressed because it is too large Load Diff

View File

@ -10,7 +10,15 @@
//++
// File: MICmdCmdData.h
//
// Overview: CMICmdCmdDataEvaluateExpression interface.
// Overview: CMICmdCmdDataEvaluateExpression interface.
// CMICmdCmdDataDisassemble interface.
// CMICmdCmdDataReadMemoryBytes interface.
// CMICmdCmdDataReadMemory interface.
// CMICmdCmdDataListRegisterNames interface.
// CMICmdCmdDataListRegisterValues interface.
// CMICmdCmdDataListRegisterChanged interface.
// CMICmdCmdDataWriteMemoryBytes interface.
// CMICmdCmdDataWriteMemory interface.
//
// To implement new MI commands derive a new command class from the command base
// class. To enable the new command for interpretation add the new command class
@ -33,6 +41,7 @@
// In-house headers:
#include "MICmdBase.h"
#include "MICmnMIValueTuple.h"
#include "MICmnMIValueList.h"
//++ ============================================================================
// Details: MI command class. MI commands derived from the command base class.
@ -45,7 +54,7 @@ class CMICmdCmdDataEvaluateExpression : public CMICmdBase
{
// Statics:
public:
// Required by the CMICmdFactory when registering *this commmand
// Required by the CMICmdFactory when registering *this command
static CMICmdBase * CreateSelf( void );
// Methods:
@ -58,9 +67,6 @@ public:
virtual bool Execute( void );
virtual bool Acknowledge( void );
virtual bool ParseArgs( void );
// Overridden:
public:
// From CMICmnBase
/* dtor */ virtual ~CMICmdCmdDataEvaluateExpression( void );
@ -76,3 +82,287 @@ private:
const CMIUtilString m_constStrArgExpr;
};
//++ ============================================================================
// Details: MI command class. MI commands derived from the command base class.
// *this class implements MI command "data-disassemble".
// Gotchas: None.
// Authors: Illya Rudkin 19/05/2014.
// Changes: None.
//--
class CMICmdCmdDataDisassemble : public CMICmdBase
{
// Statics:
public:
// Required by the CMICmdFactory when registering *this command
static CMICmdBase * CreateSelf( void );
// Methods:
public:
/* ctor */ CMICmdCmdDataDisassemble( void );
// Overridden:
public:
// From CMICmdInvoker::ICmd
virtual bool Execute( void );
virtual bool Acknowledge( void );
virtual bool ParseArgs( void );
// From CMICmnBase
/* dtor */ virtual ~CMICmdCmdDataDisassemble( void );
// Attributes:
private:
const CMIUtilString m_constStrArgThread; // Not specified in MI spec but Eclipse gives this option. Not handled by command.
const CMIUtilString m_constStrArgAddrStart; // MI spec non mandatory, *this command mandatory
const CMIUtilString m_constStrArgAddrEnd; // MI spec non mandatory, *this command mandatory
const CMIUtilString m_constStrArgConsume;
const CMIUtilString m_constStrArgMode;
CMICmnMIValueList m_miValueList;
};
//++ ============================================================================
// Details: MI command class. MI commands derived from the command base class.
// *this class implements MI command "data-read-memory-bytes".
// Gotchas: None.
// Authors: Illya Rudkin 20/05/2014.
// Changes: None.
//--
class CMICmdCmdDataReadMemoryBytes : public CMICmdBase
{
// Statics:
public:
// Required by the CMICmdFactory when registering *this command
static CMICmdBase * CreateSelf( void );
// Methods:
public:
/* ctor */ CMICmdCmdDataReadMemoryBytes( void );
// Overridden:
public:
// From CMICmdInvoker::ICmd
virtual bool Execute( void );
virtual bool Acknowledge( void );
virtual bool ParseArgs( void );
// From CMICmnBase
/* dtor */ virtual ~CMICmdCmdDataReadMemoryBytes( void );
// Attributes:
private:
const CMIUtilString m_constStrArgThread; // Not specified in MI spec but Eclipse gives this option. Not handled by command.
const CMIUtilString m_constStrArgByteOffset;
const CMIUtilString m_constStrArgAddrStart;
const CMIUtilString m_constStrArgNumBytes;
MIuchar * m_pBufferMemory;
MIuint64 m_nAddrStart;
MIuint64 m_nAddrNumBytesToRead;
MIuint64 m_nAddrOffset;
};
//++ ============================================================================
// Details: MI command class. MI commands derived from the command base class.
// *this class implements MI command "data-read-memory".
// Gotchas: None.
// Authors: Illya Rudkin 21/05/2014.
// Changes: None.
//--
class CMICmdCmdDataReadMemory : public CMICmdBase
{
// Statics:
public:
// Required by the CMICmdFactory when registering *this command
static CMICmdBase * CreateSelf( void );
// Methods:
public:
/* ctor */ CMICmdCmdDataReadMemory( void );
// Overridden:
public:
// From CMICmdInvoker::ICmd
virtual bool Execute( void );
virtual bool Acknowledge( void );
// From CMICmnBase
/* dtor */ virtual ~CMICmdCmdDataReadMemory( void );
};
//++ ============================================================================
// Details: MI command class. MI commands derived from the command base class.
// *this class implements MI command "data-list-register-names".
// Gotchas: None.
// Authors: Illya Rudkin 21/05/2014.
// Changes: None.
//--
class CMICmdCmdDataListRegisterNames : public CMICmdBase
{
// Statics:
public:
// Required by the CMICmdFactory when registering *this command
static CMICmdBase * CreateSelf( void );
// Methods:
public:
/* ctor */ CMICmdCmdDataListRegisterNames( void );
// Overridden:
public:
// From CMICmdInvoker::ICmd
virtual bool Execute( void );
virtual bool Acknowledge( void );
virtual bool ParseArgs( void );
// From CMICmnBase
/* dtor */ virtual ~CMICmdCmdDataListRegisterNames( void );
// Attributes:
private:
const CMIUtilString m_constStrArgThreadGroup; // Not specified in MI spec but Eclipse gives this option
const CMIUtilString m_constStrArgRegNo; // Not handled by *this command
CMICmnMIValueList m_miValueList;
};
//++ ============================================================================
// Details: MI command class. MI commands derived from the command base class.
// *this class implements MI command "data-list-register-values".
// Gotchas: None.
// Authors: Illya Rudkin 21/05/2014.
// Changes: None.
//--
class CMICmdCmdDataListRegisterValues : public CMICmdBase
{
// Statics:
public:
// Required by the CMICmdFactory when registering *this command
static CMICmdBase * CreateSelf( void );
// Methods:
public:
/* ctor */ CMICmdCmdDataListRegisterValues( void );
// Overridden:
public:
// From CMICmdInvoker::ICmd
virtual bool Execute( void );
virtual bool Acknowledge( void );
virtual bool ParseArgs( void );
// From CMICmnBase
/* dtor */ virtual ~CMICmdCmdDataListRegisterValues( void );
// Methods:
private:
lldb::SBValue GetRegister( const MIuint vRegisterIndex ) const;
// Attributes:
private:
const CMIUtilString m_constStrArgThread; // Not specified in MI spec but Eclipse gives this option
const CMIUtilString m_constStrArgSkip; // Not handled by *this command
const CMIUtilString m_constStrArgFormat;
const CMIUtilString m_constStrArgRegNo;
CMICmnMIValueList m_miValueList;
lldb::SBProcess * m_pProcess;
};
//++ ============================================================================
// Details: MI command class. MI commands derived from the command base class.
// *this class implements MI command "data-list-changed-registers".
// Gotchas: None.
// Authors: Illya Rudkin 22/05/2014.
// Changes: None.
//--
class CMICmdCmdDataListRegisterChanged : public CMICmdBase
{
// Statics:
public:
// Required by the CMICmdFactory when registering *this command
static CMICmdBase * CreateSelf( void );
// Methods:
public:
/* ctor */ CMICmdCmdDataListRegisterChanged( void );
// Overridden:
public:
// From CMICmdInvoker::ICmd
virtual bool Execute( void );
virtual bool Acknowledge( void );
// From CMICmnBase
/* dtor */ virtual ~CMICmdCmdDataListRegisterChanged( void );
};
//++ ============================================================================
// Details: MI command class. MI commands derived from the command base class.
// *this class implements MI command "data-read-memory-bytes".
// Gotchas: None.
// Authors: Illya Rudkin 30/05/2014.
// Changes: None.
//--
class CMICmdCmdDataWriteMemoryBytes : public CMICmdBase
{
// Statics:
public:
// Required by the CMICmdFactory when registering *this command
static CMICmdBase * CreateSelf( void );
// Methods:
public:
/* ctor */ CMICmdCmdDataWriteMemoryBytes( void );
// Overridden:
public:
// From CMICmdInvoker::ICmd
virtual bool Execute( void );
virtual bool Acknowledge( void );
virtual bool ParseArgs( void );
// From CMICmnBase
/* dtor */ virtual ~CMICmdCmdDataWriteMemoryBytes( void );
// Attributes:
private:
const CMIUtilString m_constStrArgThread; // Not specified in MI spec but Eclipse gives this option. Not handled by command.
const CMIUtilString m_constStrArgAddr;
const CMIUtilString m_constStrArgContents;
const CMIUtilString m_constStrArgCount;
MIuint64 m_nAddr;
CMIUtilString m_strContents;
MIuint64 m_nCount;
};
//++ ============================================================================
// Details: MI command class. MI commands derived from the command base class.
// *this class implements MI command "data-read-memory".
// Not specified in MI spec but Eclipse gives *this command.
// Gotchas: None.
// Authors: Illya Rudkin 02/05/2014.
// Changes: None.
//--
class CMICmdCmdDataWriteMemory : public CMICmdBase
{
// Statics:
public:
// Required by the CMICmdFactory when registering *this command
static CMICmdBase * CreateSelf( void );
// Methods:
public:
/* ctor */ CMICmdCmdDataWriteMemory( void );
// Overridden:
public:
// From CMICmdInvoker::ICmd
virtual bool Execute( void );
virtual bool Acknowledge( void );
virtual bool ParseArgs( void );
// From CMICmnBase
/* dtor */ virtual ~CMICmdCmdDataWriteMemory( void );
// Attributes:
private:
const CMIUtilString m_constStrArgThread; // Not specified in MI spec but Eclipse gives this option. Not handled by command.
const CMIUtilString m_constStrArgOffset; // Not specified in MI spec but Eclipse gives this option.
const CMIUtilString m_constStrArgAddr; // Not specified in MI spec but Eclipse gives this option.
const CMIUtilString m_constStrArgD; // Not specified in MI spec but Eclipse gives this option.
const CMIUtilString m_constStrArgNumber; // Not specified in MI spec but Eclipse gives this option.
const CMIUtilString m_constStrArgContents; // Not specified in MI spec but Eclipse gives this option.
MIuint64 m_nAddr;
CMIUtilString m_strContents;
MIuint64 m_nCount;
MIuchar * m_pBufferMemory;
};

View File

@ -53,7 +53,7 @@ CMICmdCmdEnvironmentCd::CMICmdCmdEnvironmentCd( void )
// Command factory matches this name with that received from the stdin stream
m_strMiCmd = "environment-cd";
// Required by the CMICmdFactory when registering *this commmand
// Required by the CMICmdFactory when registering *this command
m_pSelfCreatorFn = &CMICmdCmdEnvironmentCd::CreateSelf;
}
@ -109,7 +109,7 @@ bool CMICmdCmdEnvironmentCd::Execute( void )
if( bOk )
{
const CMIUtilString & rStrKeyWkDir( m_rLLDBDebugSessionInfo.m_constStrSharedDataKeyWkDir );
if( !m_rLLDBDebugSessionInfo.SharedDataAdd( rStrKeyWkDir, strWkDir ) )
if( !m_rLLDBDebugSessionInfo.SharedDataAdd< CMIUtilString >( rStrKeyWkDir, strWkDir ) )
{
SetError( CMIUtilString::Format( MIRSRC( IDS_DBGSESSION_ERR_SHARED_DATA_ADD ), m_cmdData.strMiCmd.c_str(), rStrKeyWkDir.c_str() ) );
bOk = MIstatus::failure;
@ -134,12 +134,12 @@ bool CMICmdCmdEnvironmentCd::Acknowledge( void )
{
const CMIUtilString & rStrKeyWkDir( m_rLLDBDebugSessionInfo.m_constStrSharedDataKeyWkDir );
CMIUtilString strWkDir;
const bool bOk = m_rLLDBDebugSessionInfo.SharedDataRetrieve( rStrKeyWkDir, strWkDir );
const bool bOk = m_rLLDBDebugSessionInfo.SharedDataRetrieve< CMIUtilString >( rStrKeyWkDir, strWkDir );
if( bOk )
{
const CMICmnMIValueConst miValueConst( strWkDir );
const CMICmnMIValueResult miValueResult( "path", miValueConst );
const CMICmnMIResultRecord miRecordResult( m_cmdData.nMiCmdNumber, CMICmnMIResultRecord::eResultClass_Done, miValueResult );
const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult );
m_miResultRecord = miRecordResult;
return MIstatus::success;
}
@ -149,7 +149,7 @@ bool CMICmdCmdEnvironmentCd::Acknowledge( void )
}
//++ ------------------------------------------------------------------------------------
// Details: Required by the CMICmdFactory when registering *this commmand. The factory
// Details: Required by the CMICmdFactory when registering *this command. The factory
// calls this function to create an instance of *this command.
// Type: Static method.
// Args: None.
@ -159,4 +159,4 @@ bool CMICmdCmdEnvironmentCd::Acknowledge( void )
CMICmdBase * CMICmdCmdEnvironmentCd::CreateSelf( void )
{
return new CMICmdCmdEnvironmentCd();
}
}

View File

@ -46,7 +46,7 @@ class CMICmdCmdEnvironmentCd : public CMICmdBase
{
// Statics:
public:
// Required by the CMICmdFactory when registering *this commmand
// Required by the CMICmdFactory when registering *this command
static CMICmdBase * CreateSelf( void );
// Methods:
@ -59,9 +59,6 @@ public:
virtual bool Execute( void );
virtual bool Acknowledge( void );
virtual bool ParseArgs( void );
// Overridden:
public:
// From CMICmnBase
/* dtor */ virtual ~CMICmdCmdEnvironmentCd( void );

View File

@ -12,11 +12,12 @@
//
// Overview: CMICmdCmdExecRun implementation.
// CMICmdCmdExecContinue implementation.
// Overview: CMICmdCmdExecNext implementation.
// CMICmdCmdExecNext implementation.
// CMICmdCmdExecStep implementation.
// CMICmdCmdExecNextInstruction implementation.
// CMICmdCmdExecStepInstruction implementation.
// CMICmdCmdExecFinish implementation.
// CMICmdCmdExecInterupt implementation.
//
// Environment: Compilers: Visual C++ 12.
// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
@ -43,6 +44,8 @@
#include "MICmdArgValOptionLong.h"
#include "MICmdArgValOptionShort.h"
#include "MICmdArgValListOfN.h"
#include "MICmnStreamStdout.h"
#include "MICmnMIOutOfBandRecord.h"
//++ ------------------------------------------------------------------------------------
// Details: CMICmdCmdExecRun constructor.
@ -56,7 +59,7 @@ CMICmdCmdExecRun::CMICmdCmdExecRun( void )
// Command factory matches this name with that received from the stdin stream
m_strMiCmd = "exec-run";
// Required by the CMICmdFactory when registering *this commmand
// Required by the CMICmdFactory when registering *this command
m_pSelfCreatorFn = &CMICmdCmdExecRun::CreateSelf;
}
@ -82,8 +85,21 @@ CMICmdCmdExecRun::~CMICmdCmdExecRun( void )
//--
bool CMICmdCmdExecRun::Execute( void )
{
// Do nothing
return MIstatus::success;
const MIchar * pCmd = "run";
CMICmnLLDBDebugSessionInfo & rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance() );
const lldb::ReturnStatus rtn = rSessionInfo.m_rLldbDebugger.GetCommandInterpreter().HandleCommand( pCmd, m_lldbResult ); MIunused( rtn );
if( m_lldbResult.GetErrorSize() == 0 )
{
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;
}
}
return MIstatus::success;
}
//++ ------------------------------------------------------------------------------------
@ -97,16 +113,24 @@ bool CMICmdCmdExecRun::Execute( void )
//--
bool CMICmdCmdExecRun::Acknowledge( void )
{
const CMICmnMIValueConst miValueConst( MIRSRC( IDS_CMD_ERR_NOT_IMPLEMENTED ) );
const CMICmnMIValueResult miValueResult( "msg", miValueConst );
const CMICmnMIResultRecord miRecordResult( m_cmdData.nMiCmdNumber, CMICmnMIResultRecord::eResultClass_Error, miValueResult );
m_miResultRecord = miRecordResult;
if( m_lldbResult.GetErrorSize() > 0 )
{
const CMICmnMIValueConst miValueConst( m_lldbResult.GetError() );
const CMICmnMIValueResult miValueResult( "message", miValueConst );
const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, miValueResult );
m_miResultRecord = miRecordResult;
}
else
{
const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Running );
m_miResultRecord = miRecordResult;
}
return MIstatus::success;
}
//++ ------------------------------------------------------------------------------------
// Details: Required by the CMICmdFactory when registering *this commmand. The factory
// Details: Required by the CMICmdFactory when registering *this command. The factory
// calls this function to create an instance of *this command.
// Type: Static method.
// Args: None.
@ -134,7 +158,7 @@ CMICmdCmdExecContinue::CMICmdCmdExecContinue( void )
// Command factory matches this name with that received from the stdin stream
m_strMiCmd = "exec-continue";
// Required by the CMICmdFactory when registering *this commmand
// Required by the CMICmdFactory when registering *this command
m_pSelfCreatorFn = &CMICmdCmdExecContinue::CreateSelf;
}
@ -160,11 +184,33 @@ CMICmdCmdExecContinue::~CMICmdCmdExecContinue( void )
//--
bool CMICmdCmdExecContinue::Execute( void )
{
// ToDo: Replace using LLDB public API functions instead of running a command
const char * pCmd = "continue";
const MIchar * pCmd = "continue";
CMICmnLLDBDebugSessionInfo & rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance() );
const lldb::ReturnStatus rtn = rSessionInfo.m_rLldbDebugger.GetCommandInterpreter().HandleCommand( pCmd, m_lldbResult );
const lldb::ReturnStatus rtn = rSessionInfo.m_rLldbDebugger.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 MIchar * pLldbErr = m_lldbResult.GetError();
const CMIUtilString strLldbMsg( CMIUtilString( pLldbErr ).StripCREndOfLine() );
if( strLldbMsg == "error: Process must be launched." )
{
CMIDriver::Instance().SetExitApplicationFlag( true );
}
}
return MIstatus::success;
}
@ -181,22 +227,14 @@ bool CMICmdCmdExecContinue::Acknowledge( void )
{
if( m_lldbResult.GetErrorSize() > 0 )
{
const char * pLldbErr = m_lldbResult.GetError();
const CMICmnMIValueConst miValueConst( m_lldbResult.GetError() );
const CMICmnMIValueResult miValueResult( "message", miValueConst );
const CMICmnMIResultRecord miRecordResult( m_cmdData.nMiCmdNumber, CMICmnMIResultRecord::eResultClass_Error, miValueResult );
const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, miValueResult );
m_miResultRecord = miRecordResult;
// ToDo: Re-evaluate if this is required when application near finished
const CMIUtilString strLldbMsg( CMIUtilString( pLldbErr ).StripCREndOfLine() );
if( strLldbMsg == "error: Process must be launched." )
{
CMIDriver::Instance().SetExitApplicationFlag();
}
}
else
{
const CMICmnMIResultRecord miRecordResult( m_cmdData.nMiCmdNumber, CMICmnMIResultRecord::eResultClass_Running );
const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Running );
m_miResultRecord = miRecordResult;
}
@ -204,7 +242,7 @@ bool CMICmdCmdExecContinue::Acknowledge( void )
}
//++ ------------------------------------------------------------------------------------
// Details: Required by the CMICmdFactory when registering *this commmand. The factory
// Details: Required by the CMICmdFactory when registering *this command. The factory
// calls this function to create an instance of *this command.
// Type: Static method.
// Args: None.
@ -234,7 +272,7 @@ CMICmdCmdExecNext::CMICmdCmdExecNext( void )
// Command factory matches this name with that received from the stdin stream
m_strMiCmd = "exec-next";
// Required by the CMICmdFactory when registering *this commmand
// Required by the CMICmdFactory when registering *this command
m_pSelfCreatorFn = &CMICmdCmdExecNext::CreateSelf;
}
@ -289,7 +327,7 @@ bool CMICmdCmdExecNext::Execute( void )
MIuint64 nThreadId = UINT64_MAX;
if( !pArgThread->GetExpectedOption< CMICmdArgValNumber, MIuint64 >( nThreadId ) )
{
SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_OPTION_NOT_FOUND ), m_cmdData.strMiCmd.c_str(), m_constStrArgThread.c_str() ) );
SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_THREAD_INVALID ), m_cmdData.strMiCmd.c_str(), m_constStrArgThread.c_str() ) );
return MIstatus::failure;
}
@ -316,15 +354,15 @@ bool CMICmdCmdExecNext::Acknowledge( void )
{
if( m_lldbResult.GetErrorSize() > 0 )
{
const char * pLldbErr = m_lldbResult.GetError();
const MIchar * pLldbErr = m_lldbResult.GetError(); MIunused( pLldbErr );
const CMICmnMIValueConst miValueConst( m_lldbResult.GetError() );
const CMICmnMIValueResult miValueResult( "message", miValueConst );
const CMICmnMIResultRecord miRecordResult( m_cmdData.nMiCmdNumber, CMICmnMIResultRecord::eResultClass_Error, miValueResult );
const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, miValueResult );
m_miResultRecord = miRecordResult;
}
else
{
const CMICmnMIResultRecord miRecordResult( m_cmdData.nMiCmdNumber, CMICmnMIResultRecord::eResultClass_Running );
const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Running );
m_miResultRecord = miRecordResult;
}
@ -332,7 +370,7 @@ bool CMICmdCmdExecNext::Acknowledge( void )
}
//++ ------------------------------------------------------------------------------------
// Details: Required by the CMICmdFactory when registering *this commmand. The factory
// Details: Required by the CMICmdFactory when registering *this command. The factory
// calls this function to create an instance of *this command.
// Type: Static method.
// Args: None.
@ -362,7 +400,7 @@ CMICmdCmdExecStep::CMICmdCmdExecStep( void )
// Command factory matches this name with that received from the stdin stream
m_strMiCmd = "exec-step";
// Required by the CMICmdFactory when registering *this commmand
// Required by the CMICmdFactory when registering *this command
m_pSelfCreatorFn = &CMICmdCmdExecStep::CreateSelf;
}
@ -444,15 +482,15 @@ bool CMICmdCmdExecStep::Acknowledge( void )
{
if( m_lldbResult.GetErrorSize() > 0 )
{
const char * pLldbErr = m_lldbResult.GetError();
const MIchar * pLldbErr = m_lldbResult.GetError(); MIunused( pLldbErr );
const CMICmnMIValueConst miValueConst( m_lldbResult.GetError() );
const CMICmnMIValueResult miValueResult( "message", miValueConst );
const CMICmnMIResultRecord miRecordResult( m_cmdData.nMiCmdNumber, CMICmnMIResultRecord::eResultClass_Error, miValueResult );
const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, miValueResult );
m_miResultRecord = miRecordResult;
}
else
{
const CMICmnMIResultRecord miRecordResult( m_cmdData.nMiCmdNumber, CMICmnMIResultRecord::eResultClass_Running );
const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Running );
m_miResultRecord = miRecordResult;
}
@ -460,7 +498,7 @@ bool CMICmdCmdExecStep::Acknowledge( void )
}
//++ ------------------------------------------------------------------------------------
// Details: Required by the CMICmdFactory when registering *this commmand. The factory
// Details: Required by the CMICmdFactory when registering *this command. The factory
// calls this function to create an instance of *this command.
// Type: Static method.
// Args: None.
@ -485,11 +523,12 @@ CMICmdBase * CMICmdCmdExecStep::CreateSelf( void )
//--
CMICmdCmdExecNextInstruction::CMICmdCmdExecNextInstruction( void )
: m_constStrArgThread( "thread" )
, m_constStrArgNumber( "number" )
{
// Command factory matches this name with that received from the stdin stream
m_strMiCmd = "exec-next-instruction";
// Required by the CMICmdFactory when registering *this commmand
// Required by the CMICmdFactory when registering *this command
m_pSelfCreatorFn = &CMICmdCmdExecNextInstruction::CreateSelf;
}
@ -516,6 +555,7 @@ CMICmdCmdExecNextInstruction::~CMICmdCmdExecNextInstruction( void )
bool CMICmdCmdExecNextInstruction::ParseArgs( void )
{
bool bOk = m_setCmdArgs.Add( *(new CMICmdArgValOptionLong( m_constStrArgThread, true, true, CMICmdArgValListBase::eArgValType_Number, 1 ) ) );
bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValNumber( m_constStrArgNumber, false, false ) ) );
CMICmdArgContext argCntxt( m_cmdData.strMiCmdOption );
if( bOk && !m_setCmdArgs.Validate( m_cmdData.strMiCmd, argCntxt ) )
{
@ -570,15 +610,15 @@ bool CMICmdCmdExecNextInstruction::Acknowledge( void )
{
if( m_lldbResult.GetErrorSize() > 0 )
{
const char * pLldbErr = m_lldbResult.GetError();
const MIchar * pLldbErr = m_lldbResult.GetError(); MIunused( pLldbErr );
const CMICmnMIValueConst miValueConst( m_lldbResult.GetError() );
const CMICmnMIValueResult miValueResult( "message", miValueConst );
const CMICmnMIResultRecord miRecordResult( m_cmdData.nMiCmdNumber, CMICmnMIResultRecord::eResultClass_Error, miValueResult );
const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, miValueResult );
m_miResultRecord = miRecordResult;
}
else
{
const CMICmnMIResultRecord miRecordResult( m_cmdData.nMiCmdNumber, CMICmnMIResultRecord::eResultClass_Running );
const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Running );
m_miResultRecord = miRecordResult;
}
@ -586,7 +626,7 @@ bool CMICmdCmdExecNextInstruction::Acknowledge( void )
}
//++ ------------------------------------------------------------------------------------
// Details: Required by the CMICmdFactory when registering *this commmand. The factory
// Details: Required by the CMICmdFactory when registering *this command. The factory
// calls this function to create an instance of *this command.
// Type: Static method.
// Args: None.
@ -611,11 +651,12 @@ CMICmdBase * CMICmdCmdExecNextInstruction::CreateSelf( void )
//--
CMICmdCmdExecStepInstruction::CMICmdCmdExecStepInstruction( void )
: m_constStrArgThread( "thread" )
, m_constStrArgNumber( "number" )
{
// Command factory matches this name with that received from the stdin stream
m_strMiCmd = "exec-step-instruction";
// Required by the CMICmdFactory when registering *this commmand
// Required by the CMICmdFactory when registering *this command
m_pSelfCreatorFn = &CMICmdCmdExecStepInstruction::CreateSelf;
}
@ -642,6 +683,7 @@ CMICmdCmdExecStepInstruction::~CMICmdCmdExecStepInstruction( void )
bool CMICmdCmdExecStepInstruction::ParseArgs( void )
{
bool bOk = m_setCmdArgs.Add( *(new CMICmdArgValOptionLong( m_constStrArgThread, true, true, CMICmdArgValListBase::eArgValType_Number, 1 ) ) );
bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValNumber( m_constStrArgNumber, false, false ) ) );
CMICmdArgContext argCntxt( m_cmdData.strMiCmdOption );
if( bOk && !m_setCmdArgs.Validate( m_cmdData.strMiCmd, argCntxt ) )
{
@ -696,15 +738,15 @@ bool CMICmdCmdExecStepInstruction::Acknowledge( void )
{
if( m_lldbResult.GetErrorSize() > 0 )
{
const char * pLldbErr = m_lldbResult.GetError();
const MIchar * pLldbErr = m_lldbResult.GetError(); MIunused( pLldbErr );
const CMICmnMIValueConst miValueConst( m_lldbResult.GetError() );
const CMICmnMIValueResult miValueResult( "message", miValueConst );
const CMICmnMIResultRecord miRecordResult( m_cmdData.nMiCmdNumber, CMICmnMIResultRecord::eResultClass_Error, miValueResult );
const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, miValueResult );
m_miResultRecord = miRecordResult;
}
else
{
const CMICmnMIResultRecord miRecordResult( m_cmdData.nMiCmdNumber, CMICmnMIResultRecord::eResultClass_Running );
const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Running );
m_miResultRecord = miRecordResult;
}
@ -712,7 +754,7 @@ bool CMICmdCmdExecStepInstruction::Acknowledge( void )
}
//++ ------------------------------------------------------------------------------------
// Details: Required by the CMICmdFactory when registering *this commmand. The factory
// Details: Required by the CMICmdFactory when registering *this command. The factory
// calls this function to create an instance of *this command.
// Type: Static method.
// Args: None.
@ -742,7 +784,7 @@ CMICmdCmdExecFinish::CMICmdCmdExecFinish( void )
// Command factory matches this name with that received from the stdin stream
m_strMiCmd = "exec-finish";
// Required by the CMICmdFactory when registering *this commmand
// Required by the CMICmdFactory when registering *this command
m_pSelfCreatorFn = &CMICmdCmdExecFinish::CreateSelf;
}
@ -824,15 +866,15 @@ bool CMICmdCmdExecFinish::Acknowledge( void )
{
if( m_lldbResult.GetErrorSize() > 0 )
{
const char * pLldbErr = m_lldbResult.GetError();
const MIchar * pLldbErr = m_lldbResult.GetError(); MIunused( pLldbErr );
const CMICmnMIValueConst miValueConst( m_lldbResult.GetError() );
const CMICmnMIValueResult miValueResult( "message", miValueConst );
const CMICmnMIResultRecord miRecordResult( m_cmdData.nMiCmdNumber, CMICmnMIResultRecord::eResultClass_Error, miValueResult );
const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, miValueResult );
m_miResultRecord = miRecordResult;
}
else
{
const CMICmnMIResultRecord miRecordResult( m_cmdData.nMiCmdNumber, CMICmnMIResultRecord::eResultClass_Running );
const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Running );
m_miResultRecord = miRecordResult;
}
@ -840,7 +882,7 @@ bool CMICmdCmdExecFinish::Acknowledge( void )
}
//++ ------------------------------------------------------------------------------------
// Details: Required by the CMICmdFactory when registering *this commmand. The factory
// Details: Required by the CMICmdFactory when registering *this command. The factory
// calls this function to create an instance of *this command.
// Type: Static method.
// Args: None.
@ -852,3 +894,101 @@ CMICmdBase * CMICmdCmdExecFinish::CreateSelf( void )
return new CMICmdCmdExecFinish();
}
//---------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------
//++ ------------------------------------------------------------------------------------
// Details: CMICmdCmdExecInterrupt constructor.
// Type: Method.
// Args: None.
// Return: None.
// Throws: None.
//--
CMICmdCmdExecInterrupt::CMICmdCmdExecInterrupt( void )
{
// Command factory matches this name with that received from the stdin stream
m_strMiCmd = "exec-interrupt";
// Required by the CMICmdFactory when registering *this command
m_pSelfCreatorFn = &CMICmdCmdExecInterrupt::CreateSelf;
}
//++ ------------------------------------------------------------------------------------
// Details: CMICmdCmdExecInterrupt destructor.
// Type: Overrideable.
// Args: None.
// Return: None.
// Throws: None.
//--
CMICmdCmdExecInterrupt::~CMICmdCmdExecInterrupt( void )
{
}
//++ ------------------------------------------------------------------------------------
// 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 CMICmdCmdExecInterrupt::Execute( void )
{
CMICmnLLDBDebugSessionInfo & rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance() );
lldb::SBDebugger & rDebugger = rSessionInfo.m_rLldbDebugger;
CMIUtilString strCmd( "process interrupt" );
const lldb::ReturnStatus status = rDebugger.GetCommandInterpreter().HandleCommand( strCmd.c_str(), m_lldbResult, false ); MIunused( status );
// CODETAG_DEBUG_SESSION_RUNNING_PROG_RECEIVED_SIGINT_PAUSE_PROGRAM
if( !CMIDriver::Instance().SetDriverStateRunningNotDebugging() )
{
const CMIUtilString & rErrMsg( CMIDriver::Instance().GetErrorDescription() );
SetErrorDescription( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_SET_NEW_DRIVER_STATE ), strCmd.c_str(), rErrMsg.c_str() ) );
return MIstatus::failure;
}
return MIstatus::success;
}
//++ ------------------------------------------------------------------------------------
// Details: The invoker requires this function. The command prepares a MI Record Result
// for the work carried out in the Execute().
// Type: Overridden.
// Args: None.
// Return: MIstatus::success - Functional succeeded.
// MIstatus::failure - Functional failed.
// Throws: None.
//--
bool CMICmdCmdExecInterrupt::Acknowledge( void )
{
if( m_lldbResult.GetErrorSize() > 0 )
{
const CMICmnMIValueConst miValueConst( m_lldbResult.GetError() );
const CMICmnMIValueResult miValueResult( "message", miValueConst );
const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, miValueResult );
m_miResultRecord = miRecordResult;
}
else
{
const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done );
m_miResultRecord = miRecordResult;
}
return MIstatus::success;
}
//++ ------------------------------------------------------------------------------------
// Details: Required by the CMICmdFactory when registering *this command. The factory
// calls this function to create an instance of *this command.
// Type: Static method.
// Args: None.
// Return: CMICmdBase * - Pointer to a new command.
// Throws: None.
//--
CMICmdBase * CMICmdCmdExecInterrupt::CreateSelf( void )
{
return new CMICmdCmdExecInterrupt();
}

View File

@ -17,6 +17,7 @@
// CMICmdCmdExecNextInstruction interface.
// CMICmdCmdExecStepInstruction interface.
// CMICmdCmdExecFinish interface.
// CMICmdCmdExecInterupt interface.
//
// To implement new MI commands derive a new command class from the command base
// class. To enable the new command for interpretation add the new command class
@ -53,7 +54,7 @@ class CMICmdCmdExecRun : public CMICmdBase
{
// Statics:
public:
// Required by the CMICmdFactory when registering *this commmand
// Required by the CMICmdFactory when registering *this command
static CMICmdBase * CreateSelf( void );
// Methods:
@ -65,11 +66,12 @@ public:
// From CMICmdInvoker::ICmd
virtual bool Execute( void );
virtual bool Acknowledge( void );
// Overridden:
public:
// From CMICmnBase
/* dtor */ virtual ~CMICmdCmdExecRun( void );
// Attributes:
private:
lldb::SBCommandReturnObject m_lldbResult;
};
//++ ============================================================================
@ -83,7 +85,7 @@ class CMICmdCmdExecContinue : public CMICmdBase
{
// Statics:
public:
// Required by the CMICmdFactory when registering *this commmand
// Required by the CMICmdFactory when registering *this command
static CMICmdBase * CreateSelf( void );
// Methods:
@ -95,9 +97,6 @@ public:
// From CMICmdInvoker::ICmd
virtual bool Execute( void );
virtual bool Acknowledge( void );
// Overridden:
public:
// From CMICmnBase
/* dtor */ virtual ~CMICmdCmdExecContinue( void );
@ -117,7 +116,7 @@ class CMICmdCmdExecNext : public CMICmdBase
{
// Statics:
public:
// Required by the CMICmdFactory when registering *this commmand
// Required by the CMICmdFactory when registering *this command
static CMICmdBase * CreateSelf( void );
// Methods:
@ -130,9 +129,6 @@ public:
virtual bool Execute( void );
virtual bool Acknowledge( void );
virtual bool ParseArgs( void );
// Overridden:
public:
// From CMICmnBase
/* dtor */ virtual ~CMICmdCmdExecNext( void );
@ -154,7 +150,7 @@ class CMICmdCmdExecStep : public CMICmdBase
{
// Statics:
public:
// Required by the CMICmdFactory when registering *this commmand
// Required by the CMICmdFactory when registering *this command
static CMICmdBase * CreateSelf( void );
// Methods:
@ -167,9 +163,6 @@ public:
virtual bool Execute( void );
virtual bool Acknowledge( void );
virtual bool ParseArgs( void );
// Overridden:
public:
// From CMICmnBase
/* dtor */ virtual ~CMICmdCmdExecStep( void );
@ -191,7 +184,7 @@ class CMICmdCmdExecNextInstruction : public CMICmdBase
{
// Statics:
public:
// Required by the CMICmdFactory when registering *this commmand
// Required by the CMICmdFactory when registering *this command
static CMICmdBase * CreateSelf( void );
// Methods:
@ -204,9 +197,6 @@ public:
virtual bool Execute( void );
virtual bool Acknowledge( void );
virtual bool ParseArgs( void );
// Overridden:
public:
// From CMICmnBase
/* dtor */ virtual ~CMICmdCmdExecNextInstruction( void );
@ -214,6 +204,7 @@ public:
private:
lldb::SBCommandReturnObject m_lldbResult;
const CMIUtilString m_constStrArgThread; // Not specified in MI spec but Eclipse gives this option
const CMIUtilString m_constStrArgNumber; // Not specified in MI spec but Eclipse gives this option
};
//++ ============================================================================
@ -227,7 +218,7 @@ class CMICmdCmdExecStepInstruction : public CMICmdBase
{
// Statics:
public:
// Required by the CMICmdFactory when registering *this commmand
// Required by the CMICmdFactory when registering *this command
static CMICmdBase * CreateSelf( void );
// Methods:
@ -240,9 +231,6 @@ public:
virtual bool Execute( void );
virtual bool Acknowledge( void );
virtual bool ParseArgs( void );
// Overridden:
public:
// From CMICmnBase
/* dtor */ virtual ~CMICmdCmdExecStepInstruction( void );
@ -250,6 +238,7 @@ public:
private:
lldb::SBCommandReturnObject m_lldbResult;
const CMIUtilString m_constStrArgThread; // Not specified in MI spec but Eclipse gives this option
const CMIUtilString m_constStrArgNumber; // Not specified in MI spec but Eclipse gives this option
};
//++ ============================================================================
@ -263,7 +252,7 @@ class CMICmdCmdExecFinish : public CMICmdBase
{
// Statics:
public:
// Required by the CMICmdFactory when registering *this commmand
// Required by the CMICmdFactory when registering *this command
static CMICmdBase * CreateSelf( void );
// Methods:
@ -276,9 +265,6 @@ public:
virtual bool Execute( void );
virtual bool Acknowledge( void );
virtual bool ParseArgs( void );
// Overridden:
public:
// From CMICmnBase
/* dtor */ virtual ~CMICmdCmdExecFinish( void );
@ -289,3 +275,36 @@ private:
const CMIUtilString m_constStrArgFrame; // Not specified in MI spec but Eclipse gives this option
};
// CODETAG_DEBUG_SESSION_RUNNING_PROG_RECEIVED_SIGINT_PAUSE_PROGRAM
//++ ============================================================================
// Details: MI command class. MI commands derived from the command base class.
// *this class implements MI command "exec-interrupt".
// Gotchas: Using Eclipse this command is injected into the command system when a
// SIGINT signal is received while running an inferior program.
// Authors: Illya Rudkin 03/06/2014.
// Changes: None.
//--
class CMICmdCmdExecInterrupt : public CMICmdBase
{
// Statics:
public:
// Required by the CMICmdFactory when registering *this command
static CMICmdBase * CreateSelf( void );
// Methods:
public:
/* ctor */ CMICmdCmdExecInterrupt( void );
// Overridden:
public:
// From CMICmdInvoker::ICmd
virtual bool Execute( void );
virtual bool Acknowledge( void );
// From CMICmnBase
/* dtor */ virtual ~CMICmdCmdExecInterrupt( void );
// Attributes:
private:
lldb::SBCommandReturnObject m_lldbResult;
};

View File

@ -53,7 +53,7 @@ CMICmdCmdFileExecAndSymbols::CMICmdCmdFileExecAndSymbols( void )
// Command factory matches this name with that received from the stdin stream
m_strMiCmd = "file-exec-and-symbols";
// Required by the CMICmdFactory when registering *this commmand
// Required by the CMICmdFactory when registering *this command
m_pSelfCreatorFn = &CMICmdCmdFileExecAndSymbols::CreateSelf;
}
@ -109,17 +109,17 @@ bool CMICmdCmdFileExecAndSymbols::Execute( void )
const CMIUtilString & strExeFilePath( pArgFile->GetValue() );
CMICmnLLDBDebugSessionInfo & rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance() );
lldb::SBDebugger & rDbgr = rSessionInfo.m_rLldbDebugger;
lldb::SBError error;
const char * pTargetTriple = nullptr; // Let LLDB discover the triple required
const char * pTargetPlatformName = "";
lldb::SBError error;
const MIchar * pTargetTriple = nullptr; // Let LLDB discover the triple required
const MIchar * pTargetPlatformName = "";
const bool bAddDepModules = false;
lldb::SBTarget target = rDbgr.CreateTarget( strExeFilePath.c_str(), pTargetTriple, pTargetPlatformName, bAddDepModules, error );
CMIUtilString strWkDir;
const CMIUtilString & rStrKeyWkDir( rSessionInfo.m_constStrSharedDataKeyWkDir );
if( !rSessionInfo.SharedDataRetrieve( rStrKeyWkDir, strWkDir ) )
if( !rSessionInfo.SharedDataRetrieve< CMIUtilString >( rStrKeyWkDir, strWkDir ) )
{
strWkDir = CMIUtilFileStd().StripOffFileName( strExeFilePath );
if( !rSessionInfo.SharedDataAdd( rStrKeyWkDir, strWkDir ) )
if( !rSessionInfo.SharedDataAdd< CMIUtilString >( rStrKeyWkDir, strWkDir ) )
{
SetError( CMIUtilString::Format( MIRSRC( IDS_DBGSESSION_ERR_SHARED_DATA_ADD ), m_cmdData.strMiCmd.c_str(), rStrKeyWkDir.c_str() ) );
return MIstatus::failure;
@ -133,7 +133,9 @@ bool CMICmdCmdFileExecAndSymbols::Execute( void )
}
lldb::SBStream err;
if( error.Fail() )
const bool bOk = error.GetDescription( err );
{
const bool bOk = error.GetDescription( err ); MIunused( bOk );
}
if( !target.IsValid() )
{
SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_INVALID_TARGET ), m_cmdData.strMiCmd.c_str(), strExeFilePath.c_str(), err.GetData() ) );
@ -161,14 +163,14 @@ bool CMICmdCmdFileExecAndSymbols::Execute( void )
//--
bool CMICmdCmdFileExecAndSymbols::Acknowledge( void )
{
const CMICmnMIResultRecord miRecordResult( m_cmdData.nMiCmdNumber, CMICmnMIResultRecord::eResultClass_Done );
const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done );
m_miResultRecord = miRecordResult;
return MIstatus::success;
}
//++ ------------------------------------------------------------------------------------
// Details: Required by the CMICmdFactory when registering *this commmand. The factory
// Details: Required by the CMICmdFactory when registering *this command. The factory
// calls this function to create an instance of *this command.
// Type: Static method.
// Args: None.

View File

@ -47,7 +47,7 @@ class CMICmdCmdFileExecAndSymbols : public CMICmdBase
{
// Statics:
public:
// Required by the CMICmdFactory when registering *this commmand
// Required by the CMICmdFactory when registering *this command
static CMICmdBase * CreateSelf( void );
// Methods:
@ -60,9 +60,6 @@ public:
virtual bool Execute( void );
virtual bool Acknowledge( void );
virtual bool ParseArgs( void );
// Overridden:
public:
// From CMICmnBase
/* dtor */ virtual ~CMICmdCmdFileExecAndSymbols( void );
@ -70,4 +67,4 @@ public:
private:
const CMIUtilString m_constStrArgNameFile;
const CMIUtilString m_constStrArgThreadGrp; // Not handled by *this command. Not specified in MI spec but Eclipse gives this option sometimes
};
};

View File

@ -0,0 +1,240 @@
//===-- MICmdCmdGdbInfo.cpp ------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//++
// File: MICmdCmdGdbInfo.cpp
//
// Overview: CMICmdCmdGdbInfo implementation.
//
// Environment: Compilers: Visual C++ 12.
// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
// Libraries: See MIReadmetxt.
//
// Copyright: None.
//--
// Third party headers:
#include <lldb/API/SBCommandReturnObject.h>
// In-house headers:
#include "MICmdCmdGdbInfo.h"
#include "MICmnMIResultRecord.h"
#include "MICmnMIValueConst.h"
#include "MICmdArgContext.h"
#include "MICmdArgValString.h"
#include "MICmnStreamStdout.h"
#include "MICmnLLDBDebugSessionInfo.h"
// Instantiations:
const CMICmdCmdGdbInfo::MapPrintFnNameToPrintFn_t CMICmdCmdGdbInfo::ms_mapPrintFnNameToPrintFn =
{
{ "sharedlibrary", &CMICmdCmdGdbInfo::PrintFnSharedLibrary }
};
//++ ------------------------------------------------------------------------------------
// Details: CMICmdCmdGdbInfo constructor.
// Type: Method.
// Args: None.
// Return: None.
// Throws: None.
//--
CMICmdCmdGdbInfo::CMICmdCmdGdbInfo( void )
: m_constStrArgNamedPrint( "print" )
, m_bPrintFnRecognised( true )
, m_bPrintFnSuccessful( false )
, m_strPrintFnError( MIRSRC( IDS_WORD_ERR_MSG_NOT_IMPLEMENTED_BRKTS ) )
{
// Command factory matches this name with that received from the stdin stream
m_strMiCmd = "info";
// Required by the CMICmdFactory when registering *this command
m_pSelfCreatorFn = &CMICmdCmdGdbInfo::CreateSelf;
}
//++ ------------------------------------------------------------------------------------
// Details: CMICmdCmdGdbInfo destructor.
// Type: Overrideable.
// Args: None.
// Return: None.
// Throws: None.
//--
CMICmdCmdGdbInfo::~CMICmdCmdGdbInfo( void )
{
}
//++ ------------------------------------------------------------------------------------
// Details: The invoker requires this function. The parses the command line options
// arguments to extract values for each of those arguments.
// Type: Overridden.
// Args: None.
// Return: MIstatus::success - Functional succeeded.
// MIstatus::failure - Functional failed.
// Throws: None.
//--
bool CMICmdCmdGdbInfo::ParseArgs( void )
{
bool bOk = m_setCmdArgs.Add( *(new CMICmdArgValString( m_constStrArgNamedPrint, true, true ) ) );
CMICmdArgContext argCntxt( m_cmdData.strMiCmdOption );
if( bOk && !m_setCmdArgs.Validate( m_cmdData.strMiCmd, argCntxt ) )
{
SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_ARGS ), m_cmdData.strMiCmd.c_str(), m_setCmdArgs.GetErrorDescription().c_str() ) );
return MIstatus::failure;
}
return bOk;
}
//++ ------------------------------------------------------------------------------------
// 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 CMICmdCmdGdbInfo::Execute( void )
{
CMICMDBASE_GETOPTION( pArgPrint, String, m_constStrArgNamedPrint );
const CMIUtilString & rPrintRequest( pArgPrint->GetValue() );
FnPrintPtr pPrintRequestFn = nullptr;
if( !GetPrintFn( rPrintRequest, pPrintRequestFn ) )
{
m_strPrintFnName = rPrintRequest;
m_bPrintFnRecognised = false;
return MIstatus::success;
}
m_bPrintFnSuccessful = (this->*(pPrintRequestFn))();
return MIstatus::success;
}
//++ ------------------------------------------------------------------------------------
// Details: The invoker requires this function. The command prepares a MI Record Result
// for the work carried out in the Execute().
// Type: Overridden.
// Args: None.
// Return: MIstatus::success - Functional succeeded.
// MIstatus::failure - Functional failed.
// Throws: None.
//--
bool CMICmdCmdGdbInfo::Acknowledge( void )
{
if( !m_bPrintFnRecognised )
{
const CMICmnMIValueConst miValueConst( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_INFO_PRINTFN_NOT_FOUND ), m_strPrintFnName.c_str() ) );
const CMICmnMIValueResult miValueResult( "msg", miValueConst );
const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, miValueResult );
m_miResultRecord = miRecordResult;
return MIstatus::success;
}
if( m_bPrintFnSuccessful )
{
const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done );
m_miResultRecord = miRecordResult;
return MIstatus::success;
}
const CMICmnMIValueConst miValueConst( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_INFO_PRINTFN_FAILED ), m_strPrintFnError.c_str() ) );
const CMICmnMIValueResult miValueResult( "msg", miValueConst );
const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, miValueResult );
m_miResultRecord = miRecordResult;
return MIstatus::success;
}
//++ ------------------------------------------------------------------------------------
// Details: Required by the CMICmdFactory when registering *this command. The factory
// calls this function to create an instance of *this command.
// Type: Static method.
// Args: None.
// Return: CMICmdBase * - Pointer to a new command.
// Throws: None.
//--
CMICmdBase * CMICmdCmdGdbInfo::CreateSelf( void )
{
return new CMICmdCmdGdbInfo();
}
//++ ------------------------------------------------------------------------------------
// Details: Retrieve the print function's pointer for the matching print request.
// Type: Method.
// Args: vrPrintFnName - (R) The info requested.
// vrwpFn - (W) The print function's pointer of the function to carry out
// Return: bool - True = Print request is implemented, false = not found.
// Throws: None.
//--
bool CMICmdCmdGdbInfo::GetPrintFn( const CMIUtilString & vrPrintFnName, FnPrintPtr & vrwpFn ) const
{
vrwpFn = nullptr;
const MapPrintFnNameToPrintFn_t::const_iterator it = ms_mapPrintFnNameToPrintFn.find( vrPrintFnName );
if( it != ms_mapPrintFnNameToPrintFn.end() )
{
vrwpFn = (*it).second;
return true;
}
return false;
}
//++ ------------------------------------------------------------------------------------
// Details: Carry out work to complete the request to prepare and send back information
// asked for.
// Type: Method.
// Args: None.
// Return: MIstatus::success - Functional succeeded.
// MIstatus::failure - Functional failed.
// Throws: None.
//--
bool CMICmdCmdGdbInfo::PrintFnSharedLibrary( void )
{
CMICmnStreamStdout & rStdout = CMICmnStreamStdout::Instance();
bool bOk = rStdout.TextToStdout( "~\"From To Syms Read Shared Object Library\"" );
CMICmnLLDBDebugSessionInfo & rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance() );
lldb::SBTarget & rTarget = rSessionInfo.m_lldbTarget;
const MIuint nModules = rTarget.GetNumModules();
for( MIuint i = 0; bOk && (i < nModules); i++ )
{
lldb::SBModule module = rTarget.GetModuleAtIndex( i );
if( module.IsValid() )
{
const CMIUtilString strModuleFilePath( module.GetFileSpec().GetDirectory() );
const CMIUtilString strModuleFileName( module.GetFileSpec().GetFilename() );
const CMIUtilString strModuleFullPath( CMIUtilString::Format( "%s/%s", strModuleFilePath.c_str(), strModuleFileName.c_str() ) );
const CMIUtilString strHasSymbols = (module.GetNumSymbols() > 0) ? "Yes" : "No";
lldb::addr_t addrLoadS = 0xffffffff;
lldb::addr_t addrLoadSize = 0;
bool bHaveAddrLoad = false;
const MIuint nSections = module.GetNumSections();
for( MIuint j = 0; j < nSections; j++ )
{
lldb::SBSection section = module.GetSectionAtIndex( j );
lldb::addr_t addrLoad = section.GetLoadAddress( rTarget );
if( addrLoad != (lldb::addr_t) -1 )
{
if( !bHaveAddrLoad )
{
bHaveAddrLoad = true;
addrLoadS = addrLoad;
}
addrLoadSize += section.GetByteSize();
}
}
bOk = bOk && rStdout.TextToStdout( CMIUtilString::Format( "~\"0x%08x\t0x%08x\t%s\t\t%s\"", addrLoadS, addrLoadS + addrLoadSize, strHasSymbols.c_str(), strModuleFullPath.c_str() ) );
}
}
return bOk;
}

View File

@ -0,0 +1,93 @@
//===-- MICmdCmdGdbInfo.h --------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//++
// File: MICmdCmdGdbInfo.h
//
// Overview: CMICmdCmdGdbInfo interface.
//
// To implement new MI commands derive a new command class from the command base
// class. To enable the new command for interpretation add the new command class
// to the command factory. The files of relevance are:
// MICmdCommands.cpp
// MICmdBase.h / .cpp
// MICmdCmd.h / .cpp
// For an introduction to adding a new command see CMICmdCmdSupportInfoMiCmdQuery
// command class as an example.
//
// Environment: Compilers: Visual C++ 12.
// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
// Libraries: See MIReadmetxt.
//
// Copyright: None.
//--
#pragma once
// Third party headers:
#include <map>
// In-house headers:
#include "MICmdBase.h"
//++ ============================================================================
// Details: MI command class. MI commands derived from the command base class.
// *this class implements GDB command "info".
// The design of matching the info request to a request action (or
// command) is very simple. The request function which carries out
// the task of information gathering and printing to stdout is part of
// *this class. Should the request function become more complicated then
// that request should really reside in a command type class. Then this
// class instantiates a request info command for a matching request. The
// design/code of *this class then does not then become bloated. Use a
// lightweight version of the current MI command system.
// Gotchas: None.
// Authors: Illya Rudkin 05/06/2014.
// Changes: None.
//--
class CMICmdCmdGdbInfo : public CMICmdBase
{
// Statics:
public:
// Required by the CMICmdFactory when registering *this command
static CMICmdBase * CreateSelf( void );
// Methods:
public:
/* ctor */ CMICmdCmdGdbInfo( void );
// Overridden:
public:
// From CMICmdInvoker::ICmd
virtual bool Execute( void );
virtual bool Acknowledge( void );
virtual bool ParseArgs( void );
// From CMICmnBase
/* dtor */ virtual ~CMICmdCmdGdbInfo( void );
// Typedefs:
private:
typedef bool (CMICmdCmdGdbInfo::*FnPrintPtr)();
typedef std::map< CMIUtilString, FnPrintPtr > MapPrintFnNameToPrintFn_t;
// Methods:
private:
bool GetPrintFn( const CMIUtilString & vrPrintFnName, FnPrintPtr & vrwpFn ) const;
bool PrintFnSharedLibrary( void );
// Attributes:
private:
const static MapPrintFnNameToPrintFn_t ms_mapPrintFnNameToPrintFn;
//
const CMIUtilString m_constStrArgNamedPrint;
bool m_bPrintFnRecognised; // True = This command has a function with a name that matches the Print argument, false = not found
bool m_bPrintFnSuccessful; // True = The print function completed its task ok, false = function failed for some reason
CMIUtilString m_strPrintFnName;
CMIUtilString m_strPrintFnError;
};

View File

@ -0,0 +1,265 @@
//===-- MICmdCmdGdbSet.cpp ------- -------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//++
// File: MICmdCmdGdbSet.cpp
//
// Overview: CMICmdCmdGdbSet implementation.
//
// Environment: Compilers: Visual C++ 12.
// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
// Libraries: See MIReadmetxt.
//
// Copyright: None.
//--
// In-house headers:
#include "MICmdCmdGdbSet.h"
#include "MICmnMIResultRecord.h"
#include "MICmnMIValueConst.h"
#include "MICmdArgContext.h"
#include "MICmdArgValString.h"
#include "MICmdArgValListOfN.h"
#include "MICmnLLDBDebugSessionInfo.h"
// Instantiations:
const CMICmdCmdGdbSet::MapGdbOptionNameToFnGdbOptionPtr_t CMICmdCmdGdbSet::ms_mapGdbOptionNameToFnGdbOptionPtr =
{
// { "target-async", &CMICmdCmdGdbSet::OptionFnTargetAsync }, // Example code if need to implement GDB set other options
// { "auto-solib-add", &CMICmdCmdGdbSet::OptionFnAutoSolibAdd }, // Example code if need to implement GDB set other options
{ "solib-search-path", &CMICmdCmdGdbSet::OptionFnSolibSearchPath },
{ "fallback", &CMICmdCmdGdbSet::OptionFnFallback }
};
//++ ------------------------------------------------------------------------------------
// Details: CMICmdCmdGdbSet constructor.
// Type: Method.
// Args: None.
// Return: None.
// Throws: None.
//--
CMICmdCmdGdbSet::CMICmdCmdGdbSet( void )
: m_constStrArgNamedGdbOption( "option" )
, m_bGdbOptionRecognised( true )
, m_bGdbOptionFnSuccessful( false )
, m_bGbbOptionFnHasError( false )
, m_strGdbOptionFnError( MIRSRC( IDS_WORD_ERR_MSG_NOT_IMPLEMENTED_BRKTS ) )
{
// Command factory matches this name with that received from the stdin stream
m_strMiCmd = "gdb-set";
// Required by the CMICmdFactory when registering *this command
m_pSelfCreatorFn = &CMICmdCmdGdbSet::CreateSelf;
}
//++ ------------------------------------------------------------------------------------
// Details: CMICmdCmdGdbSet destructor.
// Type: Overrideable.
// Args: None.
// Return: None.
// Throws: None.
//--
CMICmdCmdGdbSet::~CMICmdCmdGdbSet( void )
{
}
//++ ------------------------------------------------------------------------------------
// Details: The invoker requires this function. The parses the command line options
// arguments to extract values for each of those arguments.
// Type: Overridden.
// Args: None.
// Return: MIstatus::success - Functional succeeded.
// MIstatus::failure - Functional failed.
// Throws: None.
//--
bool CMICmdCmdGdbSet::ParseArgs( void )
{
bool bOk = m_setCmdArgs.Add( *(new CMICmdArgValListOfN( m_constStrArgNamedGdbOption, true, true, CMICmdArgValListBase::eArgValType_StringQuotedNumberPath ) ) );
CMICmdArgContext argCntxt( m_cmdData.strMiCmdOption );
if( bOk && !m_setCmdArgs.Validate( m_cmdData.strMiCmd, argCntxt ) )
{
SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_ARGS ), m_cmdData.strMiCmd.c_str(), m_setCmdArgs.GetErrorDescription().c_str() ) );
return MIstatus::failure;
}
return bOk;
}
//++ ------------------------------------------------------------------------------------
// 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 CMICmdCmdGdbSet::Execute( void )
{
CMICMDBASE_GETOPTION( pArgGdbOption, ListOfN, m_constStrArgNamedGdbOption );
const CMICmdArgValListBase::VecArgObjPtr_t & rVecWords( pArgGdbOption->GetExpectedOptions() );
// Get the gdb-set option to carry out
CMICmdArgValListBase::VecArgObjPtr_t::const_iterator it = rVecWords.begin();
const CMICmdArgValString * pOption = static_cast< const CMICmdArgValString * >( *it );
const CMIUtilString strOption( pOption->GetValue() );
++it;
// Retrieve the parameter(s) for the option
CMIUtilString::VecString_t vecWords;
while( it != rVecWords.end() )
{
const CMICmdArgValString * pWord = static_cast< const CMICmdArgValString * >( *it );
vecWords.push_back( pWord->GetValue() );
// Next
++it;
}
FnGdbOptionPtr pPrintRequestFn = nullptr;
if( !GetOptionFn( strOption, pPrintRequestFn ) )
{
// For unimplemented option handlers, fallback on a generic handler
// ToDo: Remove this when ALL options have been implemented
if( !GetOptionFn( "fallback", pPrintRequestFn ) )
{
m_bGdbOptionRecognised = false;
m_strGdbOptionName = "fallback"; // This would be the strOption name
return MIstatus::success;
}
}
m_bGdbOptionFnSuccessful = (this->*(pPrintRequestFn))( vecWords );
if( !m_bGdbOptionFnSuccessful && !m_bGbbOptionFnHasError )
return MIstatus::failure;
return MIstatus::success;
}
//++ ------------------------------------------------------------------------------------
// Details: The invoker requires this function. The command prepares a MI Record Result
// for the work carried out in the Execute().
// Type: Overridden.
// Args: None.
// Return: MIstatus::success - Functional succeeded.
// MIstatus::failure - Functional failed.
// Throws: None.
//--
bool CMICmdCmdGdbSet::Acknowledge( void )
{
if( !m_bGdbOptionRecognised )
{
const CMICmnMIValueConst miValueConst( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_INFO_PRINTFN_NOT_FOUND ), m_strGdbOptionName.c_str() ) );
const CMICmnMIValueResult miValueResult( "msg", miValueConst );
const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, miValueResult );
m_miResultRecord = miRecordResult;
return MIstatus::success;
}
if( m_bGdbOptionFnSuccessful )
{
const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done );
m_miResultRecord = miRecordResult;
return MIstatus::success;
}
const CMICmnMIValueConst miValueConst( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_INFO_PRINTFN_FAILED ), m_strGdbOptionFnError.c_str() ) );
const CMICmnMIValueResult miValueResult( "msg", miValueConst );
const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, miValueResult );
m_miResultRecord = miRecordResult;
return MIstatus::success;
}
//++ ------------------------------------------------------------------------------------
// Details: Required by the CMICmdFactory when registering *this command. The factory
// calls this function to create an instance of *this command.
// Type: Static method.
// Args: None.
// Return: CMICmdBase * - Pointer to a new command.
// Throws: None.
//--
CMICmdBase * CMICmdCmdGdbSet::CreateSelf( void )
{
return new CMICmdCmdGdbSet();
}
//++ ------------------------------------------------------------------------------------
// Details: Retrieve the print function's pointer for the matching print request.
// Type: Method.
// Args: vrPrintFnName - (R) The info requested.
// vrwpFn - (W) The print function's pointer of the function to carry out
// Return: bool - True = Print request is implemented, false = not found.
// Throws: None.
//--
bool CMICmdCmdGdbSet::GetOptionFn( const CMIUtilString & vrPrintFnName, FnGdbOptionPtr & vrwpFn ) const
{
vrwpFn = nullptr;
const MapGdbOptionNameToFnGdbOptionPtr_t::const_iterator it = ms_mapGdbOptionNameToFnGdbOptionPtr.find( vrPrintFnName );
if( it != ms_mapGdbOptionNameToFnGdbOptionPtr.end() )
{
vrwpFn = (*it).second;
return true;
}
return false;
}
//++ ------------------------------------------------------------------------------------
// Details: Carry out work to complete the GDB set option 'solib-search-path' to prepare
// and send back information asked for.
// Type: Method.
// Args: vrWords - (R) List of additional parameters used by this option.
// Return: MIstatus::success - Functional succeeded.
// MIstatus::failure - Functional failed.
// Throws: None.
//--
bool CMICmdCmdGdbSet::OptionFnSolibSearchPath( const CMIUtilString::VecString_t & vrWords )
{
// Check we have at least one argument
if( vrWords.size() < 1 )
{
m_bGbbOptionFnHasError = true;
m_strGdbOptionFnError = MIRSRC( IDS_CMD_ERR_GDBSET_OPT_SOLIBSEARCHPATH );
return MIstatus::failure;
}
const CMIUtilString & rStrValSolibPath( vrWords[ 0 ] );
// Add 'solib-search-path' to the shared data list
const CMIUtilString & rStrKeySolibPath( m_rLLDBDebugSessionInfo.m_constStrSharedDataSolibPath );
if( !m_rLLDBDebugSessionInfo.SharedDataAdd< CMIUtilString >( rStrKeySolibPath, rStrValSolibPath ) )
{
m_bGbbOptionFnHasError = false;
SetError( CMIUtilString::Format( MIRSRC( IDS_DBGSESSION_ERR_SHARED_DATA_ADD ), m_cmdData.strMiCmd.c_str(), rStrKeySolibPath.c_str() ) );
return MIstatus::failure;
}
return MIstatus::success;
}
//++ ------------------------------------------------------------------------------------
// Details: Carry out work to complete the GDB set option to prepare and send back information
// asked for.
// Type: Method.
// Args: None.
// Return: MIstatus::success - Functional succeeded.
// MIstatus::failure - Functional failed.
// Throws: None.
//--
bool CMICmdCmdGdbSet::OptionFnFallback( const CMIUtilString::VecString_t & vrWords )
{
MIunused( vrWords );
// Do nothing - intentional. This is a fallback temporary action function to do nothing.
// This allows the search for gdb-set options to always suceed when the option is not
// found (implemented).
return MIstatus::success;
}

View File

@ -0,0 +1,95 @@
//===-- MICmdCmdGdbSet.h ------------- ---------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//++
// File: MICmdCmdGdbSet.h
//
// Overview: CMICmdCmdGdbSet interface.
//
// To implement new MI commands derive a new command class from the command base
// class. To enable the new command for interpretation add the new command class
// to the command factory. The files of relevance are:
// MICmdCommands.cpp
// MICmdBase.h / .cpp
// MICmdCmd.h / .cpp
// For an introduction to adding a new command see CMICmdCmdSupportInfoMiCmdQuery
// command class as an example.
//
// Environment: Compilers: Visual C++ 12.
// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
// Libraries: See MIReadmetxt.
//
// Copyright: None.
//--
#pragma once
// In-house headers:
#include "MICmdBase.h"
//++ ============================================================================
// Details: MI command class. MI commands derived from the command base class.
// *this class implements MI command "gdb-set".
// This command does not follow the MI documentation exactly. While *this
// command is implemented it does not do anything with the gdb-set
// variable past in.
// The design of matching the info request to a request action (or
// command) is very simple. The request function which carries out
// the task of information gathering and printing to stdout is part of
// *this class. Should the request function become more complicated then
// that request should really reside in a command type class. Then this
// class instantiates a request info command for a matching request. The
// design/code of *this class then does not then become bloated. Use a
// lightweight version of the current MI command system.
// Gotchas: None.
// Authors: Illya Rudkin 03/03/2014.
// Changes: None.
//--
class CMICmdCmdGdbSet : public CMICmdBase
{
// Statics:
public:
// Required by the CMICmdFactory when registering *this command
static CMICmdBase * CreateSelf( void );
// Methods:
public:
/* ctor */ CMICmdCmdGdbSet( void );
// Overridden:
public:
// From CMICmdInvoker::ICmd
virtual bool Execute( void );
virtual bool Acknowledge( void );
virtual bool ParseArgs( void );
// From CMICmnBase
/* dtor */ virtual ~CMICmdCmdGdbSet( void );
// Typedefs:
private:
typedef bool (CMICmdCmdGdbSet::*FnGdbOptionPtr)( const CMIUtilString::VecString_t & vrWords );
typedef std::map< CMIUtilString, FnGdbOptionPtr > MapGdbOptionNameToFnGdbOptionPtr_t;
// Methods:
private:
bool GetOptionFn( const CMIUtilString & vrGdbOptionName, FnGdbOptionPtr & vrwpFn ) const;
bool OptionFnSolibSearchPath( const CMIUtilString::VecString_t & vrWords );
bool OptionFnFallback( const CMIUtilString::VecString_t & vrWords );
// Attributes:
private:
const static MapGdbOptionNameToFnGdbOptionPtr_t ms_mapGdbOptionNameToFnGdbOptionPtr;
//
const CMIUtilString m_constStrArgNamedGdbOption;
bool m_bGdbOptionRecognised; // True = This command has a function with a name that matches the Print argument, false = not found
bool m_bGdbOptionFnSuccessful; // True = The print function completed its task ok, false = function failed for some reason
bool m_bGbbOptionFnHasError; // True = The option function has an error condition (not the command!), false = option function ok.
CMIUtilString m_strGdbOptionName;
CMIUtilString m_strGdbOptionFnError;
};

View File

@ -0,0 +1,100 @@
//===-- MICmdCmdGdbThread.cpp -----------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//++
// File: MICmdCmdGdbThread.cpp
//
// Overview: CMICmdCmdGdbThread implementation.
//
// Environment: Compilers: Visual C++ 12.
// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
// Libraries: See MIReadmetxt.
//
// Copyright: None.
//--
// In-house headers:
#include "MICmdCmdGdbThread.h"
#include "MICmnMIResultRecord.h"
#include "MICmnMIValueConst.h"
//++ ------------------------------------------------------------------------------------
// Details: CMICmdCmdGdbThread constructor.
// Type: Method.
// Args: None.
// Return: None.
// Throws: None.
//--
CMICmdCmdGdbThread::CMICmdCmdGdbThread( void )
{
// Command factory matches this name with that received from the stdin stream
m_strMiCmd = "thread";
// Required by the CMICmdFactory when registering *this command
m_pSelfCreatorFn = &CMICmdCmdGdbThread::CreateSelf;
}
//++ ------------------------------------------------------------------------------------
// Details: CMICmdCmdThread destructor.
// Type: Overrideable.
// Args: None.
// Return: None.
// Throws: None.
//--
CMICmdCmdGdbThread::~CMICmdCmdGdbThread( void )
{
}
//++ ------------------------------------------------------------------------------------
// 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 CMICmdCmdGdbThread::Execute( void )
{
// Do nothing
return MIstatus::success;
}
//++ ------------------------------------------------------------------------------------
// Details: The invoker requires this function. The command prepares a MI Record Result
// for the work carried out in the Execute().
// Type: Overridden.
// Args: None.
// Return: MIstatus::success - Functional succeeded.
// MIstatus::failure - Functional failed.
// Throws: None.
//--
bool CMICmdCmdGdbThread::Acknowledge( void )
{
const CMICmnMIValueConst miValueConst( MIRSRC( IDS_WORD_NOT_IMPLEMENTED ) );
const CMICmnMIValueResult miValueResult( "msg", miValueConst );
const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, miValueResult );
m_miResultRecord = miRecordResult;
return MIstatus::success;
}
//++ ------------------------------------------------------------------------------------
// Details: Required by the CMICmdFactory when registering *this command. The factory
// calls this function to create an instance of *this command.
// Type: Static method.
// Args: None.
// Return: CMICmdBase * - Pointer to a new command.
// Throws: None.
//--
CMICmdBase * CMICmdCmdGdbThread::CreateSelf( void )
{
return new CMICmdCmdGdbThread();
}

View File

@ -0,0 +1,61 @@
//===-- MICmdCmdGdbThread.h -------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//++
// File: MICmdCmdGdbThread.h
//
// Overview: CMICmdCmdGdbThread interface.
//
// To implement new MI commands derive a new command class from the command base
// class. To enable the new command for interpretation add the new command class
// to the command factory. The files of relevance are:
// MICmdCommands.cpp
// MICmdBase.h / .cpp
// MICmdCmd.h / .cpp
// For an introduction to adding a new command see CMICmdCmdSupportInfoMiCmdQuery
// command class as an example.
//
// Environment: Compilers: Visual C++ 12.
// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
// Libraries: See MIReadmetxt.
//
// Copyright: None.
//--
#pragma once
// In-house headers:
#include "MICmdBase.h"
//++ ============================================================================
// Details: MI command class. MI commands derived from the command base class.
// *this class implements GDB command "thread".
// Gotchas: None.
// Authors: Illya Rudkin 25/02/2014.
// Changes: None.
//--
class CMICmdCmdGdbThread : public CMICmdBase
{
// Statics:
public:
// Required by the CMICmdFactory when registering *this command
static CMICmdBase * CreateSelf( void );
// Methods:
public:
/* ctor */ CMICmdCmdGdbThread( void );
// Overridden:
public:
// From CMICmdInvoker::ICmd
virtual bool Execute( void );
virtual bool Acknowledge( void );
// From CMICmnBase
/* dtor */ virtual ~CMICmdCmdGdbThread( void );
};

View File

@ -10,9 +10,9 @@
//++
// File: MICmdCmdMiscellanous.cpp
//
// Overview: CMICmdCmdGdbSet implementation.
// CMICmdCmdGdbExit implementation.
// Overview: CMICmdCmdGdbExit implementation.
// CMICmdCmdListThreadGroups implementation.
// CMICmdCmdInterpreterExec implementation.
//
// Environment: Compilers: Visual C++ 12.
// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
@ -22,6 +22,7 @@
//--
// Third Party Headers:
#include <lldb/API/SBCommandInterpreter.h>
#include <lldb/API/SBThread.h>
// In-house headers:
@ -41,82 +42,8 @@
#include "MICmdArgValOptionLong.h"
#include "MICmdArgValOptionShort.h"
#include "MICmdArgValListOfN.h"
//++ ------------------------------------------------------------------------------------
// Details: CMICmdCmdGdbSet constructor.
// Type: Method.
// Args: None.
// Return: None.
// Throws: None.
//--
CMICmdCmdGdbSet::CMICmdCmdGdbSet( void )
{
// Command factory matches this name with that received from the stdin stream
m_strMiCmd = "gdb-set";
// Required by the CMICmdFactory when registering *this commmand
m_pSelfCreatorFn = &CMICmdCmdGdbSet::CreateSelf;
}
//++ ------------------------------------------------------------------------------------
// Details: CMICmdCmdGdbSet destructor.
// Type: Overrideable.
// Args: None.
// Return: None.
// Throws: None.
//--
CMICmdCmdGdbSet::~CMICmdCmdGdbSet( void )
{
}
//++ ------------------------------------------------------------------------------------
// 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 CMICmdCmdGdbSet::Execute( void )
{
// Do nothing
return MIstatus::success;
}
//++ ------------------------------------------------------------------------------------
// Details: The invoker requires this function. The command prepares a MI Record Result
// for the work carried out in the Execute().
// Type: Overridden.
// Args: None.
// Return: MIstatus::success - Functional succeeded.
// MIstatus::failure - Functional failed.
// Throws: None.
//--
bool CMICmdCmdGdbSet::Acknowledge( void )
{
const CMICmnMIResultRecord miRecordResult( m_cmdData.nMiCmdNumber, CMICmnMIResultRecord::eResultClass_Done );
m_miResultRecord = miRecordResult;
return MIstatus::success;
}
//++ ------------------------------------------------------------------------------------
// Details: Required by the CMICmdFactory when registering *this commmand. The factory
// calls this function to create an instance of *this command.
// Type: Static method.
// Args: None.
// Return: CMICmdBase * - Pointer to a new command.
// Throws: None.
//--
CMICmdBase * CMICmdCmdGdbSet::CreateSelf( void )
{
return new CMICmdCmdGdbSet();
}
//---------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------
#include "MICmnStreamStdout.h"
#include "MICmnStreamStderr.h"
//++ ------------------------------------------------------------------------------------
// Details: CMICmdCmdGdbExit constructor.
@ -130,7 +57,7 @@ CMICmdCmdGdbExit::CMICmdCmdGdbExit( void )
// Command factory matches this name with that received from the stdin stream
m_strMiCmd = "gdb-exit";
// Required by the CMICmdFactory when registering *this commmand
// Required by the CMICmdFactory when registering *this command
m_pSelfCreatorFn = &CMICmdCmdGdbExit::CreateSelf;
}
@ -156,7 +83,7 @@ CMICmdCmdGdbExit::~CMICmdCmdGdbExit( void )
//--
bool CMICmdCmdGdbExit::Execute( void )
{
CMICmnLLDBDebugger::Instance().GetDriver().SetExitApplicationFlag();
CMICmnLLDBDebugger::Instance().GetDriver().SetExitApplicationFlag( true );
const lldb::SBError sbErr = m_rLLDBDebugSessionInfo.m_lldbProcess.Detach();
// Do not check for sbErr.Fail() here, m_lldbProcess is likely !IsValid()
@ -174,7 +101,7 @@ bool CMICmdCmdGdbExit::Execute( void )
//--
bool CMICmdCmdGdbExit::Acknowledge( void )
{
const CMICmnMIResultRecord miRecordResult( m_cmdData.nMiCmdNumber, CMICmnMIResultRecord::eResultClass_Exit );
const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Exit );
m_miResultRecord = miRecordResult;
// Prod the client i.e. Eclipse with out-of-band results to help it 'continue' because it is using LLDB debugger
@ -189,7 +116,7 @@ bool CMICmdCmdGdbExit::Acknowledge( void )
}
//++ ------------------------------------------------------------------------------------
// Details: Required by the CMICmdFactory when registering *this commmand. The factory
// Details: Required by the CMICmdFactory when registering *this command. The factory
// calls this function to create an instance of *this command.
// Type: Static method.
// Args: None.
@ -224,7 +151,7 @@ CMICmdCmdListThreadGroups::CMICmdCmdListThreadGroups( void )
// Command factory matches this name with that received from the stdin stream
m_strMiCmd = "list-thread-groups";
// Required by the CMICmdFactory when registering *this commmand
// Required by the CMICmdFactory when registering *this command
m_pSelfCreatorFn = &CMICmdCmdListThreadGroups::CreateSelf;
}
@ -251,10 +178,10 @@ CMICmdCmdListThreadGroups::~CMICmdCmdListThreadGroups( void )
//--
bool CMICmdCmdListThreadGroups::ParseArgs( void )
{
bool bOk = m_setCmdArgs.Add( *(new CMICmdArgValOptionLong( m_constStrArgNamedAvailable, false, true )) );
bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValOptionLong( m_constStrArgNamedRecurse, false, true, CMICmdArgValListBase::eArgValType_Number, 1 )) );
bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValListOfN( m_constStrArgNamedGroup, false, true, CMICmdArgValListBase::eArgValType_Number )) );
bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValThreadGrp( m_constStrArgNamedThreadGroup, false, true )) );
bool bOk = m_setCmdArgs.Add( *(new CMICmdArgValOptionLong( m_constStrArgNamedAvailable, false, true ) ) );
bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValOptionLong( m_constStrArgNamedRecurse, false, true, CMICmdArgValListBase::eArgValType_Number, 1 ) ) );
bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValListOfN( m_constStrArgNamedGroup, false, true, CMICmdArgValListBase::eArgValType_Number ) ) );
bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValThreadGrp( m_constStrArgNamedThreadGroup, false, true ) ) );
CMICmdArgContext argCntxt( m_cmdData.strMiCmdOption );
if( bOk && !m_setCmdArgs.Validate( m_cmdData.strMiCmd, argCntxt ) )
{
@ -286,26 +213,8 @@ bool CMICmdCmdListThreadGroups::Execute( void )
CMICMDBASE_GETOPTION( pArgAvailable, OptionLong, m_constStrArgNamedAvailable );
CMICMDBASE_GETOPTION( pArgRecurse, OptionLong, m_constStrArgNamedRecurse );
CMICMDBASE_GETOPTION( pArgGroup, ListOfN, m_constStrArgNamedGroup );
CMICMDBASE_GETOPTION( pArgThreadGroup, ThreadGrp, m_constStrArgNamedThreadGroup );
// Demo of how to get the value of long argument --recurse's option of 1 "--recurse 1"
const CMICmdArgValOptionLong::VecArgObjPtr_t & rVecOptions( pArgRecurse->GetExpectedOptions() );
const CMICmdArgValNumber * pRecurseDepthOption = (rVecOptions.size() > 0) ? static_cast< CMICmdArgValNumber * >( rVecOptions[ 1 ] ) : nullptr;
const MIuint nRecurseDepth = (pRecurseDepthOption != nullptr) ? pRecurseDepthOption->GetValue() : 0;
// Demo of how to get List of N numbers (the Group argument not implement for this command (yet))
const CMICmdArgValListOfN::VecArgObjPtr_t & rVecGroupId( pArgGroup->GetValue() );
CMICmdArgValListOfN::VecArgObjPtr_t::const_iterator it = rVecGroupId.begin();
while( it != rVecGroupId.end() )
{
const CMICmdArgValNumber * pOption = static_cast< CMICmdArgValNumber * >( *it );
const MIuint nGrpId = pOption->GetValue();
// Next
++it;
}
// Got some options so "threads"
if( pArgAvailable->GetFound() )
{
@ -366,7 +275,7 @@ bool CMICmdCmdListThreadGroups::Acknowledge( void )
{
const CMICmnMIValueConst miValueConst( MIRSRC( IDS_WORD_NOT_IMPLEMENTED_BRKTS ) );
const CMICmnMIValueResult miValueResult( "msg", miValueConst );
const CMICmnMIResultRecord miRecordResult( m_cmdData.nMiCmdNumber, CMICmnMIResultRecord::eResultClass_Error, miValueResult );
const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, miValueResult );
m_miResultRecord = miRecordResult;
return MIstatus::success;
@ -397,7 +306,7 @@ bool CMICmdCmdListThreadGroups::Acknowledge( void )
const CMICmnMIValueList miValueList( miTuple );
const CMICmnMIValueResult miValueResult6( "groups", miValueList );
const CMICmnMIResultRecord miRecordResult( m_cmdData.nMiCmdNumber, CMICmnMIResultRecord::eResultClass_Done, miValueResult6 );
const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult6 );
m_miResultRecord = miRecordResult;
return MIstatus::success;
@ -421,8 +330,8 @@ bool CMICmdCmdListThreadGroups::Acknowledge( void )
miTuple.Add( miValueResult3 );
lldb::SBTarget & rTrgt = rSessionInfo.m_lldbTarget;
const char * pDir = rTrgt.GetExecutable().GetDirectory();
const char * pFileName = rTrgt.GetExecutable().GetFilename();
const MIchar * pDir = rTrgt.GetExecutable().GetDirectory();
const MIchar * pFileName = rTrgt.GetExecutable().GetFilename();
const CMIUtilString strFile( CMIUtilString::Format( "%s/%s", pDir, pFileName ) );
const CMICmnMIValueConst miValueConst4( strFile );
const CMICmnMIValueResult miValueResult4( "executable", miValueConst4 );
@ -430,7 +339,7 @@ bool CMICmdCmdListThreadGroups::Acknowledge( void )
const CMICmnMIValueList miValueList( miTuple );
const CMICmnMIValueResult miValueResult5( "groups", miValueList );
const CMICmnMIResultRecord miRecordResult( m_cmdData.nMiCmdNumber, CMICmnMIResultRecord::eResultClass_Done, miValueResult5 );
const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult5 );
m_miResultRecord = miRecordResult;
return MIstatus::success;
}
@ -441,7 +350,7 @@ bool CMICmdCmdListThreadGroups::Acknowledge( void )
{
const CMICmnMIValueConst miValueConst( "[]" );
const CMICmnMIValueResult miValueResult( "threads", miValueConst );
const CMICmnMIResultRecord miRecordResult( m_cmdData.nMiCmdNumber, CMICmnMIResultRecord::eResultClass_Done, miValueResult );
const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult );
m_miResultRecord = miRecordResult;
return MIstatus::success;
}
@ -457,14 +366,14 @@ bool CMICmdCmdListThreadGroups::Acknowledge( void )
}
const CMICmnMIValueResult miValueResult( "threads", miValueList );
const CMICmnMIResultRecord miRecordResult( m_cmdData.nMiCmdNumber, CMICmnMIResultRecord::eResultClass_Done, miValueResult );
const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult );
m_miResultRecord = miRecordResult;
return MIstatus::success;
}
//++ ------------------------------------------------------------------------------------
// Details: Required by the CMICmdFactory when registering *this commmand. The factory
// Details: Required by the CMICmdFactory when registering *this command. The factory
// calls this function to create an instance of *this command.
// Type: Static method.
// Args: None.
@ -474,4 +383,125 @@ bool CMICmdCmdListThreadGroups::Acknowledge( void )
CMICmdBase * CMICmdCmdListThreadGroups::CreateSelf( void )
{
return new CMICmdCmdListThreadGroups();
}
}
//---------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------
//++ ------------------------------------------------------------------------------------
// Details: CMICmdCmdInterpreterExec constructor.
// Type: Method.
// Args: None.
// Return: None.
// Throws: None.
//--
CMICmdCmdInterpreterExec::CMICmdCmdInterpreterExec( void )
: m_constStrArgNamedInterpreter( "intepreter" )
, m_constStrArgNamedCommand( "command" )
{
// Command factory matches this name with that received from the stdin stream
m_strMiCmd = "interpreter-exec";
// Required by the CMICmdFactory when registering *this command
m_pSelfCreatorFn = &CMICmdCmdInterpreterExec::CreateSelf;
}
//++ ------------------------------------------------------------------------------------
// Details: CMICmdCmdInterpreterExec destructor.
// Type: Overrideable.
// Args: None.
// Return: None.
// Throws: None.
//--
CMICmdCmdInterpreterExec::~CMICmdCmdInterpreterExec( void )
{
}
//++ ------------------------------------------------------------------------------------
// Details: The invoker requires this function. The parses the command line options
// arguments to extract values for each of those arguments.
// Type: Overridden.
// Args: None.
// Return: MIstatus::success - Functional succeeded.
// MIstatus::failure - Functional failed.
// Throws: None.
//--
bool CMICmdCmdInterpreterExec::ParseArgs( void )
{
bool bOk = m_setCmdArgs.Add( *(new CMICmdArgValString( m_constStrArgNamedInterpreter, true, true ) ) );
bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValString( m_constStrArgNamedCommand, true, true, true ) ) );
CMICmdArgContext argCntxt( m_cmdData.strMiCmdOption );
if( bOk && !m_setCmdArgs.Validate( m_cmdData.strMiCmd, argCntxt ) )
{
SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_ARGS ), m_cmdData.strMiCmd.c_str(), m_setCmdArgs.GetErrorDescription().c_str() ) );
return MIstatus::failure;
}
return bOk;
}
//++ ------------------------------------------------------------------------------------
// 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 CMICmdCmdInterpreterExec::Execute( void )
{
CMICMDBASE_GETOPTION( pArgInterpreter, String, m_constStrArgNamedInterpreter );
CMICMDBASE_GETOPTION( pArgCommand, String, m_constStrArgNamedCommand );
const CMIUtilString & rStrInterpreter( pArgInterpreter->GetValue() );
const CMIUtilString & rStrCommand( pArgCommand->GetValue() );
const CMIUtilString strCmd( CMIUtilString::Format( "%s %s", rStrInterpreter.c_str(), rStrCommand.c_str() ) );
CMICmnLLDBDebugSessionInfo & rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance() );
const lldb::ReturnStatus rtn = rSessionInfo.m_rLldbDebugger.GetCommandInterpreter().HandleCommand( strCmd.c_str(), m_lldbResult, true ); MIunused( rtn );
return MIstatus::success;
}
//++ ------------------------------------------------------------------------------------
// Details: The invoker requires this function. The command prepares a MI Record Result
// for the work carried out in the Execute().
// Type: Overridden.
// Args: None.
// Return: MIstatus::success - Functional succeeded.
// MIstatus::failure - Functional failed.
// Throws: None.
//--
bool CMICmdCmdInterpreterExec::Acknowledge( void )
{
if( m_lldbResult.GetOutputSize() > 0 )
{
CMIUtilString strMsg( m_lldbResult.GetOutput() );
strMsg = strMsg.StripCREndOfLine();
CMICmnStreamStdout::TextToStdout( strMsg );
}
if( m_lldbResult.GetErrorSize() > 0 )
{
CMIUtilString strMsg( m_lldbResult.GetError() );
strMsg = strMsg.StripCREndOfLine();
CMICmnStreamStderr::TextToStderr( strMsg );
}
const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done );
m_miResultRecord = miRecordResult;
return MIstatus::success;
}
//++ ------------------------------------------------------------------------------------
// Details: Required by the CMICmdFactory when registering *this command. The factory
// calls this function to create an instance of *this command.
// Type: Static method.
// Args: None.
// Return: CMICmdBase * - Pointer to a new command.
// Throws: None.
//--
CMICmdBase * CMICmdCmdInterpreterExec::CreateSelf( void )
{
return new CMICmdCmdInterpreterExec();
}

View File

@ -10,9 +10,9 @@
//++
// File: MICmdCmdMiscellanous.h
//
// Overview: CMICmdCmdGdbSet interface.
// CMICmdCmdGdbExit interface.
// Overview: CMICmdCmdGdbExit interface.
// CMICmdCmdListThreadGroups interface.
// CMICmdCmdInterpreterExec interface.
//
// To implement new MI commands derive a new command class from the command base
// class. To enable the new command for interpretation add the new command class
@ -32,42 +32,14 @@
#pragma once
// Third party headers:
#include <lldb/API/SBCommandReturnObject.h>
// In-house headers:
#include "MICmdBase.h"
#include "MICmnMIValueTuple.h"
#include "MICmnMIValueList.h"
//++ ============================================================================
// Details: MI command class. MI commands derived from the command base class.
// *this class implements MI command "gdb-set".
// This command does not follow the MI documentation exactly.
// Gotchas: None.
// Authors: Illya Rudkin 03/03/2014.
// Changes: None.
//--
class CMICmdCmdGdbSet : public CMICmdBase
{
// Statics:
public:
// Required by the CMICmdFactory when registering *this commmand
static CMICmdBase * CreateSelf( void );
// Methods:
public:
/* ctor */ CMICmdCmdGdbSet( void );
// Overridden:
public:
// From CMICmdInvoker::ICmd
virtual bool Execute( void );
virtual bool Acknowledge( void );
// Overridden:
public:
// From CMICmnBase
/* dtor */ virtual ~CMICmdCmdGdbSet( void );
};
//++ ============================================================================
// Details: MI command class. MI commands derived from the command base class.
// *this class implements MI command "gdb-exit".
@ -79,7 +51,7 @@ class CMICmdCmdGdbExit : public CMICmdBase
{
// Statics:
public:
// Required by the CMICmdFactory when registering *this commmand
// Required by the CMICmdFactory when registering *this command
static CMICmdBase * CreateSelf( void );
// Methods:
@ -91,9 +63,6 @@ public:
// From CMICmdInvoker::ICmd
virtual bool Execute( void );
virtual bool Acknowledge( void );
// Overridden:
public:
// From CMICmnBase
/* dtor */ virtual ~CMICmdCmdGdbExit( void );
};
@ -111,7 +80,7 @@ class CMICmdCmdListThreadGroups : public CMICmdBase
{
// Statics:
public:
// Required by the CMICmdFactory when registering *this commmand
// Required by the CMICmdFactory when registering *this command
static CMICmdBase * CreateSelf( void );
// Methods:
@ -124,9 +93,6 @@ public:
virtual bool Execute( void );
virtual bool Acknowledge( void );
virtual bool ParseArgs( void );
// Overridden:
public:
// From CMICmnBase
/* dtor */ virtual ~CMICmdCmdListThreadGroups( void );
@ -144,4 +110,38 @@ private:
const CMIUtilString m_constStrArgNamedRecurse;
const CMIUtilString m_constStrArgNamedGroup;
const CMIUtilString m_constStrArgNamedThreadGroup;
};
};
//++ ============================================================================
// Details: MI command class. MI commands derived from the command base class.
// *this class implements MI command "interpreter-exec".
// Gotchas: None.
// Authors: Illya Rudkin 16/05/2014.
// Changes: None.
//--
class CMICmdCmdInterpreterExec : public CMICmdBase
{
// Statics:
public:
// Required by the CMICmdFactory when registering *this command
static CMICmdBase * CreateSelf( void );
// Methods:
public:
/* ctor */ CMICmdCmdInterpreterExec( void );
// Overridden:
public:
// From CMICmdInvoker::ICmd
virtual bool Execute( void );
virtual bool Acknowledge( void );
virtual bool ParseArgs( void );
// From CMICmnBase
/* dtor */ virtual ~CMICmdCmdInterpreterExec( void );
// Attributes:
private:
const CMIUtilString m_constStrArgNamedInterpreter;
const CMIUtilString m_constStrArgNamedCommand;
lldb::SBCommandReturnObject m_lldbResult;
};

View File

@ -56,7 +56,7 @@ CMICmdCmdStackInfoDepth::CMICmdCmdStackInfoDepth( void )
// Command factory matches this name with that received from the stdin stream
m_strMiCmd = "stack-info-depth";
// Required by the CMICmdFactory when registering *this commmand
// Required by the CMICmdFactory when registering *this command
m_pSelfCreatorFn = &CMICmdCmdStackInfoDepth::CreateSelf;
}
@ -136,14 +136,14 @@ bool CMICmdCmdStackInfoDepth::Acknowledge( void )
const CMIUtilString strDepth( CMIUtilString::Format( "%d", m_nThreadFrames ) );
const CMICmnMIValueConst miValueConst( strDepth );
const CMICmnMIValueResult miValueResult( "depth", miValueConst );
const CMICmnMIResultRecord miRecordResult( m_cmdData.nMiCmdNumber, CMICmnMIResultRecord::eResultClass_Done, miValueResult );
const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult );
m_miResultRecord = miRecordResult;
return MIstatus::success;
}
//++ ------------------------------------------------------------------------------------
// Details: Required by the CMICmdFactory when registering *this commmand. The factory
// Details: Required by the CMICmdFactory when registering *this command. The factory
// calls this function to create an instance of *this command.
// Type: Static method.
// Args: None.
@ -175,7 +175,7 @@ CMICmdCmdStackListFrames::CMICmdCmdStackListFrames( void )
// Command factory matches this name with that received from the stdin stream
m_strMiCmd = "stack-list-frames";
// Required by the CMICmdFactory when registering *this commmand
// Required by the CMICmdFactory when registering *this command
m_pSelfCreatorFn = &CMICmdCmdStackListFrames::CreateSelf;
}
@ -289,7 +289,7 @@ bool CMICmdCmdStackListFrames::Acknowledge( void )
const CMICmnMIValueTuple miValueTuple;
const CMICmnMIValueList miValueList( miValueTuple );
const CMICmnMIValueResult miValueResult( "stack", miValueList );
const CMICmnMIResultRecord miRecordResult( m_cmdData.nMiCmdNumber, CMICmnMIResultRecord::eResultClass_Done, miValueResult );
const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult );
m_miResultRecord = miRecordResult;
return MIstatus::success;
@ -303,7 +303,7 @@ bool CMICmdCmdStackListFrames::Acknowledge( void )
const CMICmnMIValueTuple miValueTuple;
const CMICmnMIValueList miValueList( miValueTuple );
const CMICmnMIValueResult miValueResult( "stack", miValueList );
const CMICmnMIResultRecord miRecordResult( m_cmdData.nMiCmdNumber, CMICmnMIResultRecord::eResultClass_Done, miValueResult );
const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult );
m_miResultRecord = miRecordResult;
return MIstatus::success;
}
@ -318,14 +318,14 @@ bool CMICmdCmdStackListFrames::Acknowledge( void )
++it;
}
const CMICmnMIValueResult miValueResult( "stack", miValueList );
const CMICmnMIResultRecord miRecordResult( m_cmdData.nMiCmdNumber, CMICmnMIResultRecord::eResultClass_Done, miValueResult );
const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult );
m_miResultRecord = miRecordResult;
return MIstatus::success;
}
//++ ------------------------------------------------------------------------------------
// Details: Required by the CMICmdFactory when registering *this commmand. The factory
// Details: Required by the CMICmdFactory when registering *this command. The factory
// calls this function to create an instance of *this command.
// Type: Static method.
// Args: None.
@ -357,7 +357,7 @@ CMICmdCmdStackListArguments::CMICmdCmdStackListArguments( void )
// Command factory matches this name with that received from the stdin stream
m_strMiCmd = "stack-list-arguments";
// Required by the CMICmdFactory when registering *this commmand
// Required by the CMICmdFactory when registering *this command
m_pSelfCreatorFn = &CMICmdCmdStackListArguments::CreateSelf;
}
@ -465,7 +465,7 @@ bool CMICmdCmdStackListArguments::Acknowledge( void )
// MI print "%s^done,stack-args=[]"
const CMICmnMIValueList miValueList( true );
const CMICmnMIValueResult miValueResult( "stack-args", miValueList );
const CMICmnMIResultRecord miRecordResult( m_cmdData.nMiCmdNumber, CMICmnMIResultRecord::eResultClass_Done, miValueResult );
const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult );
m_miResultRecord = miRecordResult;
return MIstatus::success;
}
@ -479,14 +479,14 @@ bool CMICmdCmdStackListArguments::Acknowledge( void )
const CMICmnMIValueResult miValueResult3( "frame", miValueTuple );
const CMICmnMIValueList miValueList( miValueResult3 );
const CMICmnMIValueResult miValueResult4( "stack-args", miValueList );
const CMICmnMIResultRecord miRecordResult( m_cmdData.nMiCmdNumber, CMICmnMIResultRecord::eResultClass_Done, miValueResult4 );
const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult4 );
m_miResultRecord = miRecordResult;
return MIstatus::success;
}
//++ ------------------------------------------------------------------------------------
// Details: Required by the CMICmdFactory when registering *this commmand. The factory
// Details: Required by the CMICmdFactory when registering *this command. The factory
// calls this function to create an instance of *this command.
// Type: Static method.
// Args: None.
@ -519,7 +519,7 @@ CMICmdCmdStackListLocals::CMICmdCmdStackListLocals( void )
// Command factory matches this name with that received from the stdin stream
m_strMiCmd = "stack-list-locals";
// Required by the CMICmdFactory when registering *this commmand
// Required by the CMICmdFactory when registering *this command
m_pSelfCreatorFn = &CMICmdCmdStackListLocals::CreateSelf;
}
@ -628,21 +628,21 @@ bool CMICmdCmdStackListLocals::Acknowledge( void )
// MI print "%s^done,locals=[]"
const CMICmnMIValueList miValueList( true );
const CMICmnMIValueResult miValueResult( "locals", miValueList );
const CMICmnMIResultRecord miRecordResult( m_cmdData.nMiCmdNumber, CMICmnMIResultRecord::eResultClass_Done, miValueResult );
const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult );
m_miResultRecord = miRecordResult;
return MIstatus::success;
}
// MI print "%s^done,locals=[%s]"
const CMICmnMIValueResult miValueResult( "locals", m_miValueList );
const CMICmnMIResultRecord miRecordResult( m_cmdData.nMiCmdNumber, CMICmnMIResultRecord::eResultClass_Done, miValueResult );
const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult );
m_miResultRecord = miRecordResult;
return MIstatus::success;
}
//++ ------------------------------------------------------------------------------------
// Details: Required by the CMICmdFactory when registering *this commmand. The factory
// Details: Required by the CMICmdFactory when registering *this command. The factory
// calls this function to create an instance of *this command.
// Type: Static method.
// Args: None.

View File

@ -48,7 +48,7 @@ class CMICmdCmdStackInfoDepth : public CMICmdBase
{
// Statics:
public:
// Required by the CMICmdFactory when registering *this commmand
// Required by the CMICmdFactory when registering *this command
static CMICmdBase * CreateSelf( void );
// Methods:
@ -61,9 +61,6 @@ public:
virtual bool Execute( void );
virtual bool Acknowledge( void );
virtual bool ParseArgs( void );
// Overridden:
public:
// From CMICmnBase
/* dtor */ virtual ~CMICmdCmdStackInfoDepth( void );
@ -85,7 +82,7 @@ class CMICmdCmdStackListFrames : public CMICmdBase
{
// Statics:
public:
// Required by the CMICmdFactory when registering *this commmand
// Required by the CMICmdFactory when registering *this command
static CMICmdBase * CreateSelf( void );
// Methods:
@ -98,9 +95,6 @@ public:
virtual bool Execute( void );
virtual bool Acknowledge( void );
virtual bool ParseArgs( void );
// Overridden:
public:
// From CMICmnBase
/* dtor */ virtual ~CMICmdCmdStackListFrames( void );
@ -128,7 +122,7 @@ class CMICmdCmdStackListArguments : public CMICmdBase
{
// Statics:
public:
// Required by the CMICmdFactory when registering *this commmand
// Required by the CMICmdFactory when registering *this command
static CMICmdBase * CreateSelf( void );
// Methods:
@ -141,9 +135,6 @@ public:
virtual bool Execute( void );
virtual bool Acknowledge( void );
virtual bool ParseArgs( void );
// Overridden:
public:
// From CMICmnBase
/* dtor */ virtual ~CMICmdCmdStackListArguments( void );
@ -166,7 +157,7 @@ class CMICmdCmdStackListLocals : public CMICmdBase
{
// Statics:
public:
// Required by the CMICmdFactory when registering *this commmand
// Required by the CMICmdFactory when registering *this command
static CMICmdBase * CreateSelf( void );
// Methods:
@ -179,9 +170,6 @@ public:
virtual bool Execute( void );
virtual bool Acknowledge( void );
virtual bool ParseArgs( void );
// Overridden:
public:
// From CMICmnBase
/* dtor */ virtual ~CMICmdCmdStackListLocals( void );

View File

@ -43,7 +43,7 @@ CMICmdCmdSupportInfoMiCmdQuery::CMICmdCmdSupportInfoMiCmdQuery( void )
// Command factory matches this name with that received from the stdin stream
m_strMiCmd = "info-gdb-mi-command";
// Required by the CMICmdFactory when registering *this commmand
// Required by the CMICmdFactory when registering *this command
m_pSelfCreatorFn = &CMICmdCmdSupportInfoMiCmdQuery::CreateSelf;
}
@ -118,14 +118,14 @@ bool CMICmdCmdSupportInfoMiCmdQuery::Acknowledge( void )
const CMICmnMIValueResult miValueResult( "exists", miValueConst );
const CMICmnMIValueTuple miValueTuple( miValueResult );
const CMICmnMIValueResult miValueResult2( "command", miValueTuple );
const CMICmnMIResultRecord miRecordResult( m_cmdData.nMiCmdNumber, CMICmnMIResultRecord::eResultClass_Done, miValueResult2 );
const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult2 );
m_miResultRecord = miRecordResult;
return MIstatus::success;
}
//++ ------------------------------------------------------------------------------------
// Details: Required by the CMICmdFactory when registering *this commmand. The factory
// Details: Required by the CMICmdFactory when registering *this command. The factory
// calls this function to create an instance of *this command.
// Type: Static method.
// Args: None.
@ -135,4 +135,4 @@ bool CMICmdCmdSupportInfoMiCmdQuery::Acknowledge( void )
CMICmdBase * CMICmdCmdSupportInfoMiCmdQuery::CreateSelf( void )
{
return new CMICmdCmdSupportInfoMiCmdQuery();
}
}

View File

@ -45,7 +45,7 @@ class CMICmdCmdSupportInfoMiCmdQuery : public CMICmdBase
{
// Statics:
public:
// Required by the CMICmdFactory when registering *this commmand
// Required by the CMICmdFactory when registering *this command
static CMICmdBase * CreateSelf( void );
// Methods:
@ -58,9 +58,6 @@ public:
virtual bool Execute( void );
virtual bool Acknowledge( void );
virtual bool ParseArgs( void );
// Overridden:
public:
// From CMICmnBase
/* dtor */ virtual ~CMICmdCmdSupportInfoMiCmdQuery( void );

View File

@ -38,7 +38,7 @@ CMICmdCmdSupportListFeatures::CMICmdCmdSupportListFeatures( void )
// Command factory matches this name with that received from the stdin stream
m_strMiCmd = "list-features";
// Required by the CMICmdFactory when registering *this commmand
// Required by the CMICmdFactory when registering *this command
m_pSelfCreatorFn = &CMICmdCmdSupportListFeatures::CreateSelf;
}
@ -83,14 +83,14 @@ bool CMICmdCmdSupportListFeatures::Acknowledge( void )
const CMICmnMIValueConst miValueConst( "data-read-memory-bytes" );
const CMICmnMIValueList miValueList( miValueConst );
const CMICmnMIValueResult miValueResult( "features", miValueList );
const CMICmnMIResultRecord miRecordResult( m_cmdData.nMiCmdNumber, CMICmnMIResultRecord::eResultClass_Done, miValueResult );
const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult );
m_miResultRecord = miRecordResult;
return MIstatus::success;
}
//++ ------------------------------------------------------------------------------------
// Details: Required by the CMICmdFactory when registering *this commmand. The factory
// Details: Required by the CMICmdFactory when registering *this command. The factory
// calls this function to create an instance of *this command.
// Type: Static method.
// Args: None.
@ -100,4 +100,4 @@ bool CMICmdCmdSupportListFeatures::Acknowledge( void )
CMICmdBase * CMICmdCmdSupportListFeatures::CreateSelf( void )
{
return new CMICmdCmdSupportListFeatures();
}
}

View File

@ -45,7 +45,7 @@ class CMICmdCmdSupportListFeatures : public CMICmdBase
{
// Statics:
public:
// Required by the CMICmdFactory when registering *this commmand
// Required by the CMICmdFactory when registering *this command
static CMICmdBase * CreateSelf( void );
// Methods:
@ -57,9 +57,6 @@ public:
// From CMICmdInvoker::ICmd
virtual bool Execute( void );
virtual bool Acknowledge( void );
// Overridden:
public:
// From CMICmnBase
/* dtor */ virtual ~CMICmdCmdSupportListFeatures( void );
};

View File

@ -21,6 +21,8 @@
// Third Party Headers:
#include <lldb/API/SBStream.h>
#include <lldb/API/SBCommandInterpreter.h>
#include <lldb/API/SBCommandReturnObject.h>
// In-house headers:
#include "MICmnConfig.h"
@ -53,7 +55,7 @@ CMICmdCmdTargetSelect::CMICmdCmdTargetSelect( void )
// Command factory matches this name with that received from the stdin stream
m_strMiCmd = "target-select";
// Required by the CMICmdFactory when registering *this commmand
// Required by the CMICmdFactory when registering *this command
m_pSelfCreatorFn = &CMICmdCmdTargetSelect::CreateSelf;
}
@ -108,12 +110,16 @@ bool CMICmdCmdTargetSelect::Execute( void )
CMICMDBASE_GETOPTION( pArgParameters, String, m_constStrArgNamedParameters );
CMICmnLLDBDebugSessionInfo & rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance() );
// Check we have a valid target
// Note: target created via 'file-exec-and-symbols' command
if( !rSessionInfo.m_lldbTarget.IsValid() )
{
SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_INVALID_TARGET_CURRENT ), m_cmdData.strMiCmd.c_str() ) );
return MIstatus::failure;
}
// Verify that we are executing remotely
const CMIUtilString & rRemoteType( pArgType->GetValue() );
if( rRemoteType != "remote" )
{
@ -121,26 +127,16 @@ bool CMICmdCmdTargetSelect::Execute( void )
return MIstatus::failure;
}
// Create a URL pointing to the remote gdb stub
const CMIUtilString strUrl = CMIUtilString::Format( "connect://%s", pArgParameters->GetValue().c_str() );
const char * pPlugin( "gdb-remote" );
// Ask LLDB to collect to the target port
const MIchar * pPlugin( "gdb-remote" );
lldb::SBError error;
lldb::SBProcess process = rSessionInfo.m_lldbTarget.ConnectRemote( rSessionInfo.m_rLlldbListener, strUrl.c_str(), pPlugin, error );
CMIUtilString strWkDir;
if( !rSessionInfo.SharedDataRetrieve( rSessionInfo.m_constStrSharedDataKeyWkDir, strWkDir ) )
{
SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_SHARED_DATA_NOT_FOUND ), m_cmdData.strMiCmd.c_str(), rSessionInfo.m_constStrSharedDataKeyWkDir.c_str() ) );
return MIstatus::failure;
}
lldb::SBDebugger & rDbgr = rSessionInfo.m_rLldbDebugger;
if( !rDbgr.SetCurrentPlatformSDKRoot( strWkDir.c_str() ) )
{
SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_FNFAILED ), m_cmdData.strMiCmd.c_str(), "SetCurrentPlatformSDKRoot()" ) );
return MIstatus::failure;
}
// Verify that we have managed to connect successfully
lldb::SBStream errMsg;
if( error.Fail() )
const bool bOk = error.GetDescription( errMsg );
if( !process.IsValid() )
{
SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_INVALID_TARGET_PLUGIN ), m_cmdData.strMiCmd.c_str(), errMsg.GetData() ) );
@ -152,8 +148,42 @@ bool CMICmdCmdTargetSelect::Execute( void )
return MIstatus::failure;
}
// Save the process in the session info
// Note: Order is important here since this process handle may be used by CMICmnLLDBDebugHandleEvents
// which can fire when interpreting via HandleCommand() below.
rSessionInfo.m_lldbProcess = process;
// Set the environment path if we were given one
CMIUtilString strWkDir;
if( rSessionInfo.SharedDataRetrieve< CMIUtilString >( rSessionInfo.m_constStrSharedDataKeyWkDir, strWkDir ) )
{
lldb::SBDebugger & rDbgr = rSessionInfo.m_rLldbDebugger;
if( !rDbgr.SetCurrentPlatformSDKRoot( strWkDir.c_str() ) )
{
SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_FNFAILED ), m_cmdData.strMiCmd.c_str(), "target-select" ) );
return MIstatus::failure;
}
}
// Set the shared object path if we were given one
CMIUtilString strSolibPath;
if( rSessionInfo.SharedDataRetrieve< CMIUtilString >( rSessionInfo.m_constStrSharedDataSolibPath, strSolibPath ) )
{
lldb::SBDebugger & rDbgr = rSessionInfo.m_rLldbDebugger;
lldb::SBCommandInterpreter cmdIterpreter = rDbgr.GetCommandInterpreter();
CMIUtilString strCmdString = CMIUtilString::Format( "target modules search-paths add . %s", strSolibPath.c_str() );
lldb::SBCommandReturnObject retObj;
cmdIterpreter.HandleCommand( strCmdString.c_str(), retObj, false );
if( !retObj.Succeeded() )
{
SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_FNFAILED ), m_cmdData.strMiCmd.c_str(), "target-select" ) );
return MIstatus::failure;
}
}
return MIstatus::success;
}
@ -168,7 +198,7 @@ bool CMICmdCmdTargetSelect::Execute( void )
//--
bool CMICmdCmdTargetSelect::Acknowledge( void )
{
const CMICmnMIResultRecord miRecordResult( m_cmdData.nMiCmdNumber, CMICmnMIResultRecord::eResultClass_Connected );
const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Connected );
m_miResultRecord = miRecordResult;
CMICmnLLDBDebugSessionInfo & rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance() );
@ -189,7 +219,7 @@ bool CMICmdCmdTargetSelect::Acknowledge( void )
}
//++ ------------------------------------------------------------------------------------
// Details: Required by the CMICmdFactory when registering *this commmand. The factory
// Details: Required by the CMICmdFactory when registering *this command. The factory
// calls this function to create an instance of *this command.
// Type: Static method.
// Args: None.
@ -199,4 +229,4 @@ bool CMICmdCmdTargetSelect::Acknowledge( void )
CMICmdBase * CMICmdCmdTargetSelect::CreateSelf( void )
{
return new CMICmdCmdTargetSelect();
}
}

View File

@ -47,7 +47,7 @@ class CMICmdCmdTargetSelect : public CMICmdBase
{
// Statics:
public:
// Required by the CMICmdFactory when registering *this commmand
// Required by the CMICmdFactory when registering *this command
static CMICmdBase * CreateSelf( void );
// Methods:
@ -60,9 +60,6 @@ public:
virtual bool Execute( void );
virtual bool Acknowledge( void );
virtual bool ParseArgs( void );
// Overridden:
public:
// From CMICmnBase
/* dtor */ virtual ~CMICmdCmdTargetSelect( void );
@ -70,4 +67,4 @@ public:
private:
const CMIUtilString m_constStrArgNamedType;
const CMIUtilString m_constStrArgNamedParameters;
};
};

View File

@ -10,8 +10,7 @@
//++
// File: MICmdCmdThread.cpp
//
// Overview: CMICmdCmdThread implementation.
// CMICmdCmdThreadInfo implementation.
// Overview: CMICmdCmdThreadInfo implementation.
//
// Environment: Compilers: Visual C++ 12.
// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
@ -40,85 +39,6 @@
#include "MICmdArgValOptionShort.h"
#include "MICmdArgValListOfN.h"
//++ ------------------------------------------------------------------------------------
// Details: CMICmdCmdThread constructor.
// Type: Method.
// Args: None.
// Return: None.
// Throws: None.
//--
CMICmdCmdThread::CMICmdCmdThread( void )
{
// Command factory matches this name with that received from the stdin stream
m_strMiCmd = "thread";
// Required by the CMICmdFactory when registering *this commmand
m_pSelfCreatorFn = &CMICmdCmdThread::CreateSelf;
}
//++ ------------------------------------------------------------------------------------
// Details: CMICmdCmdThread destructor.
// Type: Overrideable.
// Args: None.
// Return: None.
// Throws: None.
//--
CMICmdCmdThread::~CMICmdCmdThread( void )
{
}
//++ ------------------------------------------------------------------------------------
// 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 CMICmdCmdThread::Execute( void )
{
// Do nothing
return MIstatus::success;
}
//++ ------------------------------------------------------------------------------------
// Details: The invoker requires this function. The command prepares a MI Record Result
// for the work carried out in the Execute().
// Type: Overridden.
// Args: None.
// Return: MIstatus::success - Functional succeeded.
// MIstatus::failure - Functional failed.
// Throws: None.
//--
bool CMICmdCmdThread::Acknowledge( void )
{
const CMICmnMIValueConst miValueConst( MIRSRC( IDS_WORD_NOT_IMPLEMENTED ) );
const CMICmnMIValueResult miValueResult( "msg", miValueConst );
const CMICmnMIResultRecord miRecordResult( m_cmdData.nMiCmdNumber, CMICmnMIResultRecord::eResultClass_Error, miValueResult );
m_miResultRecord = miRecordResult;
return MIstatus::success;
}
//++ ------------------------------------------------------------------------------------
// Details: Required by the CMICmdFactory when registering *this commmand. The factory
// calls this function to create an instance of *this command.
// Type: Static method.
// Args: None.
// Return: CMICmdBase * - Pointer to a new command.
// Throws: None.
//--
CMICmdBase * CMICmdCmdThread::CreateSelf( void )
{
return new CMICmdCmdThread();
}
//---------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------
//++ ------------------------------------------------------------------------------------
// Details: CMICmdCmdThreadInfo constructor.
// Type: Method.
@ -134,7 +54,7 @@ CMICmdCmdThreadInfo::CMICmdCmdThreadInfo( void )
// Command factory matches this name with that received from the stdin stream
m_strMiCmd = "thread-info";
// Required by the CMICmdFactory when registering *this commmand
// Required by the CMICmdFactory when registering *this command
m_pSelfCreatorFn = &CMICmdCmdThreadInfo::CreateSelf;
}
@ -247,7 +167,7 @@ bool CMICmdCmdThreadInfo::Acknowledge( void )
{
const CMICmnMIValueConst miValueConst( "invalid thread id" );
const CMICmnMIValueResult miValueResult( "msg", miValueConst );
const CMICmnMIResultRecord miRecordResult( m_cmdData.nMiCmdNumber, CMICmnMIResultRecord::eResultClass_Error, miValueResult );
const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, miValueResult );
m_miResultRecord = miRecordResult;
return MIstatus::success;
}
@ -255,7 +175,7 @@ bool CMICmdCmdThreadInfo::Acknowledge( void )
// MI print "%s^done,threads=[{id=\"%d\",target-id=\"%s\",frame={},state=\"%s\"}]
const CMICmnMIValueList miValueList( m_miValueTupleThread );
const CMICmnMIValueResult miValueResult( "threads", miValueList );
const CMICmnMIResultRecord miRecordResult( m_cmdData.nMiCmdNumber, CMICmnMIResultRecord::eResultClass_Done, miValueResult );
const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult );
m_miResultRecord = miRecordResult;
return MIstatus::success;
}
@ -266,7 +186,7 @@ bool CMICmdCmdThreadInfo::Acknowledge( void )
{
const CMICmnMIValueConst miValueConst( "[]" );
const CMICmnMIValueResult miValueResult( "threads", miValueConst );
const CMICmnMIResultRecord miRecordResult( m_cmdData.nMiCmdNumber, CMICmnMIResultRecord::eResultClass_Done, miValueResult );
const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult );
m_miResultRecord = miRecordResult;
return MIstatus::success;
}
@ -282,14 +202,14 @@ bool CMICmdCmdThreadInfo::Acknowledge( void )
}
const CMICmnMIValueResult miValueResult( "threads", miValueList );
const CMICmnMIResultRecord miRecordResult( m_cmdData.nMiCmdNumber, CMICmnMIResultRecord::eResultClass_Done, miValueResult );
const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult );
m_miResultRecord = miRecordResult;
return MIstatus::success;
}
//++ ------------------------------------------------------------------------------------
// Details: Required by the CMICmdFactory when registering *this commmand. The factory
// Details: Required by the CMICmdFactory when registering *this command. The factory
// calls this function to create an instance of *this command.
// Type: Static method.
// Args: None.

View File

@ -10,8 +10,7 @@
//++
// File: MICmdCmdThread.h
//
// Overview: CMICmdCmdThread interface.
// CMICmdCmdThreadInfo interface.
// Overview: CMICmdCmdThreadInfo interface.
//
// To implement new MI commands derive a new command class from the command base
// class. To enable the new command for interpretation add the new command class
@ -36,36 +35,6 @@
#include "MICmnMIValueTuple.h"
#include "MICmnMIValueList.h"
//++ ============================================================================
// Details: MI command class. MI commands derived from the command base class.
// *this class implements MI command "thread".
// Gotchas: None.
// Authors: Illya Rudkin 25/02/2014.
// Changes: None.
//--
class CMICmdCmdThread : public CMICmdBase
{
// Statics:
public:
// Required by the CMICmdFactory when registering *this commmand
static CMICmdBase * CreateSelf( void );
// Methods:
public:
/* ctor */ CMICmdCmdThread( void );
// Overridden:
public:
// From CMICmdInvoker::ICmd
virtual bool Execute( void );
virtual bool Acknowledge( void );
// Overridden:
public:
// From CMICmnBase
/* dtor */ virtual ~CMICmdCmdThread( void );
};
//++ ============================================================================
// Details: MI command class. MI commands derived from the command base class.
// *this class implements MI command "thread-info".
@ -77,7 +46,7 @@ class CMICmdCmdThreadInfo : public CMICmdBase
{
// Statics:
public:
// Required by the CMICmdFactory when registering *this commmand
// Required by the CMICmdFactory when registering *this command
static CMICmdBase * CreateSelf( void );
// Methods:
@ -90,9 +59,6 @@ public:
virtual bool Execute( void );
virtual bool Acknowledge( void );
virtual bool ParseArgs( void );
// Overridden:
public:
// From CMICmnBase
/* dtor */ virtual ~CMICmdCmdThreadInfo( void );

View File

@ -10,7 +10,7 @@
//++
// File: MICmdCmdTrace.cpp
//
// Overview: CMICmdCmdTraceStatus implementation.
// Overview: CMICmdCmdTraceStatus implementation.
//
// Environment: Compilers: Visual C++ 12.
// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
@ -38,7 +38,7 @@ CMICmdCmdTraceStatus::CMICmdCmdTraceStatus( void )
// Command factory matches this name with that received from the stdin stream
m_strMiCmd = "trace-status";
// Required by the CMICmdFactory when registering *this commmand
// Required by the CMICmdFactory when registering *this command
m_pSelfCreatorFn = &CMICmdCmdTraceStatus::CreateSelf;
}
@ -81,14 +81,14 @@ bool CMICmdCmdTraceStatus::Acknowledge( void )
{
const CMICmnMIValueConst miValueConst( MIRSRC( IDS_CMD_ERR_NOT_IMPLEMENTED ) );
const CMICmnMIValueResult miValueResult( "msg", miValueConst );
const CMICmnMIResultRecord miRecordResult( m_cmdData.nMiCmdNumber, CMICmnMIResultRecord::eResultClass_Error, miValueResult );
const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, miValueResult );
m_miResultRecord = miRecordResult;
return MIstatus::success;
}
//++ ------------------------------------------------------------------------------------
// Details: Required by the CMICmdFactory when registering *this commmand. The factory
// Details: Required by the CMICmdFactory when registering *this command. The factory
// calls this function to create an instance of *this command.
// Type: Static method.
// Args: None.
@ -98,4 +98,4 @@ bool CMICmdCmdTraceStatus::Acknowledge( void )
CMICmdBase * CMICmdCmdTraceStatus::CreateSelf( void )
{
return new CMICmdCmdTraceStatus();
}
}

View File

@ -44,7 +44,7 @@ class CMICmdCmdTraceStatus : public CMICmdBase
{
// Statics:
public:
// Required by the CMICmdFactory when registering *this commmand
// Required by the CMICmdFactory when registering *this command
static CMICmdBase * CreateSelf( void );
// Methods:
@ -56,9 +56,6 @@ public:
// From CMICmdInvoker::ICmd
virtual bool Execute( void );
virtual bool Acknowledge( void );
// Overridden:
public:
// From CMICmnBase
/* dtor */ virtual ~CMICmdCmdTraceStatus( void );
};

View File

@ -18,6 +18,7 @@
// CMICmdCmdVarListChildren implementation.
// CMICmdCmdVarEvaluateExpression implementation.
// CMICmdCmdVarInfoPathExpression implementation.
// CMICmdCmdVarShowAttributes implementation.
//
// Environment: Compilers: Visual C++ 12.
// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
@ -44,6 +45,7 @@
#include "MICmdArgValOptionLong.h"
#include "MICmdArgValOptionShort.h"
#include "MICmdArgValListOfN.h"
#include "MICmnLLDBProxySBValue.h"
//++ ------------------------------------------------------------------------------------
// Details: CMICmdCmdVarCreate constructor.
@ -59,6 +61,7 @@ CMICmdCmdVarCreate::CMICmdCmdVarCreate( void )
, m_strType( "??" )
, m_bValid( false )
, m_constStrArgThread( "thread" )
, m_constStrArgThreadGroup( "thread-group" )
, m_constStrArgFrame( "frame" )
, m_constStrArgName( "name" )
, m_constStrArgFrameAddr( "frame-addr" )
@ -67,7 +70,7 @@ CMICmdCmdVarCreate::CMICmdCmdVarCreate( void )
// Command factory matches this name with that received from the stdin stream
m_strMiCmd = "var-create";
// Required by the CMICmdFactory when registering *this commmand
// Required by the CMICmdFactory when registering *this command
m_pSelfCreatorFn = &CMICmdCmdVarCreate::CreateSelf;
}
@ -93,11 +96,12 @@ CMICmdCmdVarCreate::~CMICmdCmdVarCreate( void )
//--
bool CMICmdCmdVarCreate::ParseArgs( void )
{
bool bOk = m_setCmdArgs.Add( *(new CMICmdArgValOptionLong( m_constStrArgThread, true, true, CMICmdArgValListBase::eArgValType_Number, 1 ) ) );
bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValOptionLong( m_constStrArgFrame, true, true, CMICmdArgValListBase::eArgValType_Number, 1 ) ) );
bool bOk = m_setCmdArgs.Add( *(new CMICmdArgValOptionLong( m_constStrArgThread, false, true, CMICmdArgValListBase::eArgValType_Number, 1 ) ) );
bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValOptionLong( m_constStrArgThreadGroup, false, false, CMICmdArgValListBase::eArgValType_ThreadGrp, 1 ) ) );
bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValOptionLong( m_constStrArgFrame, false, true, CMICmdArgValListBase::eArgValType_Number, 1 ) ) );
bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValString( m_constStrArgName, false, true ) ) );
bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValString( m_constStrArgFrameAddr, false, true ) ) );
bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValString( m_constStrArgExpression, true, true ) ) );
bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValString( m_constStrArgExpression, true, true, true, true ) ) );
CMICmdArgContext argCntxt( m_cmdData.strMiCmdOption );
if( bOk && !m_setCmdArgs.Validate( m_cmdData.strMiCmd, argCntxt ) )
{
@ -178,14 +182,14 @@ bool CMICmdCmdVarCreate::Execute( void )
{
m_bValid = true;
m_nChildren = value.GetNumChildren();
const char * pCType = value.GetTypeName();
m_strType = (pCType != nullptr) ? pCType : m_strType;
const MIchar * pCType = value.GetTypeName();
m_strType = (pCType != nullptr) ? pCType : m_strType;
}
if( m_bValid )
{
// This gets added to CMICmnLLDBDebugSessionInfoVarObj static container of varObjs
const CMICmnLLDBDebugSessionInfoVarObj varObj( rStrExpression, m_strVarName, value );
CMICmnLLDBDebugSessionInfoVarObj varObj( rStrExpression, m_strVarName, value );
}
return MIstatus::success;
@ -211,7 +215,7 @@ bool CMICmdCmdVarCreate::Acknowledge( void )
const CMICmnMIValueConst miValueConst2( strNumChild );
miValueResultAll.Add( "numchild", miValueConst2 );
CMICmnLLDBDebugSessionInfoVarObj varObj;
const bool bOk = CMICmnLLDBDebugSessionInfoVarObj::VarObjGet( m_strVarName, varObj );
const bool bOk = CMICmnLLDBDebugSessionInfoVarObj::VarObjGet( m_strVarName, varObj ); MIunused( bOk );
const CMICmnMIValueConst miValueConst3( varObj.GetValueFormatted() );
miValueResultAll.Add( "value", miValueConst3 );
const CMICmnMIValueConst miValueConst4( m_strType );
@ -222,7 +226,7 @@ bool CMICmdCmdVarCreate::Acknowledge( void )
const CMICmnMIValueConst miValueConst6( "0" );
miValueResultAll.Add( "has_more", miValueConst6 );
const CMICmnMIResultRecord miRecordResult( m_cmdData.nMiCmdNumber, CMICmnMIResultRecord::eResultClass_Done, miValueResultAll );
const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResultAll );
m_miResultRecord = miRecordResult;
return MIstatus::success;
@ -230,14 +234,14 @@ bool CMICmdCmdVarCreate::Acknowledge( void )
const CMICmnMIValueConst miValueConst( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_VARIABLE_CREATION_FAILED ), m_strExpression.c_str() ) );
CMICmnMIValueResult miValueResult( "msg", miValueConst );
const CMICmnMIResultRecord miRecordResult( m_cmdData.nMiCmdNumber, CMICmnMIResultRecord::eResultClass_Error, miValueResult );
const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, miValueResult );
m_miResultRecord = miRecordResult;
return MIstatus::success;
}
//++ ------------------------------------------------------------------------------------
// Details: Required by the CMICmdFactory when registering *this commmand. The factory
// Details: Required by the CMICmdFactory when registering *this command. The factory
// calls this function to create an instance of *this command.
// Type: Static method.
// Args: None.
@ -263,11 +267,15 @@ CMICmdBase * CMICmdCmdVarCreate::CreateSelf( void )
CMICmdCmdVarUpdate::CMICmdCmdVarUpdate( void )
: m_constStrArgPrintValues( "print-values" )
, m_constStrArgName( "name" )
, m_bValueChangedArrayType( false )
, m_bValueChangedCompositeType( false )
, m_bValueChangedNormalType( false )
, m_miValueList( true )
{
// Command factory matches this name with that received from the stdin stream
m_strMiCmd = "var-update";
// Required by the CMICmdFactory when registering *this commmand
// Required by the CMICmdFactory when registering *this command
m_pSelfCreatorFn = &CMICmdCmdVarUpdate::CreateSelf;
}
@ -326,12 +334,64 @@ bool CMICmdCmdVarUpdate::Execute( void )
return MIstatus::failure;
}
const CMIUtilString & rVarRealName( varObj.GetNameReal() ); MIunused( rVarRealName );
lldb::SBValue & rValue = const_cast< lldb::SBValue & >( varObj.GetValue() );
const bool bValid = rValue.IsValid();
if( bValid )
if( bValid && rValue.GetValueDidChange() )
{
m_bValueChangedNormalType = true;
varObj.UpdateValue();
m_strValueName = rVarObjName;
return MIstatus::success;
}
m_strValueName = rVarObjName;
// Examine an array type variable
if( !ExamineSBValueForChange( varObj, false, m_bValueChangedArrayType ) )
return MIstatus::failure;
// Handle composite types i.e. struct or arrays
const MIuint nChildren = rValue.GetNumChildren();
for( MIuint i = 0; i < nChildren; i++ )
{
lldb::SBValue member = rValue.GetChildAtIndex( i );
if( !member.IsValid() )
continue;
const CMIUtilString varName( CMIUtilString::Format( "%s.%s", rVarObjName.c_str(), member.GetName() ) );
if( member.GetValueDidChange() )
{
// Handle composite
const CMIUtilString strValue( CMICmnLLDBDebugSessionInfoVarObj::GetValueStringFormatted( member, CMICmnLLDBDebugSessionInfoVarObj::eVarFormat_Natural ) );
const CMIUtilString strInScope( member.IsInScope() ? "true" : "false" );
MIFormResponse( varName, strValue, strInScope );
m_bValueChangedCompositeType = true;
}
else
{
// Handle array of composites
CMICmnLLDBDebugSessionInfoVarObj varObj;
if( CMICmnLLDBDebugSessionInfoVarObj::VarObjGet( varName, varObj ) )
{
bool bValueChanged = false;
if( ExamineSBValueForChange( varObj, true, bValueChanged ) )
{
if( bValueChanged && CMICmnLLDBDebugSessionInfoVarObj::VarObjGet( varName, varObj ) )
{
lldb::SBValue & rValue = const_cast< lldb::SBValue & >( varObj.GetValue() );
const bool bValid = rValue.IsValid();
const CMIUtilString strValue( bValid ? varObj.GetValueFormatted() : "<unknown>" );
const CMIUtilString strInScope( (bValid && rValue.IsInScope()) ? "true" : "false" );
MIFormResponse( varName, strValue, strInScope );
m_bValueChangedCompositeType = true;
}
}
else
return MIstatus::failure;
}
}
}
return MIstatus::success;
}
@ -347,40 +407,60 @@ bool CMICmdCmdVarUpdate::Execute( void )
//--
bool CMICmdCmdVarUpdate::Acknowledge( void )
{
CMICmnLLDBDebugSessionInfoVarObj varObj;
CMICmnLLDBDebugSessionInfoVarObj::VarObjGet( m_strValueName, varObj );
lldb::SBValue & rValue = const_cast< lldb::SBValue & >( varObj.GetValue() );
const bool bValid = rValue.IsValid();
const CMIUtilString strValue( bValid ? varObj.GetValueFormatted() : "<unknown>" );
const CMIUtilString strInScope( (bValid && rValue.IsInScope()) ? "true" : "false" );
if( m_bValueChangedArrayType || m_bValueChangedNormalType )
{
CMICmnLLDBDebugSessionInfoVarObj varObj;
CMICmnLLDBDebugSessionInfoVarObj::VarObjGet( m_strValueName, varObj );
lldb::SBValue & rValue = const_cast< lldb::SBValue & >( varObj.GetValue() );
const bool bValid = rValue.IsValid();
const CMIUtilString strValue( bValid ? varObj.GetValueFormatted() : "<unknown>" );
const CMIUtilString strInScope( (bValid && rValue.IsInScope()) ? "true" : "false" );
// MI print "%s^done,changelist=[{name=\"%s\",value=\"%s\",in_scope=\"%s\",type_changed=\"false\",has_more=\"0\"}]"
const CMICmnMIValueConst miValueConst( m_strValueName );
CMICmnMIValueResult miValueResult( "name", miValueConst );
CMICmnMIValueTuple miValueTuple( miValueResult );
const CMICmnMIValueConst miValueConst2( strValue );
CMICmnMIValueResult miValueResult2( "value", miValueConst2 );
miValueTuple.Add( miValueResult2 );
const CMICmnMIValueConst miValueConst3( strInScope );
CMICmnMIValueResult miValueResult3( "in_scope", miValueConst3 );
miValueTuple.Add( miValueResult3 );
const CMICmnMIValueConst miValueConst4( "false" );
CMICmnMIValueResult miValueResult4( "type_changed", miValueConst4 );
miValueTuple.Add( miValueResult4 );
const CMICmnMIValueConst miValueConst5( "0" );
CMICmnMIValueResult miValueResult5( "has_more", miValueConst5 );
miValueTuple.Add( miValueResult5 );
const CMICmnMIValueList miValueList( miValueTuple );
// MI print "%s^done,changelist=[{name=\"%s\",value=\"%s\",in_scope=\"%s\",type_changed=\"false\",has_more=\"0\"}]"
const CMICmnMIValueConst miValueConst( m_strValueName );
CMICmnMIValueResult miValueResult( "name", miValueConst );
CMICmnMIValueTuple miValueTuple( miValueResult );
const CMICmnMIValueConst miValueConst2( strValue );
CMICmnMIValueResult miValueResult2( "value", miValueConst2 );
miValueTuple.Add( miValueResult2 );
const CMICmnMIValueConst miValueConst3( strInScope );
CMICmnMIValueResult miValueResult3( "in_scope", miValueConst3 );
miValueTuple.Add( miValueResult3 );
const CMICmnMIValueConst miValueConst4( "false" );
CMICmnMIValueResult miValueResult4( "type_changed", miValueConst4 );
miValueTuple.Add( miValueResult4 );
const CMICmnMIValueConst miValueConst5( "0" );
CMICmnMIValueResult miValueResult5( "has_more", miValueConst5 );
miValueTuple.Add( miValueResult5 );
const CMICmnMIValueList miValueList( miValueTuple );
CMICmnMIValueResult miValueResult6( "changelist", miValueList );
const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult6 );
m_miResultRecord = miRecordResult;
return MIstatus::success;
}
else if( m_bValueChangedCompositeType )
{
// MI print "%s^done,changelist=[{name=\"%s\",value=\"%s\",in_scope=\"%s\",type_changed=\"false\",has_more=\"0\"},{name=\"%s\",value=\"%s\",in_scope=\"%s\",type_changed=\"false\",has_more=\"0\"}]"
CMICmnMIValueResult miValueResult6( "changelist", m_miValueList );
const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult6 );
m_miResultRecord = miRecordResult;
}
else
{
// MI: "%s^done,changelist=[]"
const CMICmnMIValueList miValueList( true );
CMICmnMIValueResult miValueResult6( "changelist", miValueList );
const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult6 );
m_miResultRecord = miRecordResult;
return MIstatus::success;
}
CMICmnMIValueResult miValueResult6( "changelist", miValueList );
const CMICmnMIResultRecord miRecordResult( m_cmdData.nMiCmdNumber, CMICmnMIResultRecord::eResultClass_Done, miValueResult6 );
m_miResultRecord = miRecordResult;
return MIstatus::success;
}
//++ ------------------------------------------------------------------------------------
// Details: Required by the CMICmdFactory when registering *this commmand. The factory
// Details: Required by the CMICmdFactory when registering *this command. The factory
// calls this function to create an instance of *this command.
// Type: Static method.
// Args: None.
@ -392,6 +472,110 @@ CMICmdBase * CMICmdCmdVarUpdate::CreateSelf( void )
return new CMICmdCmdVarUpdate();
}
//++ ------------------------------------------------------------------------------------
// Details: Form the MI response for multiple variables.
// Type: Method.
// Args: vrStrVarName - (R) Session var object's name.
// vrStrValue - (R) Text version of the value held in the variable.
// vrStrScope - (R) In scope "yes" or "no".
// Return: MIstatus::success - Functional succeeded.
// MIstatus::failure - Functional failed.
// Throws: None.
//--
bool CMICmdCmdVarUpdate::MIFormResponse( const CMIUtilString & vrStrVarName, const CMIUtilString & vrStrValue, const CMIUtilString & vrStrScope )
{
// MI print "[{name=\"%s\",value=\"%s\",in_scope=\"%s\",type_changed=\"false\",has_more=\"0\"}]"
const CMICmnMIValueConst miValueConst( vrStrVarName );
CMICmnMIValueResult miValueResult( "name", miValueConst );
CMICmnMIValueTuple miValueTuple( miValueResult );
const CMICmnMIValueConst miValueConst2( vrStrValue );
CMICmnMIValueResult miValueResult2( "value", miValueConst2 );
bool bOk = miValueTuple.Add( miValueResult2 );
const CMICmnMIValueConst miValueConst3( vrStrScope );
CMICmnMIValueResult miValueResult3( "in_scope", miValueConst3 );
bOk = bOk && miValueTuple.Add( miValueResult3 );
const CMICmnMIValueConst miValueConst4( "false" );
CMICmnMIValueResult miValueResult4( "type_changed", miValueConst4 );
bOk = bOk && miValueTuple.Add( miValueResult4 );
const CMICmnMIValueConst miValueConst5( "0" );
CMICmnMIValueResult miValueResult5( "has_more", miValueConst5 );
bOk = bOk && miValueTuple.Add( miValueResult5 );
bOk = bOk && m_miValueList.Add( miValueTuple );
return bOk;
}
//++ ------------------------------------------------------------------------------------
// Details: Determine if the var object is a array type variable. LLDB does not 'detect'
// a value change for some types like elements in an array so have to re-evaluate
// the expression again.
// Type: Method.
// Args: vrVarObj - (R) Session var object to examine.
// vrwbChanged - (W) True = Is an array type and it changed,
// False = Not an array type or not changed.
// Return: MIstatus::success - Functional succeeded.
// MIstatus::failure - Functional failed.
// Throws: None.
//--
bool CMICmdCmdVarUpdate::ExamineSBValueForChange( const CMICmnLLDBDebugSessionInfoVarObj & vrVarObj, const bool vbIgnoreVarType, bool & vrwbChanged )
{
vrwbChanged = false;
CMICmnLLDBDebugSessionInfo & rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance() );
lldb::SBProcess & rProcess = rSessionInfo.m_lldbProcess;
lldb::SBThread thread = rProcess.GetSelectedThread();
if( thread.GetNumFrames() == 0 )
{
return MIstatus::success;
}
const CMIUtilString & strVarObjParentName = vrVarObj.GetVarParentName();
lldb::SBFrame frame = thread.GetSelectedFrame();
const CMIUtilString & rExpression( vrVarObj.GetNameReal() );
CMIUtilString varExpression;
if( strVarObjParentName.empty() )
{
varExpression = rExpression;
}
else
{
CMICmnLLDBDebugSessionInfoVarObj varObjParent;
if( CMICmnLLDBDebugSessionInfoVarObj::VarObjGet( strVarObjParentName, varObjParent ) )
varExpression = CMIUtilString::Format( "%s.%s", varObjParent.GetNameReal().c_str(), rExpression.c_str() );
else
{
// The parent is only assigned in the CMICmdCmdVarListChildren command, we have a problem, need to investigate
SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_VARIABLE_DOESNOTEXIST ), m_cmdData.strMiCmd.c_str(), strVarObjParentName.c_str() ) );
return MIstatus::failure;
}
}
lldb::SBValue value = frame.EvaluateExpression( varExpression.c_str() );
if( !value.IsValid() )
value = frame.FindVariable( rExpression.c_str() );
if( value.IsValid() )
{
lldb::SBType valueType = value.GetType();
const lldb::BasicType eValueType = valueType.GetBasicType();
if( vbIgnoreVarType || (eValueType != lldb::BasicType::eBasicTypeInvalid) )
{
MIuint64 nPrevValue = 0;
MIuint64 nRevaluateValue = 0;
lldb::SBValue & rValue = const_cast< lldb::SBValue & >( vrVarObj.GetValue() );
if( CMICmnLLDBProxySBValue::GetValueAsUnsigned( rValue, nPrevValue ) &&
CMICmnLLDBProxySBValue::GetValueAsUnsigned( value, nRevaluateValue ) &&
(nPrevValue != nRevaluateValue) )
{
// Have a value change so update the var object
vrwbChanged = true;
const CMICmnLLDBDebugSessionInfoVarObj varObj( rExpression, vrVarObj.GetName(), value, strVarObjParentName );
}
}
}
return MIstatus::success;
}
//---------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------
@ -409,7 +593,7 @@ CMICmdCmdVarDelete::CMICmdCmdVarDelete( void )
// Command factory matches this name with that received from the stdin stream
m_strMiCmd = "var-delete";
// Required by the CMICmdFactory when registering *this commmand
// Required by the CMICmdFactory when registering *this command
m_pSelfCreatorFn = &CMICmdCmdVarDelete::CreateSelf;
}
@ -476,14 +660,14 @@ bool CMICmdCmdVarDelete::Execute( void )
//--
bool CMICmdCmdVarDelete::Acknowledge( void )
{
const CMICmnMIResultRecord miRecordResult( m_cmdData.nMiCmdNumber, CMICmnMIResultRecord::eResultClass_Done );
const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done );
m_miResultRecord = miRecordResult;
return MIstatus::success;
}
//++ ------------------------------------------------------------------------------------
// Details: Required by the CMICmdFactory when registering *this commmand. The factory
// Details: Required by the CMICmdFactory when registering *this command. The factory
// calls this function to create an instance of *this command.
// Type: Static method.
// Args: None.
@ -514,7 +698,7 @@ CMICmdCmdVarAssign::CMICmdCmdVarAssign( void )
// Command factory matches this name with that received from the stdin stream
m_strMiCmd = "var-assign";
// Required by the CMICmdFactory when registering *this commmand
// Required by the CMICmdFactory when registering *this command
m_pSelfCreatorFn = &CMICmdCmdVarAssign::CreateSelf;
}
@ -605,7 +789,7 @@ bool CMICmdCmdVarAssign::Acknowledge( void )
CMICmnLLDBDebugSessionInfoVarObj::VarObjGet( m_varObjName, varObj );
const CMICmnMIValueConst miValueConst( varObj.GetValueFormatted() );
const CMICmnMIValueResult miValueResult( "value", miValueConst );
const CMICmnMIResultRecord miRecordResult( m_cmdData.nMiCmdNumber, CMICmnMIResultRecord::eResultClass_Done, miValueResult );
const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult );
m_miResultRecord = miRecordResult;
return MIstatus::success;
@ -613,14 +797,14 @@ bool CMICmdCmdVarAssign::Acknowledge( void )
const CMICmnMIValueConst miValueConst( "expression could not be evaluated" );
const CMICmnMIValueResult miValueResult( "msg", miValueConst );
const CMICmnMIResultRecord miRecordResult( m_cmdData.nMiCmdNumber, CMICmnMIResultRecord::eResultClass_Error, miValueResult );
const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, miValueResult );
m_miResultRecord = miRecordResult;
return MIstatus::success;
}
//++ ------------------------------------------------------------------------------------
// Details: Required by the CMICmdFactory when registering *this commmand. The factory
// Details: Required by the CMICmdFactory when registering *this command. The factory
// calls this function to create an instance of *this command.
// Type: Static method.
// Args: None.
@ -650,7 +834,7 @@ CMICmdCmdVarSetFormat::CMICmdCmdVarSetFormat( void )
// Command factory matches this name with that received from the stdin stream
m_strMiCmd = "var-set-format";
// Required by the CMICmdFactory when registering *this commmand
// Required by the CMICmdFactory when registering *this command
m_pSelfCreatorFn = &CMICmdCmdVarSetFormat::CreateSelf;
}
@ -756,14 +940,14 @@ bool CMICmdCmdVarSetFormat::Acknowledge( void )
const CMICmnMIValueList miValueList( miValueTuple );
const CMICmnMIValueResult miValueResult6( "changelist", miValueList );
const CMICmnMIResultRecord miRecordResult( m_cmdData.nMiCmdNumber, CMICmnMIResultRecord::eResultClass_Done, miValueResult6 );
const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult6 );
m_miResultRecord = miRecordResult;
return MIstatus::success;
}
//++ ------------------------------------------------------------------------------------
// Details: Required by the CMICmdFactory when registering *this commmand. The factory
// Details: Required by the CMICmdFactory when registering *this command. The factory
// calls this function to create an instance of *this command.
// Type: Static method.
// Args: None.
@ -795,7 +979,7 @@ CMICmdCmdVarListChildren::CMICmdCmdVarListChildren( void )
// Command factory matches this name with that received from the stdin stream
m_strMiCmd = "var-list-children";
// Required by the CMICmdFactory when registering *this commmand
// Required by the CMICmdFactory when registering *this command
m_pSelfCreatorFn = &CMICmdCmdVarListChildren::CreateSelf;
}
@ -865,40 +1049,34 @@ bool CMICmdCmdVarListChildren::Execute( void )
for( MIuint i = 0; i < m_nChildren; i++ )
{
lldb::SBValue member = rValue.GetChildAtIndex( i );
const bool bValid = member.IsValid();
const CMIUtilString varName( CMIUtilString::Format( "var%u", CMICmnLLDBDebugSessionInfoVarObj::VarObjIdGet() ) );
CMICmnLLDBDebugSessionInfoVarObj::VarObjIdInc();
const MIuint nChildren = bValid ? member.GetNumChildren() : 0;
CMIUtilString strType( MIRSRC( IDS_WORD_UNKNOWNTYPE_BRKTS ) );
if( bValid )
{
lldb::SBType type = member.GetType();
const char * pTypeName = type.GetName();
if( pTypeName != nullptr )
strType = pTypeName;
}
if( !member.IsValid() )
continue;
const MIchar * pExp = member.GetName();
const CMIUtilString strExp = (pExp != nullptr) ? pExp : "??";
const CMIUtilString name( CMIUtilString::Format( "%s.%s", rVarObjName.c_str(), strExp.c_str() ) );
const MIuint nChildren = member.GetNumChildren();
const MIchar * pTypeName = member.GetType().GetName();
const CMIUtilString strType = (pTypeName != nullptr) ? pTypeName : MIRSRC( IDS_WORD_UNKNOWNTYPE_BRKTS );
const CMIUtilString strThreadId( CMIUtilString::Format( "%u", member.GetThread().GetIndexID() ) );
// Varobj gets added to CMICmnLLDBDebugSessionInfoVarObj static container of varObjs
const CMICmnLLDBDebugSessionInfoVarObj var( (member.GetName() != nullptr) ? member.GetName() : "??", varName, member );
CMICmnLLDBDebugSessionInfoVarObj var( strExp, name, member, rVarObjName );
// MI print "child={name=\"%s\",exp=\"%s\",numchild=\"%d\",value=\"%s\",type=\"%s\",thread-id=\"%u\",has_more=\"%u\"}"
const CMICmnMIValueConst miValueConst( varName );
const CMICmnMIValueConst miValueConst( name );
const CMICmnMIValueResult miValueResult( "name", miValueConst );
CMICmnMIValueTuple miValueTuple( miValueResult );
const CMICmnMIValueConst miValueConst2( (member.GetName() != nullptr) ? member.GetName() : "??" );
const CMICmnMIValueConst miValueConst2( strExp );
const CMICmnMIValueResult miValueResult2( "exp", miValueConst2 );
miValueTuple.Add( miValueResult2 );
const CMIUtilString strNumChild( CMIUtilString::Format( "%d", nChildren ) );
const CMICmnMIValueConst miValueConst3( strNumChild );
const CMICmnMIValueResult miValueResult3( "numchild", miValueConst3 );
miValueTuple.Add( miValueResult3 );
const CMICmnMIValueConst miValueConst4( var.GetValueFormatted() );
const CMICmnMIValueResult miValueResult4( "value", miValueConst4 );
miValueTuple.Add( miValueResult4 );
const CMICmnMIValueConst miValueConst5( strType );
const CMICmnMIValueResult miValueResult5( "type", miValueConst5 );
miValueTuple.Add( miValueResult5 );
const CMIUtilString strThreadId( CMIUtilString::Format( "%u", member.GetThread().GetIndexID() ) );
const CMICmnMIValueConst miValueConst6( strThreadId );
const CMICmnMIValueResult miValueResult6( "thread-id", miValueConst6 );
miValueTuple.Add( miValueResult6 );
@ -951,7 +1129,7 @@ bool CMICmdCmdVarListChildren::Acknowledge( void )
miValueResult.Add( "children", miValueList );
}
const CMICmnMIResultRecord miRecordResult( m_cmdData.nMiCmdNumber, CMICmnMIResultRecord::eResultClass_Done, miValueResult );
const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult );
m_miResultRecord = miRecordResult;
return MIstatus::success;
}
@ -959,14 +1137,14 @@ bool CMICmdCmdVarListChildren::Acknowledge( void )
// MI print "%s^done,numchild=\"0\""
const CMICmnMIValueConst miValueConst( "0" );
const CMICmnMIValueResult miValueResult( "numchild", miValueConst );
const CMICmnMIResultRecord miRecordResult( m_cmdData.nMiCmdNumber, CMICmnMIResultRecord::eResultClass_Done, miValueResult );
const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult );
m_miResultRecord = miRecordResult;
return MIstatus::success;
}
//++ ------------------------------------------------------------------------------------
// Details: Required by the CMICmdFactory when registering *this commmand. The factory
// Details: Required by the CMICmdFactory when registering *this command. The factory
// calls this function to create an instance of *this command.
// Type: Static method.
// Args: None.
@ -997,7 +1175,7 @@ CMICmdCmdVarEvaluateExpression::CMICmdCmdVarEvaluateExpression( void )
// Command factory matches this name with that received from the stdin stream
m_strMiCmd = "var-evaluate-expression";
// Required by the CMICmdFactory when registering *this commmand
// Required by the CMICmdFactory when registering *this command
m_pSelfCreatorFn = &CMICmdCmdVarEvaluateExpression::CreateSelf;
}
@ -1084,20 +1262,20 @@ bool CMICmdCmdVarEvaluateExpression::Acknowledge( void )
CMICmnLLDBDebugSessionInfoVarObj::VarObjGet( m_varObjName, varObj );
const CMICmnMIValueConst miValueConst( varObj.GetValueFormatted() );
const CMICmnMIValueResult miValueResult( "value", miValueConst );
const CMICmnMIResultRecord miRecordResult( m_cmdData.nMiCmdNumber, CMICmnMIResultRecord::eResultClass_Done, miValueResult );
const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult );
m_miResultRecord = miRecordResult;
return MIstatus::success;
}
const CMICmnMIValueConst miValueConst( "variable invalid" );
const CMICmnMIValueResult miValueResult( "msg", miValueConst );
const CMICmnMIResultRecord miRecordResult( m_cmdData.nMiCmdNumber, CMICmnMIResultRecord::eResultClass_Error, miValueResult );
const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, miValueResult );
m_miResultRecord = miRecordResult;
return MIstatus::success;
}
//++ ------------------------------------------------------------------------------------
// Details: Required by the CMICmdFactory when registering *this commmand. The factory
// Details: Required by the CMICmdFactory when registering *this command. The factory
// calls this function to create an instance of *this command.
// Type: Static method.
// Args: None.
@ -1127,7 +1305,7 @@ CMICmdCmdVarInfoPathExpression::CMICmdCmdVarInfoPathExpression( void )
// Command factory matches this name with that received from the stdin stream
m_strMiCmd = "var-info-path-expression";
// Required by the CMICmdFactory when registering *this commmand
// Required by the CMICmdFactory when registering *this command
m_pSelfCreatorFn = &CMICmdCmdVarInfoPathExpression::CreateSelf;
}
@ -1197,8 +1375,38 @@ bool CMICmdCmdVarInfoPathExpression::Execute( void )
return MIstatus::failure;
}
m_strPathExpression = (stream.GetData() != nullptr) ? stream.GetData() : "??";
const MIchar * pPathExpression = stream.GetData();
if( pPathExpression == nullptr )
{
// Build expression from what we do know
m_strPathExpression = varObj.GetNameReal();
return MIstatus::success;
}
// Has LLDB returned a var signature of it's own
if( pPathExpression[ 0 ] != '$' )
{
m_strPathExpression = pPathExpression;
return MIstatus::success;
}
// Build expression from what we do know
const CMIUtilString & rVarParentName( varObj.GetVarParentName() );
if( rVarParentName.empty() )
{
m_strPathExpression = varObj.GetNameReal();
}
else
{
CMICmnLLDBDebugSessionInfoVarObj varObjParent;
if( !CMICmnLLDBDebugSessionInfoVarObj::VarObjGet( rVarParentName, varObjParent ) )
{
SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_VARIABLE_DOESNOTEXIST ), m_cmdData.strMiCmd.c_str(), rVarParentName.c_str() ) );
return MIstatus::failure;
}
m_strPathExpression = CMIUtilString::Format( "%s.%s", varObjParent.GetNameReal().c_str(), varObj.GetNameReal().c_str() );
}
return MIstatus::success;
}
@ -1217,21 +1425,21 @@ bool CMICmdCmdVarInfoPathExpression::Acknowledge( void )
{
const CMICmnMIValueConst miValueConst( m_strPathExpression );
const CMICmnMIValueResult miValueResult( "path_expr", miValueConst );
const CMICmnMIResultRecord miRecordResult( m_cmdData.nMiCmdNumber, CMICmnMIResultRecord::eResultClass_Done, miValueResult );
const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult );
m_miResultRecord = miRecordResult;
return MIstatus::success;
}
const CMICmnMIValueConst miValueConst( "variable invalid" );
const CMICmnMIValueResult miValueResult( "msg", miValueConst );
const CMICmnMIResultRecord miRecordResult( m_cmdData.nMiCmdNumber, CMICmnMIResultRecord::eResultClass_Error, miValueResult );
const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, miValueResult );
m_miResultRecord = miRecordResult;
return MIstatus::success;
}
//++ ------------------------------------------------------------------------------------
// Details: Required by the CMICmdFactory when registering *this commmand. The factory
// Details: Required by the CMICmdFactory when registering *this command. The factory
// calls this function to create an instance of *this command.
// Type: Static method.
// Args: None.
@ -1242,3 +1450,114 @@ CMICmdBase * CMICmdCmdVarInfoPathExpression::CreateSelf( void )
{
return new CMICmdCmdVarInfoPathExpression();
}
//---------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------
//++ ------------------------------------------------------------------------------------
// Details: CMICmdCmdVarShowAttributes constructor.
// Type: Method.
// Args: None.
// Return: None.
// Throws: None.
//--
CMICmdCmdVarShowAttributes::CMICmdCmdVarShowAttributes( void )
: m_constStrArgName( "name" )
{
// Command factory matches this name with that received from the stdin stream
m_strMiCmd = "var-show-attributes";
// Required by the CMICmdFactory when registering *this command
m_pSelfCreatorFn = &CMICmdCmdVarShowAttributes::CreateSelf;
}
//++ ------------------------------------------------------------------------------------
// Details: CMICmdCmdVarShowAttributes destructor.
// Type: Overrideable.
// Args: None.
// Return: None.
// Throws: None.
//--
CMICmdCmdVarShowAttributes::~CMICmdCmdVarShowAttributes( void )
{
}
//++ ------------------------------------------------------------------------------------
// Details: The invoker requires this function. The parses the command line options
// arguments to extract values for each of those arguments.
// Type: Overridden.
// Args: None.
// Return: MIstatus::success - Functional succeeded.
// MIstatus::failure - Functional failed.
// Throws: None.
//--
bool CMICmdCmdVarShowAttributes::ParseArgs( void )
{
bool bOk = m_setCmdArgs.Add( *(new CMICmdArgValString( m_constStrArgName, true, true ) ) );
CMICmdArgContext argCntxt( m_cmdData.strMiCmdOption );
if( bOk && !m_setCmdArgs.Validate( m_cmdData.strMiCmd, argCntxt ) )
{
SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_ARGS ), m_cmdData.strMiCmd.c_str(), m_setCmdArgs.GetErrorDescription().c_str() ) );
return MIstatus::failure;
}
return bOk;
}
//++ ------------------------------------------------------------------------------------
// 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 CMICmdCmdVarShowAttributes::Execute( void )
{
CMICMDBASE_GETOPTION( pArgName, String, m_constStrArgName );
const CMIUtilString & rVarObjName( pArgName->GetValue() );
CMICmnLLDBDebugSessionInfoVarObj varObj;
if( CMICmnLLDBDebugSessionInfoVarObj::VarObjGet( rVarObjName, varObj ) )
{
SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_VARIABLE_DOESNOTEXIST ), m_cmdData.strMiCmd.c_str(), rVarObjName.c_str() ) );
return MIstatus::failure;
}
return MIstatus::success;
}
//++ ------------------------------------------------------------------------------------
// Details: The invoker requires this function. The command prepares a MI Record Result
// for the work carried out in the Execute().
// Type: Overridden.
// Args: None.
// Return: MIstatus::success - Functional succeeded.
// MIstatus::failure - Functional failed.
// Throws: None.
//--
bool CMICmdCmdVarShowAttributes::Acknowledge( void )
{
// MI output: "%s^done,status=\"editable\"]"
const CMICmnMIValueConst miValueConst( "editable" );
const CMICmnMIValueResult miValueResult( "status", miValueConst );
const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult );
m_miResultRecord = miRecordResult;
return MIstatus::success;
}
//++ ------------------------------------------------------------------------------------
// Details: Required by the CMICmdFactory when registering *this command. The factory
// calls this function to create an instance of *this command.
// Type: Static method.
// Args: None.
// Return: CMICmdBase * - Pointer to a new command.
// Throws: None.
//--
CMICmdBase * CMICmdCmdVarShowAttributes::CreateSelf( void )
{
return new CMICmdCmdVarShowAttributes();
}

View File

@ -18,6 +18,7 @@
// CMICmdCmdVarListChildren interface.
// CMICmdCmdVarEvaluateExpression interface.
// CMICmdCmdVarInfoPathExpression interface.
// CMICmdCmdVarShowAttributes interface.
//
// To implement new MI commands derive a new command class from the command base
// class. To enable the new command for interpretation add the new command class
@ -41,6 +42,10 @@
#include "MICmdBase.h"
#include "MICmnMIValueTuple.h"
#include "MICmnMIValueList.h"
#include "MICmnLLDBDebugSessionInfoVarObj.h"
// Declarations:
class CMICmnLLDBDebugSessionInfoVarObj;
//++ ============================================================================
// Details: MI command class. MI commands derived from the command base class.
@ -53,7 +58,7 @@ class CMICmdCmdVarCreate : public CMICmdBase
{
// Statics:
public:
// Required by the CMICmdFactory when registering *this commmand
// Required by the CMICmdFactory when registering *this command
static CMICmdBase * CreateSelf( void );
// Methods:
@ -66,9 +71,6 @@ public:
virtual bool Execute( void );
virtual bool Acknowledge( void );
virtual bool ParseArgs( void );
// Overridden:
public:
// From CMICmnBase
/* dtor */ virtual ~CMICmdCmdVarCreate( void );
@ -82,6 +84,7 @@ private:
bool m_bValid; // True = Variable is valid, false = not valid
CMIUtilString m_strExpression;
const CMIUtilString m_constStrArgThread; // Not specified in MI spec but Eclipse gives this option
const CMIUtilString m_constStrArgThreadGroup; // Not specified in MI spec but Eclipse gives this option
const CMIUtilString m_constStrArgFrame; // Not specified in MI spec but Eclipse gives this option
const CMIUtilString m_constStrArgName;
const CMIUtilString m_constStrArgFrameAddr;
@ -99,7 +102,7 @@ class CMICmdCmdVarUpdate : public CMICmdBase
{
// Statics:
public:
// Required by the CMICmdFactory when registering *this commmand
// Required by the CMICmdFactory when registering *this command
static CMICmdBase * CreateSelf( void );
// Methods:
@ -118,11 +121,20 @@ public:
// From CMICmnBase
/* dtor */ virtual ~CMICmdCmdVarUpdate( void );
// Methods:
private:
bool ExamineSBValueForChange( const CMICmnLLDBDebugSessionInfoVarObj & vrVarObj, const bool vbIgnoreVarType, bool & vrwbChanged );
bool MIFormResponse( const CMIUtilString & vrStrVarName, const CMIUtilString & vrStrValue, const CMIUtilString & vrStrScope );
// Attribute:
private:
CMIUtilString m_strValueName;
const CMIUtilString m_constStrArgPrintValues; // Not handled by *this command
const CMIUtilString m_constStrArgPrintValues; // Not handled by *this command
const CMIUtilString m_constStrArgName;
bool m_bValueChangedArrayType; // True = yes value changed, false = no change
bool m_bValueChangedCompositeType; // True = yes value changed, false = no change
bool m_bValueChangedNormalType; // True = yes value changed, false = no change
CMICmnMIValueList m_miValueList;
};
//++ ============================================================================
@ -136,7 +148,7 @@ class CMICmdCmdVarDelete : public CMICmdBase
{
// Statics:
public:
// Required by the CMICmdFactory when registering *this commmand
// Required by the CMICmdFactory when registering *this command
static CMICmdBase * CreateSelf( void );
// Methods:
@ -149,9 +161,6 @@ public:
virtual bool Execute( void );
virtual bool Acknowledge( void );
virtual bool ParseArgs( void );
// Overridden:
public:
// From CMICmnBase
/* dtor */ virtual ~CMICmdCmdVarDelete( void );
@ -171,7 +180,7 @@ class CMICmdCmdVarAssign : public CMICmdBase
{
// Statics:
public:
// Required by the CMICmdFactory when registering *this commmand
// Required by the CMICmdFactory when registering *this command
static CMICmdBase * CreateSelf( void );
// Methods:
@ -184,9 +193,6 @@ public:
virtual bool Execute( void );
virtual bool Acknowledge( void );
virtual bool ParseArgs( void );
// Overridden:
public:
// From CMICmnBase
/* dtor */ virtual ~CMICmdCmdVarAssign( void );
@ -209,7 +215,7 @@ class CMICmdCmdVarSetFormat : public CMICmdBase
{
// Statics:
public:
// Required by the CMICmdFactory when registering *this commmand
// Required by the CMICmdFactory when registering *this command
static CMICmdBase * CreateSelf( void );
// Methods:
@ -222,9 +228,6 @@ public:
virtual bool Execute( void );
virtual bool Acknowledge( void );
virtual bool ParseArgs( void );
// Overridden:
public:
// From CMICmnBase
/* dtor */ virtual ~CMICmdCmdVarSetFormat( void );
@ -246,7 +249,7 @@ class CMICmdCmdVarListChildren : public CMICmdBase
{
// Statics:
public:
// Required by the CMICmdFactory when registering *this commmand
// Required by the CMICmdFactory when registering *this command
static CMICmdBase * CreateSelf( void );
// Methods:
@ -259,9 +262,6 @@ public:
virtual bool Execute( void );
virtual bool Acknowledge( void );
virtual bool ParseArgs( void );
// Overridden:
public:
// From CMICmnBase
/* dtor */ virtual ~CMICmdCmdVarListChildren( void );
@ -289,7 +289,7 @@ class CMICmdCmdVarEvaluateExpression : public CMICmdBase
{
// Statics:
public:
// Required by the CMICmdFactory when registering *this commmand
// Required by the CMICmdFactory when registering *this command
static CMICmdBase * CreateSelf( void );
// Methods:
@ -302,9 +302,6 @@ public:
virtual bool Execute( void );
virtual bool Acknowledge( void );
virtual bool ParseArgs( void );
// Overridden:
public:
// From CMICmnBase
/* dtor */ virtual ~CMICmdCmdVarEvaluateExpression( void );
@ -327,7 +324,7 @@ class CMICmdCmdVarInfoPathExpression : public CMICmdBase
{
// Statics:
public:
// Required by the CMICmdFactory when registering *this commmand
// Required by the CMICmdFactory when registering *this command
static CMICmdBase * CreateSelf( void );
// Methods:
@ -340,9 +337,6 @@ public:
virtual bool Execute( void );
virtual bool Acknowledge( void );
virtual bool ParseArgs( void );
// Overridden:
public:
// From CMICmnBase
/* dtor */ virtual ~CMICmdCmdVarInfoPathExpression( void );
@ -353,3 +347,35 @@ private:
const CMIUtilString m_constStrArgName;
};
//++ ============================================================================
// Details: MI command class. MI commands derived from the command base class.
// *this class implements MI command "var-show-attributes".
// Gotchas: None.
// Authors: Illya Rudkin 19/05/2014.
// Changes: None.
//--
class CMICmdCmdVarShowAttributes : public CMICmdBase
{
// Statics:
public:
// Required by the CMICmdFactory when registering *this command
static CMICmdBase * CreateSelf( void );
// Methods:
public:
/* ctor */ CMICmdCmdVarShowAttributes( void );
// Overridden:
public:
// From CMICmdInvoker::ICmd
virtual bool Execute( void );
virtual bool Acknowledge( void );
virtual bool ParseArgs( void );
// From CMICmnBase
/* dtor */ virtual ~CMICmdCmdVarShowAttributes( void );
// Attributes:
private:
const CMIUtilString m_constStrArgName;
};

View File

@ -35,6 +35,9 @@
#include "MICmdCmdEnviro.h"
#include "MICmdCmdExec.h"
#include "MICmdCmdFile.h"
#include "MICmdCmdGdbInfo.h"
#include "MICmdCmdGdbSet.h"
#include "MICmdCmdGdbThread.h"
#include "MICmdCmdMiscellanous.h"
#include "MICmdCmdStack.h"
#include "MICmdCmdSupportInfo.h"
@ -53,7 +56,7 @@ namespace MICmnCommands
//++ ------------------------------------------------------------------------------------
// Details: Command to command factory registration function.
// Type: Template function.
// Args: None.
// Args: typename T - A command type class.
// Return: bool - True = yes command is registered, false = command failed to register.
// Throws: None.
//--
@ -79,40 +82,53 @@ bool MICmnCommands::RegisterAll( void )
bool bOk = MIstatus::success;
bOk &= Register< CMICmdCmdSupportInfoMiCmdQuery >();
bOk &= Register< CMICmdCmdSupportListFeatures >();
bOk &= Register< CMICmdCmdEnvironmentCd >();
bOk &= Register< CMICmdCmdGdbSet >();
bOk &= Register< CMICmdCmdEnablePrettyPrinting >();
bOk &= Register< CMICmdCmdGdbExit >();
bOk &= Register< CMICmdCmdSource >();
bOk &= Register< CMICmdCmdFileExecAndSymbols >();
bOk &= Register< CMICmdCmdTargetSelect >();
bOk &= Register< CMICmdCmdListThreadGroups >();
bOk &= Register< CMICmdCmdExecRun >();
bOk &= Register< CMICmdCmdExecContinue >();
bOk &= Register< CMICmdCmdTraceStatus >();
bOk &= Register< CMICmdCmdThreadInfo >();
bOk &= Register< CMICmdCmdBreakInsert >();
bOk &= Register< CMICmdCmdBreakAfter >();
bOk &= Register< CMICmdCmdBreakCondition >();
bOk &= Register< CMICmdCmdBreakDelete >();
bOk &= Register< CMICmdCmdThread >();
bOk &= Register< CMICmdCmdBreakDisable >();
bOk &= Register< CMICmdCmdBreakEnable >();
bOk &= Register< CMICmdCmdBreakInsert >();
bOk &= Register< CMICmdCmdDataDisassemble >();
bOk &= Register< CMICmdCmdDataEvaluateExpression >();
bOk &= Register< CMICmdCmdDataReadMemoryBytes >();
bOk &= Register< CMICmdCmdDataReadMemory >();
bOk &= Register< CMICmdCmdDataListRegisterNames >();
bOk &= Register< CMICmdCmdDataListRegisterValues >();
bOk &= Register< CMICmdCmdDataWriteMemory >();
bOk &= Register< CMICmdCmdEnablePrettyPrinting >();
bOk &= Register< CMICmdCmdEnvironmentCd >();
bOk &= Register< CMICmdCmdExecContinue >();
bOk &= Register< CMICmdCmdExecInterrupt >();
bOk &= Register< CMICmdCmdExecFinish >();
bOk &= Register< CMICmdCmdExecNext >();
bOk &= Register< CMICmdCmdExecNextInstruction >();
bOk &= Register< CMICmdCmdExecRun >();
bOk &= Register< CMICmdCmdExecStep >();
bOk &= Register< CMICmdCmdExecStepInstruction >();
bOk &= Register< CMICmdCmdFileExecAndSymbols >();
bOk &= Register< CMICmdCmdGdbExit >();
bOk &= Register< CMICmdCmdGdbInfo >();
bOk &= Register< CMICmdCmdGdbSet >();
bOk &= Register< CMICmdCmdGdbThread >();
bOk &= Register< CMICmdCmdInterpreterExec >();
bOk &= Register< CMICmdCmdListThreadGroups >();
bOk &= Register< CMICmdCmdSource >();
bOk &= Register< CMICmdCmdStackInfoDepth >();
bOk &= Register< CMICmdCmdStackListFrames >();
bOk &= Register< CMICmdCmdStackListArguments >();
bOk &= Register< CMICmdCmdStackListLocals >();
bOk &= Register< CMICmdCmdVarCreate >();
bOk &= Register< CMICmdCmdExecNext >();
bOk &= Register< CMICmdCmdExecStep >();
bOk &= Register< CMICmdCmdExecNextInstruction >();
bOk &= Register< CMICmdCmdExecStepInstruction >();
bOk &= Register< CMICmdCmdExecFinish >();
bOk &= Register< CMICmdCmdVarUpdate >();
bOk &= Register< CMICmdCmdVarDelete >();
bOk &= Register< CMICmdCmdSupportListFeatures >();
bOk &= Register< CMICmdCmdTargetSelect >();
bOk &= Register< CMICmdCmdThreadInfo >();
bOk &= Register< CMICmdCmdVarAssign >();
bOk &= Register< CMICmdCmdVarSetFormat >();
bOk &= Register< CMICmdCmdVarListChildren >();
bOk &= Register< CMICmdCmdVarCreate >();
bOk &= Register< CMICmdCmdVarDelete >();
bOk &= Register< CMICmdCmdVarEvaluateExpression >();
bOk &= Register< CMICmdCmdVarInfoPathExpression >();
bOk &= Register< CMICmdCmdDataEvaluateExpression >();
bOk &= Register< CMICmdCmdVarListChildren >();
bOk &= Register< CMICmdCmdVarSetFormat >();
bOk &= Register< CMICmdCmdVarShowAttributes >();
bOk &= Register< CMICmdCmdVarUpdate >();
return bOk;
}
}

View File

@ -35,7 +35,6 @@ struct SMICmdData
{
SMICmdData( void )
: id( 0 )
, nMiCmdNumber( -1 )
, bCmdValid( false )
, bCmdExecutedSuccessfully( false )
, bMIOldStyle( false )
@ -44,7 +43,7 @@ struct SMICmdData
};
MIuint id; // A command's unique ID i.e. GUID
MIuint nMiCmdNumber; // The command's MI response number
CMIUtilString strMiCmdToken; // The command's MI token (a number)
CMIUtilString strMiCmd; // The command's name
CMIUtilString strMiCmdOption; // The command's arguments or options
CMIUtilString strMiCmdAll; // The text as received from the client
@ -59,8 +58,8 @@ struct SMICmdData
void Clear( void )
{
id = 0;
nMiCmdNumber = 0;
strMiCmd = MIRSRC( IDS_WORD_INVALIDBRKTS );
strMiCmdToken.clear();
strMiCmd = MIRSRC( IDS_CMD_ERR_CMD_RUN_BUT_NO_ACTION );
strMiCmdOption.clear();
strMiCmdAll.clear();
strMiCmdResultRecord.clear();

View File

@ -158,16 +158,19 @@ bool CMICmdFactory::HaveAlready( const CMIUtilString & vMiCmd ) const
//--
bool CMICmdFactory::IsValid( const CMIUtilString & vMiCmd ) const
{
bool bValid = true;
if( vMiCmd.empty() )
{
bValid = false;
return false;
}
const MIint nPos = vMiCmd.find( " " );
if( nPos != (MIint) std::string::npos )
return false;
return true;
bValid = false;
return bValid;
}
//++ ------------------------------------------------------------------------------------
@ -212,7 +215,7 @@ bool CMICmdFactory::CmdCreate( const CMIUtilString & vMiCmd, const SMICmdData &
}
const MapMiCmdToCmdCreatorFn_t::const_iterator it = m_mapMiCmdToCmdCreatorFn.find( vMiCmd );
const CMIUtilString & rMiCmd( (*it).first );
const CMIUtilString & rMiCmd( (*it).first ); MIunused( rMiCmd );
CmdCreatorFnPtr pFn = (*it).second;
CMICmdBase * pCmd = (*pFn)();

View File

@ -61,7 +61,7 @@ public:
public:
virtual const CMIUtilString & GetMiCmd( void ) const = 0;
virtual CmdCreatorFnPtr GetCmdCreatorFn( void ) const = 0;
//virtual CMICmdBase * CreateSelf( void ) = 0; // Not possible as require a static creator function in the commmand class, here for awareness
//virtual CMICmdBase * CreateSelf( void ) = 0; // Not possible as require a static creator function in the command class, here for awareness
/* dtor */ virtual ~ICmd( void ) {};
};

View File

@ -93,7 +93,7 @@ bool CMICmdInterpreter::Shutdown( void )
// Type: Method.
// Args: vTextLine - (R) Text data to interpret.
// vwbYesValid - (W) True = MI type command, false = not recognised.
// vwbCmdNotInCmdFactor - (W) True = MI command not found in the command factor, false = recognised.
// vwbCmdNotInCmdFactor - (W) True = MI command not found in the command factory, false = recognised.
// Return: MIstatus::success - Functional succeeded.
// MIstatus::failure - Functional failed.
// Throws: None.
@ -115,7 +115,7 @@ bool CMICmdInterpreter::ValidateIsMi( const CMIUtilString & vTextLine, bool & vw
m_miCmdData.strMiCmd = vTextLine;
// The following change m_miCmdData as valid parts are indentified
vwbYesValid = (MiHasCmdNumberEndingHypthen( vTextLine ) || MiHasCmdNumberEndingAlpha( vTextLine ));
vwbYesValid = (MiHasCmdTokenEndingHypthen( vTextLine ) || MiHasCmdTokenEndingAlpha( vTextLine ));
vwbYesValid = vwbYesValid && MiHasCmd( vTextLine );
if( vwbYesValid )
{
@ -123,9 +123,9 @@ bool CMICmdInterpreter::ValidateIsMi( const CMIUtilString & vTextLine, bool & vw
vwbYesValid = !vwbCmdNotInCmdFactor;
}
// Update command's meta data
// Update command's meta data valid state
m_miCmdData.bCmdValid = vwbYesValid;
// Ok to return new updated command information
rwCmdData = MiGetCmdData();
@ -149,25 +149,30 @@ bool CMICmdInterpreter::HasCmdFactoryGotMiCmd( const SMICmdData & vCmd ) const
// 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 number present? The command number is entered into the
// 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: vCmd - (R) Command information structure.
// Return: bool - True = yes command number present, false = command not recognised.
// Args: vTextLine - (R) Text data to interpret.
// Return: bool - True = yes command token present, false = command not recognised.
// Throws: None.
//--
bool CMICmdInterpreter::MiHasCmdNumberEndingHypthen( const CMIUtilString & vTextLine )
bool CMICmdInterpreter::MiHasCmdTokenEndingHypthen( const CMIUtilString & vTextLine )
{
// The hythen is mandatory
const MIint nPos = vTextLine.find( "-", 0 );
if( (nPos == (MIint) std::string::npos) || (nPos == 0) )
if( (nPos == (MIint) std::string::npos) )
return false;
const std::string strNum = vTextLine.substr( 0, nPos );
if( !CMIUtilString( strNum.c_str() ).IsNumber() )
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.nMiCmdNumber = std::stoi( strNum );
m_miCmdData.bMIOldStyle = false;
return true;
@ -176,18 +181,18 @@ bool CMICmdInterpreter::MiHasCmdNumberEndingHypthen( const CMIUtilString & vText
//++ ------------------------------------------------------------------------------------
// Details: Does the command entered match the criteria for a MI command format.
// The format to validate against is 'nnA' where there can be 1 to n digits.
// 'A' represents any non numeric number. I.e. '1source .gdbinit'.
// Is the execution number present? The command number is entered into the
// 'A' represents any non numeric token. I.e. '1source .gdbinit'.
// 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: vCmd - (R) Command information structure.
// Return: bool - True = yes command number present, false = command not recognised.
// Args: vTextLine - (R) Text data to interpret.
// Return: bool - True = yes command token present, false = command not recognised.
// Throws: None.
//--
bool CMICmdInterpreter::MiHasCmdNumberEndingAlpha( const CMIUtilString & vTextLine )
bool CMICmdInterpreter::MiHasCmdTokenEndingAlpha( const CMIUtilString & vTextLine )
{
char cChar = vTextLine[ 0 ];
MIchar cChar = vTextLine[ 0 ];
MIuint i = 0;
while( ::isdigit( cChar ) != 0 )
{
@ -199,12 +204,26 @@ bool CMICmdInterpreter::MiHasCmdNumberEndingAlpha( const CMIUtilString & vTextLi
return false;
const std::string strNum = vTextLine.substr( 0, i );
m_miCmdData.nMiCmdNumber = std::stoi( strNum );
m_miCmdData.strMiCmdToken = strNum.c_str();
m_miCmdData.bMIOldStyle = true;
return true;
}
//++ ------------------------------------------------------------------------------------
// Details: Does the command entered match the criteria for a MI command format.
// Is the command token present before the hypen?
// Type: Method.
// Args: vTextLine - (R) Text data to interpret.
// Return: bool - True = yes command token present, false = token not present.
// Throws: None.
//--
bool CMICmdInterpreter::MiHasCmdTokenPresent( const CMIUtilString & vTextLine )
{
const MIint nPos = vTextLine.find( "-", 0 );
return (nPos > 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
@ -232,8 +251,6 @@ bool CMICmdInterpreter::MiHasCmd( const CMIUtilString & vTextLine )
else
{
nPos = vTextLine.find( "-", 0 );
if( (nPos == (MIint) std::string::npos) || (nPos == 0) )
return false;
}
bool bFoundCmd = false;

View File

@ -60,11 +60,12 @@ private:
void operator=( const CMICmdInterpreter & );
bool HasCmdFactoryGotMiCmd( const SMICmdData & vCmdData ) const;
bool MiHasCmdNumberEndingHypthen( const CMIUtilString & vTextLine );
bool MiHasCmdNumberEndingAlpha( const CMIUtilString & vTextLine );
bool MiHasCmdTokenEndingHypthen( const CMIUtilString & vTextLine );
bool MiHasCmdTokenEndingAlpha( const CMIUtilString & vTextLine );
bool MiHasCmd( const CMIUtilString & vTextLine );
bool MiHasCmdTokenPresent( const CMIUtilString & vTextLine );
const SMICmdData & MiGetCmdData() const;
// Overridden:
private:
// From CMICmnBase

View File

@ -106,9 +106,9 @@ void CMICmdInvoker::CmdDeleteAll( void )
MapCmdIdToCmd_t::const_iterator it = m_mapCmdIdToCmd.begin();
while( it != m_mapCmdIdToCmd.end() )
{
const MIuint cmdId( (*it).first );
const MIuint cmdId( (*it).first ); MIunused( cmdId );
CMICmdBase * pCmd = (*it).second;
const CMIUtilString & rCmdName( pCmd->GetCmdData().strMiCmd );
const CMIUtilString & rCmdName( pCmd->GetCmdData().strMiCmd ); MIunused( rCmdName );
rMgr.CmdDelete( pCmd->GetCmdData() );
// Next
@ -258,8 +258,10 @@ bool CMICmdInvoker::CmdExecuteFinished( CMICmdBase & vCmd )
cmdData.strMiCmdResultRecordExtra = rMIExtra; // Precautionary copy as the command might forget to do this
}
// Delete the command object as do not require anymore
// Send command's MI response to the client
bool bOk = CmdStdout( cmdData );
// Delete the command object as do not require anymore
bOk = bOk && CmdDelete( vCmd.GetCmdData().id );
return bOk;
@ -280,7 +282,7 @@ bool CMICmdInvoker::CmdStdout( const SMICmdData & vCmdData ) const
bOk = bOk && bLock && m_rStreamOut.WriteMIResponse( vCmdData.strMiCmdResultRecord );
if( bOk && vCmdData.bHasResultRecordExtra )
{
bOk = bOk && m_rStreamOut.WriteMIResponse( vCmdData.strMiCmdResultRecordExtra );
bOk = m_rStreamOut.WriteMIResponse( vCmdData.strMiCmdResultRecordExtra );
}
bOk = bLock && m_rStreamOut.Unlock();

View File

@ -21,29 +21,28 @@
//--
#pragma once
// 1 = Yes compile MI version, 0 = compile original LLDB driver
// 1 = Yes compile MI Driver version, 0 = compile original LLDB driver code only.
// 0 was mainly just for testing purposes and so may be removed at a later time.
#define MICONFIG_COMPILE_MIDRIVER_VERSION 1
// 1 = Show modal dialog, 0 = do not show
// 1 = Show debug process attach modal dialog, 0 = do not show
// For windows only ATM, other OS use an infinite loop which a debug has to change a value to continue
#define MICONFIG_DEBUG_SHOW_ATTACH_DBG_DLG 0
// 1 = Compile in and init LLDB driver code alongside MI version, 0 = do not use
// 1 = Compile in and init LLDB driver code alongside MI version, 0 = do not compile in
// ToDo: This has not been fully implemented as may not be required in the future
#define MICONFIG_COMPILE_MIDRIVER_WITH_LLDBDRIVER 0
#define MICONFIG_COMPILE_MIDRIVER_WITH_LLDBDRIVER 1
// 1 = Give runtime our own custom buffer, 0 = Use runtime managed buffer
#define MICONFIG_CREATE_OWN_STDIN_BUFFER 0
// 1 = Use the MI driver regardless of --interpreter, 0 = require --interpreter argument
#define MICONFIG_DEFAULT_TO_MI_DRIVER 1
// This depends on MICONFIG_COMPILE_MIDRIVER_WITH_LLDBDRIVER
#define MICONFIG_DEFAULT_TO_MI_DRIVER 0
// 1 = Check for stdin before we issue blocking read, 0 = issue blocking call always
#define MICONFIG_POLL_FOR_STD_IN 1
// Temp workaround while needing different triples
// ToDo: Temp workaround while needing different triples - not used ATM, may not be required anymore
//#define MICONFIG_TRIPLE "arm"
// 1 = Write to MI's Log file warnings about commands that did not handle arguments or
// options present to them by the driver's client, 0 = no warnings given
#define MICONFIG_GIVE_WARNING_CMD_ARGS_NOT_HANDLED 1

View File

@ -26,6 +26,7 @@
#else
#include <unistd.h> // For the ::access()
#endif // _WIN32
#include <lldb/API/SBBreakpointLocation.h>
// In-house headers:
#include "MICmnLLDBDebugSessionInfo.h"
@ -45,13 +46,12 @@
// Throws: None.
//--
CMICmnLLDBDebugSessionInfo::CMICmnLLDBDebugSessionInfo( void )
// Todo: AD: Use of these singletons may need to be removed from the constructor
: m_rLldbDebugger( CMICmnLLDBDebugger::Instance().GetTheDebugger() )
, m_rLlldbListener( CMICmnLLDBDebugger::Instance().GetTheListener() )
, m_nBrkPointCnt( 0 )
, m_nBrkPointCntMax( INT32_MAX )
, m_currentSelectedThread( LLDB_INVALID_THREAD_ID )
, m_constStrSharedDataKeyWkDir( "Working Directory" )
, m_constStrSharedDataSolibPath( "Solib Path" )
{
}
@ -68,7 +68,7 @@ CMICmnLLDBDebugSessionInfo::~CMICmnLLDBDebugSessionInfo( void )
}
//++ ------------------------------------------------------------------------------------
// Details: Initialize resources for *this broardcaster object.
// Details: Initialize resources for *this object.
// Type: Method.
// Args: None.
// Return: MIstatus::success - Functionality succeeded.
@ -82,7 +82,6 @@ bool CMICmnLLDBDebugSessionInfo::Initialize( void )
if( m_bInitialized )
return MIstatus::success;
m_nBrkPointCnt = 0;
m_currentSelectedThread = LLDB_INVALID_THREAD_ID;
CMICmnLLDBDebugSessionInfoVarObj::VarObjIdResetToZero();
@ -92,7 +91,7 @@ bool CMICmnLLDBDebugSessionInfo::Initialize( void )
}
//++ ------------------------------------------------------------------------------------
// Details: Release resources for *this broardcaster object.
// Details: Release resources for *this object.
// Type: Method.
// Args: None.
// Return: MIstatus::success - Functionality succeeded.
@ -127,6 +126,7 @@ bool CMICmnLLDBDebugSessionInfo::Shutdown( void )
//++ ------------------------------------------------------------------------------------
// Details: Command instances can create and share data between other instances of commands.
// Data can also be assigned by a command and retrieved by LLDB event handler.
// This function takes down those resources build up over the use of the commands.
// This function should be called when the creation and running of command has
// stopped i.e. application shutdown.
@ -138,53 +138,72 @@ bool CMICmnLLDBDebugSessionInfo::Shutdown( void )
//--
bool CMICmnLLDBDebugSessionInfo::SharedDataDestroy( void )
{
m_mapKeyToStringValue.clear();
m_mapIdToSessionData.Clear();
m_vecVarObj.clear();
m_mapBrkPtIdToBrkPtInfo.clear();
return MIstatus::success;
}
//++ ------------------------------------------------------------------------------------
// Details: Command instances can create and share data between other instances of commands.
// This function adds new data to the shared data. Using the same ID more than
// once replaces any previous matching data keys.
// Details: Record information about a LLDB break point so that is can be recalled in other
// commands or LLDB event handling functions.
// Type: Method.
// Args: vKey - (R) A non empty unique data key to retrieve by.
// vData - (R) Data to be added to the share.
// Args: vBrkPtId - (R) LLDB break point ID.
// vrBrkPtInfo - (R) Break point information object.
// Return: MIstatus::success - Functional succeeded.
// MIstatus::failure - Functional failed.
// Throws: None.
//--
bool CMICmnLLDBDebugSessionInfo::SharedDataAdd( const CMIUtilString & vKey, const CMIUtilString & vData )
bool CMICmnLLDBDebugSessionInfo::RecordBrkPtInfo( const MIuint vnBrkPtId, const SBrkPtInfo & vrBrkPtInfo )
{
if( vKey.empty() )
return MIstatus::failure;
MapPairKeyToStringValue_t pr( vKey, vData );
m_mapKeyToStringValue.insert( pr );
MapPairBrkPtIdToBrkPtInfo_t pr( vnBrkPtId, vrBrkPtInfo );
m_mapBrkPtIdToBrkPtInfo.insert( pr );
return MIstatus::success;
}
//++ ------------------------------------------------------------------------------------
// Details: Command instances can create and share data between other instances of commands.
// This function retrieves data from the shared data container.
// Details: Retrieve information about a LLDB break point previous recorded either by
// commands or LLDB event handling functions.
// Type: Method.
// Args: vKey - (R) A non empty unique data key to retrieve by.
// vData - (W) Data.
// Return: bool - True = data found, false = key now found.
// Args: vBrkPtId - (R) LLDB break point ID.
// vrwBrkPtInfo - (W) Break point information object.
// Return: MIstatus::success - Functional succeeded.
// MIstatus::failure - Functional failed.
// Throws: None.
//--
bool CMICmnLLDBDebugSessionInfo::SharedDataRetrieve( const CMIUtilString & vKey, CMIUtilString & vwData )
bool CMICmnLLDBDebugSessionInfo::RecordBrkPtInfoGet( const MIuint vnBrkPtId, SBrkPtInfo & vrwBrkPtInfo ) const
{
const MapKeyToStringValue_t::const_iterator it = m_mapKeyToStringValue.find( vKey );
if( it != m_mapKeyToStringValue.end() )
const MapBrkPtIdToBrkPtInfo_t::const_iterator it = m_mapBrkPtIdToBrkPtInfo.find( vnBrkPtId );
if( it != m_mapBrkPtIdToBrkPtInfo.end() )
{
vwData = (*it).second;
return true;
vrwBrkPtInfo = (*it).second;
return MIstatus::success;
}
return false;
return MIstatus::failure;
}
//++ ------------------------------------------------------------------------------------
// Details: Delete information about a specific LLDB break point object. This function
// should be called when a LLDB break point is deleted.
// Type: Method.
// Args: vBrkPtId - (R) LLDB break point ID.
// Return: MIstatus::success - Functional succeeded.
// MIstatus::failure - Functional failed.
// Throws: None.
//--
bool CMICmnLLDBDebugSessionInfo::RecordBrkPtInfoDelete( const MIuint vnBrkPtId )
{
const MapBrkPtIdToBrkPtInfo_t::const_iterator it = m_mapBrkPtIdToBrkPtInfo.find( vnBrkPtId );
if( it != m_mapBrkPtIdToBrkPtInfo.end() )
{
m_mapBrkPtIdToBrkPtInfo.erase( it );
return MIstatus::success;
}
return MIstatus::failure;
}
//++ ------------------------------------------------------------------------------------
@ -263,10 +282,10 @@ bool CMICmnLLDBDebugSessionInfo::ResolvePath( const SMICmdData & vCmdData, const
// ToDo: Verify this code as it does not work as vPath is always empty
CMIUtilString strResolvedPath;
if( !SharedDataRetrieve( "Working Directory", strResolvedPath ) )
if( !SharedDataRetrieve< CMIUtilString >( m_constStrSharedDataKeyWkDir, strResolvedPath ) )
{
vwrResolvedPath = "";
SetErrorDescription( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_SHARED_DATA_NOT_FOUND ), vCmdData.strMiCmd.c_str(), "Working Directory" ) );
SetErrorDescription( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_SHARED_DATA_NOT_FOUND ), vCmdData.strMiCmd.c_str(), m_constStrSharedDataKeyWkDir.c_str() ) );
return MIstatus::failure;
}
@ -295,7 +314,7 @@ bool CMICmnLLDBDebugSessionInfo::ResolvePath( const CMIUtilString & vstrUnknown,
bool bOk = MIstatus::success;
CMIUtilString::VecString_t vecPathFolders;
const MIuint nSplits = vwrResolvedPath.Split( "/", vecPathFolders );
const MIuint nSplits = vwrResolvedPath.Split( "/", vecPathFolders ); MIunused( nSplits );
MIuint nFoldersBack = 1; // 1 is just the file (last element of vector)
while( bOk && (vecPathFolders.size() >= nFoldersBack) )
{
@ -376,7 +395,7 @@ bool CMICmnLLDBDebugSessionInfo::MIResponseFormThreadInfo( const SMICmdData & vC
return MIstatus::failure;
// Add "target-id"
const char * pThreadName = rThread.GetName();
const MIchar * 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 arbitary number
const MIchar * pThrdFmt = bHaveName ? "%s" : "Thread %d";
@ -433,9 +452,9 @@ bool CMICmnLLDBDebugSessionInfo::MIResponseFormVariableInfo( const lldb::SBFrame
for( MIuint i = 0; bOk && (i < nArgs); i++ )
{
lldb::SBValue val = listArg.GetValueAtIndex( i );
const char * pValue = val.GetValue();
const MIchar * pValue = val.GetValue();
pValue = (pValue != nullptr) ? pValue : pUnkwn;
const char * pName = val.GetName();
const MIchar * pName = val.GetName();
pName = (pName != nullptr) ? pName : pUnkwn;
const CMICmnMIValueConst miValueConst( pName );
const CMICmnMIValueResult miValueResult( "name", miValueConst );
@ -508,7 +527,7 @@ bool CMICmnLLDBDebugSessionInfo::GetFrameInfo( const lldb::SBFrame & vrFrame, ll
lldb::SBFrame & rFrame = const_cast< lldb::SBFrame & >( vrFrame );
static char pBuffer[ MAX_PATH ];
const MIuint nBytes = rFrame.GetLineEntry().GetFileSpec().GetPath( &pBuffer[ 0 ], sizeof( pBuffer ) );
const MIuint nBytes = rFrame.GetLineEntry().GetFileSpec().GetPath( &pBuffer[ 0 ], sizeof( pBuffer ) ); MIunused( nBytes );
CMIUtilString strResolvedPath( &pBuffer[ 0 ] );
const MIchar * pUnkwn = "??";
if( !ResolvePath( pUnkwn, strResolvedPath ) )
@ -579,37 +598,33 @@ bool CMICmnLLDBDebugSessionInfo::MIResponseFormFrameInfo( const lldb::addr_t vPc
// Details: Form MI partial response by appending more MI value type objects to the
// tuple type object past in.
// Type: Method.
// Args: vPc - (R) Address number.
// vFnName - (R) Function name.
// vFileName - (R) File name text.
// vPath - (R) Full file name and path text.
// vnLine - (R) File line number.
// Args: vrBrkPtInfo - (R) Break point information object.
// vwrMIValueTuple - (W) MI value tuple object.
// Return: MIstatus::success - Functional succeeded.
// MIstatus::failure - Functional failed.
// Throws: None.
//--
bool CMICmnLLDBDebugSessionInfo::MIResponseFormBrkPtFrameInfo( const lldb::addr_t vPc, const CMIUtilString & vFnName, const CMIUtilString & vFileName, const CMIUtilString & vPath, const MIuint vnLine, CMICmnMIValueTuple & vwrMiValueTuple )
bool CMICmnLLDBDebugSessionInfo::MIResponseFormBrkPtFrameInfo( const SBrkPtInfo & vrBrkPtInfo, CMICmnMIValueTuple & vwrMiValueTuple )
{
const CMIUtilString strAddr( CMIUtilString::Format( "0x%08llx", vPc ) );
const CMIUtilString strAddr( CMIUtilString::Format( "0x%08llx", vrBrkPtInfo.m_pc ) );
const CMICmnMIValueConst miValueConst2( strAddr );
const CMICmnMIValueResult miValueResult2( "addr", miValueConst2 );
if( !vwrMiValueTuple.Add( miValueResult2 ) )
return MIstatus::failure;
const CMICmnMIValueConst miValueConst3( vFnName );
const CMICmnMIValueConst miValueConst3( vrBrkPtInfo.m_fnName );
const CMICmnMIValueResult miValueResult3( "func", miValueConst3 );
if( !vwrMiValueTuple.Add( miValueResult3 ) )
return MIstatus::failure;
const CMICmnMIValueConst miValueConst5( vFileName );
const CMICmnMIValueConst miValueConst5( vrBrkPtInfo.m_fileName );
const CMICmnMIValueResult miValueResult5( "file", miValueConst5 );
if( !vwrMiValueTuple.Add( miValueResult5 ) )
return MIstatus::failure;
const CMIUtilString strN5 = CMIUtilString::Format( "%s/%s", vPath.c_str(), vFileName.c_str() );
const CMIUtilString strN5 = CMIUtilString::Format( "%s/%s", vrBrkPtInfo.m_path.c_str(), vrBrkPtInfo.m_fileName.c_str() );
const CMICmnMIValueConst miValueConst6( strN5 );
const CMICmnMIValueResult miValueResult6( "fullname", miValueConst6 );
if( !vwrMiValueTuple.Add( miValueResult6 ) )
return MIstatus::failure;
const CMIUtilString strLine( CMIUtilString::Format( "%d", vnLine ) );
const CMIUtilString strLine( CMIUtilString::Format( "%d", vrBrkPtInfo.m_nLine ) );
const CMICmnMIValueConst miValueConst7( strLine );
const CMICmnMIValueResult miValueResult7( "line", miValueConst7 );
if( !vwrMiValueTuple.Add( miValueResult7 ) )
@ -622,43 +637,30 @@ bool CMICmnLLDBDebugSessionInfo::MIResponseFormBrkPtFrameInfo( const lldb::addr_
// Details: Form MI partial response by appending more MI value type objects to the
// tuple type object past in.
// Type: Method.
// Args: vId - (R) Break point ID.
// vStrType - (R) Break point type.
// vbDisp - (R) True = "del", false = "keep".
// vbEnabled - (R) True = enabled, false = disabled break point.
// vPc - (R) Address number.
// vFnName - (R) Function name.
// vFileName - (R) File name text.
// vPath - (R) Full file name and path text.
// vnLine - (R) File line number.
// vbHaveArgOptionThreadGrp - (R) True = include MI field, false = do not include "thread-groups".
// vStrOptThrdGrp - (R) Thread group number.
// vnTimes - (R) The count of the breakpoint existence.
// vStrOrigLoc - (R) The name of the break point.
// Args: vrBrkPtInfo - (R) Break point information object.
// vwrMIValueTuple - (W) MI value tuple object.
// Return: MIstatus::success - Functional succeeded.
// MIstatus::failure - Functional failed.
// Throws: None.
//--
bool CMICmnLLDBDebugSessionInfo::MIResponseFormBrkPtInfo( const lldb::break_id_t vId, const CMIUtilString & vStrType, const bool vbDisp, const bool vbEnabled, const lldb::addr_t vPc, const CMIUtilString & vFnName, const CMIUtilString & vFileName, const CMIUtilString & vPath, const MIuint vnLine, const bool vbHaveArgOptionThreadGrp, const CMIUtilString & vStrOptThrdGrp, const MIuint & vnTimes, const CMIUtilString & vStrOrigLoc, CMICmnMIValueTuple & vwrMiValueTuple )
bool CMICmnLLDBDebugSessionInfo::MIResponseFormBrkPtInfo( const SBrkPtInfo & vrBrkPtInfo, CMICmnMIValueTuple & vwrMiValueTuple )
{
// MI print "=breakpoint-modified,bkpt={number=\"%d\",type=\"breakpoint\",disp=\"%s\",enabled=\"%c\",addr=\"0x%08x\", func=\"%s\",file=\"%s\",fullname=\"%s/%s\",line=\"%d\",times=\"%d\",original-location=\"%s\"}"
// "number="
const CMIUtilString strN = CMIUtilString::Format( "%d", vId );
const CMICmnMIValueConst miValueConst( strN );
const CMICmnMIValueConst miValueConst( CMIUtilString::Format( "%d", vrBrkPtInfo.m_id ) );
const CMICmnMIValueResult miValueResult( "number", miValueConst );
CMICmnMIValueTuple miValueTuple( miValueResult );
// "type="
const CMICmnMIValueConst miValueConst2( vStrType );
const CMICmnMIValueConst miValueConst2( vrBrkPtInfo.m_strType );
const CMICmnMIValueResult miValueResult2( "type", miValueConst2 );
bool bOk = miValueTuple.Add( miValueResult2 );
// "disp="
const CMICmnMIValueConst miValueConst3( vbDisp ? "del" : "keep" );
const CMICmnMIValueConst miValueConst3( vrBrkPtInfo.m_bDisp ? "del" : "keep" );
const CMICmnMIValueResult miValueResult3( "disp", miValueConst3 );
bOk = bOk && miValueTuple.Add( miValueResult3 );
// "enabled="
const CMICmnMIValueConst miValueConst4( vbEnabled ? "y" : "n" );
const CMICmnMIValueConst miValueConst4( vrBrkPtInfo.m_bEnabled ? "y" : "n" );
const CMICmnMIValueResult miValueResult4( "enabled", miValueConst4 );
bOk = bOk && miValueTuple.Add( miValueResult4 );
// "addr="
@ -666,21 +668,49 @@ bool CMICmnLLDBDebugSessionInfo::MIResponseFormBrkPtInfo( const lldb::break_id_t
// "file="
// "fullname="
// "line="
bOk = bOk && CMICmnLLDBDebugSessionInfo::Instance().MIResponseFormBrkPtFrameInfo( vPc, vFnName, vFileName, vPath, vnLine, miValueTuple );
if( vbHaveArgOptionThreadGrp )
bOk = bOk && MIResponseFormBrkPtFrameInfo( vrBrkPtInfo, miValueTuple );
// "pending="
if( vrBrkPtInfo.m_bPending )
{
const CMICmnMIValueConst miValueConst( vStrOptThrdGrp );
const CMICmnMIValueConst miValueConst( vrBrkPtInfo.m_strOrigLoc );
const CMICmnMIValueList miValueList( miValueConst );
const CMICmnMIValueResult miValueResult( "pending", miValueList );
bOk = bOk && miValueTuple.Add( miValueResult );
}
if( vrBrkPtInfo.m_bHaveArgOptionThreadGrp )
{
const CMICmnMIValueConst miValueConst( vrBrkPtInfo.m_strOptThrdGrp );
const CMICmnMIValueList miValueList( miValueConst );
const CMICmnMIValueResult miValueResult( "thread-groups", miValueList );
bOk = bOk && miValueTuple.Add( miValueResult );
}
// "times="
const CMIUtilString strN4 = CMIUtilString::Format( "%d", vnTimes );
const CMICmnMIValueConst miValueConstB( strN4 );
const CMICmnMIValueConst miValueConstB( CMIUtilString::Format( "%d", vrBrkPtInfo.m_nTimes ) );
const CMICmnMIValueResult miValueResultB( "times", miValueConstB );
bOk = bOk && miValueTuple.Add( miValueResultB );
// "thread="
if( vrBrkPtInfo.m_bBrkPtThreadId )
{
const CMICmnMIValueConst miValueConst( CMIUtilString::Format( "%d", vrBrkPtInfo.m_nBrkPtThreadId ) );
const CMICmnMIValueResult miValueResult( "thread", miValueConst );
bOk = bOk && miValueTuple.Add( miValueResult );
}
// "cond="
if( vrBrkPtInfo.m_bCondition )
{
const CMICmnMIValueConst miValueConst( vrBrkPtInfo.m_strCondition );
const CMICmnMIValueResult miValueResult( "cond", miValueConst );
bOk = bOk && miValueTuple.Add( miValueResult );
}
// "ignore="
if( vrBrkPtInfo.m_nIgnore != 0 )
{
const CMICmnMIValueConst miValueConst( CMIUtilString::Format( "%d", vrBrkPtInfo.m_nIgnore ) );
const CMICmnMIValueResult miValueResult( "ignore", miValueConst );
bOk = bOk && miValueTuple.Add( miValueResult );
}
// "original-location="
const CMICmnMIValueConst miValueConstC( vStrOrigLoc );
const CMICmnMIValueConst miValueConstC( vrBrkPtInfo.m_strOrigLoc );
const CMICmnMIValueResult miValueResultC( "original-location", miValueConstC );
bOk = bOk && miValueTuple.Add( miValueResultC );
@ -688,3 +718,57 @@ bool CMICmnLLDBDebugSessionInfo::MIResponseFormBrkPtInfo( const lldb::break_id_t
return MIstatus::success;
}
//++ ------------------------------------------------------------------------------------
// Details: Retrieve breakpoint information and write into the given breakpoint information
// object. Note not all possible information is retrieved and so the information
// object may need to be filled in with more information after calling this
// function. Mainly breakpoint location information of information that is
// unlikely to change.
// Type: Method.
// Args: vBrkPt - (R) LLDB break point object.
// vrBrkPtInfo - (W) Break point information object.
// Return: MIstatus::success - Functional succeeded.
// MIstatus::failure - Functional failed.
// Throws: None.
//--
bool CMICmnLLDBDebugSessionInfo::GetBrkPtInfo( const lldb::SBBreakpoint & vBrkPt, SBrkPtInfo & vrwBrkPtInfo ) const
{
lldb::SBBreakpoint & rBrkPt = const_cast< lldb::SBBreakpoint & >( vBrkPt );
lldb::SBBreakpointLocation brkPtLoc = rBrkPt.GetLocationAtIndex( 0 );
lldb::SBAddress brkPtAddr = brkPtLoc.GetAddress();
lldb::SBSymbolContext symbolCntxt = brkPtAddr.GetSymbolContext( lldb::eSymbolContextEverything );
const MIchar * pUnkwn = "??";
lldb::SBModule rModule = symbolCntxt.GetModule();
const MIchar * pModule = rModule.IsValid() ? rModule.GetFileSpec().GetFilename() : pUnkwn; MIunused( pModule );
const MIchar * pFile = pUnkwn;
const MIchar * pFn = pUnkwn;
const MIchar * pFilePath = pUnkwn;
size_t nLine = 0;
const size_t nAddr = brkPtAddr.GetLoadAddress( m_lldbTarget );
lldb::SBCompileUnit rCmplUnit = symbolCntxt.GetCompileUnit();
if( rCmplUnit.IsValid() )
{
lldb::SBFileSpec rFileSpec = rCmplUnit.GetFileSpec();
pFile = rFileSpec.GetFilename();
pFilePath = rFileSpec.GetDirectory();
lldb::SBFunction rFn = symbolCntxt.GetFunction();
if( rFn.IsValid() )
pFn = rFn.GetName();
lldb::SBLineEntry rLnEntry = symbolCntxt.GetLineEntry();
if( rLnEntry.GetLine() > 0 )
nLine = rLnEntry.GetLine();
}
vrwBrkPtInfo.m_id = vBrkPt.GetID();
vrwBrkPtInfo.m_strType = "breakpoint";
vrwBrkPtInfo.m_pc = nAddr;
vrwBrkPtInfo.m_fnName = pFn;
vrwBrkPtInfo.m_fileName = pFile;
vrwBrkPtInfo.m_path = pFilePath;
vrwBrkPtInfo.m_nLine = nLine;
vrwBrkPtInfo.m_nTimes = vBrkPt.GetHitCount();
return MIstatus::success;
}

View File

@ -34,6 +34,7 @@
#include "MIUtilSingletonBase.h"
#include "MICmnLLDBDebugSessionInfoVarObj.h"
#include "MICmnMIValueTuple.h"
#include "MIUtilMapIdToVariant.h"
// Declarations:
class CMICmnLLDBDebugger;
@ -58,6 +59,52 @@ class CMICmnLLDBDebugSessionInfo
{
friend class MI::ISingleton< CMICmnLLDBDebugSessionInfo >;
// Structs:
public:
//++ ============================================================================
// Details: Break point information object. Used to easily pass information about
// a break around and record break point information to be recalled by
// other commands or LLDB event handling functions.
//--
struct SBrkPtInfo
{
SBrkPtInfo( void )
: m_id( 0 )
, m_bDisp( false )
, m_bEnabled( false )
, m_pc( 0 )
, m_nLine( 0 )
, m_bHaveArgOptionThreadGrp( false )
, m_nTimes( 0 )
, m_bPending( false )
, m_nIgnore( 0 )
, m_bCondition( false )
, m_bBrkPtThreadId( false )
, m_nBrkPtThreadId( 0 )
{
}
MIuint m_id; // LLDB break point ID.
CMIUtilString m_strType; // Break point type.
bool m_bDisp ; // True = "del", false = "keep".
bool m_bEnabled; // True = enabled, false = disabled break point.
MIuint m_pc; // Address number.
CMIUtilString m_fnName; // Function name.
CMIUtilString m_fileName; // File name text.
CMIUtilString m_path; // Full file name and path text.
MIuint m_nLine; // File line number.
bool m_bHaveArgOptionThreadGrp; // True = include MI field, false = do not include "thread-groups".
CMIUtilString m_strOptThrdGrp; // Thread group number.
MIuint m_nTimes; // The count of the breakpoint existence.
CMIUtilString m_strOrigLoc; // The name of the break point.
bool m_bPending; // True = the breakpoint has not been established yet, false = location found
MIuint m_nIgnore; // The number of time the breakpoint is run over before it is stopped on a hit
bool m_bCondition; // True = break point is conditional, use condition expression, false = no condition
CMIUtilString m_strCondition; // Break point condition expression
bool m_bBrkPtThreadId; // True = break point is specified to work with a specific thread, false = no specified thread given
MIuint m_nBrkPtThreadId; // Restrict the breakpoint to the specified thread-id
};
// Typedefs:
public:
typedef std::vector< uint32_t > VecActiveThreadId_t;
@ -68,8 +115,10 @@ public:
bool Shutdown( void );
// Variant type data which can be assigned and retrieved across all command instances
bool SharedDataAdd( const CMIUtilString & vKey, const CMIUtilString & vData );
bool SharedDataRetrieve( const CMIUtilString & vKey, CMIUtilString & vwData );
template< typename T >
bool SharedDataAdd( const CMIUtilString & vKey, const T & vData );
template< typename T >
bool SharedDataRetrieve( const CMIUtilString & vKey, T & vwData );
bool SharedDataDestroy( void );
// Common command required functionality
@ -82,28 +131,34 @@ public:
bool MIResponseFormFrameInfo( const lldb::addr_t vPc, const CMIUtilString & vFnName, const CMIUtilString & vArgs, const CMIUtilString & vFileName, const CMIUtilString & vPath, const MIuint vnLine, CMICmnMIValueTuple & vwrMiValueTuple );
bool MIResponseFormThreadInfo( const SMICmdData & vCmdData, const lldb::SBThread & vrThread, CMICmnMIValueTuple & vwrMIValueTuple );
bool MIResponseFormVariableInfo( const lldb::SBFrame & vrFrame, const MIuint vMaskVarTypes, CMICmnMIValueList & vwrMiValueList );
bool MIResponseFormBrkPtFrameInfo( const lldb::addr_t vPc, const CMIUtilString & vFnName, const CMIUtilString & vFileName, const CMIUtilString & vPath, const MIuint vnLine, CMICmnMIValueTuple & vwrMiValueTuple );
bool MIResponseFormBrkPtInfo( const lldb::break_id_t vId, const CMIUtilString & vStrType, const bool vbDisp, const bool vbEnabled, const lldb::addr_t vPc, const CMIUtilString & vFnName, const CMIUtilString & vFileName, const CMIUtilString & vPath, const MIuint vnLine, const bool vbHaveArgOptionThreadGrp, const CMIUtilString & vStrOptThrdGrp, const MIuint & vnTimes, const CMIUtilString & vStrOrigLoc, CMICmnMIValueTuple & vwrMiValueTuple );
bool MIResponseFormBrkPtFrameInfo( const SBrkPtInfo & vrBrkPtInfo, CMICmnMIValueTuple & vwrMiValueTuple );
bool MIResponseFormBrkPtInfo( const SBrkPtInfo & vrBrkPtInfo, CMICmnMIValueTuple & vwrMiValueTuple );
bool GetBrkPtInfo( const lldb::SBBreakpoint & vBrkPt, SBrkPtInfo & vrwBrkPtInfo ) const;
bool RecordBrkPtInfo( const MIuint vnBrkPtId, const SBrkPtInfo & vrBrkPtInfo );
bool RecordBrkPtInfoGet( const MIuint vnBrkPtId, SBrkPtInfo & vrwBrkPtInfo ) const;
bool RecordBrkPtInfoDelete( const MIuint vnBrkPtId );
// Attributes:
// Attributes:
public:
// The following are available to all command instances
lldb::SBDebugger & m_rLldbDebugger;
lldb::SBListener & m_rLlldbListener;
lldb::SBTarget m_lldbTarget;
lldb::SBProcess m_lldbProcess;
MIuint m_nBrkPointCnt;
const MIuint m_nBrkPointCntMax;
VecActiveThreadId_t m_vecActiveThreadId;
lldb::tid_t m_currentSelectedThread;
//
// These are keys that can be used to access the shared data map
// Note: This list is expected to grow and will be moved and abstracted in the future.
const CMIUtilString m_constStrSharedDataKeyWkDir;
const CMIUtilString m_constStrSharedDataSolibPath;
// Typedefs:
private:
typedef std::map< CMIUtilString, CMIUtilString > MapKeyToStringValue_t; // Todo: change this to be a variant type
typedef std::pair< CMIUtilString, CMIUtilString > MapPairKeyToStringValue_t;
typedef std::vector< CMICmnLLDBDebugSessionInfoVarObj > VecVarObj_t;
typedef std::map< MIuint, SBrkPtInfo > MapBrkPtIdToBrkPtInfo_t;
typedef std::pair< MIuint, SBrkPtInfo > MapPairBrkPtIdToBrkPtInfo_t;
// Methods:
private:
@ -118,6 +173,55 @@ private:
// Attributes:
private:
MapKeyToStringValue_t m_mapKeyToStringValue; // Hold and retrieve key to value data available across all commands
CMIUtilMapIdToVariant m_mapIdToSessionData; // Hold and retrieve key to value data available across all commands
VecVarObj_t m_vecVarObj; // Vector of session variable objects
MapBrkPtIdToBrkPtInfo_t m_mapBrkPtIdToBrkPtInfo;
};
//++ ------------------------------------------------------------------------------------
// Details: Command instances can create and share data between other instances of commands.
// This function adds new data to the shared data. Using the same ID more than
// once replaces any previous matching data keys.
// Type: Template method.
// Args: T - The type of the object to be stored.
// vKey - (R) A non empty unique data key to retrieve the data by.
// vData - (R) Data to be added to the share.
// Return: MIstatus::success - Functional succeeded.
// MIstatus::failure - Functional failed.
// Throws: None.
//--
template< typename T >
bool CMICmnLLDBDebugSessionInfo::SharedDataAdd( const CMIUtilString & vKey, const T & vData )
{
if( !m_mapIdToSessionData.Add< T >( vKey, vData ) )
{
SetErrorDescription( m_mapIdToSessionData.GetErrorDescription() );
return MIstatus::failure;
}
return MIstatus::success;
}
//++ ------------------------------------------------------------------------------------
// Details: Command instances can create and share data between other instances of commands.
// This function retrieves data from the shared data container.
// Type: Method.
// Args: T - The type of the object being retrieved.
// vKey - (R) A non empty unique data key to retrieve the data by.
// vData - (W) The data.
// Return: bool - True = data found, false = data not found or an error occurred trying to fetch.
// Throws: None.
//--
template< typename T >
bool CMICmnLLDBDebugSessionInfo::SharedDataRetrieve( const CMIUtilString & vKey, T & vwData )
{
bool bDataFound = false;
if( !m_mapIdToSessionData.Get< T >( vKey, vwData, bDataFound ) )
{
SetErrorDescription( m_mapIdToSessionData.GetErrorDescription() );
return MIstatus::failure;
}
return bDataFound;
}

View File

@ -46,8 +46,8 @@ const MIchar * CMICmnLLDBDebugSessionInfoVarObj::ms_aVarFormatChars[] =
"x",
"N"
};
CMICmnLLDBDebugSessionInfoVarObj::VecVarObj_t CMICmnLLDBDebugSessionInfoVarObj::ms_vecVarObj;
MIuint CMICmnLLDBDebugSessionInfoVarObj::ms_nVarUniqueId = 0; // Index from 0
CMICmnLLDBDebugSessionInfoVarObj::MapKeyToVarObj_t CMICmnLLDBDebugSessionInfoVarObj::ms_mapVarIdToVarObj;
MIuint CMICmnLLDBDebugSessionInfoVarObj::ms_nVarUniqueId = 0; // Index from 0
//++ ------------------------------------------------------------------------------------
// Details: CMICmnLLDBDebugSessionInfoVarObj constructor.
@ -60,13 +60,15 @@ CMICmnLLDBDebugSessionInfoVarObj::CMICmnLLDBDebugSessionInfoVarObj( void )
: m_eVarFormat( eVarFormat_Natural )
, m_eVarType( eVarType_Internal )
{
// Do not out UpdateValue() in here as not necessary
// Do not call UpdateValue() in here as not necessary
}
//++ ------------------------------------------------------------------------------------
// Details: CMICmnLLDBDebugSessionInfoVarObj constructor.
// Type: Method.
// Args: None.
// Args: vrStrNameReal - (R) The actual name of the variable, the expression.
// vrStrName - (R) The name given for *this var object.
// vrValue - (R) The LLDB SBValue object represented by *this object.
// Return: None.
// Throws: None.
//--
@ -80,6 +82,90 @@ CMICmnLLDBDebugSessionInfoVarObj::CMICmnLLDBDebugSessionInfoVarObj( const CMIUti
UpdateValue();
}
//++ ------------------------------------------------------------------------------------
// Details: CMICmnLLDBDebugSessionInfoVarObj constructor.
// Type: Method.
// Args: vrStrNameReal - (R) The actual name of the variable, the expression.
// vrStrName - (R) The name given for *this var object.
// vrValue - (R) The LLDB SBValue object represented by *this object.
// vrStrVarObjParentName - (R) The var object parent to *this var object (LLDB SBValue equivalent).
// Return: None.
// Throws: None.
//--
CMICmnLLDBDebugSessionInfoVarObj::CMICmnLLDBDebugSessionInfoVarObj( const CMIUtilString & vrStrNameReal, const CMIUtilString & vrStrName, const lldb::SBValue & vrValue, const CMIUtilString & vrStrVarObjParentName )
: m_eVarFormat( eVarFormat_Natural )
, m_eVarType( eVarType_Internal )
, m_strName( vrStrName )
, m_SBValue( vrValue )
, m_strNameReal( vrStrNameReal )
, m_strVarObjParentName( vrStrVarObjParentName )
{
UpdateValue();
}
//++ ------------------------------------------------------------------------------------
// Details: CMICmnLLDBDebugSessionInfoVarObj copy constructor.
// Type: Method.
// Args: vrOther - (R) The object to copy from.
// Return: None.
// Throws: None.
//--
CMICmnLLDBDebugSessionInfoVarObj::CMICmnLLDBDebugSessionInfoVarObj( const CMICmnLLDBDebugSessionInfoVarObj & vrOther )
{
CopyOther( vrOther );
}
//++ ------------------------------------------------------------------------------------
// Details: CMICmnLLDBDebugSessionInfoVarObj copy constructor.
// Type: Method.
// Args: vrOther - (R) The object to copy from.
// Return: None.
// Throws: None.
//--
CMICmnLLDBDebugSessionInfoVarObj::CMICmnLLDBDebugSessionInfoVarObj( CMICmnLLDBDebugSessionInfoVarObj & vrOther )
{
CopyOther( vrOther );
}
//++ ------------------------------------------------------------------------------------
// Details: CMICmnLLDBDebugSessionInfoVarObj assignment opertator.
// Type: Method.
// Args: vrOther - (R) The object to copy from.
// Return: CMICmnLLDBDebugSessionInfoVarObj & - Updated *this object.
// Throws: None.
//--
CMICmnLLDBDebugSessionInfoVarObj & CMICmnLLDBDebugSessionInfoVarObj::operator= ( const CMICmnLLDBDebugSessionInfoVarObj & vrOther )
{
CopyOther( vrOther );
return *this;
}
//++ ------------------------------------------------------------------------------------
// Details: Copy the other instance of *this object to *this object.
// Type: Method.
// Args: vrOther - (R) The object to copy from.
// Return: MIstatus::success - Functional succeeded.
// MIstatus::failure - Functional failed.
// Throws: None.
//--
bool CMICmnLLDBDebugSessionInfoVarObj::CopyOther( const CMICmnLLDBDebugSessionInfoVarObj & vrOther )
{
// Check for self-assignment
if( this == &vrOther )
return MIstatus::success;
m_eVarFormat = vrOther.m_eVarFormat;
m_eVarType = vrOther.m_eVarType;
m_strName = vrOther.m_strName;
m_SBValue = vrOther.m_SBValue;
m_strNameReal = vrOther.m_strNameReal;
m_strFormattedValue = vrOther.m_strFormattedValue;
m_strVarObjParentName = vrOther.m_strVarObjParentName;
return MIstatus::success;
}
//++ ------------------------------------------------------------------------------------
// Details: CMICmnLLDBDebugSessionInfoVarObj destructor.
// Type: Overridable.
@ -138,6 +224,10 @@ CMICmnLLDBDebugSessionInfoVarObj::varFormat_e CMICmnLLDBDebugSessionInfoVarObj::
//++ ------------------------------------------------------------------------------------
// Details: Return the equivalent var value formatted string for the given value type.
// The SBValue vrValue parameter is checked by LLDB private code for valid
// scalar type via MI Driver proxy function as the valued returned can also be
// an error condition. The proxy function determines if the check was valid
// otherwise return an error condition state by other means saying so.
// Type: Static method.
// Args: vrValue - (R) The var value object.
// veVarFormat - (R) Var format enumeration.
@ -151,27 +241,8 @@ CMIUtilString CMICmnLLDBDebugSessionInfoVarObj::GetValueStringFormatted( const l
MIuint64 nValue = 0;
if( CMICmnLLDBProxySBValue::GetValueAsUnsigned( vrValue, nValue ) == MIstatus::success )
{
switch( veVarFormat )
{
case eVarFormat_Binary:
strFormattedValue = CMIUtilString::FormatBinary( nValue );
break;
case eVarFormat_Octal:
strFormattedValue = CMIUtilString::Format( "0%llo", nValue );
break;
case eVarFormat_Decimal:
strFormattedValue = CMIUtilString::Format( "%lld", nValue );
break;
case eVarFormat_Hex:
strFormattedValue = CMIUtilString::Format( "0x%llx", nValue );
break;
case eVarFormat_Natural:
default:
{
const char * pTmp = const_cast< lldb::SBValue & >( vrValue ).GetValue();
strFormattedValue = (pTmp != nullptr) ? pTmp : "";
}
}
lldb::SBValue & rValue = const_cast< lldb::SBValue & >( vrValue );
strFormattedValue = GetStringFormatted( nValue, rValue.GetValue(), veVarFormat );
}
else
{
@ -182,6 +253,43 @@ CMIUtilString CMICmnLLDBDebugSessionInfoVarObj::GetValueStringFormatted( const l
return strFormattedValue;
}
//++ ------------------------------------------------------------------------------------
// Details: Return nuber formatted string according to the given value type.
// Type: Static method.
// Args: vnValue - (R) The number value to get formatted.
// vpStrValueNatural - (R) The natural representation of the number value.
// veVarFormat - (R) Var format enumeration.
// Returns: CMIUtilString - Numerical formatted string.
// Throws: None.
//--
CMIUtilString CMICmnLLDBDebugSessionInfoVarObj::GetStringFormatted( const MIuint64 vnValue, const MIchar * vpStrValueNatural, const CMICmnLLDBDebugSessionInfoVarObj::varFormat_e veVarFormat )
{
CMIUtilString strFormattedValue;
switch( veVarFormat )
{
case eVarFormat_Binary:
strFormattedValue = CMIUtilString::FormatBinary( vnValue );
break;
case eVarFormat_Octal:
strFormattedValue = CMIUtilString::Format( "0%llo", vnValue );
break;
case eVarFormat_Decimal:
strFormattedValue = CMIUtilString::Format( "%lld", vnValue );
break;
case eVarFormat_Hex:
strFormattedValue = CMIUtilString::Format( "0x%llx", vnValue );
break;
case eVarFormat_Natural:
default:
{
strFormattedValue = (vpStrValueNatural != nullptr) ? vpStrValueNatural : "";
}
}
return strFormattedValue;
}
//++ ------------------------------------------------------------------------------------
// Details: Delete internal container contents.
// Type: Static method.
@ -191,7 +299,7 @@ CMIUtilString CMICmnLLDBDebugSessionInfoVarObj::GetValueStringFormatted( const l
//--
void CMICmnLLDBDebugSessionInfoVarObj::VarObjClear( void )
{
ms_vecVarObj.clear();
ms_mapVarIdToVarObj.clear();
}
//++ ------------------------------------------------------------------------------------
@ -203,8 +311,9 @@ void CMICmnLLDBDebugSessionInfoVarObj::VarObjClear( void )
//--
void CMICmnLLDBDebugSessionInfoVarObj::VarObjAdd( const CMICmnLLDBDebugSessionInfoVarObj & vrVarObj )
{
VarObjDelete( vrVarObj.GetName() ); // Be sure do not have duplicates (trouble with set so vector)
ms_vecVarObj.push_back( vrVarObj );
VarObjDelete( vrVarObj.GetName() );
MapPairKeyToVarObj_t pr( vrVarObj.GetName(), vrVarObj );
ms_mapVarIdToVarObj.insert( pr );
}
//++ ------------------------------------------------------------------------------------
@ -216,22 +325,10 @@ void CMICmnLLDBDebugSessionInfoVarObj::VarObjAdd( const CMICmnLLDBDebugSessionIn
//--
void CMICmnLLDBDebugSessionInfoVarObj::VarObjDelete( const CMIUtilString & vrVarName )
{
if( vrVarName.empty() || (vrVarName == "") )
return;
VecVarObj_t::iterator it = ms_vecVarObj.begin();
while( it != ms_vecVarObj.end() )
const MapKeyToVarObj_t::const_iterator it = ms_mapVarIdToVarObj.find( vrVarName );
if( it != ms_mapVarIdToVarObj.end() )
{
const CMICmnLLDBDebugSessionInfoVarObj & rVarObj = *it;
const CMIUtilString & rVarName = rVarObj.GetName();
if( rVarName == vrVarName )
{
ms_vecVarObj.erase( it );
return;
}
// Next
++it;
ms_mapVarIdToVarObj.erase( it );
}
}
@ -257,19 +354,12 @@ void CMICmnLLDBDebugSessionInfoVarObj::VarObjUpdate( const CMICmnLLDBDebugSessio
//--
bool CMICmnLLDBDebugSessionInfoVarObj::VarObjGet( const CMIUtilString & vrVarName, CMICmnLLDBDebugSessionInfoVarObj & vrwVarObj )
{
VecVarObj_t::iterator it = ms_vecVarObj.begin();
while( it != ms_vecVarObj.end() )
const MapKeyToVarObj_t::const_iterator it = ms_mapVarIdToVarObj.find( vrVarName );
if( it != ms_mapVarIdToVarObj.end() )
{
const CMICmnLLDBDebugSessionInfoVarObj & rVarObj = *it;
const CMIUtilString & rVarName = rVarObj.GetName();
if( rVarName == vrVarName )
{
vrwVarObj = rVarObj;
return true;
}
// Next
++it;
const CMICmnLLDBDebugSessionInfoVarObj & rVarObj = (*it).second;
vrwVarObj = rVarObj;
return true;
}
return false;
@ -410,4 +500,18 @@ CMICmnLLDBDebugSessionInfoVarObj::varType_e CMICmnLLDBDebugSessionInfoVarObj::Ge
{
return m_eVarType;
}
//++ ------------------------------------------------------------------------------------
// Details: Retrieve the parent var object's name, the parent var object to *this var
// object (if assigned). The parent is equivalent to LLDB SBValue variable's
// parent.
// Type: Method.
// Args: None.
// Returns: CMIUtilString & - Pointer to var object, NULL = no parent.
// Throws: None.
//--
const CMIUtilString & CMICmnLLDBDebugSessionInfoVarObj::GetVarParentName( void ) const
{
return m_strVarObjParentName;
}

View File

@ -22,7 +22,6 @@
#pragma once
// Third Party Headers:
#include <vector>
#include <map>
#include <lldb/API/SBValue.h>
@ -30,17 +29,14 @@
#include "MIUtilString.h"
//++ ============================================================================
// Details: MI debug session variable object.
// Details: MI debug session variable object. The static functionality in *this
// class manages a map container of *these variable objects.
// Gotchas: None.
// Authors: Illya Rudkin 24/03/2014.
// Changes: None.
//--
class CMICmnLLDBDebugSessionInfoVarObj
{
// Typedefs:
public:
typedef std::vector< CMICmnLLDBDebugSessionInfoVarObj > VecVarObj_t;
// Enums:
public:
//++ ----------------------------------------------------------------------
@ -88,6 +84,11 @@ public:
public:
/* ctor */ CMICmnLLDBDebugSessionInfoVarObj( void );
/* ctor */ CMICmnLLDBDebugSessionInfoVarObj( const CMIUtilString & vrStrNameReal, const CMIUtilString & vrStrName, const lldb::SBValue & vrValue );
/* ctor */ CMICmnLLDBDebugSessionInfoVarObj( const CMIUtilString & vrStrNameReal, const CMIUtilString & vrStrName, const lldb::SBValue & vrValue, const CMIUtilString & vrStrVarObjParentName );
/* ctor */ CMICmnLLDBDebugSessionInfoVarObj( const CMICmnLLDBDebugSessionInfoVarObj & vrOther );
/* ctor */ CMICmnLLDBDebugSessionInfoVarObj( CMICmnLLDBDebugSessionInfoVarObj & vrOther );
//
CMICmnLLDBDebugSessionInfoVarObj & operator= ( const CMICmnLLDBDebugSessionInfoVarObj & vrOther );
//
const CMIUtilString & GetName( void ) const;
const CMIUtilString & GetNameReal( void ) const;
@ -95,6 +96,7 @@ public:
const lldb::SBValue & GetValue( void ) const;
varType_e GetType( void ) const;
bool SetVarFormat( const varFormat_e veVarFormat );
const CMIUtilString & GetVarParentName( void ) const;
void UpdateValue( void );
// Overridden:
@ -104,25 +106,31 @@ public:
// Typedefs:
private:
typedef std::map< CMIUtilString, CMICmnLLDBDebugSessionInfoVarObj * > MapVarRealNameToVarObject_t; // ToDo: Do I need this?
typedef std::pair< CMIUtilString, CMICmnLLDBDebugSessionInfoVarObj * > MapPairVarRealNameToVarObject_t; // ToDo: Do I need this?
typedef std::map< CMIUtilString, CMICmnLLDBDebugSessionInfoVarObj > MapKeyToVarObj_t;
typedef std::pair< CMIUtilString, CMICmnLLDBDebugSessionInfoVarObj > MapPairKeyToVarObj_t;
// Statics:
private:
static bool MapVarObjAdd( const CMIUtilString & vrVarRealName, const CMICmnLLDBDebugSessionInfoVarObj & vrVarObj );
static bool MapVarObjDelete( const CMIUtilString & vrVarName );
static CMIUtilString GetStringFormatted( const MIuint64 vnValue, const MIchar * vpStrValueNatural, varFormat_e veVarFormat );
// Methods:
private:
bool CopyOther( const CMICmnLLDBDebugSessionInfoVarObj & vrOther );
// Attributes:
private:
static const MIchar * ms_aVarFormatStrings[];
static const MIchar * ms_aVarFormatChars[];
static VecVarObj_t ms_vecVarObj; // ToDo: Replace this vector container for something more efficient (set will not compile)
static MapKeyToVarObj_t ms_mapVarIdToVarObj;
static MIuint ms_nVarUniqueId;
//
// *** Upate the copy constructors and assignment operator ***
varFormat_e m_eVarFormat;
varType_e m_eVarType;
CMIUtilString m_strName;
lldb::SBValue m_SBValue;
CMIUtilString m_strNameReal;
CMIUtilString m_strFormattedValue;
CMIUtilString m_strVarObjParentName;
// *** Upate the copy constructors and assignment operator ***
};

View File

@ -148,10 +148,10 @@ bool CMICmnLLDBDebugger::Shutdown( void )
// LLDB debugger may hang in its Destroy() fn waiting on events
m_lldbDebugger.DeleteTarget( CMICmnLLDBDebugSessionInfo::Instance().m_lldbTarget );
// ToDo: Avaluate if we still need this
// 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 );
//const std::chrono::milliseconds time( 1000 );
//std::this_thread::sleep_for( time );
lldb::SBDebugger::Destroy( m_lldbDebugger );
lldb::SBDebugger::Terminate();
@ -325,7 +325,7 @@ bool CMICmnLLDBDebugger::RegisterForEvent( const CMIUtilString & vClientName, co
if( !ClientSaveMask( vClientName, vBroadcasterClass, vEventMask ) )
return MIstatus::failure;
const char * pBroadCasterName = vBroadcasterClass.c_str();
const MIchar * pBroadCasterName = vBroadcasterClass.c_str();
MIuint eventMask = vEventMask;
eventMask += existingMask;
const MIuint result = m_lldbListener.StartListeningForEventClass( m_lldbDebugger, pBroadCasterName, eventMask );
@ -351,7 +351,7 @@ bool CMICmnLLDBDebugger::RegisterForEvent( const CMIUtilString & vClientName, co
//--
bool CMICmnLLDBDebugger::RegisterForEvent( const CMIUtilString & vClientName, const lldb::SBBroadcaster & vBroadcaster, const MIuint vEventMask )
{
const char * pBroadcasterName = vBroadcaster.GetName();
const MIchar * pBroadcasterName = vBroadcaster.GetName();
if( pBroadcasterName == nullptr )
{
SetErrorDescription( CMIUtilString::Format( MIRSRC( IDS_LLDBDEBUGGER_ERR_BROARDCASTER_NAME ), MIRSRC( IDS_WORD_INVALIDNULLPTR ) ) );
@ -415,7 +415,7 @@ bool CMICmnLLDBDebugger::UnregisterForEvent( const CMIUtilString & vClientName,
}
}
const char * pBroadCasterName = vBroadcasterClass.c_str();
const MIchar * pBroadCasterName = vBroadcasterClass.c_str();
if( !m_lldbListener.StopListeningForEventClass( m_lldbDebugger, pBroadCasterName, newEventMask ) )
{
SetErrorDescription( CMIUtilString::Format( MIRSRC( IDS_LLDBDEBUGGER_ERR_STOPLISTENER ), vClientName.c_str(), pBroadCasterName ) );
@ -425,72 +425,18 @@ bool CMICmnLLDBDebugger::UnregisterForEvent( const CMIUtilString & vClientName,
return BroadcasterSaveMask( vBroadcasterClass, otherClientsEventMask );
}
//++ ------------------------------------------------------------------------------------
// Details: Unregister with the debugger, the SBListener, the type of events you are no
// longer interested in. Others, like commands, may still remain interested so
// an event may not necessarily be stopped.
// Type: Method.
// Args: vClientName - (R) ID of the client who no longer requires these events.
// vBroadcaster - (R) An SBBroadcaster's derived class.
// Return: MIstatus::success - Functionality succeeded.
// MIstatus::failure - Functionality failed.
// Throws: None.
//--
bool CMICmnLLDBDebugger::UnregisterForEvent( const CMIUtilString & vClientName, const lldb::SBBroadcaster & vBroadcaster )
{
const char * pBroadcasterName = vBroadcaster.GetName();
if( pBroadcasterName == nullptr )
{
SetErrorDescription( CMIUtilString::Format( MIRSRC( IDS_LLDBDEBUGGER_ERR_BROARDCASTER_NAME ), MIRSRC( IDS_WORD_INVALIDNULLPTR ) ) );
return MIstatus::failure;
}
CMIUtilString broadcasterName( pBroadcasterName );
if( broadcasterName.length() == 0 )
{
SetErrorDescription( CMIUtilString::Format( MIRSRC( IDS_LLDBDEBUGGER_ERR_BROARDCASTER_NAME ), MIRSRC( IDS_WORD_INVALIDEMPTY ) ) );
return MIstatus::failure;
}
MIuint clientsEventMask = 0;
if( !ClientGetTheirMask( vClientName, broadcasterName, clientsEventMask ) )
return MIstatus::failure;
if( !ClientRemoveTheirMask( vClientName, broadcasterName ) )
return MIstatus::failure;
const MIuint otherClientsEventMask = ClientGetMaskForAllClients( broadcasterName );
MIuint newEventMask = 0;
for( MIuint i = 0; i < 32; i++ )
{
const MIuint bit = 1 << i;
const MIuint clientBit = bit & clientsEventMask;
const MIuint othersBit = bit & otherClientsEventMask;
if( (clientBit != 0) && (othersBit == 0) )
{
newEventMask += clientBit;
}
}
if( !m_lldbListener.StopListeningForEvents( vBroadcaster, newEventMask ) )
{
SetErrorDescription( CMIUtilString::Format( MIRSRC( IDS_LLDBDEBUGGER_ERR_STOPLISTENER ), vClientName.c_str(), pBroadcasterName ) );
return MIstatus::failure;
}
return BroadcasterSaveMask( broadcasterName, otherClientsEventMask );
}
//++ ------------------------------------------------------------------------------------
// Details: Given the SBBroadcaster class name retrieve it's current event mask.
// Type: Method.
// Args: vBroadcasterClass - (R) The SBBroadcaster's class name.
// vEventMask - (R) The mask of events to listen for.
// vEventMask - (W) The mask of events to listen for.
// Return: MIstatus::success - Functionality succeeded.
// MIstatus::failure - Functionality failed.
// Throws: None.
//--
bool CMICmnLLDBDebugger::BroadcasterGetMask( const CMIUtilString & vBroadcasterClass, MIuint & vEventMask ) const
bool CMICmnLLDBDebugger::BroadcasterGetMask( const CMIUtilString & vBroadcasterClass, MIuint & vwEventMask ) const
{
vEventMask = 0;
vwEventMask = 0;
if( vBroadcasterClass.empty() )
{
@ -499,13 +445,29 @@ bool CMICmnLLDBDebugger::BroadcasterGetMask( const CMIUtilString & vBroadcasterC
}
const MapBroadcastClassNameToEventMask_t::const_iterator it = m_mapBroadcastClassNameToEventMask.find( vBroadcasterClass );
if( it == m_mapBroadcastClassNameToEventMask.end() )
if( it != m_mapBroadcastClassNameToEventMask.end() )
{
vEventMask = 0;
return MIstatus::success;
vwEventMask = (*it).second;
}
vEventMask = (*it).second;
return MIstatus::success;
}
//++ ------------------------------------------------------------------------------------
// Details: Remove the event mask for the specified SBBroadcaster class name.
// Type: Method.
// Args: vBroadcasterClass - (R) The SBBroadcaster's class name.
// Return: MIstatus::success - Functionality succeeded.
// MIstatus::failure - Functionality failed.
// Throws: None.
//--
bool CMICmnLLDBDebugger::BroadcasterRemoveMask( const CMIUtilString & vBroadcasterClass )
{
MapBroadcastClassNameToEventMask_t::const_iterator it = m_mapBroadcastClassNameToEventMask.find( vBroadcasterClass );
if( it != m_mapBroadcastClassNameToEventMask.end() )
{
m_mapBroadcastClassNameToEventMask.erase( it );
}
return MIstatus::success;
}
@ -527,6 +489,7 @@ bool CMICmnLLDBDebugger::BroadcasterSaveMask( const CMIUtilString & vBroadcaster
return MIstatus::failure;
}
BroadcasterRemoveMask( vBroadcasterClass );
MapPairBroadcastClassNameToEventMask_t pr( vBroadcasterClass, vEventMask );
m_mapBroadcastClassNameToEventMask.insert( pr );
@ -579,9 +542,10 @@ bool CMICmnLLDBDebugger::ClientSaveMask( const CMIUtilString & vClientName, cons
return MIstatus::failure;
}
CMIUtilString strId( vBroadcasterClass.c_str() );
CMIUtilString strId( vBroadcasterClass );
strId += vClientName;
ClientRemoveTheirMask( vClientName, vBroadcasterClass );
MapPairIdToEventMask_t pr( strId, vEventMask );
m_mapIdToEventMask.insert( pr );
@ -605,26 +569,14 @@ bool CMICmnLLDBDebugger::ClientRemoveTheirMask( const CMIUtilString & vClientNam
return MIstatus::failure;
}
CMIUtilString strId( vBroadcasterClass.c_str() );
CMIUtilString strId( vBroadcasterClass );
strId += vClientName;
bool bFound = false;
MapIdToEventMask_t::const_iterator it = m_mapIdToEventMask.begin();
while( it != m_mapIdToEventMask.end() )
const MapIdToEventMask_t::const_iterator it = m_mapIdToEventMask.find( strId );
if( it != m_mapIdToEventMask.end() )
{
const CMIUtilString & rId( (*it).first );
if( rId == strId )
{
bFound = true;
break;
}
// Next
++it;
}
if( bFound )
m_mapIdToEventMask.erase( it );
}
return MIstatus::success;
}
@ -634,7 +586,7 @@ bool CMICmnLLDBDebugger::ClientRemoveTheirMask( const CMIUtilString & vClientNam
// Type: Method.
// Args: vClientName - (R) The Client's unique ID.
// vBroadcasterClass - (R) The SBBroadcaster's class name.
// vwEventMask - (RW) The client's mask.
// vwEventMask - (W) The client's mask.
// Return: MIstatus::success - Functionality succeeded.
// MIstatus::failure - Functionality failed.
// Throws: None.
@ -652,22 +604,14 @@ bool CMICmnLLDBDebugger::ClientGetTheirMask( const CMIUtilString & vClientName,
CMIUtilString strId( vBroadcasterClass.c_str() );
strId += vClientName;
bool bFound = false;
MapIdToEventMask_t::const_iterator it = m_mapIdToEventMask.begin();
while( it != m_mapIdToEventMask.end() )
const MapIdToEventMask_t::const_iterator it = m_mapIdToEventMask.find( strId );
if( it != m_mapIdToEventMask.end() )
{
const CMIUtilString & rId( (*it).first );
if( rId == strId )
{
vwEventMask = (*it).second;
return MIstatus::success;
}
// Next
++it;
vwEventMask = (*it).second;
}
SetErrorDescription( CMIUtilString::Format( MIRSRC( IDS_LLDBDEBUGGER_ERR_CLIENTNOTREGISTERD ), vClientName.c_str() ) );
return MIstatus::failure;
}
@ -717,7 +661,7 @@ bool CMICmnLLDBDebugger::MonitorSBListenerEvents( bool & vrbIsAlive )
if( bExitAppEvent )
{
// Set the application to shutdown
m_pClientDriver->SetExitApplicationFlag();
m_pClientDriver->SetExitApplicationFlag( true );
// Kill *this thread
vrbIsAlive = false;

View File

@ -41,7 +41,8 @@ class CMICmnLLDBDebuggerHandleEvents;
//++ ============================================================================
// Details: MI proxy/adapter for the LLDB public SBDebugger API. The CMIDriver
// requires *this object. Command classes make calls on *this object
// to facilitate their work effort.
// to facilitate their work effort. The instance runs in its own worker
// thread.
// A singleton class.
// Gotchas: None.
// Authors: Illya Rudkin 26/02/2014.
@ -67,8 +68,8 @@ public:
// MI Commands can use these functions to listen for events they require
bool RegisterForEvent( const CMIUtilString & vClientName, const CMIUtilString & vBroadcasterClass, const MIuint vEventMask );
bool UnregisterForEvent( const CMIUtilString & vClientName, const CMIUtilString & vBroadcasterClass );
bool RegisterForEvent( const CMIUtilString & vClientName, const lldb::SBBroadcaster & vBroadcaster, const MIuint vEventMask ); // ToDo: Check required
bool UnregisterForEvent( const CMIUtilString & vClientName, const lldb::SBBroadcaster & vBroadcaster ); // ToDo: Check required
bool RegisterForEvent( const CMIUtilString & vClientName, const lldb::SBBroadcaster & vBroadcaster, const MIuint vEventMask );
bool UnregisterForEvent( const CMIUtilString & vClientName, const lldb::SBBroadcaster & vBroadcaster );
// Overridden:
public:
@ -100,6 +101,7 @@ private:
bool MonitorSBListenerEvents( bool & vrbYesExit );
bool BroadcasterGetMask( const CMIUtilString & vBroadcasterClass, MIuint & vEventMask ) const;
bool BroadcasterRemoveMask( const CMIUtilString & vBroadcasterClass );
bool BroadcasterSaveMask( const CMIUtilString & vBroadcasterClass, const MIuint vEventMask );
MIuint ClientGetMaskForAllClients( const CMIUtilString & vBroadcasterClass ) const;

View File

@ -20,7 +20,6 @@
//--
// Third party headers:
#include <lldb/API/SBBreakpointLocation.h>
#include <lldb/API/SBEvent.h>
#include <lldb/API/SBProcess.h>
#include <lldb/API/SBBreakpoint.h>
@ -47,6 +46,7 @@
#include "MICmnStreamStdout.h"
#include "MICmnStreamStderr.h"
#include "MIUtilDebug.h"
#include "MIDriver.h"
//++ ------------------------------------------------------------------------------------
// Details: CMICmnLLDBDebuggerHandleEvents constructor.
@ -302,52 +302,41 @@ bool CMICmnLLDBDebuggerHandleEvents::HandleEventSBBreakpointCmn( const lldb::SBE
if( !brkPt.IsValid() )
return MIstatus::success;
lldb::SBBreakpointLocation loc = brkPt.GetLocationAtIndex( 0 );
lldb::SBAddress addr = loc.GetAddress();
lldb::SBSymbolContext symbolContext = addr.GetSymbolContext( lldb::eSymbolContextEverything );
const char * pUnkwn = "??";
const char * pModule = pUnkwn;
const char * pFile = pUnkwn;
const char * pFunction = pUnkwn;
const char * pFilePath = pUnkwn;
//const char * pBrkName = brkPt.pUnkwn;
size_t nLine = 0;
lldb::SBTarget & rTarget = CMICmnLLDBDebugSessionInfo::Instance().m_lldbTarget;
size_t nAddr = addr.GetLoadAddress( rTarget );
lldb::SBModule module = symbolContext.GetModule();
if( module.IsValid() )
pModule = module.GetFileSpec().GetFilename();
lldb::SBCompileUnit compileUnit = symbolContext.GetCompileUnit();
if( compileUnit.IsValid() )
CMICmnLLDBDebugSessionInfo & rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance() );
CMICmnLLDBDebugSessionInfo::SBrkPtInfo sBrkPtInfo;
if( !rSessionInfo.GetBrkPtInfo( brkPt, sBrkPtInfo ) )
{
lldb::SBFileSpec fileSpec = compileUnit.GetFileSpec();
pFile = fileSpec.GetFilename();
pFilePath = fileSpec.GetDirectory();
lldb::SBFunction fn = symbolContext.GetFunction();
if( fn.IsValid() )
pFunction = fn.GetName();
const MIuint nLn = symbolContext.GetLineEntry().GetLine();
if( nLn > 0 )
nLine = nLn;
SetErrorDescription( CMIUtilString::Format( MIRSRC( IDS_LLDBOUTOFBAND_ERR_BRKPT_INFO_GET ), "HandleEventSBBreakpointCmn()", brkPt.GetID() ) );
return MIstatus::failure;
}
// CODETAG_LLDB_BREAKPOINT_CREATION
// This is in a worker thread
// Add more breakpoint information or overwrite existing information
CMICmnLLDBDebugSessionInfo::SBrkPtInfo sBrkPtInfoRec;
if( !rSessionInfo.RecordBrkPtInfoGet( brkPt.GetID(), sBrkPtInfoRec ) )
{
SetErrorDescription( CMIUtilString::Format( MIRSRC( IDS_LLDBOUTOFBAND_ERR_BRKPT_NOTFOUND ), "HandleEventSBBreakpointCmn()", brkPt.GetID() ) );
return MIstatus::failure;
}
sBrkPtInfo.m_bDisp = sBrkPtInfoRec.m_bDisp;
sBrkPtInfo.m_bEnabled = brkPt.IsEnabled();
sBrkPtInfo.m_bHaveArgOptionThreadGrp = false;
sBrkPtInfo.m_strOptThrdGrp = "";
sBrkPtInfo.m_nTimes = brkPt.GetHitCount();
sBrkPtInfo.m_strOrigLoc = sBrkPtInfoRec.m_strOrigLoc;
sBrkPtInfo.m_nIgnore = sBrkPtInfoRec.m_nIgnore;
sBrkPtInfo.m_bPending = sBrkPtInfoRec.m_bPending;
sBrkPtInfo.m_bCondition = sBrkPtInfoRec.m_bCondition;
sBrkPtInfo.m_strCondition = sBrkPtInfoRec.m_strCondition;
sBrkPtInfo.m_bBrkPtThreadId = sBrkPtInfoRec.m_bBrkPtThreadId;
sBrkPtInfo.m_nBrkPtThreadId = sBrkPtInfoRec.m_nBrkPtThreadId;
// MI print "=breakpoint-modified,bkpt={number=\"%d\",type=\"breakpoint\",disp=\"%s\",enabled=\"%c\",addr=\"0x%08x\", func=\"%s\",file=\"%s\",fullname=\"%s/%s\",line=\"%d\",times=\"%d\",original-location=\"%s\"}"
CMICmnMIValueTuple miValueTuple;
if( !CMICmnLLDBDebugSessionInfo::Instance().MIResponseFormBrkPtInfo( brkPt.GetID(), // "number="
"breakpoint", // "type="
false, // "disp="
brkPt.IsEnabled(), // "enabled="
nAddr, // "addr="
pFunction, // "func="
pFile, // "file="
pFilePath, // "fullname="
nLine, // "line="
false, //
"", // "thread-groups="
brkPt.GetHitCount(), // "times="
"unknown", // "original-location="
miValueTuple ))
if( !rSessionInfo.MIResponseFormBrkPtInfo( sBrkPtInfo, miValueTuple ) )
{
SetErrorDescription( CMIUtilString::Format( MIRSRC( IDS_LLDBOUTOFBAND_ERR_FORM_MI_RESPONSE ), "HandleEventSBBreakpointCmn()" ) );
return MIstatus::failure;
}
@ -618,7 +607,7 @@ bool CMICmnLLDBDebuggerHandleEvents::HandleProcessEventStateSuspended( const lld
return MIstatus::failure;
lldb::SBCommandReturnObject result;
const lldb::ReturnStatus status = rDebugger.GetCommandInterpreter().HandleCommand( "process status", result, false );
const lldb::ReturnStatus status = rDebugger.GetCommandInterpreter().HandleCommand( "process status", result, false ); MIunused( status );
bOk = TextToStderr( result.GetError() );
bOk = bOk && TextToStdout( result.GetOutput() );
}
@ -735,13 +724,33 @@ bool CMICmnLLDBDebuggerHandleEvents::HandleProcessEventStopSignal( bool & vwrbSh
const MIuint64 nStopReason = rProcess.GetSelectedThread().GetStopReasonDataAtIndex( 0 );
switch( nStopReason )
{
case 11:
case 2: // Terminal interrupt signal. SIGINT
{
// MI print "*stopped,reason=\"signal-received\",signal-name=\"SIGSEGV \",signal-meaning=\"Segmentation fault\",thread-id=\"%d\",frame={%s}"
// MI print "*stopped,reason=\"signal-received\",signal-name=\"SIGNINT\",signal-meaning=\"Interrupt\",frame={%s}"
const CMICmnMIValueConst miValueConst( "signal-received" );
const CMICmnMIValueResult miValueResult( "reason", miValueConst );
CMICmnMIOutOfBandRecord miOutOfBandRecord( CMICmnMIOutOfBandRecord::eOutOfBand_Stopped, miValueResult );
const CMICmnMIValueConst miValueConst2( "SIGSEGV " );
const CMICmnMIValueConst miValueConst2( "SIGINT" );
const CMICmnMIValueResult miValueResult2( "signal-name", miValueConst2 );
bOk = miOutOfBandRecord.Add( miValueResult2 );
const CMICmnMIValueConst miValueConst3( "Interrupt" );
const CMICmnMIValueResult miValueResult3( "signal-meaning", miValueConst3 );
bOk = bOk && miOutOfBandRecord.Add( miValueResult3 );
CMICmnMIValueTuple miValueTuple;
bOk = bOk && MiHelpGetCurrentThreadFrame( miValueTuple );
const CMICmnMIValueResult miValueResult5( "frame", miValueTuple );
bOk = bOk && miOutOfBandRecord.Add( miValueResult5 );
bOk = bOk && MiOutOfBandRecordToStdout( miOutOfBandRecord );
bOk = bOk && TextToStdout( "(gdb)" );
}
break;
case 11: // Invalid memory reference. SIGSEGV
{
// MI print "*stopped,reason=\"signal-received\",signal-name=\"SIGSEGV\",signal-meaning=\"Segmentation fault\",thread-id=\"%d\",frame={%s}"
const CMICmnMIValueConst miValueConst( "signal-received" );
const CMICmnMIValueResult miValueResult( "reason", miValueConst );
CMICmnMIOutOfBandRecord miOutOfBandRecord( CMICmnMIOutOfBandRecord::eOutOfBand_Stopped, miValueResult );
const CMICmnMIValueConst miValueConst2( "SIGSEGV" );
const CMICmnMIValueResult miValueResult2( "signal-name", miValueConst2 );
bOk = miOutOfBandRecord.Add( miValueResult2 );
const CMICmnMIValueConst miValueConst3( "Segmentation fault" );
@ -763,7 +772,7 @@ bool CMICmnLLDBDebuggerHandleEvents::HandleProcessEventStopSignal( bool & vwrbSh
if( rProcess.IsValid() )
rProcess.Continue();
break;
case 5:
case 5: // Trace/breakpoint trap. SIGTRAP
{
lldb::SBThread thread = rProcess.GetSelectedThread();
const MIuint nFrames = thread.GetNumFrames();
@ -848,7 +857,10 @@ bool CMICmnLLDBDebuggerHandleEvents::MiHelpGetCurrentThreadFrame( CMICmnMIValueT
CMICmnMIValueTuple miValueTuple;
if( !CMICmnLLDBDebugSessionInfo::Instance().MIResponseFormFrameInfo( thread, 0, miValueTuple ) )
{
SetErrorDescription( CMIUtilString::Format( MIRSRC( IDS_LLDBOUTOFBAND_ERR_FORM_MI_RESPONSE ), "MiHelpGetCurrentThreadFrame()" ) );
return MIstatus::failure;
}
vwrMiValueTuple = miValueTuple;
@ -865,22 +877,31 @@ bool CMICmnLLDBDebuggerHandleEvents::MiHelpGetCurrentThreadFrame( CMICmnMIValueT
//--
bool CMICmnLLDBDebuggerHandleEvents::HandleProcessEventStopReasonBreakpoint( void )
{
// CODETAG_DEBUG_SESSION_RUNNING_PROG_RECEIVED_SIGINT_PAUSE_PROGRAM
if( !CMIDriver::Instance().SetDriverStateRunningNotDebugging() )
{
const CMIUtilString & rErrMsg( CMIDriver::Instance().GetErrorDescription() );
SetErrorDescription( CMIUtilString::Format( MIRSRC( IDS_LLDBOUTOFBAND_ERR_SETNEWDRIVERSTATE ), "HandleProcessEventStopReasonBreakpoint()", rErrMsg.c_str() ) );
return MIstatus::failure;
}
lldb::SBProcess & rProcess = CMICmnLLDBDebugSessionInfo::Instance().m_lldbProcess;
const MIuint64 brkPtId = rProcess.GetSelectedThread().GetStopReasonDataAtIndex( 0 );
lldb::SBBreakpoint brkPt = CMICmnLLDBDebugSessionInfo::Instance().m_lldbTarget.GetBreakpointAtIndex( (MIuint) brkPtId );
return MiStoppedAtBreakPoint( brkPt );
return MiStoppedAtBreakPoint( brkPtId, brkPt );
}
//++ ------------------------------------------------------------------------------------
// Details: .
// Details: Form the MI Out-of-band response for stopped reason on hitting a break point.
// Type: Method.
// Args: None.
// Args: vBrkPtId - (R) The LLDB break point's ID
// vBrkPt - (R) THe LLDB break point object.
// Return: MIstatus::success - Functionality succeeded.
// MIstatus::failure - Functionality failed.
// Throws: None.
//--
bool CMICmnLLDBDebuggerHandleEvents::MiStoppedAtBreakPoint( const lldb::SBBreakpoint & vBrkPt )
bool CMICmnLLDBDebuggerHandleEvents::MiStoppedAtBreakPoint( const MIuint64 vBrkPtId, const lldb::SBBreakpoint & vBrkPt )
{
bool bOk = MIstatus::success;
@ -896,7 +917,7 @@ bool CMICmnLLDBDebuggerHandleEvents::MiStoppedAtBreakPoint( const lldb::SBBreakp
const CMICmnMIValueConst miValueConst2( "del" );
const CMICmnMIValueResult miValueResult2( "disp", miValueConst2 );
bOk = miOutOfBandRecord.Add( miValueResult2 );
const CMIUtilString strBkp( CMIUtilString::Format( "%d", vBrkPt.GetID() ) );
const CMIUtilString strBkp( CMIUtilString::Format( "%d", vBrkPtId ) );
const CMICmnMIValueConst miValueConst3( strBkp );
CMICmnMIValueResult miValueResult3( "bkptno", miValueConst3 );
bOk = bOk && miOutOfBandRecord.Add( miValueResult3 );
@ -924,8 +945,11 @@ bool CMICmnLLDBDebuggerHandleEvents::MiStoppedAtBreakPoint( const lldb::SBBreakp
CMIUtilString path;
MIuint nLine = 0;
if( !rSession.GetFrameInfo( frame, pc, fnName, fileName, path, nLine ) )
{
SetErrorDescription( CMIUtilString::Format( MIRSRC( IDS_LLDBOUTOFBAND_ERR_FRAME_INFO_GET ), "MiStoppedAtBreakPoint()" ) );
return MIstatus::failure;
}
// MI print "*stopped,reason=\"breakpoint-hit\",disp=\"del\",bkptno=\"%d\",frame={addr=\"0x%08x\",func=\"%s\",args=[],file=\"%s\",fullname=\"%s\",line=\"%d\"},thread-id=\"%d\",stopped-threads=\"all\""
const CMICmnMIValueConst miValueConst( "breakpoint-hit" );
const CMICmnMIValueResult miValueResult( "reason", miValueConst );
@ -933,7 +957,7 @@ bool CMICmnLLDBDebuggerHandleEvents::MiStoppedAtBreakPoint( const lldb::SBBreakp
const CMICmnMIValueConst miValueConstA( "del" );
const CMICmnMIValueResult miValueResultA( "disp", miValueConstA );
bOk = miOutOfBandRecord.Add( miValueResultA );
const CMIUtilString strBkp( CMIUtilString::Format( "%d", vBrkPt.GetID() + 1 ) );
const CMIUtilString strBkp( CMIUtilString::Format( "%d", vBrkPtId ) );
const CMICmnMIValueConst miValueConstB( strBkp );
CMICmnMIValueResult miValueResultB( "bkptno", miValueConstB );
bOk = bOk && miOutOfBandRecord.Add( miValueResultB );
@ -1008,7 +1032,10 @@ bool CMICmnLLDBDebuggerHandleEvents::HandleProcessEventStopReasonTrace( void )
CMIUtilString path;
MIuint nLine = 0;
if( !rSession.GetFrameInfo( frame, pc, fnName, fileName, path, nLine ) )
{
SetErrorDescription( CMIUtilString::Format( MIRSRC( IDS_LLDBOUTOFBAND_ERR_FRAME_INFO_GET ), "HandleProcessEventStopReasonTrace()" ) );
return MIstatus::failure;
}
// frame={addr=\"0x%08x\",func=\"%s\",args=[],file=\"%s\",fullname=\"%s\",line=\"%d\"}
CMICmnMIValueTuple miValueTuple;
@ -1413,11 +1440,7 @@ bool CMICmnLLDBDebuggerHandleEvents::MiOutOfBandRecordToStdout( const CMICmnMIOu
//--
bool CMICmnLLDBDebuggerHandleEvents::TextToStdout( const CMIUtilString & vrTxt )
{
const bool bLock = CMICmnStreamStdout::Instance().Lock();
const bool bOk = bLock && CMICmnStreamStdout::Instance().WriteMIResponse( vrTxt );
bLock && CMICmnStreamStdout::Instance().Unlock();
return bOk;
return CMICmnStreamStdout::TextToStdout( vrTxt );
}
//++ ------------------------------------------------------------------------------------
@ -1431,5 +1454,5 @@ bool CMICmnLLDBDebuggerHandleEvents::TextToStdout( const CMIUtilString & vrTxt )
//--
bool CMICmnLLDBDebuggerHandleEvents::TextToStderr( const CMIUtilString & vrTxt )
{
return CMICmnStreamStderr::Instance().Write( vrTxt );
return CMICmnStreamStderr::TextToStderr( vrTxt );
}

View File

@ -82,7 +82,7 @@ private:
bool MiHelpGetCurrentThreadFrame( CMICmnMIValueTuple & vwrMiValueTuple );
bool MiResultRecordToStdout( const CMICmnMIResultRecord & vrMiResultRecord );
bool MiOutOfBandRecordToStdout( const CMICmnMIOutOfBandRecord & vrMiResultRecord );
bool MiStoppedAtBreakPoint( const lldb::SBBreakpoint & vBrkPt );
bool MiStoppedAtBreakPoint( const MIuint64 vBrkPtId, const lldb::SBBreakpoint & vBrkPt );
bool TextToStdout( const CMIUtilString & vrTxt );
bool TextToStderr( const CMIUtilString & vrTxt );
bool UpdateSelectedThread( void );

View File

@ -19,10 +19,9 @@
// Copyright: None.
//--
#include <stdlib.h>
// Third Party Headers:
#include <lldb/API/SBError.h>
#include <cstdlib>
// In-house headers:
#include "MICmnLLDBProxySBValue.h"
@ -112,7 +111,7 @@ bool CMICmnLLDBProxySBValue::GetValueAsSigned( const lldb::SBValue & vrValue, MI
bool CMICmnLLDBProxySBValue::GetCString( const lldb::SBValue & vrValue, CMIUtilString & vwCString )
{
lldb::SBValue & rValue = const_cast< lldb::SBValue & >( vrValue );
const char * pCType = rValue.GetTypeName();
const MIchar * pCType = rValue.GetTypeName();
if( pCType == nullptr )
return MIstatus::failure;
@ -129,7 +128,7 @@ bool CMICmnLLDBProxySBValue::GetCString( const lldb::SBValue & vrValue, CMIUtilS
lldb::SBProcess & rProcess = rSessionInfo.m_lldbProcess;
MIuint nBufferSize = 64;
bool bNeedResize = false;
char * pBuffer = static_cast< char * >( ::malloc( nBufferSize ) );
MIchar * pBuffer = static_cast< MIchar * >( ::malloc( nBufferSize ) );
do
{
lldb::SBError error;
@ -138,7 +137,7 @@ bool CMICmnLLDBProxySBValue::GetCString( const lldb::SBValue & vrValue, CMIUtilS
{
bNeedResize = true;
nBufferSize = nBufferSize << 1;
pBuffer = static_cast< char * >( ::realloc( pBuffer, nBufferSize ) );
pBuffer = static_cast< MIchar * >( ::realloc( pBuffer, nBufferSize ) );
}
else
bNeedResize = false;

View File

@ -275,7 +275,7 @@ bool CMICmnLog::Write( const CMIUtilString & vData, const ELogVerbosity veType )
while( it != m_mapMediumToName.end() )
{
IMedium * pMedium = (*it).first;
const CMIUtilString & rNameMedium = (*it).second;
const CMIUtilString & rNameMedium = (*it).second; MIunused( rNameMedium );
if( pMedium->Write( vData, veType ) )
cnt++;
else

View File

@ -28,7 +28,7 @@
#if defined( _MSC_VER )
#include "MIUtilSystemWindows.h"
#elif defined( __FreeBSD__ ) || defined( __linux )
#elif defined( __linux )
#include "MIUtilSystemLinux.h"
#elif defined( __APPLE__ )
#include "MIUtilSystemOsx.h"

View File

@ -61,20 +61,20 @@ CMICmnMIOutOfBandRecord::MapOutOfBandToOutOfBandText_t ms_constMapAsyncRecordTex
// Throws: None.
//--
CMICmnMIOutOfBandRecord::CMICmnMIOutOfBandRecord( void )
: m_strAsyncRecord( MIRSRC( IDS_WORD_INVALIDBRKTS ) )
: m_strAsyncRecord( MIRSRC( IDS_CMD_ERR_EVENT_HANDLED_BUT_NO_ACTION ) )
{
}
//++ ------------------------------------------------------------------------------------
// Details: CMICmnMIOutOfBandRecord constructor.
// Type: Method.
// Args: veType - (R) A MI result class enumeration.
// Args: veType - (R) A MI Out-of-Bound enumeration.
// Return: None.
// Throws: None.
//--
CMICmnMIOutOfBandRecord::CMICmnMIOutOfBandRecord( const OutOfBand_e veType )
: m_eResultAsyncRecordClass( veType )
, m_strAsyncRecord( MIRSRC( IDS_WORD_INVALIDBRKTS ) )
, m_strAsyncRecord( MIRSRC( IDS_CMD_ERR_EVENT_HANDLED_BUT_NO_ACTION ) )
{
BuildAsyncRecord();
}
@ -82,14 +82,14 @@ CMICmnMIOutOfBandRecord::CMICmnMIOutOfBandRecord( const OutOfBand_e veType )
//++ ------------------------------------------------------------------------------------
// Details: CMICmnMIOutOfBandRecord constructor.
// Type: Method.
// Args: veType - (R) A MI result class enumeration.
// Args: veType - (R) A MI Out-of-Bound enumeration.
// vMIResult - (R) A MI result object.
// Return: None.
// Throws: None.
//--
CMICmnMIOutOfBandRecord::CMICmnMIOutOfBandRecord( const OutOfBand_e veType, const CMICmnMIValueResult & vValue )
: m_eResultAsyncRecordClass( veType )
, m_strAsyncRecord( MIRSRC( IDS_WORD_INVALIDBRKTS ) )
, m_strAsyncRecord( MIRSRC( IDS_CMD_ERR_EVENT_HANDLED_BUT_NO_ACTION ) )
, m_partResult( vValue )
{
BuildAsyncRecord();
@ -133,7 +133,7 @@ const CMIUtilString & CMICmnMIOutOfBandRecord::GetString( void ) const
//--
bool CMICmnMIOutOfBandRecord::BuildAsyncRecord( void )
{
const char * pFormat = "%s%s";
const MIchar * pFormat = "%s%s";
const CMIUtilString & rStrAsyncRecord( ms_MapOutOfBandToOutOfBandText[ m_eResultAsyncRecordClass ] );
const CMIUtilString & rStrToken( ms_constMapAsyncRecordTextToToken[ m_eResultAsyncRecordClass ] );
m_strAsyncRecord = CMIUtilString::Format( pFormat, rStrToken.c_str(), rStrAsyncRecord.c_str() );

View File

@ -42,22 +42,22 @@ const CMIUtilString CMICmnMIResultRecord::ms_constStrResultRecordHat( "^");
// Throws: None.
//--
CMICmnMIResultRecord::CMICmnMIResultRecord( void )
: m_strResultRecord( MIRSRC( IDS_WORD_INVALIDBRKTS ) )
: m_strResultRecord( MIRSRC( IDS_CMD_ERR_CMD_RUN_BUT_NO_ACTION ) )
{
}
//++ ------------------------------------------------------------------------------------
// Details: CMICmnMIResultRecord constructor.
// Type: Method.
// Args: vToken - (R) The command's number.
// Args: vrToken - (R) The command's transaction ID or token.
// veType - (R) A MI result class enumeration.
// Return: None.
// Throws: None.
//--
CMICmnMIResultRecord::CMICmnMIResultRecord( const MIuint vToken, const ResultClass_e veType )
: m_nResultRecordToken( vToken )
CMICmnMIResultRecord::CMICmnMIResultRecord( const CMIUtilString & vrToken, const ResultClass_e veType )
: m_strResultRecordToken( vrToken )
, m_eResultRecordResultClass( veType )
, m_strResultRecord( MIRSRC( IDS_WORD_INVALIDBRKTS ) )
, m_strResultRecord( MIRSRC( IDS_CMD_ERR_CMD_RUN_BUT_NO_ACTION ) )
{
BuildResultRecord();
}
@ -65,16 +65,16 @@ CMICmnMIResultRecord::CMICmnMIResultRecord( const MIuint vToken, const ResultCla
//++ ------------------------------------------------------------------------------------
// Details: CMICmnMIResultRecord constructor.
// Type: Method.
// Args: vToken - (R) The command's number.
// Args: vrToken - (R) The command's transaction ID or token.
// veType - (R) A MI result class enumeration.
// vMIResult - (R) A MI result object.
// Return: None.
// Throws: None.
//--
CMICmnMIResultRecord::CMICmnMIResultRecord( const MIuint vToken, const ResultClass_e veType, const CMICmnMIValueResult & vValue )
: m_nResultRecordToken( vToken )
CMICmnMIResultRecord::CMICmnMIResultRecord( const CMIUtilString & vrToken, const ResultClass_e veType, const CMICmnMIValueResult & vValue )
: m_strResultRecordToken( vrToken )
, m_eResultRecordResultClass( veType )
, m_strResultRecord( MIRSRC( IDS_WORD_INVALIDBRKTS ) )
, m_strResultRecord( MIRSRC( IDS_CMD_ERR_CMD_RUN_BUT_NO_ACTION ) )
, m_partResult( vValue )
{
BuildResultRecord();
@ -118,9 +118,9 @@ const CMIUtilString & CMICmnMIResultRecord::GetString( void ) const
//--
bool CMICmnMIResultRecord::BuildResultRecord( void )
{
const char * pFormat = "%d%s%s";
const MIchar * pFormat = "%s%s%s";
const CMIUtilString & rStrResultRecord( ms_MapResultClassToResultClassText[ m_eResultRecordResultClass ] );
m_strResultRecord = CMIUtilString::Format( pFormat, m_nResultRecordToken, ms_constStrResultRecordHat.c_str(), rStrResultRecord.c_str() );
m_strResultRecord = CMIUtilString::Format( pFormat, m_strResultRecordToken.c_str(), ms_constStrResultRecordHat.c_str(), rStrResultRecord.c_str() );
return MIstatus::success;
}
@ -140,26 +140,3 @@ bool CMICmnMIResultRecord::Add( const CMICmnMIValue & vMIValue )
return MIstatus::success;
}
// Example usage:
// Forms: 5^done,stack-args=[frame={level="0",args=[{name="argc",value="1"},{name="argv",value="
// #include "MICmnMIResultRecord.h"
// #include "MICmnMIValueList.h"
// #include "MICmnMIValueConst.h"
// #include "MICmnMIValueResult.h"
// #include "MICmnMIValueTuple.h"
//CMICmnMIValueResult miValueResult1( "name", CMICmnMIValueConst( "argc") );
//CMICmnMIValueResult miValueResult2( "value", CMICmnMIValueConst( "1") );
//CMICmnMIValueTuple miValueTuple1( miValueResult1 );
//miValueTuple1.Add( miValueResult2 );
//CMICmnMIValueList miValueList1( miValueTuple1 );
//miValueList1.Add( miValueTuple1 );
//CMICmnMIValueResult miValueResult3( "args", miValueList1 );
//CMICmnMIValueResult miValueResult4( "level", CMICmnMIValueConst( "0" ) );
//CMICmnMIValueTuple miValueTuple2( miValueResult4 );
//miValueTuple2.Add( miValueResult3 );
//CMICmnMIValueResult miValueResult5( "frame", miValueTuple2 );
//CMICmnMIValueList miValueList2( miValueResult5 );
//CMICmnMIValueResult miValueResult6( "stack-args", miValueList2 );
//CMICmnMIResultRecord miResultRecord( 5, CMICmnMIResultRecord::eResultClass_Done, miValueResult6 );
//CMIUtilString str( miResultRecord.GetString() );

View File

@ -79,8 +79,8 @@ public:
// Methods:
public:
/* ctor */ CMICmnMIResultRecord( void );
/* ctor */ CMICmnMIResultRecord( const MIuint vToken, const ResultClass_e veType );
/* ctor */ CMICmnMIResultRecord( const MIuint vToken, const ResultClass_e veType, const CMICmnMIValueResult & vValue );
/* ctor */ CMICmnMIResultRecord( const CMIUtilString & vrToken, const ResultClass_e veType );
/* ctor */ CMICmnMIResultRecord( const CMIUtilString & vrToken, const ResultClass_e veType, const CMICmnMIValueResult & vValue );
//
const CMIUtilString & GetString( void ) const;
bool Add( const CMICmnMIValue & vMIValue );
@ -99,7 +99,7 @@ private:
static const CMIUtilString ms_constStrResultRecordHat;
static MapResultClassToResultClassText_t ms_constMapResultClassToResultClassText;
//
MIuint m_nResultRecordToken;
CMIUtilString m_strResultRecordToken;
ResultClass_e m_eResultRecordResultClass;
CMIUtilString m_strResultRecord; // Holds the text version of the result record to date
CMICmnMIValueResult m_partResult;

View File

@ -84,13 +84,13 @@ bool CMICmnMIValueConst::BuildConst( void )
}
else
{
const char * pFormat = "%s%s%s";
const MIchar * pFormat = "%s%s%s";
m_strValue = CMIUtilString::Format( pFormat, ms_constStrDblQuote.c_str(), strValue.c_str(), ms_constStrDblQuote.c_str() );
}
}
else
{
const char * pFormat = "%s%s";
const MIchar * pFormat = "%s%s";
m_strValue = CMIUtilString::Format( pFormat, ms_constStrDblQuote.c_str(), ms_constStrDblQuote.c_str() );
}

View File

@ -87,7 +87,7 @@ CMICmnMIValueList::~CMICmnMIValueList( void )
//--
bool CMICmnMIValueList::BuildList( void )
{
const char * pFormat = "[%s]";
const MIchar * pFormat = "[%s]";
m_strValue = CMIUtilString::Format( pFormat, m_strValue.c_str() );
return MIstatus::success;
@ -143,19 +143,16 @@ bool CMICmnMIValueList::BuildList( const CMICmnMIValueResult & vResult )
return BuildList();
}
// ToDo: Fix this fudge with std::string cause CMIUtilString does not have a copy constructor
std::string str = m_strValue;
if( str[ 0 ] == '[' )
if( m_strValue[ 0 ] == '[' )
{
str = str.substr( 1, m_strValue.size() - 1 );
m_strValue = m_strValue.substr( 1, m_strValue.size() - 1 );
}
if( str[ str.size() - 1 ] == ']' )
if( m_strValue[ m_strValue.size() - 1 ] == ']' )
{
str = str.substr( 0, m_strValue.size() - 2 );
m_strValue = m_strValue.substr( 0, m_strValue.size() - 1 );
}
m_strValue = str.c_str();
const char * pFormat = "[%s,%s]";
const MIchar * pFormat = "[%s,%s]";
m_strValue = CMIUtilString::Format( pFormat, m_strValue.c_str(), vResult.GetString().c_str() );
return MIstatus::success;
@ -181,7 +178,7 @@ bool CMICmnMIValueList::BuildList( const CMICmnMIValue & vValue )
return BuildList();
}
const char * pFormat = "[%s,%s]";
const MIchar * pFormat = "[%s,%s]";
m_strValue = m_strValue.FindAndReplace( "[", "" );
m_strValue = m_strValue.FindAndReplace( "]", "" );
m_strValue = CMIUtilString::Format( pFormat, m_strValue.c_str(), vValue.GetString().c_str() );

View File

@ -94,7 +94,7 @@ CMICmnMIValueResult::~CMICmnMIValueResult( void )
//--
bool CMICmnMIValueResult::BuildResult( void )
{
const char * pFormat = m_bUseSpacing ? "%s %s %s" : "%s%s%s";
const MIchar * pFormat = m_bUseSpacing ? "%s %s %s" : "%s%s%s";
m_strValue = CMIUtilString::Format( pFormat, m_strPartVariable.c_str(), ms_constStrEqual.c_str(), m_partMIValue.GetString().c_str() );
return MIstatus::success;
@ -111,7 +111,7 @@ bool CMICmnMIValueResult::BuildResult( void )
//--
bool CMICmnMIValueResult::BuildResult( const CMIUtilString & vVariable, const CMICmnMIValue & vValue )
{
const char * pFormat = m_bUseSpacing ? "%s, %s %s %s" : "%s,%s%s%s";
const MIchar * pFormat = m_bUseSpacing ? "%s, %s %s %s" : "%s,%s%s%s";
m_strValue = CMIUtilString::Format( pFormat, m_strValue.c_str(), vVariable.c_str(), ms_constStrEqual.c_str(), vValue.GetString().c_str() );
return MIstatus::success;

View File

@ -87,7 +87,7 @@ CMICmnMIValueTuple::~CMICmnMIValueTuple( void )
//--
bool CMICmnMIValueTuple::BuildTuple( void )
{
const char * pFormat = "{%s}";
const MIchar * pFormat = "{%s}";
m_strValue = CMIUtilString::Format( pFormat, m_strValue.c_str() );
return MIstatus::success;
@ -111,19 +111,16 @@ bool CMICmnMIValueTuple::BuildTuple( const CMICmnMIValueResult & vResult )
return BuildTuple();
}
// ToDo: Fix this fudge with std::string cause CMIUtilString does not have a copy constructor
std::string str = m_strValue;
if( str[ 0 ] == '{' )
if( m_strValue[ 0 ] == '{' )
{
str = str.substr( 1, m_strValue.size() - 1 );
m_strValue = m_strValue.substr( 1, m_strValue.size() - 1 );
}
if( str[ str.size() - 1 ] == '}' )
if( m_strValue[ m_strValue.size() - 1 ] == '}' )
{
str = str.substr( 0, m_strValue.size() - 2 );
m_strValue = m_strValue.substr( 0, m_strValue.size() - 1 );
}
m_strValue = str.c_str();
const char * pFormat = m_bSpaceAfterComma ? "{%s, %s}" : "{%s,%s}";
const MIchar * pFormat = m_bSpaceAfterComma ? "{%s, %s}" : "{%s,%s}";
m_strValue = CMIUtilString::Format( pFormat, m_strValue.c_str(), vResult.GetString().c_str() );
return MIstatus::success;

View File

@ -26,12 +26,11 @@
#include "MICmnResources.h"
// Instantiations:
// *** Be sure to update resource string definitions array ****
const CMICmnResources::SRsrcTextData CMICmnResources::ms_pResourceId2TextData[] =
{
{ IDS_PROJNAME, "LLDB Machine Interface Driver (MI) All rights reserved" },
{ IDS_MI_VERSION_DESCRIPTION_DEBUG, "Version: 1.0.0.3 (Debug)" }, // See version history in MIDriverMain.cpp
{ IDS_MI_VERSION_DESCRIPTION, "Version: 1.0.0.3" },
{ IDS_MI_VERSION_DESCRIPTION_DEBUG, "Version: 1.0.0.6 (Debug)" }, // See version history in MIDriverMain.cpp
{ IDS_MI_VERSION_DESCRIPTION, "Version: 1.0.0.6" },
{ IDS_MI_APPNAME_SHORT, "MI" },
{ IDS_MI_APPNAME_LONG, "Machine Interface Driver" },
{ IDS_MI_APP_FILEPATHNAME, "Application: %s" },
@ -49,7 +48,7 @@ const CMICmnResources::SRsrcTextData CMICmnResources::ms_pResourceId2TextData[]
{ IDS_LOG_MSG_FILE_LOGGER_PATH, "File logger path: %s%s" },
{ IDS_LOG_MSG_VERSION, "Version: %s%s" },
{ IDS_LOG_ERR_FILE_LOGGER_DISABLED, "Log. File logger temporarily disabled due to file error '%s'" },
{ IDS_LOG_MEDIUM_ERR_INIT, "Log. Medium '%s' initialize failed. %s" },
{ IDS_LOG_MEDIUM_ERR_INIT, "Log. Medium '%s' initialise failed. %s" },
{ IDS_LOG_MEDIUM_ERR_WRITE_ANY, "Log. Failed to write log data to any medium." },
{ IDS_LOG_MEDIUM_ERR_WRITE_MEDIUMFAIL, "Log. One or mediums failed writing log data." },
{ IDS_MEDIUMFILE_NAME, "File" },
@ -59,16 +58,19 @@ const CMICmnResources::SRsrcTextData CMICmnResources::ms_pResourceId2TextData[]
{ IDE_MEDIUMFILE_ERR_GET_FILE_PATHNAME_SYS, "File Medium. Failed to retrieve the system/executable path for the Log file" },
{ IDE_OS_ERR_UNKNOWN, "Unknown OS error" },
{ IDE_OS_ERR_RETRIEVING, "Unabled to retrieve OS error message" },
{ IDS_DRIVERMGR_DRIVER_ERR_INIT, "Driver Manager. Driver '%s' (ID:'%s') initialize failed. %s" },
{ IDS_DRIVERMGR_DRIVER_ERR_INIT, "Driver Manager. Driver '%s' (ID:'%s') initialise failed. %s" },
{ IDE_MEDIUMSTDERR_NAME, "Stderr" },
{ IDE_MEDIUMSTDOUT_NAME, "Stdout" },
{ IDE_MI_APP_EXIT_OK, "Program exited OK" },
{ IDE_MI_APP_EXIT_WITH_PROBLEM, "Program exited with a problem, see %s file" },
{ IDE_MI_APP_EXIT_WITH_PROBLEM, "Program exited with a problem, see '%s' file" },
{ IDE_MI_APP_EXIT_WITH_PROBLEM_NO_LOG, "Program exited with a problem, the application's log file '%s' was disabled" },
{ IDE_MI_APP_ARG_USAGE, "MI driver usage:" },
{ IDE_MI_APP_ARG_HELP, "-h\n--help\n\tPrints out usage information for the MI debugger." },
{ IDE_MI_APP_ARG_VERSION, "--version\n\tPrints out GNU (gdb) version information." },
{ IDE_MI_APP_ARG_VERSION_LONG, "--versionLong\n\tPrints out MI version information." },
{ IDE_MI_APP_ARG_INTERPRETER, "--interpreter\n\tUse the MI driver for the debugger (Default is the LLDB driver).\n\tAny LLDB command line options are ignored even if the MI driver\n\tfalls through to the LLDB driver. (Depends on MICmnConfig.h)" },
{ IDE_MI_APP_ARG_INTERPRETER, "--interpreter\n\tUse the MI driver for the debugger (Default is the LLDB driver).\n\tAny LLDB command line options are ignored even if the MI driver\n\tfalls through to the LLDB driver. (Depends on build\n\t configuration see MICmnConfig.h)" },
{ IDE_MI_APP_ARG_NO_APP_LOG, "--noLog\n\tUse this argument to tell the MI driver not to update it's log\n\tfile '%s'." },
{ IDE_MI_APP_ARG_EXAMPLE, "Example MI command:\n\t3-info-gdb-mi-command gdb-set\n\t3^done,command={exists=\"true\"}" },
{ IDS_STDIN_ERR_INVALID_PROMPT, "Stdin. Invalid prompt description '%s'" },
{ IDS_STDIN_ERR_THREAD_CREATION_FAILED, "Stdin. Thread creation failed '%s'" },
{ IDS_STDIN_ERR_THREAD_DELETE, "Stdin. Thread failed to delete '%s'" },
@ -86,14 +88,16 @@ const CMICmnResources::SRsrcTextData CMICmnResources::ms_pResourceId2TextData[]
{ IDS_CMDMGR_ERR_CMD_FAILED_CREATE, "Command manager. Command creation failed. %s" },
{ IDS_CMDMGR_ERR_CMD_INVOKER, "Command manager. %s " },
{ IDS_PROCESS_SIGNAL_RECEIVED, "Process signal. Application received signal '%s' (%d)" },
{ IDS_MI_INIT_ERR_LOG, "Log. Error occurred during initialization %s" },
{ IDS_MI_INIT_ERR_RESOURCES, "Resources. Error occurred during initialization %s" },
{ IDS_MI_INIT_ERR_INIT, "Driver. Error occurred during initialization %s" },
{ IDS_MI_INIT_ERR_STREAMSTDIN, "Stdin. Error occurred during initialization %s" },
{ IDS_MI_INIT_ERR_STREAMSTDOUT, "Stdout. Error occurred during initialization %s" },
{ IDS_MI_INIT_ERR_STREAMSTDERR, "Stderr. Error occurred during initialization %s" },
{ IDS_MI_INIT_ERR_FALLTHRUDRIVER, "Fall Through Driver. Error occurred during initialization %s" },
{ IDS_MI_INIT_ERR_THREADMGR, "Thread Mgr. Error occurred during initialization %s" },
{ IDS_MI_INIT_ERR_LOG, "Log. Error occurred during initialisation %s" },
{ IDS_MI_INIT_ERR_RESOURCES, "Resources. Error occurred during initialisation %s" },
{ IDS_MI_INIT_ERR_INIT, "Driver. Error occurred during initialisation %s" },
{ IDS_MI_INIT_ERR_STREAMSTDIN, "Stdin. Error occurred during initialisation %s" },
{ IDS_MI_INIT_ERR_STREAMSTDIN_OSHANDLER, "Stdin. The OS specific stdin stream handler has not been specified for this OS" },
{ IDS_MI_INIT_ERR_OS_STDIN_HANDLER, "Stdin handler. Error occurred during initialisation %s" },
{ IDS_MI_INIT_ERR_STREAMSTDOUT, "Stdout. Error occurred during initialisation %s" },
{ IDS_MI_INIT_ERR_STREAMSTDERR, "Stderr. Error occurred during initialisation %s" },
{ IDS_MI_INIT_ERR_FALLTHRUDRIVER, "Fall Through Driver. Error occurred during initialisation %s" },
{ IDS_MI_INIT_ERR_THREADMGR, "Thread Mgr. Error occurred during initialisation %s" },
{ IDS_MI_INIT_ERR_CMDINTERPRETER, "Command interpreter. %s" },
{ IDS_MI_INIT_ERR_CMDMGR, "Command manager. %s" },
{ IDS_MI_INIT_ERR_CMDFACTORY, "Command factory. %s" },
@ -107,9 +111,10 @@ const CMICmnResources::SRsrcTextData CMICmnResources::ms_pResourceId2TextData[]
{ IDS_MI_INIT_ERR_THREADMANAGER, "Unable to init thread manager." },
{ IDS_CODE_ERR_INVALID_PARAMETER_VALUE, "Code. Invalid parameter passed to function '%s'" },
{ IDS_CODE_ERR_INVALID_PARAM_NULL_POINTER, "Code. NULL pointer passes as a parameter to function '%s'" },
{ IDS_CODE_ERR_INVALID_ENUMERATION_VALUE, "Code. Invalid enumeration value encountered in function '%s'" },
{ IDS_LLDBDEBUGGER_ERR_INVALIDLISTENER, "LLDB Debugger. LLDB Listener is not valid", },
{ IDS_LLDBDEBUGGER_ERR_INVALIDDEBUGGER, "LLDB Debugger. LLDB Debugger is not valid", },
{ IDS_LLDBDEBUGGER_ERR_CLIENTDRIVER, "LLDB Debugger. CMIDriverBase derived driver needs to be set prior to CMICmnLLDBDDebugger initialization" },
{ IDS_LLDBDEBUGGER_ERR_CLIENTDRIVER, "LLDB Debugger. CMIDriverBase derived driver needs to be set prior to CMICmnLLDBDDebugger initialisation" },
{ IDS_LLDBDEBUGGER_ERR_STARTLISTENER, "LLDB Debugger. Starting listening events for '%s' failed" },
{ IDS_LLDBDEBUGGER_ERR_THREADCREATIONFAIL, "LLDB Debugger. Thread creation failed '%s'" },
{ IDS_LLDBDEBUGGER_ERR_THREAD_DELETE, "LLDB Debugger. Thread failed to delete '%s'" },
@ -119,15 +124,21 @@ const CMICmnResources::SRsrcTextData CMICmnResources::ms_pResourceId2TextData[]
{ IDS_LLDBDEBUGGER_ERR_STOPLISTENER, "LLDB Debugger. Failure occurred stopping event for client '%s' SBBroadcaster '%s'" },
{ IDS_LLDBDEBUGGER_ERR_BROARDCASTER_NAME, "LLDB Debugger. Broardcaster's name '%s' is not valid" },
{ IDS_LLDBDEBUGGER_WRN_UNKNOWN_EVENT, "LLDB Debugger. Unhandled event '%s'" },
{ IDS_LLDBOUTOFBAND_ERR_UNKNOWN_EVENT, "LLDB Out-of-band. Handling event for '%s', an event enumeration '%d' not recognized" },
{ IDS_LLDBOUTOFBAND_ERR_UNKNOWN_EVENT, "LLDB Out-of-band. Handling event for '%s', an event enumeration '%d' not recognised" },
{ IDS_LLDBOUTOFBAND_ERR_PROCESS_INVALID, "LLDB Out-of-band. Invalid '%s' in '%s'" },
{ IDS_LLDBOUTOFBAND_ERR_BRKPT_NOTFOUND, "LLDB Out-of-band. %s. Breakpoint information for breakpoint ID %d not found" },
{ IDS_LLDBOUTOFBAND_ERR_BRKPT_INFO_GET, "LLDB Out-of-band. %s. Failed to retrieve breakpoint information for for breakpoint ID %d" },
{ IDS_LLDBOUTOFBAND_ERR_FORM_MI_RESPONSE, "LLDB Out-of-band. %s. Failed to form the MI Out-of-band response" },
{ IDS_LLDBOUTOFBAND_ERR_FRAME_INFO_GET, "LLDB Out-of-band. %s. Failed to retrieve frame information" },
{ IDS_LLDBOUTOFBAND_ERR_SETNEWDRIVERSTATE, "LLDB Out-of-band. %s. Event handler tried to set new MI Driver running state and failed. %s" },
{ IDS_DBGSESSION_ERR_SHARED_DATA_RELEASE, "LLDB debug session info. Release some or all of the data shared across command instances failed" },
{ IDS_DBGSESSION_ERR_SHARED_DATA_ADD, "LLDB debug session info. Failed to add '%s' data to the shared data command container" },
{ IDS_MI_SHTDWN_ERR_LOG, "Log. Error occurred during shutdown. %s" },
{ IDS_MI_SHUTDOWN_ERR, "Server shutdown failure. %s" },
{ IDE_MI_SHTDWN_ERR_RESOURCES, "Resources. Error occurred during shutdown. %s" },
{ IDE_MI_SHTDWN_ERR_STREAMSTDIN, "Stdin. Error occurred during shutdown. %s" },
{ IDS_MI_SHTDWN_ERR_STREAMSTDOUT, "Stdout. Error occurred during shutdown. %s" },
{ IDS_MI_SHTDWN_ERR_OS_STDIN_HANDLER, "Stdin handler. Error occurred during shutdown. %s" },
{ IDS_MI_SHTDWN_ERR_STREAMSTDOUT, "Stdout. Error occurred during shutdown. %s" },
{ IDS_MI_SHTDWN_ERR_STREAMSTDERR, "Stderr. Error occurred during shutdown. %s" },
{ IDS_MI_SHTDWN_ERR_THREADMGR, "Thread Mgr. Error occurred during shutdown. %s" },
{ IDS_MI_SHTDWN_ERR_CMDINTERPRETER, "Command interpreter. Error occurred during shutdown. %s" },
@ -150,6 +161,7 @@ const CMICmnResources::SRsrcTextData CMICmnResources::ms_pResourceId2TextData[]
{ IDS_DRIVER_ERR_FALLTHRU_DRIVER_ERR, "Driver. Fall through driver '%s' (ID:'%s') error '%s'" },
{ IDS_DRIVER_CMD_RECEIVED, "Driver. Received command '%s'. It was %shandled%s" },
{ IDS_DRIVER_CMD_NOT_IN_FACTORY, ". Command '%s' not in Command Factory" },
{ IDS_DRIVER_ERR_DRIVER_STATE_ERROR, "Driver. Driver running state error. Cannot go to next state from present state as not allowed", },
{ IDS_DRIVER_WAITING_STDIN_DATA, "Driver. Main thread suspended waiting on Stdin Monitor to resume main thread" },
{ IDS_STDOUT_ERR_NOT_ALL_DATA_WRITTEN, "Stdout. Not all data was written to stream. The data '%s'" },
{ IDS_STDERR_ERR_NOT_ALL_DATA_WRITTEN, "Stderr. Not all data was written to stream. The data '%s'" },
@ -159,16 +171,19 @@ const CMICmnResources::SRsrcTextData CMICmnResources::ms_pResourceId2TextData[]
{ IDS_CMD_ARGS_ERR_VALIDATION_INVALID, "Command Args. Validation failed. Invalid args: %s" },
{ IDS_CMD_ARGS_ERR_VALIDATION_MAN_INVALID, "Command Args. Validation failed. Mandatory args not found: %s. Invalid args: %s" },
{ IDS_CMD_ARGS_ERR_VALIDATION_MISSING_INF, "Command Args. Validation failed. Args missing additional information: %s." },
{ IDS_CMD_ARGS_ERR_CONTEXT_NOT_ALL_EATTEN, "Command Args. Validation failed. Not all arguments or options were recognized: %s" },
{ IDS_CMD_ARGS_ERR_CONTEXT_NOT_ALL_EATTEN, "Command Args. Validation failed. Not all arguments or options were recognised: %s" },
{ IDS_VARIANT_ERR_USED_BASECLASS, "Variant container: Variant object used the base class. See CMIUtilVariant" },
{ IDS_VARIANT_ERR_MAP_KEY_INVALID, "Variant container: Invalid ID '%s'" },
{ IDS_WORD_INVALIDBRKTS, "<Invalid>" },
{ IDS_WORD_NONE, "None" },
{ IDS_WORD_NOT, "not" },
{ IDS_WORD_INVALIDEMPTY, "<Empty>" },
{ IDS_WORD_INVALIDEMPTY, "<empty>" },
{ IDS_WORD_INVALIDNULLPTR, "<NULL ptr>" },
{ IDS_WORD_UNKNOWNBRKTS, "<unkown>" },
{ IDS_WORD_NOT_IMPLEMENTED, "Not implemented" },
{ IDS_WORD_NOT_IMPLEMENTED_BRKTS, "<not implemented>" },
{ IDS_WORD_UNKNOWNTYPE_BRKTS, "<unknowntype>" },
{ IDS_WORD_ERR_MSG_NOT_IMPLEMENTED_BRKTS, "<error message not implemented>" },
{ IDS_CMD_ERR_N_OPTIONS_REQUIRED, "Command '%s'. Missing options, %d required" },
{ IDS_CMD_ERR_OPTION_NOT_FOUND, "Command '%s'. Option '%s' not found" },
{ IDS_CMD_ERR_ARGS, "Command '%s'. %s" },
@ -179,11 +194,12 @@ const CMICmnResources::SRsrcTextData CMICmnResources::ms_pResourceId2TextData[]
{ IDS_CMD_ERR_SETWKDIR, "Command '%s'. Failed to set working directory '%s'" },
{ IDS_CMD_ERR_INVALID_TARGET, "Command '%s'. Target binary '%s' is invalid. %s" },
{ IDS_CMD_ERR_INVALID_TARGET_CURRENT, "Command '%s'. Current SBTarget is invalid" },
{ IDS_CMD_ERR_INVALID_TARGET_TYPE, "Command '%s'. Target type '%s' is not recognized" },
{ IDS_CMD_ERR_INVALID_TARGET_TYPE, "Command '%s'. Target type '%s' is not recognised" },
{ IDS_CMD_ERR_INVALID_TARGET_PLUGIN, "Command '%s'. Target plugin is invalid. %s" },
{ IDS_CMD_ERR_CONNECT_TO_TARGET, "Command '%s'. Error connecting to target: '%s'" },
{ IDS_CMD_ERR_INVALID_TARGETPLUGINCURRENT, "Command '%s'. Current target plugin is invalid" },
{ IDS_CMD_ERR_NOT_IMPLEMENTED, "Command '%s'. Command not implemented" },
{ IDS_CMD_ERR_NOT_IMPLEMENTED_DEPRECATED, "Command '%s'. Command not implemented as it has been deprecated" },
{ IDS_CMD_ERR_CREATE_TARGET, "Command '%s'. Create target failed: %s" },
{ IDS_CMD_ERR_BRKPT_LOCATION_FORMAT, "Command '%s'. Incorrect format for breakpoint location '%s'" },
{ IDS_CMD_ERR_BRKPT_INVALID, "Command '%s'. Breakpoint '%s' invalid" },
@ -195,8 +211,24 @@ const CMICmnResources::SRsrcTextData CMICmnResources::ms_pResourceId2TextData[]
{ IDS_CMD_ERR_VARIABLE_DOESNOTEXIST, "Command '%s'. Variable '%s' does not exist" },
{ IDS_CMD_ERR_VARIABLE_ENUM_INVALID, "Command '%s'. Invalid enumeration for variable '%s' formatted string '%s'" },
{ IDS_CMD_ERR_VARIABLE_EXPRESSIONPATH, "Command '%s'. Failed to get expression for variable '%s'" },
{ IDS_CMD_ERR_VARIABLE_CREATION_FAILED, "Command '%s'. Failed to create variable object for '%s'" }
};
{ IDS_CMD_ERR_VARIABLE_CREATION_FAILED, "Failed to create variable object for '%s'" },
{ IDS_CMD_ERR_CMD_RUN_BUT_NO_ACTION, "<Error: Command run but command did not do anything useful. No MI response formed>" },
{ IDS_CMD_ERR_EVENT_HANDLED_BUT_NO_ACTION, "<Error: Command run and event caught, did nothing useful. No MI Out-of-Bound formed>"},
{ IDS_CMD_ERR_DISASM_ADDR_START_INVALID, "Command '%s'. Invalid start value '%s'" },
{ IDS_CMD_ERR_DISASM_ADDR_END_INVALID, "Command '%s'. Invalid end value '%s'" },
{ IDS_CMD_ERR_MEMORY_ALLOC_FAILURE, "Command '%s'. Failed to allocate memory %d bytes" },
{ IDS_CMD_ERR_LLDB_ERR_NOT_READ_WHOLE_BLK, "Command '%s'. LLDB unable to read entire memory block of %u bytes at address 0x%08x" },
{ IDS_CMD_ERR_LLDB_ERR_READ_MEM_BYTES, "Command '%s'. Unable to read memory block of %u bytes at address 0x%08x: %s " },
{ IDS_CMD_ERR_INVALID_PROCESS, "Command '%s'. Invalid process during debug session" },
{ IDS_CMD_ERR_INVALID_FORMAT_TYPE, "Command '%s'. Invalid var format type '%s'" },
{ IDS_CMD_ERR_BRKPT_INFO_OBJ_NOT_FOUND, "Command '%s'. Breakpoint information for breakpoint ID %d not found" },
{ IDS_CMD_ERR_LLDB_ERR_READ_MEM_BYTES, "Command '%s'. Unable to write memory block of %u bytes at address 0x%08x: %s " },
{ IDS_CMD_ERR_LLDB_ERR_NOT_WRITE_WHOLEBLK, "Command '%s'. LLDB unable to write entire memory block of %u bytes at address 0x%08x" },
{ IDS_CMD_ERR_SET_NEW_DRIVER_STATE, "Command '%s'. Command tried to set new MI Driver running state and failed. %s" },
{ IDS_CMD_ERR_INFO_PRINTFN_NOT_FOUND, "The request '%s' was not recogised, not implemented" },
{ IDS_CMD_ERR_INFO_PRINTFN_FAILED, "The request '%s' failed." },
{ IDS_CMD_ERR_GDBSET_OPT_SOLIBSEARCHPATH, "'solib-search-path' requires at least one argument" }
};
//++ ------------------------------------------------------------------------------------
// Details: CMICmnResources constructor.
@ -298,7 +330,7 @@ bool CMICmnResources::ReadResourceStringData( void )
CMIUtilString CMICmnResources::GetString( const MIuint vResourceId ) const
{
CMIUtilString str;
const bool bFound = GetStringFromResource( vResourceId, str );
const bool bFound = GetStringFromResource( vResourceId, str ); MIunused( bFound );
assert( bFound );
return str;
@ -353,7 +385,7 @@ bool CMICmnResources::GetStringFromResource( const MIuint vResourceId, CMIUtilSt
}
}
const MIuint nRsrcId( (*it).first );
const MIuint nRsrcId( (*it).first ); MIunused( nRsrcId );
const MIchar * pRsrcData( (*it).second );
// Return result

View File

@ -32,7 +32,7 @@
//++ ============================================================================
// Details: MI string test data resource definitions. These IDs match up with
// actual string data in a map internal to CMICmnResources.
// *** Be sure to update ms_ppResourceId2TextData[] array ****
// *** Be sure to update ms_pResourceId2TextData[] array ****
enum
{
IDS_PROJNAME = 1,
@ -79,12 +79,15 @@ enum
IDE_MI_APP_EXIT_OK = 120,
IDE_MI_APP_EXIT_WITH_PROBLEM ,
IDE_MI_APP_EXIT_WITH_PROBLEM_NO_LOG ,
IDE_MI_APP_ARG_USAGE = 130,
IDE_MI_APP_ARG_HELP ,
IDE_MI_APP_ARG_VERSION ,
IDE_MI_APP_ARG_VERSION_LONG ,
IDE_MI_APP_ARG_INTERPRETER ,
IDE_MI_APP_ARG_NO_APP_LOG ,
IDE_MI_APP_ARG_EXAMPLE ,
IDS_STDIN_ERR_INVALID_PROMPT = 140,
IDS_STDIN_ERR_THREAD_CREATION_FAILED ,
@ -114,6 +117,8 @@ enum
IDS_MI_INIT_ERR_RESOURCES ,
IDS_MI_INIT_ERR_INIT ,
IDS_MI_INIT_ERR_STREAMSTDIN ,
IDS_MI_INIT_ERR_STREAMSTDIN_OSHANDLER ,
IDS_MI_INIT_ERR_OS_STDIN_HANDLER ,
IDS_MI_INIT_ERR_STREAMSTDOUT ,
IDS_MI_INIT_ERR_STREAMSTDERR ,
IDS_MI_INIT_ERR_FALLTHRUDRIVER ,
@ -132,6 +137,7 @@ enum
IDS_CODE_ERR_INVALID_PARAMETER_VALUE = 250,
IDS_CODE_ERR_INVALID_PARAM_NULL_POINTER ,
IDS_CODE_ERR_INVALID_ENUMERATION_VALUE ,
IDS_LLDBDEBUGGER_ERR_INVALIDLISTENER = 260,
IDS_LLDBDEBUGGER_ERR_INVALIDDEBUGGER ,
@ -148,14 +154,21 @@ enum
IDS_LLDBOUTOFBAND_ERR_UNKNOWN_EVENT = 280,
IDS_LLDBOUTOFBAND_ERR_PROCESS_INVALID ,
IDS_LLDBOUTOFBAND_ERR_BRKPT_NOTFOUND ,
IDS_LLDBOUTOFBAND_ERR_BRKPT_INFO_GET ,
IDS_LLDBOUTOFBAND_ERR_FORM_MI_RESPONSE ,
IDS_LLDBOUTOFBAND_ERR_FRAME_INFO_GET ,
IDS_LLDBOUTOFBAND_ERR_SETNEWDRIVERSTATE ,
IDS_DBGSESSION_ERR_SHARED_DATA_RELEASE = 290,
IDS_DBGSESSION_ERR_SHARED_DATA_RELEASE = 290,
IDS_DBGSESSION_ERR_SHARED_DATA_ADD ,
IDS_MI_SHTDWN_ERR_LOG = 340,
IDS_MI_SHUTDOWN_ERR ,
IDE_MI_SHTDWN_ERR_RESOURCES ,
IDE_MI_SHTDWN_ERR_STREAMSTDIN ,
IDS_MI_SHTDWN_ERR_OS_STDIN_HANDLER ,
IDS_MI_SHTDWN_ERR_STREAMSTDOUT ,
IDS_MI_SHTDWN_ERR_STREAMSTDERR ,
IDS_MI_SHTDWN_ERR_THREADMGR ,
@ -180,21 +193,25 @@ enum
IDS_DRIVER_ERR_FALLTHRU_DRIVER_ERR ,
IDS_DRIVER_CMD_RECEIVED ,
IDS_DRIVER_CMD_NOT_IN_FACTORY ,
IDS_DRIVER_ERR_DRIVER_STATE_ERROR ,
IDS_DRIVER_WAITING_STDIN_DATA = 410,
IDS_DRIVER_WAITING_STDIN_DATA = 420,
IDS_STDOUT_ERR_NOT_ALL_DATA_WRITTEN = 420,
IDS_STDERR_ERR_NOT_ALL_DATA_WRITTEN = 430,
IDS_STDOUT_ERR_NOT_ALL_DATA_WRITTEN = 430,
IDS_STDERR_ERR_NOT_ALL_DATA_WRITTEN = 440,
IDS_CMD_ARGS_ERR_N_OPTIONS_REQUIRED = 440,
IDS_CMD_ARGS_ERR_N_OPTIONS_REQUIRED = 450,
IDS_CMD_ARGS_ERR_OPTION_NOT_FOUND ,
IDS_CMD_ARGS_ERR_VALIDATION_MANDATORY ,
IDS_CMD_ARGS_ERR_VALIDATION_INVALID ,
IDS_CMD_ARGS_ERR_VALIDATION_MAN_INVALID ,
IDS_CMD_ARGS_ERR_VALIDATION_MISSING_INF ,
IDS_CMD_ARGS_ERR_CONTEXT_NOT_ALL_EATTEN ,
IDS_WORD_INVALIDBRKTS = 1000,
IDS_VARIANT_ERR_USED_BASECLASS = 460,
IDS_VARIANT_ERR_MAP_KEY_INVALID,
IDS_WORD_INVALIDBRKTS = 1000,
IDS_WORD_NONE ,
IDS_WORD_NOT ,
IDS_WORD_INVALIDEMPTY ,
@ -203,6 +220,7 @@ enum
IDS_WORD_NOT_IMPLEMENTED ,
IDS_WORD_NOT_IMPLEMENTED_BRKTS ,
IDS_WORD_UNKNOWNTYPE_BRKTS ,
IDS_WORD_ERR_MSG_NOT_IMPLEMENTED_BRKTS ,
IDS_CMD_ERR_N_OPTIONS_REQUIRED = 2000,
IDS_CMD_ERR_OPTION_NOT_FOUND ,
@ -219,6 +237,7 @@ enum
IDS_CMD_ERR_CONNECT_TO_TARGET ,
IDS_CMD_ERR_INVALID_TARGETPLUGINCURRENT ,
IDS_CMD_ERR_NOT_IMPLEMENTED ,
IDS_CMD_ERR_NOT_IMPLEMENTED_DEPRECATED ,
IDS_CMD_ERR_CREATE_TARGET ,
IDS_CMD_ERR_BRKPT_LOCATION_FORMAT ,
IDS_CMD_ERR_BRKPT_INVALID ,
@ -230,7 +249,23 @@ enum
IDS_CMD_ERR_VARIABLE_DOESNOTEXIST ,
IDS_CMD_ERR_VARIABLE_ENUM_INVALID ,
IDS_CMD_ERR_VARIABLE_EXPRESSIONPATH ,
IDS_CMD_ERR_VARIABLE_CREATION_FAILED
IDS_CMD_ERR_VARIABLE_CREATION_FAILED ,
IDS_CMD_ERR_CMD_RUN_BUT_NO_ACTION ,
IDS_CMD_ERR_EVENT_HANDLED_BUT_NO_ACTION ,
IDS_CMD_ERR_DISASM_ADDR_START_INVALID ,
IDS_CMD_ERR_DISASM_ADDR_END_INVALID ,
IDS_CMD_ERR_MEMORY_ALLOC_FAILURE ,
IDS_CMD_ERR_LLDB_ERR_NOT_READ_WHOLE_BLK ,
IDS_CMD_ERR_LLDB_ERR_READ_MEM_BYTES ,
IDS_CMD_ERR_INVALID_PROCESS ,
IDS_CMD_ERR_INVALID_FORMAT_TYPE ,
IDS_CMD_ERR_BRKPT_INFO_OBJ_NOT_FOUND ,
IDS_CMD_ERR_LLDB_ERR_WRITE_MEM_BYTES ,
IDS_CMD_ERR_LLDB_ERR_NOT_WRITE_WHOLEBLK ,
IDS_CMD_ERR_SET_NEW_DRIVER_STATE ,
IDS_CMD_ERR_INFO_PRINTFN_NOT_FOUND ,
IDS_CMD_ERR_INFO_PRINTFN_FAILED ,
IDS_CMD_ERR_GDBSET_OPT_SOLIBSEARCHPATH
};
//++ ============================================================================

View File

@ -194,3 +194,21 @@ bool CMICmnStreamStderr::Unlock( void )
m_mutex.Unlock();
return MIstatus::success;
}
//++ ------------------------------------------------------------------------------------
// Details: Take a text data and send to the stderr stream. Also output to the MI Log
// file.
// Type: Static method.
// Args: vrTxt - (R) Text.
// Return: MIstatus::success - Functionality succeeded.
// MIstatus::failure - Functionality failed.
// Throws: None.
//--
bool CMICmnStreamStderr::TextToStderr( const CMIUtilString & vrTxt )
{
const bool bLock = CMICmnStreamStderr::Instance().Lock();
const bool bOk = bLock && CMICmnStreamStderr::Instance().Write( vrTxt );
bLock && CMICmnStreamStderr::Instance().Unlock();
return bOk;
}

View File

@ -42,7 +42,11 @@ class CMICmnStreamStderr
{
friend class MI::ISingleton< CMICmnStreamStderr >;
// Methods:
// Statics:
public:
static bool TextToStderr( const CMIUtilString & vrTxt );
// Methods:
public:
bool Initialize( void );
bool Shutdown( void );

View File

@ -19,18 +19,6 @@
// Copyright: None.
//--
// Third Party Headers:
#if !defined( _MSC_VER )
#include <sys/select.h>
#include <termios.h>
#else
#include <stdio.h>
#include <Windows.h>
#include <io.h>
#include <conio.h>
#endif // !defined( _MSC_VER )
#include <string.h> // For std::strerror()
// In-house headers:
#include "MICmnStreamStdin.h"
#include "MICmnStreamStdout.h"
@ -41,6 +29,9 @@
#include "MIDriver.h"
#if defined( _MSC_VER )
#include "MIUtilSystemWindows.h"
#include "MICmnStreamStdinWindows.h"
#else
#include "MICmnStreamStdinLinux.h"
#endif // defined( _MSC_VER )
//++ ------------------------------------------------------------------------------------
@ -52,15 +43,12 @@
//--
CMICmnStreamStdin::CMICmnStreamStdin( void )
: m_constStrThisThreadname( "MI stdin thread" )
, m_constBufferSize( 1024 )
, m_pCmdBuffer( nullptr )
, m_pVisitor( nullptr )
, m_strPromptCurrent( "(gdb)" )
, m_bKeyCtrlCHit( false )
, m_pStdin( nullptr )
, m_bShowPrompt( false )
, m_bRedrawPrompt( true )
, m_pStdinBuffer( nullptr )
, m_pStdinReadHandler( nullptr )
{
}
@ -93,29 +81,33 @@ bool CMICmnStreamStdin::Initialize( void )
bool bOk = MIstatus::success;
CMIUtilString errMsg;
// 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 );
// 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 );
MI::ModuleInit< CMICmnThreadMgrStd >( IDS_MI_INIT_ERR_THREADMGR, bOk, errMsg );
#ifdef _MSC_VER
MI::ModuleInit< CMICmnStreamStdinWindows >( IDS_MI_INIT_ERR_OS_STDIN_HANDLER, bOk, errMsg );
bOk = bOk && SetOSStdinHandler( CMICmnStreamStdinWindows::Instance() );
#else
MI::ModuleInit< CMICmnStreamStdinLinux >( IDS_MI_INIT_ERR_OS_STDIN_HANDLER, bOk, errMsg );
bOk = bOk && SetOSStdinHandler( CMICmnStreamStdinLinux::Instance() );
#endif // ( _MSC_VER )
// The OS specific stdin stream handler must be set before *this class initialises
if( bOk && m_pStdinReadHandler == nullptr )
{
CMIUtilString strInitError( CMIUtilString::Format( MIRSRC( IDS_MI_INIT_ERR_STREAMSTDIN_OSHANDLER ), errMsg.c_str() ) );
SetErrorDescription( strInitError );
return MIstatus::failure;
}
// Other resources required
if( bOk )
{
m_pCmdBuffer = new MIchar[ m_constBufferSize ];
m_bKeyCtrlCHit = false; // Reset
m_pStdin = stdin;
#if MICONFIG_CREATE_OWN_STDIN_BUFFER
// Give stdinput a user defined buffer
m_pStdinBuffer = new char[ 1024 ];
::setbuf( stdin, m_pStdinBuffer );
#endif // MICONFIG_CREATE_OWN_STDIN_BUFFER
}
// Clear error indicators for std input
clearerr( stdin );
m_bInitialized = bOk;
if( !bOk )
@ -151,29 +143,22 @@ bool CMICmnStreamStdin::Shutdown( void )
bool bOk = MIstatus::success;
CMIUtilString errMsg;
if( m_pCmdBuffer != nullptr )
{
delete [] m_pCmdBuffer;
m_pCmdBuffer = nullptr;
}
m_pVisitor = nullptr;
m_bKeyCtrlCHit = false;
m_pStdin = nullptr;
#if MICONFIG_CREATE_OWN_STDIN_BUFFER
if ( m_pStdinBuffer )
delete [] m_pStdinBuffer;
m_pStdinBuffer = nullptr;
#endif // MICONFIG_CREATE_OWN_STDIN_BUFFER
// Note shutdown order is important here
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 );
#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( IDS_MI_SHUTDOWN_ERR ), errMsg.c_str() );
SetErrorDescriptionn( MIRSRC( IDE_MI_SHTDWN_ERR_STREAMSTDIN ), errMsg.c_str() );
}
return MIstatus::success;
@ -266,60 +251,9 @@ bool CMICmnStreamStdin::GetEnablePrompt( void ) const
// MIstatus::failure - Functional failed.
// Throws: None.
//--
bool CMICmnStreamStdin::InputAvailable( bool & vwbAvail ) const
bool CMICmnStreamStdin::InputAvailable( bool & vwbAvail )
{
// Windows method to check how many bytes are in stdin
#ifdef _MSC_VER
// Get a windows handle to std input stream
HANDLE handle = ::GetStdHandle( STD_INPUT_HANDLE );
DWORD nBytesWaiting = 0;
// If running in a terminal use _kbhit()
if( ::_isatty( ::fileno( stdin ) ) )
nBytesWaiting = ::_kbhit();
else
{
// Ask how many bytes are available
if( ::PeekNamedPipe( handle, nullptr, 0, nullptr, &nBytesWaiting, nullptr ) == FALSE )
{
// This can occur when the client i.e. Eclipse closes the stdin stream 'cause it deems its work is finished
// for that debug session. May be we should be handling SIGKILL somehow?
const CMIUtilString osErrMsg( CMIUtilSystemWindows().GetOSLastError().StripCRAll() );
SetErrorDescription( CMIUtilString::Format( MIRSRC( IDS_STDIN_ERR_CHKING_BYTE_AVAILABLE ), osErrMsg.c_str() ) );
return MIstatus::failure;
}
}
// Return the number of bytes waiting
vwbAvail = (nBytesWaiting > 0);
return MIstatus::success;
// Unix method to check how many bytes are in stdin
#else
/* AD: disable while porting to linux
static const int STDIN = 0;
static bool bInitialized = false;
if( !bInitialized )
{
// Use termios to turn off line buffering
::termios term;
::tcgetattr( STDIN, &term );
::term.c_lflag &= ~ICANON;
::tcsetattr( STDIN, TCSANOW, &term );
::setbuf( stdin, NULL );
bInitialized = true;
}
int nBytesWaiting;
::ioctl( STDIN, FIONREAD, &nBytesWaiting );
vwbAvail = (nBytesWaiting > 0);
return MIstatus::success;
*/
return MIstatus::success;
#endif // _MSC_VER
return m_pStdinReadHandler->InputAvailable( vwbAvail );
}
//++ ------------------------------------------------------------------------------------
@ -328,12 +262,12 @@ bool CMICmnStreamStdin::InputAvailable( bool & vwbAvail ) const
// true for bYesExit flag. Errors output to log file.
// This function runs in the thread "MI stdin monitor".
// Type: Method.
// vrbYesExit - (W) True = yes exit stdin monitoring, false = continue monitor.
// 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 & vrbYesExit )
bool CMICmnStreamStdin::MonitorStdin( bool & vrwbYesAlive )
{
if( m_bShowPrompt )
{
@ -342,11 +276,19 @@ bool CMICmnStreamStdin::MonitorStdin( bool & vrbYesExit )
m_bRedrawPrompt = false;
}
// CODETAG_DEBUG_SESSION_RUNNING_PROG_RECEIVED_SIGINT_PAUSE_PROGRAM
if( m_bKeyCtrlCHit )
{
vrbYesExit = true;
CMIDriver::Instance().SetExitApplicationFlag();
return MIstatus::failure;
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
@ -360,8 +302,8 @@ bool CMICmnStreamStdin::MonitorStdin( bool & vrbYesExit )
}
else
{
vrbYesExit = true;
CMIDriver::Instance().SetExitApplicationFlag();
vrwbYesAlive = false;
CMIDriver::Instance().SetExitApplicationFlag( true );
return MIstatus::failure;
}
#endif // MICONFIG_POLL_FOR_STD_IN
@ -376,7 +318,7 @@ bool CMICmnStreamStdin::MonitorStdin( bool & vrbYesExit )
{
if( bHaveError )
{
CMICmnStreamStdout::Instance().Write( pText );
CMICmnStreamStdout::Instance().Write( stdinErrMsg );
}
return MIstatus::failure;
}
@ -385,8 +327,10 @@ bool CMICmnStreamStdin::MonitorStdin( bool & vrbYesExit )
bool bOk = MIstatus::success;
if( m_pVisitor != nullptr )
{
bOk = m_pVisitor->ReadLine( CMIUtilString( pText ), vrbYesExit );
bool bYesExit = false;
bOk = m_pVisitor->ReadLine( CMIUtilString( pText ), bYesExit );
m_bRedrawPrompt = true;
vrwbYesAlive = !bYesExit;
}
return bOk;
@ -401,28 +345,7 @@ bool CMICmnStreamStdin::MonitorStdin( bool & vrbYesExit )
//--
const MIchar * CMICmnStreamStdin::ReadLine( CMIUtilString & vwErrMsg )
{
vwErrMsg.clear();
// Read user input
const MIchar * pText = ::fgets( &m_pCmdBuffer[ 0 ], m_constBufferSize, stdin );
if( pText == nullptr )
{
if( ::ferror( m_pStdin ) != 0 )
vwErrMsg = ::strerror( errno );
return nullptr;
}
// Strip off new line characters
for( MIchar * pI = m_pCmdBuffer; *pI != '\0'; pI++ )
{
if( (*pI == '\n') || (*pI == '\r') )
{
*pI = '\0';
break;
}
}
return pText;
return m_pStdinReadHandler->ReadLine( vwErrMsg );
}
//++ ------------------------------------------------------------------------------------
@ -475,7 +398,24 @@ bool CMICmnStreamStdin::ThreadFinish( void )
// Return: CMIUtilString & - Text.
// Throws: None.
//--
const CMIUtilString &CMICmnStreamStdin::ThreadGetName( void ) const
const CMIUtilString & CMICmnStreamStdin::ThreadGetName( void ) const
{
return m_constStrThisThreadname;
}
//++ ------------------------------------------------------------------------------------
// Details: Mandatory set the OS specific stream stdin handler. *this class utilises the
// handler to read data from the stdin stream and put into a queue for the
// driver to read when able.
// Type: Method.
// Args: None.
// Return: MIstatus::success - Functional succeeded.
// MIstatus::failure - Functional failed.
// Throws: None.
//--
bool CMICmnStreamStdin::SetOSStdinHandler( IOSStdinHandler & vrHandler )
{
m_pStdinReadHandler = &vrHandler;
return MIstatus::success;
}

View File

@ -31,12 +31,11 @@
// Details: MI common code class. Used to handle stream data from Stdin.
// Singleton class using the Visitor pattern. A driver using the interface
// provide can receive callbacks when a new line of data is received.
// Each line is determined by a carriage return. Function WaitOnStdin()
// monitors the Stdin stream.
// Each line is determined by a carriage return.
// A singleton class.
// Gotchas: None.
// Authors: Illya Rudkin 10/02/2014.
// Changes: None.
// Changes: Factored out OS specific handling of reading stdin - IOR 16/06/2014.
//--
class CMICmnStreamStdin
: public CMICmnBase
@ -55,10 +54,24 @@ public:
class IStreamStdin
{
public:
virtual bool ReadLine( const CMIUtilString & vStdInBuffer, bool & vbYesExit ) = 0;
virtual bool ReadLine( const CMIUtilString & vStdInBuffer, bool & vrwbYesExit ) = 0;
/* dtor */ virtual ~IStreamStdin( void ) {};
};
//++
// Description: Specific OS stdin handling implementations are created and used by *this
// class. Seperates out functionality and enables handler to be set
// dynamically depended on the OS detected.
//--
class IOSStdinHandler
{
public:
virtual bool InputAvailable( bool & vwbAvail ) = 0;
virtual const MIchar * ReadLine( CMIUtilString & vwErrMsg ) = 0;
/* dtor */ virtual ~IOSStdinHandler( void ) {};
};
// Methods:
public:
@ -71,6 +84,7 @@ public:
bool GetEnablePrompt( void ) const;
void SetCtrlCHit( void );
bool SetVisitor( IStreamStdin & vrVisitor );
bool SetOSStdinHandler( IOSStdinHandler & vrHandler );
// Overridden:
public:
@ -81,7 +95,7 @@ public:
protected:
// From CMIUtilThreadActiveObjBase
virtual bool ThreadRun( bool & vrIsAlive );
virtual bool ThreadFinish( void ); // Let this thread clean up after itself
virtual bool ThreadFinish( void ); // Let this thread clean up after itself
// Methods:
private:
@ -89,9 +103,9 @@ private:
/* ctor */ CMICmnStreamStdin( const CMICmnStreamStdin & );
void operator=( const CMICmnStreamStdin & );
bool MonitorStdin( bool & vrbYesExit );
bool MonitorStdin( bool & vrwbYesExit );
const MIchar * ReadLine( CMIUtilString & vwErrMsg );
bool InputAvailable( bool & vbAvail ) const; // Bytes are available on stdin
bool InputAvailable( bool & vbAvail ); // Bytes are available on stdin
// Overridden:
private:
@ -101,14 +115,11 @@ private:
// Attributes:
private:
const CMIUtilString m_constStrThisThreadname;
const MIuint m_constBufferSize;
MIchar * m_pCmdBuffer;
IStreamStdin * m_pVisitor;
CMIUtilString m_strPromptCurrent; // Command line prompt as shown to the user
volatile bool m_bKeyCtrlCHit; // True = User hit Ctrl-C, false = has not yet
FILE * m_pStdin;
bool m_bShowPrompt; // True = Yes prompt is shown/output to the user (stdout), false = no prompt
bool m_bRedrawPrompt; // True = Prompt needs to be redrawn
MIchar * m_pStdinBuffer; // Custom buffer to store std input
IOSStdinHandler * m_pStdinReadHandler;
};

View File

@ -0,0 +1,214 @@
//===-- MICmnStreamStdinLinux.cpp --------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//++
// File: MIUtilStreamStdin.cpp
//
// Overview: CMICmnStreamStdinLinux implementation.
//
// Environment: Compilers: Visual C++ 12.
// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
// Libraries: See MIReadmetxt.
//
// Copyright: None.
//--
// Third Party Headers:
#if !defined( _MSC_VER )
#include <sys/select.h>
#include <termios.h>
#include <stropts.h>
#endif // !defined( _MSC_VER )
#include <string.h> // For std::strerror()
// In-house headers:
#include "MICmnStreamStdinLinux.h"
#include "MICmnLog.h"
#include "MICmnResources.h"
#include "MIUtilSingletonHelper.h"
//++ ------------------------------------------------------------------------------------
// Details: CMICmnStreamStdinLinux constructor.
// Type: Method.
// Args: None.
// Return: None.
// Throws: None.
//--
CMICmnStreamStdinLinux::CMICmnStreamStdinLinux( void )
: m_constBufferSize( 1024 )
, m_pStdin( nullptr )
, m_pCmdBuffer( nullptr )
{
}
//++ ------------------------------------------------------------------------------------
// Details: CMICmnStreamStdinLinux destructor.
// Type: Overridable.
// Args: None.
// Return: None.
// Throws: None.
//--
CMICmnStreamStdinLinux::~CMICmnStreamStdinLinux( void )
{
Shutdown();
}
//++ ------------------------------------------------------------------------------------
// Details: Initialize resources for *this Stdin stream.
// Type: Method.
// Args: None.
// Return: MIstatus::success - Functional succeeded.
// MIstatus::failure - Functional failed.
// Throws: None.
//--
bool CMICmnStreamStdinLinux::Initialize( void )
{
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 );
// Other resources required
if( bOk )
{
m_pCmdBuffer = new MIchar[ m_constBufferSize ];
m_pStdin = stdin;
}
// Clear error indicators for std input
::clearerr( stdin );
m_bInitialized = bOk;
if( !bOk )
{
CMIUtilString strInitError( CMIUtilString::Format( MIRSRC( IDS_MI_INIT_ERR_OS_STDIN_HANDLER ), errMsg.c_str() ) );
SetErrorDescription( strInitError );
return MIstatus::failure;
}
return MIstatus::success;
}
//++ ------------------------------------------------------------------------------------
// Details: Release resources for *this Stdin stream.
// Type: Method.
// Args: None.
// Return: MIstatus::success - Functional succeeded.
// MIstatus::failure - Functional failed.
// Throws: None.
//--
bool CMICmnStreamStdinLinux::Shutdown( void )
{
if( !m_bInitialized )
return MIstatus::success;
m_bInitialized = false;
ClrErrorDescription();
bool bOk = MIstatus::success;
CMIUtilString errMsg;
// Tidy up
if( m_pCmdBuffer != nullptr )
{
delete [] m_pCmdBuffer;
m_pCmdBuffer = nullptr;
}
m_pStdin = nullptr;
// Note shutdown order is important here
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_OS_STDIN_HANDLER ), errMsg.c_str() );
}
return MIstatus::success;
}
//++ ------------------------------------------------------------------------------------
// Details: Determine if stdin has any characters present in its buffer.
// Type: Method.
// Args: vwbAvail - (W) True = There is chars available, false = nothing there.
// Return: MIstatus::success - Functional succeeded.
// MIstatus::failure - Functional failed.
// Throws: None.
//--
bool CMICmnStreamStdinLinux::InputAvailable( bool & vwbAvail )
{
#ifndef _MSC_VER
/* AD: Not used ATM but could come in handy just in case we need to do
this, poll for input
static const int STDIN = 0;
static bool bInitialized = false;
if( !bInitialized )
{
// Use termios to turn off line buffering
::termios term;
::tcgetattr( STDIN, &term );
::term.c_lflag &= ~ICANON;
::tcsetattr( STDIN, TCSANOW, &term );
::setbuf( stdin, NULL );
bInitialized = true;
}
int nBytesWaiting;
::ioctl( STDIN, FIONREAD, &nBytesWaiting );
vwbAvail = (nBytesWaiting > 0);
return MIstatus::success;
*/
#endif // ifndef _MSC_VER
return MIstatus::success;
}
//++ ------------------------------------------------------------------------------------
// Details: Wait on new line of data from stdin stream (completed by '\n' or '\r').
// Type: Method.
// Args: vwErrMsg - (W) Empty string ok or error description.
// Return: MIchar * - text buffer pointer or NULL on failure.
// Throws: None.
//--
const MIchar * CMICmnStreamStdinLinux::ReadLine( CMIUtilString & vwErrMsg )
{
vwErrMsg.clear();
// Read user input
const MIchar * pText = ::fgets( &m_pCmdBuffer[ 0 ], m_constBufferSize, stdin );
if( pText == nullptr )
{
if( ::ferror( m_pStdin ) != 0 )
vwErrMsg = ::strerror( errno );
return nullptr;
}
// Strip off new line characters
for( MIchar * pI = m_pCmdBuffer; *pI != '\0'; pI++ )
{
if( (*pI == '\n') || (*pI == '\r') )
{
*pI = '\0';
break;
}
}
return pText;
}

View File

@ -0,0 +1,75 @@
//===-- MICmnStreamStdinWindows.h --------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//++
// File: MIUtilStreamStdin.h
//
// Overview: CMICmnStreamStdinLinux interface.
//
// Environment: Compilers: Visual C++ 12.
// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
// Libraries: See MIReadmetxt.
//
// Copyright: None.
//--
#pragma once
// In-house headers:
#include "MICmnBase.h"
#include "MICmnStreamStdin.h"
#include "MIUtilSingletonBase.h"
//++ ============================================================================
// Details: MI common code class. Specific OS stdin handling implementation.
// CMICmnStreamStdin instance is set with stdin handler before using the
// the stream. An instance of this class must be set up and ready to give
// to the CMICmnStreamStdin before it initialises other CMICmnStreamStdin
// will give an error.
// Gotchas: None.
// Authors: Illya Rudkin 16/06/2014.
// Changes: None.
//--
class CMICmnStreamStdinLinux
: public CMICmnBase
, public CMICmnStreamStdin::IOSStdinHandler
, public MI::ISingleton< CMICmnStreamStdinLinux >
{
// Give singleton access to private constructors
friend MI::ISingleton< CMICmnStreamStdinLinux >;
// Methods:
public:
bool Initialize( void );
bool Shutdown( void );
// Overridden:
public:
// From CMICmnStreamStdin::IOSpecificReadStreamStdin
virtual bool InputAvailable( bool & vwbAvail );
virtual const MIchar * ReadLine( CMIUtilString & vwErrMsg );
// Methods:
private:
/* ctor */ CMICmnStreamStdinLinux( void );
/* ctor */ CMICmnStreamStdinLinux( const CMICmnStreamStdin & );
void operator=( const CMICmnStreamStdin & );
// Overridden:
private:
// From CMICmnBase
/* dtor */ virtual ~CMICmnStreamStdinLinux( void );
// Attributes:
private:
const MIuint m_constBufferSize;
FILE * m_pStdin;
MIchar * m_pCmdBuffer;
};

View File

@ -0,0 +1,287 @@
//===-- MICmnStreamStdinWindows.cpp -----------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//++
// File: MIUtilStreamStdin.cpp
//
// Overview: CMICmnStreamStdinWindows implementation.
//
// Environment: Compilers: Visual C++ 12.
// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
// Libraries: See MIReadmetxt.
//
// Copyright: None.
//--
// Third Party Headers:
#if defined( _MSC_VER )
#include <stdio.h>
#include <Windows.h>
#include <io.h>
#include <conio.h>
#endif // defined( _MSC_VER )
#include <string.h>
// In-house headers:
#include "MICmnStreamStdinWindows.h"
#include "MICmnLog.h"
#include "MICmnResources.h"
#include "MIUtilSystemWindows.h"
#include "MIUtilSingletonHelper.h"
//++ ------------------------------------------------------------------------------------
// Details: CMICmnStreamStdinWindows constructor.
// Type: Method.
// Args: None.
// Return: None.
// Throws: None.
//--
CMICmnStreamStdinWindows::CMICmnStreamStdinWindows( void )
: m_constBufferSize( 1024 )
, m_pStdin( nullptr )
, m_pCmdBuffer( nullptr )
, m_pStdinBuffer( nullptr )
, m_nBytesToBeRead( 0 )
, m_bRunningInConsoleWin( false )
{
}
//++ ------------------------------------------------------------------------------------
// Details: CMICmnStreamStdinWindows destructor.
// Type: Overridable.
// Args: None.
// Return: None.
// Throws: None.
//--
CMICmnStreamStdinWindows::~CMICmnStreamStdinWindows( void )
{
Shutdown();
}
//++ ------------------------------------------------------------------------------------
// Details: Initialize resources for *this Stdin stream.
// Type: Method.
// Args: None.
// Return: MIstatus::success - Functional succeeded.
// MIstatus::failure - Functional failed.
// Throws: None.
//--
bool CMICmnStreamStdinWindows::Initialize( void )
{
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 );
// Other resources required
if( bOk )
{
m_pCmdBuffer = new MIchar[ m_constBufferSize ];
m_pStdin = stdin;
#if MICONFIG_CREATE_OWN_STDIN_BUFFER
// Give stdinput a user defined buffer
m_pStdinBuffer = new char[ 1024 ];
::setbuf( stdin, m_pStdinBuffer );
#endif // MICONFIG_CREATE_OWN_STDIN_BUFFER
// Clear error indicators for std input
::clearerr( stdin );
}
if( bOk )
{
#if defined( _MSC_VER )
m_bRunningInConsoleWin = ::_isatty( ::fileno( stdin ) );
#endif // #if defined( _MSC_VER )
}
m_bInitialized = bOk;
if( !bOk )
{
CMIUtilString strInitError( CMIUtilString::Format( MIRSRC( IDS_MI_INIT_ERR_OS_STDIN_HANDLER ), errMsg.c_str() ) );
SetErrorDescription( strInitError );
return MIstatus::failure;
}
return MIstatus::success;
}
//++ ------------------------------------------------------------------------------------
// Details: Release resources for *this Stdin stream.
// Type: Method.
// Args: None.
// Return: MIstatus::success - Functional succeeded.
// MIstatus::failure - Functional failed.
// Throws: None.
//--
bool CMICmnStreamStdinWindows::Shutdown( void )
{
if( !m_bInitialized )
return MIstatus::success;
m_bInitialized = false;
ClrErrorDescription();
bool bOk = MIstatus::success;
CMIUtilString errMsg;
// Tidy up
if( m_pCmdBuffer != nullptr )
{
delete [] m_pCmdBuffer;
m_pCmdBuffer = nullptr;
}
m_pStdin = nullptr;
#if MICONFIG_CREATE_OWN_STDIN_BUFFER
if ( m_pStdinBuffer )
delete [] m_pStdinBuffer;
m_pStdinBuffer = nullptr;
#endif // MICONFIG_CREATE_OWN_STDIN_BUFFER
// Note shutdown order is important here
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_OS_STDIN_HANDLER ), errMsg.c_str() );
}
return MIstatus::success;
}
//++ ------------------------------------------------------------------------------------
// Details: Determine if stdin has any characters present in its buffer.
// Type: Method.
// Args: vwbAvail - (W) True = There is chars available, false = nothing there.
// Return: MIstatus::success - Functional succeeded.
// MIstatus::failure - Functional failed.
// Throws: None.
//--
bool CMICmnStreamStdinWindows::InputAvailable( bool & vwbAvail )
{
#ifdef _MSC_VER
return m_bRunningInConsoleWin ? InputAvailableConsoleWin( vwbAvail ) : InputAvailableApplication( vwbAvail );
#else
// Do nothing
return MIstatus::success;
#endif // ifdef _MSC_VER
}
//++ ------------------------------------------------------------------------------------
// Details: Determine if stdin has any characters present in its buffer. If running in a
// terminal use _kbhit().
// Type: Method.
// Args: vwbAvail - (W) True = There is chars available, false = nothing there.
// Return: MIstatus::success - Functional succeeded.
// MIstatus::failure - Functional failed.
// Throws: None.
//--
bool CMICmnStreamStdinWindows::InputAvailableConsoleWin( bool & vwbAvail )
{
#ifdef _MSC_VER
if( m_nBytesToBeRead == 0 )
{
// Get a windows handle to std input stream
HANDLE handle = ::GetStdHandle( STD_INPUT_HANDLE );
DWORD nBytesWaiting = ::_kbhit();
// Save the number of bytes to be read so that we can check if input is available to be read
m_nBytesToBeRead = nBytesWaiting;
// Return state of whether bytes are waiting or not
vwbAvail = (nBytesWaiting > 0);
}
#endif // ifdef _MSC_VER
return MIstatus::success;
}
//++ ------------------------------------------------------------------------------------
// Details: Determine if stdin has any characters present in its buffer.
// Type: Method.
// Args: vwbAvail - (W) True = There is chars available, false = nothing there.
// Return: MIstatus::success - Functional succeeded.
// MIstatus::failure - Functional failed.
// Throws: None.
//--
bool CMICmnStreamStdinWindows::InputAvailableApplication( bool & vwbAvail )
{
#ifdef _MSC_VER
if( m_nBytesToBeRead == 0 )
{
// Get a windows handle to std input stream
HANDLE handle = ::GetStdHandle( STD_INPUT_HANDLE );
DWORD nBytesWaiting = 0;
// Ask how many bytes are available
if( ::PeekNamedPipe( handle, nullptr, 0, nullptr, &nBytesWaiting, nullptr ) == FALSE )
{
// This can occur when the client i.e. Eclipse closes the stdin stream 'cause it deems its work is finished
// for that debug session. May be we should be handling SIGKILL somehow?
const CMIUtilString osErrMsg( CMIUtilSystemWindows().GetOSLastError().StripCRAll() );
SetErrorDescription( CMIUtilString::Format( MIRSRC( IDS_STDIN_ERR_CHKING_BYTE_AVAILABLE ), osErrMsg.c_str() ) );
return MIstatus::failure;
}
// Save the number of bytes to be read so that we can check if input is available to be read
m_nBytesToBeRead = nBytesWaiting;
// Return state of whether bytes are waiting or not
vwbAvail = (nBytesWaiting > 0);
}
#endif // ifdef _MSC_VER
return MIstatus::success;
}
//++ ------------------------------------------------------------------------------------
// Details: Wait on new line of data from stdin stream (completed by '\n' or '\r').
// Type: Method.
// Args: vwErrMsg - (W) Empty string ok or error description.
// Return: MIchar * - text buffer pointer or NULL on failure.
// Throws: None.
//--
const MIchar * CMICmnStreamStdinWindows::ReadLine( CMIUtilString & vwErrMsg )
{
vwErrMsg.clear();
// Read user input
const MIchar * pText = ::fgets( &m_pCmdBuffer[ 0 ], m_constBufferSize, stdin );
if( pText == nullptr )
{
if( ::ferror( m_pStdin ) != 0 )
vwErrMsg = ::strerror( errno );
return nullptr;
}
// Subtract the number of bytes read so that we can check if input is available to be read
m_nBytesToBeRead = m_nBytesToBeRead - ::strlen( pText );
// Strip off new line characters
for( MIchar * pI = m_pCmdBuffer; *pI != '\0'; pI++ )
{
if( (*pI == '\n') || (*pI == '\r') )
{
*pI = '\0';
break;
}
}
return pText;
}

View File

@ -0,0 +1,81 @@
//===-- MICmnStreamStdinWindows.h -------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//++
// File: MIUtilStreamStdin.h
//
// Overview: CMICmnStreamStdinWindows interface.
//
// Environment: Compilers: Visual C++ 12.
// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
// Libraries: See MIReadmetxt.
//
// Copyright: None.
//--
#pragma once
// In-house headers:
#include "MICmnBase.h"
#include "MICmnStreamStdin.h"
#include "MIUtilSingletonBase.h"
//++ ============================================================================
// Details: MI common code class. Specific OS stdin handling implementation.
// CMICmnStreamStdin instance is set with stdin handler before using the
// the stream. An instance of this class must be set up and ready to give
// to the CMICmnStreamStdin before it initialises other CMICmnStreamStdin
// will give an error.
// Gotchas: None.
// Authors: Illya Rudkin 16/06/2014.
// Changes: None.
//--
class CMICmnStreamStdinWindows
: public CMICmnBase
, public CMICmnStreamStdin::IOSStdinHandler
, public MI::ISingleton< CMICmnStreamStdinWindows >
{
// Give singleton access to private constructors
friend MI::ISingleton< CMICmnStreamStdinWindows >;
// Methods:
public:
bool Initialize( void );
bool Shutdown( void );
// Overridden:
public:
// From CMICmnStreamStdin::IOSpecificReadStreamStdin
virtual bool InputAvailable( bool & vwbAvail );
virtual const MIchar * ReadLine( CMIUtilString & vwErrMsg );
// Methods:
private:
/* ctor */ CMICmnStreamStdinWindows( void );
/* ctor */ CMICmnStreamStdinWindows( const CMICmnStreamStdinWindows & );
void operator=( const CMICmnStreamStdinWindows & );
//
bool InputAvailableConsoleWin( bool & vwbAvail );
bool InputAvailableApplication( bool & vwbAvail );
// Overridden:
private:
// From CMICmnBase
/* dtor */ virtual ~CMICmnStreamStdinWindows( void );
// Attributes:
private:
const MIuint m_constBufferSize;
FILE * m_pStdin;
MIchar * m_pCmdBuffer;
MIchar * m_pStdinBuffer; // Custom buffer to store std input
MIuint m_nBytesToBeRead; // Checks that ::fgets() is holding on to data while ::PeekNamedPipe() returns nothing which causes a problem
bool m_bRunningInConsoleWin; // True = The application is being run in a Windows command line prompt window, false = by other means
};

View File

@ -210,3 +210,21 @@ bool CMICmnStreamStdout::Unlock( void )
m_mutex.Unlock();
return MIstatus::success;
}
//++ ------------------------------------------------------------------------------------
// Details: Take a text data and send to the stdout stream. Also output to the MI Log
// file.
// Type: Static method.
// Args: vrTxt - (R) Text.
// Return: MIstatus::success - Functionality succeeded.
// MIstatus::failure - Functionality failed.
// Throws: None.
//--
bool CMICmnStreamStdout::TextToStdout( const CMIUtilString & vrTxt )
{
const bool bLock = CMICmnStreamStdout::Instance().Lock();
const bool bOk = bLock && CMICmnStreamStdout::Instance().WriteMIResponse( vrTxt );
bLock && CMICmnStreamStdout::Instance().Unlock();
return bOk;
}

View File

@ -42,6 +42,10 @@ class CMICmnStreamStdout
{
friend class MI::ISingleton< CMICmnStreamStdout >;
// Statics:
public:
static bool TextToStdout( const CMIUtilString & vrTxt );
// Methods:
public:
bool Initialize( void );

View File

@ -20,7 +20,6 @@
//--
// In-house headers:
#include "MICmnConfig.h"
#include "MICmnThreadMgrStd.h"
#include "MICmnLog.h"
#include "MICmnResources.h"
@ -50,7 +49,7 @@ CMICmnThreadMgrStd::~CMICmnThreadMgrStd( void )
}
//++ ------------------------------------------------------------------------------------
// Details: Initialize resources for *this thread manager.
// Details: Initialise resources for *this thread manager.
// Type: Method.
// Args: None.
// Return: MIstatus::success - Functional succeeded.
@ -69,7 +68,7 @@ bool CMICmnThreadMgrStd::Initialize( void )
ClrErrorDescription();
CMIUtilString errMsg;
// Note initialization order is important here as some resources depend on previous
// 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 );
@ -133,16 +132,11 @@ bool CMICmnThreadMgrStd::Shutdown( void )
//--
bool CMICmnThreadMgrStd::ThreadAllTerminate( void )
{
// Find an iterator object for the list
ThreadList_t::const_iterator it = m_threadList.begin();
// Loop over all entries in the list
for( ; it != m_threadList.end(); ++it )
{
// Get the thread object from the list
CMIUtilThreadActiveObjBase * pThread = *it;
// If the thread is still running
CMIUtilThreadActiveObjBase * pThread = *it;
if( pThread->ThreadIsActive() )
{
// Ask this thread to kill itself
@ -167,7 +161,6 @@ bool CMICmnThreadMgrStd::ThreadAllTerminate( void )
//--
bool CMICmnThreadMgrStd::AddThread( const CMIUtilThreadActiveObjBase & vrObj )
{
// Push this thread onto the thread list
m_threadList.push_back( const_cast< CMIUtilThreadActiveObjBase * >( &vrObj ) );
return MIstatus::success;

View File

@ -22,13 +22,10 @@
#pragma once
// Third party headers:
#include <map>
#include <vector>
// In-house headers:
#include "MICmnConfig.h"
#include "MICmnBase.h"
#include "MIUtilSetID.h"
#include "MIUtilThreadBaseStd.h"
#include "MICmnResources.h"
#include "MIUtilSingletonBase.h"
@ -85,50 +82,50 @@ private:
// Details: Given a thread object start its (worker) thread to do work. The object is
// added to the *this manager for housekeeping and deletion of all thread objects.
// Type: Template method.
// Args: vrThreadObj - (R) A CMIUtilThreadActiveObjBase derived object.
// Args: vrwThreadObj - (RW) A CMIUtilThreadActiveObjBase derived object.
// Return: MIstatus::success - Functional succeeded.
// MIstatus::failure - Functional failed.
// Throws: None.
//--
template< typename T >
bool CMICmnThreadMgrStd::ThreadStart( T & vrThreadObj )
bool CMICmnThreadMgrStd::ThreadStart( T & vrwThreadObj )
{
bool bOk = MIstatus::success;
// Grab a reference to the base object type
CMIUtilThreadActiveObjBase & rObj = static_cast< CMIUtilThreadActiveObjBase & >( vrThreadObj );
CMIUtilThreadActiveObjBase & rObj = static_cast< CMIUtilThreadActiveObjBase & >( vrwThreadObj );
// Add to the thread managers internal database
bOk &= AddThread( rObj );
if( !bOk )
{
const CMIUtilString errMsg( CMIUtilString::Format( MIRSRC( IDS_THREADMGR_ERR_THREAD_FAIL_CREATE ), vrThreadObj.ThreadGetName().c_str() ) );
const CMIUtilString errMsg( CMIUtilString::Format( MIRSRC( IDS_THREADMGR_ERR_THREAD_FAIL_CREATE ), vrwThreadObj.ThreadGetName().c_str() ) );
SetErrorDescription( errMsg );
return MIstatus::failure;
}
// Grab a reference on behalf of the caller
bOk &= vrThreadObj.Acquire();
bOk &= vrwThreadObj.Acquire();
if( !bOk )
{
const CMIUtilString errMsg( CMIUtilString::Format( MIRSRC( IDS_THREADMGR_ERR_THREAD_FAIL_CREATE ), vrThreadObj.ThreadGetName().c_str() ) );
const CMIUtilString errMsg( CMIUtilString::Format( MIRSRC( IDS_THREADMGR_ERR_THREAD_FAIL_CREATE ), vrwThreadObj.ThreadGetName().c_str() ) );
SetErrorDescription( errMsg );
return MIstatus::failure;
}
// Thread is already started
//AD: this call must come after the reference count increment
if( vrThreadObj.ThreadIsActive() )
// This call must come after the reference count increment
if( vrwThreadObj.ThreadIsActive() )
{
// Early exit on thread already running condition
return MIstatus::success;
}
// Start the thread running
bOk &= vrThreadObj.ThreadExecute();
bOk &= vrwThreadObj.ThreadExecute();
if( !bOk )
{
const CMIUtilString errMsg( CMIUtilString::Format( MIRSRC( IDS_THREADMGR_ERR_THREAD_FAIL_CREATE ), vrThreadObj.ThreadGetName().c_str() ) );
const CMIUtilString errMsg( CMIUtilString::Format( MIRSRC( IDS_THREADMGR_ERR_THREAD_FAIL_CREATE ), vrwThreadObj.ThreadGetName().c_str() ) );
SetErrorDescription( errMsg );
return MIstatus::failure;
}

View File

@ -21,6 +21,7 @@
// Third party headers:
#include <stdarg.h> // va_list, va_start, var_end
#include <iostream>
#include <lldb/API/SBError.h>
// In-house headers:
@ -61,6 +62,7 @@ CMIDriver::CMIDriver( void )
, m_rStdin( CMICmnStreamStdin::Instance() )
, m_rLldbDebugger( CMICmnLLDBDebugger::Instance() )
, m_rStdOut( CMICmnStreamStdout::Instance() )
, m_eCurrentDriverState( eDriverState_NotRunning )
{
}
@ -151,6 +153,7 @@ const CMIUtilString & CMIDriver::GetVersionDescription( void ) const
//--
bool CMIDriver::Initialize( void )
{
m_eCurrentDriverState = eDriverState_Initialising;
m_clientUsageRefCnt++;
ClrErrorDescription();
@ -188,9 +191,11 @@ bool CMIDriver::Initialize( void )
}
#endif // MICONFIG_COMPILE_MIDRIVER_WITH_LLDBDRIVER
m_bExitApp = false;
m_bExitApp = false;
bOk = bOk && InitClientIDEToMIDriver(); // Init Eclipse IDE
m_bInitialized = bOk;
if( !bOk )
{
const CMIUtilString msg = CMIUtilString::Format( MIRSRC( IDS_MI_INIT_ERR_DRIVER ), errMsg.c_str() );
@ -198,6 +203,8 @@ bool CMIDriver::Initialize( void )
return MIstatus::failure;
}
m_eCurrentDriverState = eDriverState_RunningNotDebugging;
return bOk;
}
@ -217,6 +224,8 @@ bool CMIDriver::Shutdown( void )
if( !m_bInitialized )
return MIstatus::success;
m_eCurrentDriverState = eDriverState_ShuttingDown;
ClrErrorDescription();
bool bOk = MIstatus::success;
@ -237,6 +246,8 @@ bool CMIDriver::Shutdown( void )
SetErrorDescriptionn( MIRSRC( IDS_MI_SHUTDOWN_ERR ), errMsg.c_str() );
}
m_eCurrentDriverState = eDriverState_NotRunning;
return bOk;
}
@ -423,12 +434,12 @@ bool CMIDriver::GetDriverIsGDBMICompatibleDriver( void ) const
// "stdin monitor" thread (ID).
// Type: Overridden.
// Args: vStdInBuffer - (R) Copy of the current stdin line data.
// vrbYesExit - (W) True = yes exit stdin monitoring, false = continue monitor.
// vrbYesExit - (RW) True = yes exit stdin monitoring, false = continue monitor.
// Return: MIstatus::success - Functional succeeded.
// MIstatus::failure - Functional failed.
// Throws: None.
//--
bool CMIDriver::ReadLine( const CMIUtilString & vStdInBuffer, bool & vrbYesExit )
bool CMIDriver::ReadLine( const CMIUtilString & vStdInBuffer, bool & vrwbYesExit )
{
// For debugging. Update prompt show stdin is working
//printf( "%s\n", vStdInBuffer.c_str() );
@ -437,20 +448,18 @@ bool CMIDriver::ReadLine( const CMIUtilString & vStdInBuffer, bool & vrbYesExit
// Special case look for the quit command here so stop monitoring stdin stream
// So we do not go back to fgetc() and wait and hang thread on exit
if( vStdInBuffer == "quit" )
vrbYesExit = true;
vrwbYesExit = true;
// 1. Put new line in the queue container by stdin monitor thread
// 2. Then *this driver ReadStdinLineQueuer() should when ready read the quence
{
CMIUtilThreadLock lock( m_threadMutex );
m_queueStdinLine.push( vStdInBuffer );
// 2. Then *this driver calls ReadStdinLineQueue() when ready to read the queue in its
// own thread
const bool bOk = QueueMICommand( vStdInBuffer );
// Check to see if the *this driver is shutting down (exit application)
if( !vrbYesExit )
vrbYesExit = m_bDriverIsExiting;
}
return MIstatus::success;
// Check to see if the *this driver is shutting down (exit application)
if( !vrwbYesExit )
vrwbYesExit = m_bDriverIsExiting;
return bOk;
}
//++ ------------------------------------------------------------------------------------
@ -582,14 +591,14 @@ bool CMIDriver::ReadStdinLineQueue( void )
}
// Process the command
bool bCmdYesValid = false;
bool bOk = InterpretCommand( lineText, bCmdYesValid );
if( bOk && !bCmdYesValid )
bOk = InterpretCommandFallThruDriver( lineText, bCmdYesValid );
const bool bOk = InterpretCommand( lineText );
// Draw prompt if desired
if( bOk && m_rStdin.GetEnablePrompt() )
m_rStdOut.WriteMIResponse( m_rStdin.GetPrompt() );
// Input has been processed
bHaveInput = false;
}
else
{
@ -640,7 +649,7 @@ bool CMIDriver::InterpretCommandFallThruDriver( const CMIUtilString & vTextLine,
MIunused( vTextLine );
MIunused( vwbCmdYesValid );
// ToDo: Implement when less urgent work to be done
// ToDo: Implement when less urgent work to be done or decide remove as not required
//bool bOk = MIstatus::success;
//bool bCmdNotUnderstood = true;
//if( bCmdNotUnderstood && GetEnableFallThru() )
@ -802,6 +811,62 @@ const CMIUtilString & CMIDriver::GetId( void ) const
return m_strDriverId;
}
//++ ------------------------------------------------------------------------------------
// Details: Inject a command into the command processing system to be interpreted as a
// command read from stdin. The text representing the command is also written
// out to stdout as the command did not come from via stdin.
// Type: Method.
// Args: vMICmd - (R) Text data representing a possible command.
// Return: MIstatus::success - Functional succeeded.
// MIstatus::failure - Functional failed.
// Throws: None.
//--
bool CMIDriver::InjectMICommand( const CMIUtilString & vMICmd )
{
const bool bOk = m_rStdOut.WriteMIResponse( vMICmd );
return bOk && QueueMICommand( vMICmd );
}
//++ ------------------------------------------------------------------------------------
// Details: Add a new command candidate to the command queue to be processed by the
// command system.
// Type: Method.
// Args: vMICmd - (R) Text data representing a possible command.
// Return: MIstatus::success - Functional succeeded.
// MIstatus::failure - Functional failed.
// Throws: None.
//--
bool CMIDriver::QueueMICommand( const CMIUtilString & vMICmd )
{
CMIUtilThreadLock lock( m_threadMutex );
m_queueStdinLine.push( vMICmd );
return MIstatus::success;
}
//++ ------------------------------------------------------------------------------------
// Details: Interpret the text data and match against current commands to see if there
// is a match. If a match then the command is issued and actioned on. The
// text data if not understood by *this driver is past on to the Fall Thru
// driver.
// This function is used by the application's main thread.
// Type: Method.
// Args: vTextLine - (R) Text data representing a possible command.
// Return: MIstatus::success - Functional succeeded.
// MIstatus::failure - Functional failed.
// Throws: None.
//--
bool CMIDriver::InterpretCommand( const CMIUtilString & vTextLine )
{
bool bCmdYesValid = false;
bool bOk = InterpretCommandThisDriver( vTextLine, bCmdYesValid );
if( bOk && !bCmdYesValid )
bOk = InterpretCommandFallThruDriver( vTextLine, bCmdYesValid );
return bOk;
}
//++ ------------------------------------------------------------------------------------
// Details: Interpret the text data and match against current commands to see if there
// is a match. If a match then the command is issued and actioned on. If a
@ -815,7 +880,7 @@ const CMIUtilString & CMIDriver::GetId( void ) const
// MIstatus::failure - Functional failed.
// Throws: None.
//--
bool CMIDriver::InterpretCommand( const CMIUtilString & vTextLine, bool & vwbCmdYesValid )
bool CMIDriver::InterpretCommandThisDriver( const CMIUtilString & vTextLine, bool & vwbCmdYesValid )
{
vwbCmdYesValid = false;
@ -842,7 +907,7 @@ bool CMIDriver::InterpretCommand( const CMIUtilString & vTextLine, bool & vwbCmd
const CMIUtilString msg( CMIUtilString::Format( MIRSRC( IDS_DRIVER_CMD_RECEIVED ), vTextLine.c_str(), strNot.c_str(), strNotInCmdFactory.c_str() ) );
const CMICmnMIValueConst vconst = CMICmnMIValueConst( msg );
const CMICmnMIValueResult valueResult( "msg", vconst );
const CMICmnMIResultRecord miResultRecord( cmdData.nMiCmdNumber, CMICmnMIResultRecord::eResultClass_Error, valueResult );
const CMICmnMIResultRecord miResultRecord( cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, valueResult );
m_rStdOut.WriteMIResponse( miResultRecord.GetString() );
// Proceed to wait for or execute next command
@ -866,15 +931,187 @@ bool CMIDriver::ExecuteCommand( const SMICmdData & vCmdData )
}
//++ ------------------------------------------------------------------------------------
// Details: Set the exit application flag. The application checks this flag after every
// stdin line is read so the exit may not be instantious.
// Type: Method.
// Details: Set the MI Driver's exit application flag. The application checks this flag
// after every stdin line is read so the exit may not be instantious.
// If vbForceExit is false the MI Driver queries its state and determines if is
// should exit or continue operating depending on that running state.
// This is related to the running state of the MI driver.
// Type: Overridden.
// Args: None.
// Return: None.
// Throws: None.
//--
void CMIDriver::SetExitApplicationFlag( void )
void CMIDriver::SetExitApplicationFlag( const bool vbForceExit )
{
CMIUtilThreadLock lock( m_threadMutex );
if( vbForceExit )
{
CMIUtilThreadLock lock( m_threadMutex );
m_bExitApp = true;
return;
}
// CODETAG_DEBUG_SESSION_RUNNING_PROG_RECEIVED_SIGINT_PAUSE_PROGRAM
// Did we receive a SIGINT from the client during a running debug program, if
// so then SIGINT is not to be taken as meaning kill the MI driver application
// but halt the inferior program being debugged instead
if( m_eCurrentDriverState == eDriverState_RunningDebugging )
{
InjectMICommand( "-exec-interrupt" );
return;
}
m_bExitApp = true;
}
//++ ------------------------------------------------------------------------------------
// Details: Get the MI Driver's exit exit application flag.
// This is related to the running state of the MI driver.
// Type: Method.
// Args: None.
// Return: bool - True = MI Driver is shutting down, false = MI driver is running.
// Throws: None.
//--
bool CMIDriver::GetExitApplicationFlag( void ) const
{
return m_bExitApp;
}
//++ ------------------------------------------------------------------------------------
// Details: Get the current running state of the MI Driver.
// Type: Method.
// Args: None.
// Return: DriverState_e - The current running state of the application.
// Throws: None.
//--
CMIDriver::DriverState_e CMIDriver::GetCurrentDriverState( void ) const
{
return m_eCurrentDriverState;
}
//++ ------------------------------------------------------------------------------------
// Details: Set the current running state of the MI Driver to running and currently in
// a debug session. The driver's state must in the state running and not in a
// debug session to set this new state.
// Type: Method.
// Return: MIstatus::success - Functionality succeeded.
// MIstatus::failure - Functionality failed.
// Return: DriverState_e - The current running state of the application.
// Throws: None.
//--
bool CMIDriver::SetDriverStateRunningNotDebugging( void )
{
// CODETAG_DEBUG_SESSION_RUNNING_PROG_RECEIVED_SIGINT_PAUSE_PROGRAM
if( m_eCurrentDriverState == eDriverState_RunningNotDebugging )
return MIstatus::success;
// Driver cannot be in the following states to set eDriverState_RunningNotDebugging
switch( m_eCurrentDriverState )
{
case eDriverState_NotRunning:
case eDriverState_Initialising:
case eDriverState_ShuttingDown:
{
SetErrorDescription( MIRSRC( IDS_DRIVER_ERR_DRIVER_STATE_ERROR ) );
return MIstatus::failure;
}
case eDriverState_RunningDebugging:
case eDriverState_RunningNotDebugging:
break;
case eDriverState_count:
default:
SetErrorDescription( CMIUtilString::Format( MIRSRC( IDS_CODE_ERR_INVALID_ENUMERATION_VALUE ), "SetDriverStateRunningNotDebugging()" ) );
return MIstatus::failure;
}
// Driver must be in this state to set eDriverState_RunningNotDebugging
if( m_eCurrentDriverState != eDriverState_RunningDebugging )
{
SetErrorDescription( MIRSRC( IDS_DRIVER_ERR_DRIVER_STATE_ERROR ) );
return MIstatus::failure;
}
m_eCurrentDriverState = eDriverState_RunningNotDebugging;
return MIstatus::success;
}
//++ ------------------------------------------------------------------------------------
// Details: Set the current running state of the MI Driver to running and currently not in
// a debug session. The driver's state must in the state running and in a
// debug session to set this new state.
// Type: Method.
// Return: MIstatus::success - Functionality succeeded.
// MIstatus::failure - Functionality failed.
// Return: DriverState_e - The current running state of the application.
// Throws: None.
//--
bool CMIDriver::SetDriverStateRunningDebugging( void )
{
// CODETAG_DEBUG_SESSION_RUNNING_PROG_RECEIVED_SIGINT_PAUSE_PROGRAM
if( m_eCurrentDriverState == eDriverState_RunningDebugging )
return MIstatus::success;
// Driver cannot be in the following states to set eDriverState_RunningDebugging
switch( m_eCurrentDriverState )
{
case eDriverState_NotRunning:
case eDriverState_Initialising:
case eDriverState_ShuttingDown:
{
SetErrorDescription( MIRSRC( IDS_DRIVER_ERR_DRIVER_STATE_ERROR ) );
return MIstatus::failure;
}
case eDriverState_RunningDebugging:
case eDriverState_RunningNotDebugging:
break;
case eDriverState_count:
default:
SetErrorDescription( CMIUtilString::Format( MIRSRC( IDS_CODE_ERR_INVALID_ENUMERATION_VALUE ), "SetDriverStateRunningDebugging()" ) );
return MIstatus::failure;
}
// Driver must be in this state to set eDriverState_RunningDebugging
if( m_eCurrentDriverState != eDriverState_RunningNotDebugging )
{
SetErrorDescription( MIRSRC( IDS_DRIVER_ERR_DRIVER_STATE_ERROR ) );
return MIstatus::failure;
}
m_eCurrentDriverState = eDriverState_RunningDebugging;
return MIstatus::success;
}
//++ ------------------------------------------------------------------------------------
// Details: Prepare the client IDE so it will start working/communicating with *this MI
// driver.
// Type: Method.
// Args: None.
// Return: MIstatus::success - Functionality succeeded.
// MIstatus::failure - Functionality failed.
// Throws: None.
//--
bool CMIDriver::InitClientIDEToMIDriver( void ) const
{
// Put other IDE init functions here
return InitClientIDEEclipse();
}
//++ ------------------------------------------------------------------------------------
// Details: The IDE Eclipse when debugging locally expects "(gdb)\n" character
// sequence otherwise it refuses to communicate and times out. This should be
// sent to Eclipse before anything else.
// Type: Method.
// Args: None.
// Return: MIstatus::success - Functionality succeeded.
// MIstatus::failure - Functionality failed.
// Throws: None.
//--
bool CMIDriver::InitClientIDEEclipse( void ) const
{
std::cout << "(gdb)" << std::endl;
return MIstatus::success;
}

View File

@ -57,12 +57,40 @@ class CMIDriver
{
friend class MI::ISingleton< CMIDriver >;
// Enumerations:
public:
//++ ----------------------------------------------------------------------
// Details: The MI Driver has a running state which is used to help determin
// which specific action(s) it should take or not allow.
// The driver when operational and not shutting down alternates
// between eDriverState_RunningNotDebugging and
// eDriverState_RunningDebugging. eDriverState_RunningNotDebugging
// is normally set when a breakpoint is hit or halted.
// eDriverState_RunningDebugging is normally set when "exec-continue"
// or "exec-run" is issued.
//--
enum DriverState_e
{
eDriverState_NotRunning = 0, // The MI Driver is not operating
eDriverState_Initialising, // The MI Driver is setting itself up
eDriverState_RunningNotDebugging, // The MI Driver is operational acting on any MI commands sent to it
eDriverState_RunningDebugging, // The MI Driver is currently overseeing an inferior program that is running
eDriverState_ShuttingDown, // The MI Driver is tearing down resources and about exit
eDriverState_count // Always last
};
// Methods:
public:
// MI system
bool Initialize( void );
bool Shutdown( void );
bool Initialize( void );
bool Shutdown( void );
// MI state
bool GetExitApplicationFlag( void ) const;
DriverState_e GetCurrentDriverState( void ) const;
bool SetDriverStateRunningNotDebugging( void );
bool SetDriverStateRunningDebugging( void );
// MI information about itself
const CMIUtilString & GetAppNameShort( void ) const;
const CMIUtilString & GetAppNameLong( void ) const;
@ -72,7 +100,8 @@ public:
bool WriteMessageToLog( const CMIUtilString & vMessage );
bool SetEnableFallThru( const bool vbYes );
bool GetEnableFallThru( void ) const;
bool InjectMICommand( const CMIUtilString & vMICmd );
// Overridden:
public:
// From CMIDriverMgr::IDriver
@ -88,7 +117,7 @@ public:
virtual bool SetId( const CMIUtilString & vId );
virtual const CMIUtilString & GetId( void ) const;
// From CMIDriverBase
virtual void SetExitApplicationFlag( void );
virtual void SetExitApplicationFlag( const bool vbForceExit );
virtual bool DoFallThruToAnotherDriver( const CMIUtilString & vCmd, CMIUtilString & vwErrMsg );
virtual bool SetDriverToFallThruTo( const CMIDriverBase & vrOtherDriver );
virtual FILE * GetStdin( void ) const;
@ -112,11 +141,15 @@ private:
lldb::SBError ParseArgs( const int argc, const char * argv[], FILE * vpStdOut, bool & vwbExiting );
bool ReadStdinLineQueue( void );
bool DoAppQuit( void );
bool InterpretCommand( const CMIUtilString & vTextLine, bool & vwbCmdYesValid );
bool InterpretCommand( const CMIUtilString & vTextLine );
bool InterpretCommandThisDriver( const CMIUtilString & vTextLine, bool & vwbCmdYesValid );
bool InterpretCommandFallThruDriver( const CMIUtilString & vTextLine, bool & vwbCmdYesValid );
bool ExecuteCommand( const SMICmdData & vCmdData );
bool StartWorkerThreads( void );
bool StopWorkerThreads( void );
bool InitClientIDEToMIDriver( void ) const;
bool InitClientIDEEclipse( void ) const;
bool QueueMICommand( const CMIUtilString & vMICmd );
// Overridden:
private:
@ -137,4 +170,5 @@ private:
CMICmnStreamStdin & m_rStdin;
CMICmnLLDBDebugger & m_rLldbDebugger;
CMICmnStreamStdout & m_rStdOut;
DriverState_e m_eCurrentDriverState;
};

View File

@ -178,14 +178,18 @@ FILE * CMIDriverBase::GetStderr( void ) const
}
//++ ------------------------------------------------------------------------------------
// Details: Set the exit application flag. The application checks this flag after every
// stdin line is read so the exit may not be instantious.
// Type: Method.
// Args: None.
// Details: Set the MI Driver's exit application flag. The application checks this flag
// after every stdin line is read so the exit may not be instantious.
// If vbForceExit is false the MI Driver queries its state and determines if is
// should exit or continue operating depending on that running state.
// Type: Overrideable.
// Args: vbForceExit - (R) True = Do not query, set state to exit, false = query if can/should exit right now.
// Return: None.
// Throws: None.
//--
void CMIDriverBase::SetExitApplicationFlag( void )
void CMIDriverBase::SetExitApplicationFlag( const bool vbForceExit )
{
MIunused( vbForceExit );
// Do nothing - override and implement
}

View File

@ -62,7 +62,7 @@ public:
virtual bool SetDriverParent( const CMIDriverBase & vrOtherDriver );
virtual const CMIUtilString & GetDriverName( void ) const = 0;
virtual const CMIUtilString & GetDriverId( void ) const = 0;
virtual void SetExitApplicationFlag( void );
virtual void SetExitApplicationFlag( const bool vbForceExit );
// MI provide information for the pass through (child) assigned driver
virtual FILE * GetStdin( void ) const;

View File

@ -24,8 +24,11 @@
// MICmdBase.h / .cpp
// MICmdCmd.h / .cpp
// Versions: 1.0.0.1 First version from scratch 28/1/2014 to 28/3/2014. MI not complete.
// 1.0.0.2 7/3/2014. MI not complete.
// 1.0.0.3 7/5/2014. MI not complete.
// 1.0.0.2 First deliverable to client 7/3/2014. MI not complete.
// 1.0.0.3 Code refactor tidy. Release to community for evaluation 17/5/2014. MI not complete.
// 1.0.0.4 Post release to community for evaluation 17/5/2014. MI not complete.
// 1.0.0.5 Second deliverable to client 16/6/2014.
// 1.0.0.6 Post release of second deliverable to client 16/6/2014.
// See MIreadme.txt for list of MI commands implemented.
//
// Environment: Compilers: Visual C++ 12.
@ -116,7 +119,8 @@ void sigint_handler( int vSigno )
CMICmnLog::Instance().WriteLog( CMIUtilString::Format( MIRSRC( IDS_PROCESS_SIGNAL_RECEIVED ), "SIGINT", vSigno ) );
// Signal MI to shutdown
// CODETAG_DEBUG_SESSION_RUNNING_PROG_RECEIVED_SIGINT_PAUSE_PROGRAM
// Signal MI to shutdown or halt a running debug session
CMICmnStreamStdin::Instance().SetCtrlCHit();
}

View File

@ -78,7 +78,7 @@ bool CMIDriverMgr::Initialize( void )
bool bOk = MIstatus::success;
CMIUtilString errMsg;
// Note initialization order is important here as some resources depend on previous
// 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 );
@ -124,6 +124,8 @@ bool CMIDriverMgr::Shutdown( void )
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
@ -132,8 +134,19 @@ bool CMIDriverMgr::Shutdown( void )
}
else
{
const CMIUtilString msg( CMIUtilString::Format( MIRSRC( IDE_MI_APP_EXIT_WITH_PROBLEM ), CMICmnLogMediumFile::Instance().GetFileName().c_str() ) );
CMICmnStreamStdout::Instance().Write( msg );
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;
@ -478,6 +491,7 @@ bool CMIDriverMgr::ParseArgs( const int argc, const char * argv[], bool & vwbExi
bool bHaveArgInterpret = false;
bool bHaveArgVersion = false;
bool bHaveArgVersionLong = false;
bool bHaveArgNoLog = false;
bool bHaveArgHelp = false;
// Hardcode the use of the MI driver
@ -503,12 +517,21 @@ bool CMIDriverMgr::ParseArgs( const int argc, const char * argv[], bool & vwbExi
{
bHaveArgVersionLong = true;
}
if( 0 == strArg.compare( "--noLog" ) )
{
bHaveArgNoLog = true;
}
if( (0 == strArg.compare( "--help" )) || (0 == strArg.compare( "-h" )) )
{
bHaveArgHelp = true;
}
}
}
if( bHaveArgNoLog )
{
CMICmnLog::Instance().SetEnabled( false );
}
// 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.
@ -542,7 +565,7 @@ bool CMIDriverMgr::ParseArgs( const int argc, const char * argv[], bool & vwbExi
// 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.
// of drivers. Or this 'feature' may be removed if deemed not required.
IDriver * pLldbDriver = GetFirstNonMIDriver();
IDriver * pMi2Driver = GetFirstMIDriver();
if( bHaveArgInterpret && (pMi2Driver != nullptr) )
@ -595,7 +618,9 @@ CMIUtilString CMIDriverMgr::GetHelpOnCmdLineArgOptions( void ) const
MIRSRC( IDE_MI_APP_ARG_VERSION ),
MIRSRC( IDE_MI_APP_ARG_VERSION_LONG ),
MIRSRC( IDE_MI_APP_ARG_INTERPRETER ),
MIRSRC( IDS_CMD_QUIT_HELP )
CMIUtilString::Format( MIRSRC( IDE_MI_APP_ARG_NO_APP_LOG ), CMICmnLogMediumFile::Instance().GetFileName().c_str() ),
MIRSRC( IDS_CMD_QUIT_HELP ),
MIRSRC( IDE_MI_APP_ARG_EXAMPLE )
};
const MIuint nHelpItems = sizeof pHelp / sizeof pHelp[ 0 ];
CMIUtilString strHelp;
@ -622,7 +647,7 @@ CMIDriverMgr::IDriver * CMIDriverMgr::GetFirstMIDriver( void ) const
MapDriverIdToDriver_t::const_iterator it = m_mapDriverIdToDriver.begin();
while( it != m_mapDriverIdToDriver.end() )
{
const CMIUtilString & dvrId = (*it).first;
const CMIUtilString & rDrvId = (*it).first; MIunused( rDrvId );
IDriver * pDvr = (*it).second;
if( pDvr->GetDriverIsGDBMICompatibleDriver() )
{
@ -651,7 +676,7 @@ CMIDriverMgr::IDriver * CMIDriverMgr::GetFirstNonMIDriver( void ) const
MapDriverIdToDriver_t::const_iterator it = m_mapDriverIdToDriver.begin();
while( it != m_mapDriverIdToDriver.end() )
{
const CMIUtilString & dvrId = (*it).first;
const CMIUtilString & rDrvId = (*it).first; MIunused( rDrvId );
IDriver * pDvr = (*it).second;
if( !pDvr->GetDriverIsGDBMICompatibleDriver() )
{
@ -683,4 +708,4 @@ CMIDriverMgr::IDriver * CMIDriverMgr::GetDriver( const CMIUtilString & vrDriverI
return pDriver;
}

View File

@ -1,16 +1,16 @@
========================================================================
LLDB Machine Interface V2 (MI) Project Overview
The MI Driver - LLDB Machine Interface V2 (MI) Project Overview
28/01/2014
========================================================================
All the files in this directory are required to build the MI executable.
The executable is intended to compile and work on the following platforms:
Windows (Vista or newer)
LINUX
OSX
Windows (Vista or newer) (Compiler: Visual C++ 12)
LINUX (Compiler: gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1)
OSX (Not tested)
The MI driver (CMIDriver) is a driver in its own right to work alongside
The MI Driver (CMIDriver) is a driver in its own right to work alongside
the LLDB driver (driver .h/.cpp). Only one is operated at a time depending
on the options entered on the command line. The MI driver inputs and
outputs MI (GDB instruction) to be interpreted by a client i.e. Eclipse.
@ -23,6 +23,14 @@ Type --help for instruction on using the MI driver. MI produces a MILog.txt file
which records the actions of the MI driver (only) found in the directory
of the lldbMI executable.
Note any command or text sent to the MI Driver that is not a command registered
in the MI Driver's Command Factory will be rejected given an error.
The MILogfile.txt keeps a history of the MI Driver's activity for one session
only. It is used to aid debugging the MI Driver. As well as recorded commands
that are recognised by the MI Driver it also gives warnings about command's which
do not support certain argument or options.
All the files prefix with MI are specifically for the MI driver code only.
Non prefixed code is the original LLDB driver which has been left untouched
as much as possible. This allows the LLDB driver code to develop
@ -33,25 +41,98 @@ common global functions common to the two drivers.
=========================================================================
Versions:
1.0.0.1 First version from scratch 28/1/2014 to 28/3/2014.
1.0.0.1 First version from scratch 28/1/2014 to 28/3/2014.
MI working alpha. MI framework not complete.
1.0.0.2 7/3/2014.
1.0.0.2 First deliverable to client 7/3/2014.
MI working beta. MI framework not complete.
1.0.0.3 Code refactor tidy. Release to community for evaluation
7/5/2014.
MI working beta - code refactored and tidied. MI framework
complete. Just missing commands (which may still require
changes).
1.0.0.4 Post release to community for evaluation 7/5/2014.
1. MI command token now optional
2. MI command token is now fixed length
3. New commands added see section "MI commands implemented are:"
4. Able to debug a local target as well as remote target
5. MI Driver now sends to the client "(gdb)" + '\n' on
initialising
6. Improve coverage of parsing and fix command argument parsing
7. Fix bug with stdin thinking there was no input when there was which
caused communication between the client and the MI Driver to halt
due to internal buffering, we now keep track of it ourself.
8. Code comment fixes and additions. Code style fixes.
9. MI Driver now on receiving Ctrl-C (SIGINT) when the client pauses
an inferior program does not quit but continues operating.
10.Fix commands "var-update", "var-evaluate-expression" to which did
not send back information to correctly update arrays and structures.
11.Commands "Not implemented" are now not registered to the command
factory except for GDB command "thread". Commands not registered
with the command factory produce MI error message "...not in
Command Factory". (Removed from command section in this readme.txt)
1.0.0.5 Second deliverable to client 16/6/2014.
1.0.0.6 Post release of second deliverable to client 16/6/2014.
1. The MI Driver has a new option --noLog. If present the MI Driver
does not output progress or status messages to it's log file.
2. Moved OS specific handling of the stdin stream to their own class
implementations so any changes to one handler will not affect
another OS's handler.
3. The session data/information map for sharing data between commands
now uses a variant object which enables objects of different types
to be stored instead of previously just text information.
4. Debug session var object create, update and retrieve efficiency
improved by using a map type container.
5. Re-enable the MI Driver's command line option --interpreter (see
--help). Up until now it was implementented but not enforced, it
was always the MI Driver interpreter.
6. Re-enable the compilation of the original LLDB driver code into
the MI Driver's code. See MICmnConfig.h for build configuration.
=========================================================================
MI commands implemented are:
Current limitations:
1. Commands implemented likely not to have all their arguments supported
2. The MI Driver has only been tested with Eclipse Juno with an in-house
plugin
3. Local target has been implemented but not tested
4. The MI Driver has been designed primarily to work in a 'remote-target'
mode only. The MI Driver does not currently except arguments beyond
those described above.
5. The MI Driver does not accept as arguments an executable to create a
target instance.
6. Not all MI commands have been implemented. See section MI Driver
commands for those that have been fully or partially implemented (not
indicated - see command class).
7. Not necessarily a limitation but the MI Driver is used with Codeplay's
own Eclipse plugin (not supplied) which has allowed more control over
the interaction with the MI Driver between Eclipse.
=========================================================================
MI Driver Commands
MI commands below are written to work for Eclipse Juno 7.4. If may be
one are more commands required by other IDEs are missing or do not
support all arguments or options. Additionally some commands may handle
additional arguments or options not documented here
https://sourceware.org/gdb/onlinedocs/gdb/GDB_002fMI-Data-Manipulation.html#GDB_002fMI-Data-Manipulation.
The command implemented are:
CMICmdCmdBreakAfter
CMICmdCmdBreakCondition
CMICmdCmdBreakDelete
CMICmdCmdBreakDisable
CMICmdCmdBreakEnable
CMICmdCmdBreakInsert
CMICmdCmdDataEvaluateExpression
CMICmdCmdDataDisassemble
CMICmdCmdDataListRegisterChanged
CMICmdCmdDataListRegisterNames
CMICmdCmdDataListRegisterValues
CMICmdCmdDataReadMemory
CMICmdCmdDataReadMemoryBytes
CMICmdCmdDataWriteMemory
CMICmdCmdEnablePrettyPrinting
CMICmdCmdEnvironmentCd
CMICmdCmdExecContinue
CMICmdCmdExecFinish
CMICmdCmdExecInterrupt
CMICmdCmdExecNext
CMICmdCmdExecNextInstruction
CMICmdCmdExecRun
@ -59,7 +140,10 @@ CMICmdCmdExecStep
CMICmdCmdExecStepInstruction
CMICmdCmdFileExecAndSymbols
CMICmdCmdGdbExit
CMICmdCmdGdbInfo
CMICmdCmdGdbSet
CMICmdCmdGdbSet - solib-search-path option
CMICmdCmdInterpreterExec
CMICmdCmdListThreadGroups
CMICmdCmdSource
CMICmdCmdStackInfoDepth
@ -71,7 +155,7 @@ CMICmdCmdSupportListFeatures
CMICmdCmdTargetSelect
CMICmdCmdThread
CMICmdCmdThreadInfo
CMICmdCmdTraceStatus
CMICmdCmdTraceStatus (not functionally implemented)
CMICmdCmdVarAssign
CMICmdCmdVarCreate
CMICmdCmdVarDelete
@ -79,16 +163,37 @@ CMICmdCmdVarEvaluateExpression
CMICmdCmdVarInfoPathExpression
CMICmdCmdVarListChildren
CMICmdCmdVarSetFormat
CMICmdCmdVarShowAttributes
CMICmdCmdVarUpdate
=========================================================================
MI build configuration:
The MI Driver build configuration:
MICmnConfig.h defines various preprocessor build options i.e. enable
LLDB fall through should MI interpretor not recognise a command (option
not fully implemented - may be removed in the future).
LLDB driver fall through (Driver.h/.cpp) should MI Driver not recognise a
command (option not fully implemented - may be removed in the future).
=========================================================================
MI uses the following libraries:
Code standard, documentation and code style scope:
The coding style and coding documentation scope covers all MI prefixed
files and where MI code is implemented in the LLDB driver files. Should
you wish to make improvements or fixes to the MI code (which is encouraged)
please DO comment your code in the style already applied. The same applies
to the coding style. Class names should also follow this lead and ideally
should be one class per file (.h/.cpp). Class interface files (.h) should
not contain any implementation code unless there is a performance issue or
templated functions. You get the idea, look around the existing code and
follow by example :)
Where code comment or documentation is wrong or can be improved to help
others then it is strongly encouraged you DO improve the documentation.
=========================================================================
MI Driver license:
The MI Driver code is under the University of Illinois Open Source License
agreement. Submitted by Codeplay Ltd UK.
=========================================================================
The MI Driver uses the following libraries:
Standard Template library
Thread
Containers

Some files were not shown because too many files have changed in this diff Show More