Add -exec-abort command (MI); Don't exit on eStateExited
authorIlia K <ki.stfu@gmail.com>
Tue, 24 Feb 2015 10:40:45 +0000 (10:40 +0000)
committerIlia K <ki.stfu@gmail.com>
Tue, 24 Feb 2015 10:40:45 +0000 (10:40 +0000)
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

lldb/test/tools/lldb-mi/control/TestMiExec.py
lldb/tools/lldb-mi/MICmdCmdExec.cpp
lldb/tools/lldb-mi/MICmdCmdExec.h
lldb/tools/lldb-mi/MICmdCommands.cpp
lldb/tools/lldb-mi/MICmnLLDBDebugger.cpp
lldb/tools/lldb-mi/MICmnLLDBDebuggerHandleEvents.cpp
lldb/tools/lldb-mi/MICmnLLDBDebuggerHandleEvents.h
lldb/tools/lldb-mi/MICmnResources.cpp
lldb/tools/lldb-mi/MICmnResources.h

index 7ab479d..97f7fe4 100644 (file)
@@ -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."""
 
index 9b5fbbf..20d0fcd 100644 (file)
@@ -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();
+}
index 1a3e749..1a1281f 100644 (file)
@@ -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);
+};
index a2e10d1..772311d 100644 (file)
@@ -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>();
index 37ddda4..d1452e9 100644 (file)
@@ -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;
 }
 
index 2c7f746..847adf1 100644 (file)
@@ -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:
index dec8b23..5fe9af1 100644 (file)
@@ -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);
index bc1fa30..84179bb 100644 (file)
@@ -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"},
index b561473..b02c9c6 100644 (file)
@@ -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,