forked from OSchip/llvm-project
Add -exec-abort command (MI); Don't exit on eStateExited
Summary: Add -exec-abort command + test. Also, I had fixed an error, when lldb-mi exits on eStateExited. With current patch we can re-run target: ``` -file-exec-and-symbols hello ^done -exec-run ^running *stopped,reason="breakpoint-hit"... -exec-abort ^done *stopped,reason="exited-normally"... <- program exits -exec-run <- run again ^running *stopped,reason="breakpoint-hit"... ``` All tests pass on OS X. Reviewers: zturner, emaste, abidh, clayborg Reviewed By: abidh, clayborg Subscribers: lldb-commits, emaste, zturner, clayborg, abidh Differential Revision: http://reviews.llvm.org/D7794 llvm-svn: 230321
This commit is contained in:
parent
327b6f5942
commit
2f85244553
|
@ -12,7 +12,7 @@ class MiExecTestCase(lldbmi_testcase.MiTestCaseBase):
|
|||
|
||||
@lldbmi_test
|
||||
@expectedFailureWindows("llvm.org/pr22274: need a pexpect replacement for windows")
|
||||
@unittest2.skip("-exec-abort isn't implemented")
|
||||
@skipIfFreeBSD # llvm.org/pr22411: Failure presumably due to known thread races
|
||||
def test_lldbmi_exec_abort(self):
|
||||
"""Test that 'lldb-mi --interpreter' works for -exec-abort."""
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
// CMICmdCmdExecFinish implementation.
|
||||
// CMICmdCmdExecInterrupt implementation.
|
||||
// CMICmdCmdExecArguments implementation.
|
||||
// CMICmdCmdExecAbort implementation.
|
||||
//
|
||||
// Environment: Compilers: Visual C++ 12.
|
||||
// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
|
||||
|
@ -1136,3 +1137,95 @@ CMICmdCmdExecArguments::CreateSelf(void)
|
|||
{
|
||||
return new CMICmdCmdExecArguments();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------
|
||||
//---------------------------------------------------------------------------------------
|
||||
//---------------------------------------------------------------------------------------
|
||||
|
||||
//++ ------------------------------------------------------------------------------------
|
||||
// Details: CMICmdCmdExecAbort constructor.
|
||||
// Type: Method.
|
||||
// Args: None.
|
||||
// Return: None.
|
||||
// Throws: None.
|
||||
//--
|
||||
CMICmdCmdExecAbort::CMICmdCmdExecAbort(void)
|
||||
{
|
||||
// Command factory matches this name with that received from the stdin stream
|
||||
m_strMiCmd = "exec-abort";
|
||||
|
||||
// Required by the CMICmdFactory when registering *this command
|
||||
m_pSelfCreatorFn = &CMICmdCmdExecAbort::CreateSelf;
|
||||
}
|
||||
|
||||
//++ ------------------------------------------------------------------------------------
|
||||
// Details: CMICmdCmdExecAbort destructor.
|
||||
// Type: Overrideable.
|
||||
// Args: None.
|
||||
// Return: None.
|
||||
// Throws: None.
|
||||
//--
|
||||
CMICmdCmdExecAbort::~CMICmdCmdExecAbort(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 - Function succeeded.
|
||||
// MIstatus::failure - Function failed.
|
||||
// Throws: None.
|
||||
//--
|
||||
bool
|
||||
CMICmdCmdExecAbort::Execute(void)
|
||||
{
|
||||
CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());
|
||||
lldb::SBProcess sbProcess = rSessionInfo.GetProcess();
|
||||
if (!sbProcess.IsValid())
|
||||
{
|
||||
SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_INVALID_PROCESS), m_cmdData.strMiCmd.c_str()));
|
||||
return MIstatus::failure;
|
||||
}
|
||||
|
||||
lldb::SBError sbError = sbProcess.Destroy();
|
||||
if (sbError.Fail())
|
||||
{
|
||||
SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_LLDBPROCESS_DESTROY), m_cmdData.strMiCmd.c_str(), sbError.GetCString()));
|
||||
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 - Function succeeded.
|
||||
// MIstatus::failure - Function failed.
|
||||
// Throws: None.
|
||||
//--
|
||||
bool
|
||||
CMICmdCmdExecAbort::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 *
|
||||
CMICmdCmdExecAbort::CreateSelf(void)
|
||||
{
|
||||
return new CMICmdCmdExecAbort();
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
// CMICmdCmdExecFinish interface.
|
||||
// CMICmdCmdExecInterrupt interface.
|
||||
// CMICmdCmdExecArguments interface.
|
||||
// CMICmdCmdExecAbort 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
|
||||
|
@ -340,3 +341,27 @@ class CMICmdCmdExecArguments : public CMICmdBase
|
|||
private:
|
||||
const CMIUtilString m_constStrArgArguments;
|
||||
};
|
||||
|
||||
//++ ============================================================================
|
||||
// Details: MI command class. MI commands derived from the command base class.
|
||||
// *this class implements MI command "exec-abort".
|
||||
//--
|
||||
class CMICmdCmdExecAbort : public CMICmdBase
|
||||
{
|
||||
// Statics:
|
||||
public:
|
||||
// Required by the CMICmdFactory when registering *this command
|
||||
static CMICmdBase *CreateSelf(void);
|
||||
|
||||
// Methods:
|
||||
public:
|
||||
/* ctor */ CMICmdCmdExecAbort(void);
|
||||
|
||||
// Overridden:
|
||||
public:
|
||||
// From CMICmdInvoker::ICmd
|
||||
virtual bool Execute(void);
|
||||
virtual bool Acknowledge(void);
|
||||
// From CMICmnBase
|
||||
/* dtor */ virtual ~CMICmdCmdExecAbort(void);
|
||||
};
|
||||
|
|
|
@ -99,6 +99,7 @@ MICmnCommands::RegisterAll(void)
|
|||
bOk &= Register<CMICmdCmdDataWriteMemory>();
|
||||
bOk &= Register<CMICmdCmdEnablePrettyPrinting>();
|
||||
bOk &= Register<CMICmdCmdEnvironmentCd>();
|
||||
bOk &= Register<CMICmdCmdExecAbort>();
|
||||
bOk &= Register<CMICmdCmdExecArguments>();
|
||||
bOk &= Register<CMICmdCmdExecContinue>();
|
||||
bOk &= Register<CMICmdCmdExecInterrupt>();
|
||||
|
|
|
@ -663,13 +663,12 @@ CMICmnLLDBDebugger::MonitorSBListenerEvents(bool &vrbIsAlive)
|
|||
m_pLog->WriteLog(CMIUtilString::Format("##### An event occurred: %s", event.GetBroadcasterClass()));
|
||||
|
||||
bool bHandledEvent = false;
|
||||
bool bExitAppEvent = false;
|
||||
|
||||
bool bOk = false;
|
||||
{
|
||||
// Lock Mutex before handling events so that we don't disturb a running cmd
|
||||
CMIUtilThreadLock lock(CMICmnLLDBDebugSessionInfo::Instance().GetSessionMutex());
|
||||
bOk = CMICmnLLDBDebuggerHandleEvents::Instance().HandleEvent(event, bHandledEvent, bExitAppEvent);
|
||||
bOk = CMICmnLLDBDebuggerHandleEvents::Instance().HandleEvent(event, bHandledEvent);
|
||||
}
|
||||
if (!bHandledEvent)
|
||||
{
|
||||
|
@ -681,15 +680,6 @@ CMICmnLLDBDebugger::MonitorSBListenerEvents(bool &vrbIsAlive)
|
|||
m_pLog->WriteLog(CMICmnLLDBDebuggerHandleEvents::Instance().GetErrorDescription());
|
||||
}
|
||||
|
||||
if (bExitAppEvent)
|
||||
{
|
||||
// Set the application to shutdown
|
||||
m_pClientDriver->SetExitApplicationFlag(true);
|
||||
|
||||
// Kill *this thread
|
||||
vrbIsAlive = false;
|
||||
}
|
||||
|
||||
return bOk;
|
||||
}
|
||||
|
||||
|
|
|
@ -126,22 +126,20 @@ CMICmnLLDBDebuggerHandleEvents::Shutdown(void)
|
|||
// Type: Method.
|
||||
// Args: vEvent - (R) An LLDB broadcast event.
|
||||
// vrbHandledEvent - (W) True - event handled, false = not handled.
|
||||
// vrbExitAppEvent - (W) True - Received LLDB exit app event, false = did not.
|
||||
// Return: MIstatus::success - Functionality succeeded.
|
||||
// MIstatus::failure - Functionality failed.
|
||||
// Throws: None.
|
||||
//--
|
||||
bool
|
||||
CMICmnLLDBDebuggerHandleEvents::HandleEvent(const lldb::SBEvent &vEvent, bool &vrbHandledEvent, bool &vrbExitAppEvent)
|
||||
CMICmnLLDBDebuggerHandleEvents::HandleEvent(const lldb::SBEvent &vEvent, bool &vrbHandledEvent)
|
||||
{
|
||||
bool bOk = MIstatus::success;
|
||||
vrbHandledEvent = false;
|
||||
vrbExitAppEvent = false;
|
||||
|
||||
if (lldb::SBProcess::EventIsProcessEvent(vEvent))
|
||||
{
|
||||
vrbHandledEvent = true;
|
||||
bOk = HandleEventSBProcess(vEvent, vrbExitAppEvent);
|
||||
bOk = HandleEventSBProcess(vEvent);
|
||||
}
|
||||
else if (lldb::SBBreakpoint::EventIsBreakpointEvent(vEvent))
|
||||
{
|
||||
|
@ -161,13 +159,12 @@ CMICmnLLDBDebuggerHandleEvents::HandleEvent(const lldb::SBEvent &vEvent, bool &v
|
|||
// Details: Handle a LLDB SBProcess event.
|
||||
// Type: Method.
|
||||
// Args: vEvent - (R) An LLDB broadcast event.
|
||||
// vrbExitAppEvent - (W) True - Received LLDB exit app event, false = did not.
|
||||
// Return: MIstatus::success - Functionality succeeded.
|
||||
// MIstatus::failure - Functionality failed.
|
||||
// Throws: None.
|
||||
//--
|
||||
bool
|
||||
CMICmnLLDBDebuggerHandleEvents::HandleEventSBProcess(const lldb::SBEvent &vEvent, bool &vrbExitAppEvent)
|
||||
CMICmnLLDBDebuggerHandleEvents::HandleEventSBProcess(const lldb::SBEvent &vEvent)
|
||||
{
|
||||
bool bOk = MIstatus::success;
|
||||
|
||||
|
@ -183,7 +180,7 @@ CMICmnLLDBDebuggerHandleEvents::HandleEventSBProcess(const lldb::SBEvent &vEvent
|
|||
break;
|
||||
case lldb::SBProcess::eBroadcastBitStateChanged:
|
||||
pEventType = "eBroadcastBitStateChanged";
|
||||
bOk = HandleProcessEventBroadcastBitStateChanged(vEvent, vrbExitAppEvent);
|
||||
bOk = HandleProcessEventBroadcastBitStateChanged(vEvent);
|
||||
break;
|
||||
case lldb::SBProcess::eBroadcastBitSTDERR:
|
||||
pEventType = "eBroadcastBitSTDERR";
|
||||
|
@ -627,13 +624,12 @@ CMICmnLLDBDebuggerHandleEvents::HandleEventSBCommandInterpreter(const lldb::SBEv
|
|||
// Details: Handle SBProcess event eBroadcastBitStateChanged.
|
||||
// Type: Method.
|
||||
// Args: vEvent - (R) An LLDB event object.
|
||||
// vrbExitAppEvent - (W) True - Received LLDB exit app event, false = did not.
|
||||
// Return: MIstatus::success - Functionality succeeded.
|
||||
// MIstatus::failure - Functionality failed.
|
||||
// Throws: None.
|
||||
//--
|
||||
bool
|
||||
CMICmnLLDBDebuggerHandleEvents::HandleProcessEventBroadcastBitStateChanged(const lldb::SBEvent &vEvent, bool &vrbExitAppEvent)
|
||||
CMICmnLLDBDebuggerHandleEvents::HandleProcessEventBroadcastBitStateChanged(const lldb::SBEvent &vEvent)
|
||||
{
|
||||
bool bOk = ChkForStateChanges();
|
||||
bOk = bOk && GetProcessStdout();
|
||||
|
@ -693,8 +689,8 @@ CMICmnLLDBDebuggerHandleEvents::HandleProcessEventBroadcastBitStateChanged(const
|
|||
pEventType = "eStateDetached";
|
||||
break;
|
||||
case lldb::eStateExited:
|
||||
// Don't exit from lldb-mi here. We should be able to re-run target.
|
||||
pEventType = "eStateExited";
|
||||
vrbExitAppEvent = true;
|
||||
bOk = HandleProcessEventStateExited();
|
||||
break;
|
||||
default:
|
||||
|
|
|
@ -50,7 +50,7 @@ class CMICmnLLDBDebuggerHandleEvents : public CMICmnBase, public MI::ISingleton<
|
|||
bool Initialize(void);
|
||||
bool Shutdown(void);
|
||||
//
|
||||
bool HandleEvent(const lldb::SBEvent &vEvent, bool &vrbHandledEvent, bool &vrbExitAppEvent);
|
||||
bool HandleEvent(const lldb::SBEvent &vEvent, bool &vrbHandledEvent);
|
||||
|
||||
// Methods:
|
||||
private:
|
||||
|
@ -65,12 +65,12 @@ class CMICmnLLDBDebuggerHandleEvents : public CMICmnBase, public MI::ISingleton<
|
|||
bool HandleEventSBBreakpointCmn(const lldb::SBEvent &vEvent);
|
||||
bool HandleEventSBBreakpointAdded(const lldb::SBEvent &vEvent);
|
||||
bool HandleEventSBBreakpointLocationsAdded(const lldb::SBEvent &vEvent);
|
||||
bool HandleEventSBProcess(const lldb::SBEvent &vEvent, bool &vrbExitAppEvent);
|
||||
bool HandleEventSBProcess(const lldb::SBEvent &vEvent);
|
||||
bool HandleEventSBThread(const lldb::SBEvent &vEvent);
|
||||
bool HandleEventSBThreadBitStackChanged(const lldb::SBEvent &vEvent);
|
||||
bool HandleEventSBThreadSuspended(const lldb::SBEvent &vEvent);
|
||||
bool HandleEventSBCommandInterpreter(const lldb::SBEvent &vEvent);
|
||||
bool HandleProcessEventBroadcastBitStateChanged(const lldb::SBEvent &vEvent, bool &vrbExitAppEvent);
|
||||
bool HandleProcessEventBroadcastBitStateChanged(const lldb::SBEvent &vEvent);
|
||||
bool HandleProcessEventStateRunning(void);
|
||||
bool HandleProcessEventStateExited(void);
|
||||
bool HandleProcessEventStateStopped(bool &vwrbShouldBrk);
|
||||
|
|
|
@ -225,6 +225,7 @@ const CMICmnResources::SRsrcTextData CMICmnResources::ms_pResourceId2TextData[]
|
|||
{IDS_CMD_ERR_FNFAILED, "Command '%s'. Fn '%s' failed"},
|
||||
{IDS_CMD_ERR_SHARED_DATA_NOT_FOUND, "Command '%s'. Shared data '%s' not found"},
|
||||
{IDS_CMD_ERR_LLDBPROCESS_DETACH, "Command '%s'. Process detach failed. '%s'"},
|
||||
{IDS_CMD_ERR_LLDBPROCESS_DESTROY, "Command '%s'. Process destroy failed. '%s'"},
|
||||
{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"},
|
||||
|
|
|
@ -241,6 +241,7 @@ enum
|
|||
IDS_CMD_ERR_FNFAILED,
|
||||
IDS_CMD_ERR_SHARED_DATA_NOT_FOUND,
|
||||
IDS_CMD_ERR_LLDBPROCESS_DETACH,
|
||||
IDS_CMD_ERR_LLDBPROCESS_DESTROY,
|
||||
IDS_CMD_ERR_SETWKDIR,
|
||||
IDS_CMD_ERR_INVALID_TARGET,
|
||||
IDS_CMD_ERR_INVALID_TARGET_CURRENT,
|
||||
|
|
Loading…
Reference in New Issue