summaryrefslogtreecommitdiffstats
path: root/lldb/tools/lldb-mi/MICmdCmdBreak.cpp
diff options
context:
space:
mode:
authorDeepak Panickal <deepak@codeplay.com>2014-05-16 10:51:01 +0000
committerDeepak Panickal <deepak@codeplay.com>2014-05-16 10:51:01 +0000
commit6f9c46810298dd00dc95d4ffb60faf7d914ab978 (patch)
tree7d8abbb2b6cd0aa3dfb8824f318baa432bb9e3c4 /lldb/tools/lldb-mi/MICmdCmdBreak.cpp
parentd04688d1c6cdffae4623a3a60e2d46f0bd72fe48 (diff)
downloadbcm5719-llvm-6f9c46810298dd00dc95d4ffb60faf7d914ab978.tar.gz
bcm5719-llvm-6f9c46810298dd00dc95d4ffb60faf7d914ab978.zip
Initial commit of LLDB Machine Interface Frontend.
- Tested with Eclipse, likely to work with other GDB/MI compatible GUIs. - Some but not all MI commands have been implemented. See MIReadme.txt for more info. - Written from scratch, no GPL code, based on LLDB Public API. - Built for Linux, Windows and OSX. Tested on Linux and Windows. - GDB/MI Command Reference, https://sourceware.org/gdb/onlinedocs/gdb/GDB_002fMI.html llvm-svn: 208972
Diffstat (limited to 'lldb/tools/lldb-mi/MICmdCmdBreak.cpp')
-rw-r--r--lldb/tools/lldb-mi/MICmdCmdBreak.cpp432
1 files changed, 432 insertions, 0 deletions
diff --git a/lldb/tools/lldb-mi/MICmdCmdBreak.cpp b/lldb/tools/lldb-mi/MICmdCmdBreak.cpp
new file mode 100644
index 00000000000..63ac8aa6af7
--- /dev/null
+++ b/lldb/tools/lldb-mi/MICmdCmdBreak.cpp
@@ -0,0 +1,432 @@
+//===-- MICmdCmdBreak.cpp ---------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+//++
+// File: MICmdCmdBreak.cpp
+//
+// Overview: CMICmdCmdBreakInsert implementation.
+// CMICmdCmdBreakDelete 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/SBBreakpointLocation.h>
+
+// In-house headers:
+#include "MICmnConfig.h"
+#include "MICmdCmdBreak.h"
+#include "MICmnMIResultRecord.h"
+#include "MICmnMIValueConst.h"
+#include "MICmnLLDBDebugger.h"
+#include "MICmnLLDBDebugSessionInfo.h"
+#include "MICmdArgContext.h"
+#include "MICmdArgValFile.h"
+#include "MICmdArgValNumber.h"
+#include "MICmdArgValString.h"
+#include "MICmdArgValThreadGrp.h"
+#include "MICmdArgValOptionLong.h"
+#include "MICmdArgValOptionShort.h"
+#include "MICmdArgValListOfN.h"
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdCmdBreakInsert constructor.
+// Type: Method.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdBreakInsert::CMICmdCmdBreakInsert( void )
+: m_bBrkPtIsTemp( false )
+, m_brkName()
+, m_constStrArgNamedTempBrkPt( "t" )
+, m_constStrArgNamedHWBrkPt( "h" )
+, m_constStrArgNamedPendinfBrkPt( "f" )
+, m_constStrArgNamedDisableBrkPt( "d" )
+, m_constStrArgNamedTracePt( "a" )
+, m_constStrArgNamedConditionalBrkPt( "c" )
+, m_constStrArgNamedInoreCnt( "i" )
+, m_constStrArgNamedRestrictBrkPtToThreadId( "p" )
+, m_constStrArgNamedLocation( "location" )
+, m_constStrArgNamedThreadGroup( "thread-group" )
+{
+ // Command factory matches this name with that received from the stdin stream
+ m_strMiCmd = "break-insert";
+
+ // Required by the CMICmdFactory when registering *this commmand
+ m_pSelfCreatorFn = &CMICmdCmdBreakInsert::CreateSelf;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdCmdBreakInsert destructor.
+// Type: Overrideable.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdBreakInsert::~CMICmdCmdBreakInsert( 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 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 ) ) );
+ 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 ) ) );
+ 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 );
+ 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 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 );
+
+ 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 );
+ }
+ m_brkName = pArgLocation->GetFound() ? pArgLocation->GetValue() : "";
+
+ // 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;
+ const MIint nPosColon = m_brkName.find( cColon );
+ if( nPosColon != (MIint) std::string::npos )
+ {
+ CMIUtilString::VecString_t vecFileAndLocation;
+ const MIuint nSplits = m_brkName.Split( cColon, vecFileAndLocation );
+ if( vecFileAndLocation.size() != 2 )
+ {
+ SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_BRKPT_LOCATION_FORMAT ), m_cmdData.strMiCmd.c_str(), m_brkName.c_str() ) );
+ return MIstatus::failure;
+ }
+ fileName = vecFileAndLocation.at( 0 );
+ const CMIUtilString & rStrLineOrFn( vecFileAndLocation.at( 1 ) );
+ if( rStrLineOrFn.empty() )
+ eBrkPtType = eBreakPoint_ByName;
+ else
+ {
+ MIint64 nValue = 0;
+ if( rStrLineOrFn.ExtractNumber( nValue ) )
+ {
+ nFileLine = static_cast< MIuint >( nValue );
+ eBrkPtType = eBreakPoint_ByFileLine;
+ }
+ else
+ {
+ strFileFn = rStrLineOrFn;
+ eBrkPtType = eBreakPoint_ByFileFn;
+ }
+ }
+ }
+
+ // Determine if break defined as an address
+ lldb::addr_t nAddress = 0;
+ if( eBrkPtType == eBreakPoint_NotDefineYet )
+ {
+ MIint64 nValue = 0;
+ if( m_brkName.ExtractNumber( nValue ) )
+ {
+ nAddress = static_cast< lldb::addr_t >( nValue );
+ eBrkPtType = eBreakPoint_ByAddress;
+ }
+ }
+
+ // Break defined as an function
+ if( eBrkPtType == eBreakPoint_NotDefineYet )
+ {
+ eBrkPtType = eBreakPoint_ByName;
+ }
+
+ // Ask LLDB to create a breakpoint
+ bool bOk = MIstatus::success;
+ CMICmnLLDBDebugSessionInfo & rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance() );
+ lldb::SBTarget & rTarget = rSessionInfo.m_lldbTarget;
+ switch( eBrkPtType )
+ {
+ case eBreakPoint_ByAddress:
+ m_brkPt = rTarget.BreakpointCreateByAddress( nAddress );
+ break;
+ case eBreakPoint_ByFileFn:
+ m_brkPt = rTarget.BreakpointCreateByName( strFileFn.c_str(), fileName.c_str() );
+ break;
+ case eBreakPoint_ByFileLine:
+ m_brkPt = rTarget.BreakpointCreateByLocation( fileName.c_str(), nFileLine );
+ break;
+ case eBreakPoint_ByName:
+ m_brkPt = rTarget.BreakpointCreateByName( m_brkName.c_str(), rTarget.GetExecutable().GetFilename() );
+ break;
+ case eBreakPoint_count:
+ case eBreakPoint_NotDefineYet:
+ case eBreakPoint_Invalid:
+ bOk = MIstatus::failure;
+ break;
+ }
+ if( !m_brkPt.IsValid() || !bOk )
+ {
+ SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_BRKPT_INVALID ), m_cmdData.strMiCmd.c_str(), m_brkName.c_str() ) );
+ return MIstatus::failure;
+ }
+ if( m_brkPt.GetID() > (lldb::break_id_t) rSessionInfo.m_nBrkPointCntMax )
+ {
+ SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_BRKPT_CNT_EXCEEDED ), m_cmdData.strMiCmd.c_str(), rSessionInfo.m_nBrkPointCntMax, m_brkName.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 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() )
+ {
+ 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();
+ }
+
+ // 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\"}"
+ 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 ))
+ {
+ return MIstatus::failure;
+ }
+
+ const CMICmnMIValueResult miValueResultD( "bkpt", miValueTuple );
+ const CMICmnMIResultRecord miRecordResult( m_cmdData.nMiCmdNumber, CMICmnMIResultRecord::eResultClass_Done, miValueResultD );
+ 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 * CMICmdCmdBreakInsert::CreateSelf( void )
+{
+ return new CMICmdCmdBreakInsert();
+}
+
+//---------------------------------------------------------------------------------------
+//---------------------------------------------------------------------------------------
+//---------------------------------------------------------------------------------------
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdCmdBreakDelete constructor.
+// Type: Method.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdBreakDelete::CMICmdCmdBreakDelete( void )
+: m_constStrArgNamedBrkPt( "breakpoint" )
+, 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
+ m_pSelfCreatorFn = &CMICmdCmdBreakDelete::CreateSelf;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdCmdBreakDelete destructor.
+// Type: Overrideable.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdBreakDelete::~CMICmdCmdBreakDelete( 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 CMICmdCmdBreakDelete::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 CMICmdCmdBreakDelete::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 ) )
+ {
+ 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() ) );
+ 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 )
+ {
+ SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_BRKPT_INVALID ), m_cmdData.strMiCmd.c_str(), strBrkNum.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 CMICmdCmdBreakDelete::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 * CMICmdCmdBreakDelete::CreateSelf( void )
+{
+ return new CMICmdCmdBreakDelete();
+}
OpenPOWER on IntegriCloud