summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIlia K <ki.stfu@gmail.com>2015-05-07 06:51:46 +0000
committerIlia K <ki.stfu@gmail.com>2015-05-07 06:51:46 +0000
commitd3da77e84ef9d90793e0bf5a748f79b79728506d (patch)
treece5b8bb6f4f9560e2dbc9570752cb0cc7ded923d
parent8913012ee97c8911b4bf95784f70ada3dd94ce44 (diff)
downloadbcm5719-llvm-d3da77e84ef9d90793e0bf5a748f79b79728506d.tar.gz
bcm5719-llvm-d3da77e84ef9d90793e0bf5a748f79b79728506d.zip
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 llvm-svn: 236703
-rw-r--r--lldb/test/tools/lldb-mi/startup_options/TestMiStartupOptions.py99
-rw-r--r--lldb/test/tools/lldb-mi/startup_options/main.cpp3
-rw-r--r--lldb/test/tools/lldb-mi/startup_options/start_script5
-rw-r--r--lldb/test/tools/lldb-mi/startup_options/start_script_error2
-rw-r--r--lldb/test/tools/lldb-mi/startup_options/start_script_exit7
-rw-r--r--lldb/tools/lldb-mi/MIDriver.cpp105
-rw-r--r--lldb/tools/lldb-mi/MIDriver.h3
7 files changed, 219 insertions, 5 deletions
diff --git a/lldb/test/tools/lldb-mi/startup_options/TestMiStartupOptions.py b/lldb/test/tools/lldb-mi/startup_options/TestMiStartupOptions.py
index a38df68dfbf..088fea7f0e4 100644
--- a/lldb/test/tools/lldb-mi/startup_options/TestMiStartupOptions.py
+++ b/lldb/test/tools/lldb-mi/startup_options/TestMiStartupOptions.py
@@ -127,6 +127,105 @@ class MiStartupOptionsTestCase(lldbmi_testcase.MiTestCaseBase):
# 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")
diff --git a/lldb/test/tools/lldb-mi/startup_options/main.cpp b/lldb/test/tools/lldb-mi/startup_options/main.cpp
index 1e27c641e5c..8b9e2d0b34b 100644
--- a/lldb/test/tools/lldb-mi/startup_options/main.cpp
+++ b/lldb/test/tools/lldb-mi/startup_options/main.cpp
@@ -10,5 +10,6 @@
int
main(int argc, char const *argv[])
{
- return 0;
+ int a = 10;
+ return 0; // BP_return
}
diff --git a/lldb/test/tools/lldb-mi/startup_options/start_script b/lldb/test/tools/lldb-mi/startup_options/start_script
new file mode 100644
index 00000000000..511c0224825
--- /dev/null
+++ b/lldb/test/tools/lldb-mi/startup_options/start_script
@@ -0,0 +1,5 @@
+-file-exec-and-symbols a.out
+-break-insert -f main
+-exec-run
+-break-insert main.cpp:14
+-exec-continue
diff --git a/lldb/test/tools/lldb-mi/startup_options/start_script_error b/lldb/test/tools/lldb-mi/startup_options/start_script_error
new file mode 100644
index 00000000000..d834e7407c5
--- /dev/null
+++ b/lldb/test/tools/lldb-mi/startup_options/start_script_error
@@ -0,0 +1,2 @@
+-file-exec-and-symbols a.out
+-break-ins -f main
diff --git a/lldb/test/tools/lldb-mi/startup_options/start_script_exit b/lldb/test/tools/lldb-mi/startup_options/start_script_exit
new file mode 100644
index 00000000000..8379018c29d
--- /dev/null
+++ b/lldb/test/tools/lldb-mi/startup_options/start_script_exit
@@ -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
diff --git a/lldb/tools/lldb-mi/MIDriver.cpp b/lldb/tools/lldb-mi/MIDriver.cpp
index 7d1d9e45b6d..55f9a6ce3a8 100644
--- a/lldb/tools/lldb-mi/MIDriver.cpp
+++ b/lldb/tools/lldb-mi/MIDriver.cpp
@@ -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, const char *argv[], FILE *vpStdOut, bool &v
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::IsDriverDebuggingArgExecutable(void) const
}
//++ ------------------------------------------------------------------------------------
+// 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.
diff --git a/lldb/tools/lldb-mi/MIDriver.h b/lldb/tools/lldb-mi/MIDriver.h
index 66e5d5bc20d..795549e0f4a 100644
--- a/lldb/tools/lldb-mi/MIDriver.h
+++ b/lldb/tools/lldb-mi/MIDriver.h
@@ -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;
};
OpenPOWER on IntegriCloud