[Lldb-commits] [lldb] r236703 - Add -s/--source option support (MI)

Ilia K ki.stfu at gmail.com
Wed May 6 23:51:46 PDT 2015


Author: ki.stfu
Date: Thu May  7 01:51:46 2015
New Revision: 236703

URL: http://llvm.org/viewvc/llvm-project?rev=236703&view=rev
Log:
Add -s/--source option support (MI)

Summary:
This patch adds -s/--source option to execute source file with prepared command.
For example:
```
$ cat start_script 
target create ~/p/hello
process launch -s
continue
$ bin/lldb-mi -s start_script 
(gdb)
target create ~/p/hello
Current executable set to '~/p/hello' (x86_64).
^done
(gdb)
process launch -s
=shlibs-added,shlib-info=[num="1",name="hello",dyld-addr="-",reason="dyld",path="/Users/IliaK/p/hello",loaded_addr="-",dsym-objpath="/Users/IliaK/p/hello.dSYM/Contents/Resources/DWARF/hello"]
Process 33289 launched: '/Users/IliaK/p/hello' (x86_64)
^done
(gdb)
continue
=thread-created,id="1",group-id="i1"
=thread-selected,id="1"
(gdb)
Process 33289 resuming
Process 33289 exited with status = 0 (0x00000000) 
^done
```

Test Plan: ./dotest.py -v --executable $BUILDDIR/bin/lldb tools/lldb-mi/

Reviewers: abidh

Reviewed By: abidh

Subscribers: lldb-commits, abidh

Differential Revision: http://reviews.llvm.org/D9278

Added:
    lldb/trunk/test/tools/lldb-mi/startup_options/start_script
    lldb/trunk/test/tools/lldb-mi/startup_options/start_script_error
    lldb/trunk/test/tools/lldb-mi/startup_options/start_script_exit
Modified:
    lldb/trunk/test/tools/lldb-mi/startup_options/TestMiStartupOptions.py
    lldb/trunk/test/tools/lldb-mi/startup_options/main.cpp
    lldb/trunk/tools/lldb-mi/MIDriver.cpp
    lldb/trunk/tools/lldb-mi/MIDriver.h

