forked from OSchip/llvm-project
Added support for new MI commands and bug fixes. More details in MIReadme.txt.
llvm-svn: 211607
This commit is contained in:
parent
f93ef4e450
commit
877569c2b8
|
@ -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 ()
|
||||
|
|
|
@ -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
|
|
@ -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.
|
||||
|
|
|
@ -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 );
|
||||
|
||||
|
|
|
@ -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 ) )
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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 );
|
||||
};
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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() )
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
|
|
@ -169,5 +169,4 @@ bool CMICmdArgValThreadGrp::ExtractNumber( const CMIUtilString & vrTxt )
|
|||
MIuint CMICmdArgValThreadGrp::GetNumber( void ) const
|
||||
{
|
||||
return m_nThreadGrp;
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 );
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
@ -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;
|
||||
};
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 );
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
};
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
};
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
};
|
|
@ -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();
|
||||
}
|
|
@ -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 );
|
||||
};
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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 );
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 );
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 );
|
||||
};
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
};
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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 );
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 );
|
||||
};
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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)();
|
||||
|
||||
|
|
|
@ -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 ) {};
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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 ***
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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() );
|
||||
|
|
|
@ -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() );
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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() );
|
||||
}
|
||||
|
||||
|
|
|
@ -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() );
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
||||
//++ ============================================================================
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
};
|
||||
|
|
@ -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;
|
||||
}
|
|
@ -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
|
||||
};
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -42,6 +42,10 @@ class CMICmnStreamStdout
|
|||
{
|
||||
friend class MI::ISingleton< CMICmnStreamStdout >;
|
||||
|
||||
// Statics:
|
||||
public:
|
||||
static bool TextToStdout( const CMIUtilString & vrTxt );
|
||||
|
||||
// Methods:
|
||||
public:
|
||||
bool Initialize( void );
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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
|
||||
}
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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
Loading…
Reference in New Issue