Modified: lldb/trunk/test/tools/lldb-mi/startup_options/TestMiStartupOptions.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/tools/lldb-mi/startup_options/TestMiStartupOptions.py?rev=236703&r1=236702&r2=236703&view=diff
==============================================================================
--- lldb/trunk/test/tools/lldb-mi/startup_options/TestMiStartupOptions.py (original)
+++ lldb/trunk/test/tools/lldb-mi/startup_options/TestMiStartupOptions.py Thu May  7 01:51:46 2015
@@ -127,6 +127,105 @@ class MiStartupOptionsTestCase(lldbmi_te
 
         # Test that lldb-mi is ready when executable was loaded
         self.expect(self.child_prompt, exactly = True)
+
+    @lldbmi_test
+    @expectedFailureWindows("llvm.org/pr22274: need a pexpect replacement for windows")
+    def test_lldbmi_source_option_start_script(self):
+        """Test that 'lldb-mi --interpreter' can execute user's commands after initial commands were executed."""
+
+        # Prepared source file
+        sourceFile = "start_script"
+
+        self.spawnLldbMi(args = "--source %s" % sourceFile)
+
+        # After '-file-exec-and-symbols a.out'
+        self.expect("-file-exec-and-symbols %s" % self.myexe)
+        self.expect("\^done")
+
+        # After '-break-insert -f main'
+        self.expect("-break-insert -f main")
+        self.expect("\^done,bkpt={number=\"1\"")
+
+        # After '-exec-run'
+        self.expect("-exec-run")
+        self.expect("\^running")
+
+        # After '-break-insert main.cpp:BP_return'
+        line = line_number('main.cpp', '// BP_return')
+        self.expect("-break-insert main.cpp:%d" % line)
+        self.expect("\^done,bkpt={number=\"2\"")
+
+        # After '-exec-continue'
+        self.expect("-exec-continue")
+        self.expect("\^running")
+
+        # Test that lldb-mi is ready after execution of --source start_script
+        self.expect(self.child_prompt, exactly = True)
+
+        # Try to evaluate 'a' expression
+        self.runCmd("-data-evaluate-expression a")
+        self.expect("\^done,value=\"10\"")
+        self.expect(self.child_prompt, exactly = True)
+
+    @lldbmi_test
+    @expectedFailureWindows("llvm.org/pr22274: need a pexpect replacement for windows")
+    def test_lldbmi_source_option_start_script_exit(self):
+        """Test that 'lldb-mi --interpreter' can execute a prepared file which passed via --source option."""
+
+        # Prepared source file
+        sourceFile = "start_script_exit"
+
+        self.spawnLldbMi(args = "--source %s" % sourceFile)
+
+        # After '-file-exec-and-symbols a.out'
+        self.expect("-file-exec-and-symbols %s" % self.myexe)
+        self.expect("\^done")
+
+        # After '-break-insert -f main'
+        self.expect("-break-insert -f main")
+        self.expect("\^done,bkpt={number=\"1\"")
+
+        # After '-exec-run'
+        self.expect("-exec-run")
+        self.expect("\^running")
+
+        # After '-break-insert main.cpp:BP_return'
+        line = line_number('main.cpp', '// BP_return')
+        self.expect("-break-insert main.cpp:%d" % line)
+        self.expect("\^done,bkpt={number=\"2\"")
+
+        # After '-exec-continue'
+        self.expect("-exec-continue")
+        self.expect("\^running")
+
+        # After '-data-evaluate-expression a'
+        self.expect("-data-evaluate-expression a")
+        self.expect("\^done,value=\"10\"")
+
+        # After '-gdb-exit'
+        self.expect("-gdb-exit")
+        self.expect("\^exit")
+
+    @lldbmi_test
+    @expectedFailureWindows("llvm.org/pr22274: need a pexpect replacement for windows")
+    def test_lldbmi_source_option_start_script_error(self):
+        """Test that 'lldb-mi --interpreter' stops execution of initial commands in case of error."""
+
+        # Prepared source file
+        sourceFile = "start_script_error"
+
+        self.spawnLldbMi(args = "--source %s" % sourceFile)
+
+        # After '-file-exec-and-symbols a.out'
+        self.expect("-file-exec-and-symbols %s" % self.myexe)
+        self.expect("\^done")
+
+        # After '-break-ins -f main'
+        self.expect("-break-ins -f main")
+        self.expect("\^error")
+
+        # Test that lldb-mi is ready after execution of --source start_script
+        self.expect(self.child_prompt, exactly = True)
     
     @lldbmi_test
     @expectedFailureWindows("llvm.org/pr22274: need a pexpect replacement for windows")

Modified: lldb/trunk/test/tools/lldb-mi/startup_options/main.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/tools/lldb-mi/startup_options/main.cpp?rev=236703&r1=236702&r2=236703&view=diff
==============================================================================
--- lldb/trunk/test/tools/lldb-mi/startup_options/main.cpp (original)
+++ lldb/trunk/test/tools/lldb-mi/startup_options/main.cpp Thu May  7 01:51:46 2015
@@ -10,5 +10,6 @@
 int
 main(int argc, char const *argv[])
 {
-    return 0;
+    int a = 10;
+    return 0; // BP_return
 }

Added: lldb/trunk/test/tools/lldb-mi/startup_options/start_script
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/tools/lldb-mi/startup_options/start_script?rev=236703&view=auto
==============================================================================
--- lldb/trunk/test/tools/lldb-mi/startup_options/start_script (added)
+++ lldb/trunk/test/tools/lldb-mi/startup_options/start_script Thu May  7 01:51:46 2015
@@ -0,0 +1,5 @@
+-file-exec-and-symbols a.out
+-break-insert -f main
+-exec-run
+-break-insert main.cpp:14
+-exec-continue

Added: lldb/trunk/test/tools/lldb-mi/startup_options/start_script_error
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/tools/lldb-mi/startup_options/start_script_error?rev=236703&view=auto
==============================================================================
--- lldb/trunk/test/tools/lldb-mi/startup_options/start_script_error (added)
+++ lldb/trunk/test/tools/lldb-mi/startup_options/start_script_error Thu May  7 01:51:46 2015
@@ -0,0 +1,2 @@
+-file-exec-and-symbols a.out
+-break-ins -f main

Added: lldb/trunk/test/tools/lldb-mi/startup_options/start_script_exit
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/tools/lldb-mi/startup_options/start_script_exit?rev=236703&view=auto
==============================================================================
--- lldb/trunk/test/tools/lldb-mi/startup_options/start_script_exit (added)
+++ lldb/trunk/test/tools/lldb-mi/startup_options/start_script_exit Thu May  7 01:51:46 2015
@@ -0,0 +1,7 @@
+-file-exec-and-symbols a.out
+-break-insert -f main
+-exec-run
+-break-insert main.cpp:14
+-exec-continue
+-data-evaluate-expression a
+-gdb-exit

Modified: lldb/trunk/tools/lldb-mi/MIDriver.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/lldb-mi/MIDriver.cpp?rev=236703&r1=236702&r2=236703&view=diff
==============================================================================
--- lldb/trunk/tools/lldb-mi/MIDriver.cpp (original)
+++ lldb/trunk/tools/lldb-mi/MIDriver.cpp Thu May  7 01:51:46 2015
@@ -8,6 +8,7 @@
 //===----------------------------------------------------------------------===//
 
 // Third party headers:
+#include <fstream>
 #include "lldb/API/SBError.h"
 
 // In-house headers:
@@ -54,6 +55,7 @@ CMIDriver::CMIDriver(void)
     , m_eCurrentDriverState(eDriverState_NotRunning)
     , m_bHaveExecutableFileNamePathOnCmdLine(false)
     , m_bDriverDebuggingArgExecutable(false)
+    , m_bHaveCommandFileNamePathOnCmdLine(false)
 {
 }
 
@@ -407,20 +409,40 @@ CMIDriver::ParseArgs(const int argc, con
 
     if (bHaveArgs)
     {
-        // Search right to left to look for the executable
+        // Search right to left to look for filenames
         for (MIint i = argc - 1; i > 0; i--)
         {
             const CMIUtilString strArg(argv[i]);
             const CMICmdArgValFile argFile;
+
+            // Check for a filename
             if (argFile.IsFilePath(strArg) || CMICmdArgValString(true, false, true).IsStringArg(strArg))
             {
+                // Is this the command file for the '-s' or '--source' options?
+                const CMIUtilString strPrevArg(argv[i - 1]);
+                if (strPrevArg.compare("-s") == 0 || strPrevArg.compare("--source") == 0)
+                {
+                    m_strCmdLineArgCommandFileNamePath = strArg;
+                    m_bHaveCommandFileNamePathOnCmdLine = true;
+                    i--; // skip '-s' on the next loop
+                    continue;
+                }
+                // Else, must be the executable
                 bHaveExecutableFileNamePath = true;
                 m_strCmdLineArgExecuteableFileNamePath = strArg;
                 m_bHaveExecutableFileNamePathOnCmdLine = true;
             }
-            // This argument is also check for in CMIDriverMgr::ParseArgs()
-            if (0 == strArg.compare("--executable")) // Used to specify that there is executable argument also on the command line
-            {                                        // See fn description.
+            // Report error if no command file was specified for the '-s' or '--source' options
+            else if (strArg.compare("-s") == 0 || strArg.compare("--source") == 0)
+            {
+                vwbExiting = true;
+                const CMIUtilString errMsg = CMIUtilString::Format(MIRSRC(IDS_CMD_ARGS_ERR_VALIDATION_MISSING_INF), strArg.c_str());
+                errStatus.SetErrorString(errMsg.c_str());
+                break;
+            }
+            // This argument is also checked for in CMIDriverMgr::ParseArgs()
+            else if (strArg.compare("--executable") == 0) // Used to specify that there is executable argument also on the command line
+            {                                             // See fn description.
                 bHaveExecutableLongOption = true;
             }
         }
@@ -526,6 +548,13 @@ CMIDriver::DoMainLoop(void)
     // App is not quitting currently
     m_bExitApp = false;
 
+    // Handle source file
+    if (m_bHaveCommandFileNamePathOnCmdLine)
+    {
+        const bool bAsyncMode = false;
+        ExecuteCommandFile(bAsyncMode);
+    }
+
     // While the app is active
     while (bOk && !m_bExitApp)
     {
@@ -1229,6 +1258,74 @@ CMIDriver::IsDriverDebuggingArgExecutabl
 }
 
 //++ ------------------------------------------------------------------------------------
+// Details: Execute commands from prepared source file
+// Type:    Method.
+// Args:    vbAsyncMode       - (R) True = execute commands in asynchronous mode, false = otherwise.
+// Return:  MIstatus::success - Function succeeded.
+//          MIstatus::failure - Function failed.
+// Throws:  None.
+//--
+bool
+CMIDriver::ExecuteCommandFile(const bool vbAsyncMode)
+{
+    std::ifstream ifsStartScript(m_strCmdLineArgCommandFileNamePath.c_str());
+    if (!ifsStartScript.is_open())
+    {
+        const CMIUtilString errMsg(
+            CMIUtilString::Format(MIRSRC(IDS_UTIL_FILE_ERR_OPENING_FILE_UNKNOWN), m_strCmdLineArgCommandFileNamePath.c_str()));
+        SetErrorDescription(errMsg.c_str());
+        const bool bForceExit = true;
+        SetExitApplicationFlag(bForceExit);
+        return MIstatus::failure;
+    }
+
+    // Switch lldb to synchronous mode
+    CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());
+    const bool bAsyncSetting = rSessionInfo.GetDebugger().GetAsync();
+    rSessionInfo.GetDebugger().SetAsync(vbAsyncMode);
+
+    // Execute commands from file
+    bool bOk = MIstatus::success;
+    CMIUtilString strCommand;
+    while (!m_bExitApp && std::getline(ifsStartScript, strCommand))
+    {
+        // Print command
+        bOk = CMICmnStreamStdout::TextToStdout(strCommand);
+
+        // Skip if it's a comment or empty line
+        if (strCommand.empty() || strCommand[0] == '#')
+            continue;
+
+        // Execute if no error
+        if (bOk)
+        {
+            CMIUtilThreadLock lock(rSessionInfo.GetSessionMutex());
+            bOk = InterpretCommand(strCommand);
+        }
+
+        // Draw the prompt after command will be executed (if enabled)
+        if (bOk && m_rStdin.GetEnablePrompt())
+            bOk = m_rStdOut.WriteMIResponse(m_rStdin.GetPrompt());
+
+        // Exit if there is an error
+        if (!bOk)
+        {
+            const bool bForceExit = true;
+            SetExitApplicationFlag(bForceExit);
+            break;
+        }
+
+        // Wait while the handler thread handles incoming events
+        CMICmnLLDBDebugger::Instance().WaitForHandleEvent();
+    }
+
+    // Switch lldb back to initial mode
+    rSessionInfo.GetDebugger().SetAsync(bAsyncSetting);
+
+    return bOk;
+}
+
+//++ ------------------------------------------------------------------------------------
 // Details: Gets called when lldb-mi gets a signal. Stops the process if it was SIGINT.
 //
 // Type:    Method.

Modified: lldb/trunk/tools/lldb-mi/MIDriver.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/lldb-mi/MIDriver.h?rev=236703&r1=236702&r2=236703&view=diff
==============================================================================
--- lldb/trunk/tools/lldb-mi/MIDriver.h (original)
+++ lldb/trunk/tools/lldb-mi/MIDriver.h Thu May  7 01:51:46 2015
@@ -137,6 +137,7 @@ class CMIDriver : public CMICmnBase,
     bool InitClientIDEToMIDriver(void) const;
     bool InitClientIDEEclipse(void) const;
     bool LocalDebugSessionStartupExecuteCommands(void);
+    bool ExecuteCommandFile(const bool vbAsyncMode);
 
     // Overridden:
   private:
@@ -161,4 +162,6 @@ class CMIDriver : public CMICmnBase,
     CMIUtilString m_strCmdLineArgExecuteableFileNamePath;
     bool m_bDriverDebuggingArgExecutable; // True = the MI Driver (MI mode) is debugging executable passed as argument,
                                           // false = running via a client (e.g. Eclipse)
+    bool m_bHaveCommandFileNamePathOnCmdLine; // True = file with initial commands given as one of the parameters to the MI Driver, false = not found
+    CMIUtilString m_strCmdLineArgCommandFileNamePath;
 };





More information about the lldb-commits mailing list