Index: lldb/trunk/packages/Python/lldbsuite/test/tools/lldb-mi/TestMiEnvironmentCd.py =================================================================== --- lldb/trunk/packages/Python/lldbsuite/test/tools/lldb-mi/TestMiEnvironmentCd.py +++ lldb/trunk/packages/Python/lldbsuite/test/tools/lldb-mi/TestMiEnvironmentCd.py @@ -0,0 +1,36 @@ +""" +Test lldb-mi -environment-cd command. +""" + +from __future__ import print_function + + +import lldbmi_testcase +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class MiEnvironmentCdTestCase(lldbmi_testcase.MiTestCaseBase): + + mydir = TestBase.compute_mydir(__file__) + + @skipIfWindows # llvm.org/pr24452: Get lldb-mi tests working on Windows + @skipIfFreeBSD # llvm.org/pr22411: Failure presumably due to known thread races + def test_lldbmi_environment_cd(self): + """Test that 'lldb-mi --interpreter' changes working directory for inferior.""" + + self.spawnLldbMi(args=None) + + # Load executable + self.runCmd("-file-exec-and-symbols %s" % self.myexe) + self.expect("\^done") + + # cd to a different directory + self.runCmd("-environment-cd /tmp") + self.expect("\^done") + + # Run to the end + self.runCmd("-exec-run") + self.expect("\^running") + self.expect("@\"cwd: /tmp\\r\\n\"", exactly=True) Index: lldb/trunk/packages/Python/lldbsuite/test/tools/lldb-mi/TestMiGdbSetShow.py =================================================================== --- lldb/trunk/packages/Python/lldbsuite/test/tools/lldb-mi/TestMiGdbSetShow.py +++ lldb/trunk/packages/Python/lldbsuite/test/tools/lldb-mi/TestMiGdbSetShow.py @@ -208,3 +208,44 @@ self.expect("\^done") self.runCmd("-var-evaluate-expression var_a") self.expect("\^done,value=\"10\"") + + @skipIfWindows # llvm.org/pr24452: Get lldb-mi tests working on Windows + @skipIfFreeBSD # llvm.org/pr22411: Failure presumably due to known thread races + @expectedFailureAll( + bugnumber="llvm.org/pr31485: data-disassemble doesn't follow flavor settings") + def test_lldbmi_gdb_set_disassembly_flavor(self): + """Test that 'lldb-mi --interpreter' works for -gdb-set disassembly-flavor.""" + + self.spawnLldbMi(args=None) + + # Load executable + self.runCmd("-file-exec-and-symbols %s" % self.myexe) + self.expect("\^done") + + # Run to BP_printf + line = line_number('main.cpp', '// BP_printf') + self.runCmd("-break-insert main.cpp:%d" % line) + self.expect("\^done,bkpt={number=\"1\"") + self.runCmd("-exec-run") + self.expect("\^running") + self.expect("\*stopped,reason=\"breakpoint-hit\".+addr=\"(0x[0-9a-f]+)\"") + + # Get starting and ending address from $pc + pc = int(self.child.match.group(1), base=16) + s_addr, e_addr = pc, pc + 1 + + # Test default output (att) + self.runCmd("-data-disassemble -s %d -e %d -- 0" % (s_addr, e_addr)) + self.expect("movl ") + + # Test intel style + self.runCmd("-gdb-set disassembly-flavor intel") + self.expect("\^done") + self.runCmd("-data-disassemble -s %d -e %d -- 0" % (s_addr, e_addr)) + self.expect("mov ") + + # Test AT&T style + self.runCmd("-gdb-set disassembly-flavor intel") + self.expect("\^done") + self.runCmd("-data-disassemble -s %d -e %d -- 0" % (s_addr, e_addr)) + self.expect("movl ") Index: lldb/trunk/packages/Python/lldbsuite/test/tools/lldb-mi/control/TestMiExec.py =================================================================== --- lldb/trunk/packages/Python/lldbsuite/test/tools/lldb-mi/control/TestMiExec.py +++ lldb/trunk/packages/Python/lldbsuite/test/tools/lldb-mi/control/TestMiExec.py @@ -111,24 +111,25 @@ self.expect("\*stopped,reason=\"breakpoint-hit\"") # Check argc and argv to see if arg passed + # Note that exactly=True is needed to avoid extra escaping for re self.runCmd("-data-evaluate-expression argc") self.expect("\^done,value=\"5\"") #self.runCmd("-data-evaluate-expression argv[1]") # self.expect("\^done,value=\"--arg1\"") self.runCmd("-interpreter-exec command \"print argv[1]\"") - self.expect("\"--arg1\"") + self.expect("\\\"--arg1\\\"", exactly=True) #self.runCmd("-data-evaluate-expression argv[2]") #self.expect("\^done,value=\"2nd arg\"") self.runCmd("-interpreter-exec command \"print argv[2]\"") - self.expect("\"2nd arg\"") + self.expect("\\\"2nd arg\\\"", exactly=True) #self.runCmd("-data-evaluate-expression argv[3]") # self.expect("\^done,value=\"third_arg\"") self.runCmd("-interpreter-exec command \"print argv[3]\"") - self.expect("\"third_arg\"") + self.expect("\\\"third_arg\\\"", exactly=True) #self.runCmd("-data-evaluate-expression argv[4]") #self.expect("\^done,value=\"fourth=\\\\\\\"4th arg\\\\\\\"\"") self.runCmd("-interpreter-exec command \"print argv[4]\"") - self.expect("\"fourth=\\\\\\\"4th arg\\\\\\\"\"") + self.expect("\\\"fourth=\\\\\\\"4th arg\\\\\\\"\\\"", exactly=True) @skipIfWindows # llvm.org/pr24452: Get lldb-mi tests working on Windows @skipIfFreeBSD # llvm.org/pr22411: Failure presumably due to known thread races Index: lldb/trunk/packages/Python/lldbsuite/test/tools/lldb-mi/main.cpp =================================================================== --- lldb/trunk/packages/Python/lldbsuite/test/tools/lldb-mi/main.cpp +++ lldb/trunk/packages/Python/lldbsuite/test/tools/lldb-mi/main.cpp @@ -9,11 +9,25 @@ #include +#ifdef _WIN32 + #include + #define getcwd _getcwd // suppress "deprecation" warning +#else + #include +#endif + int main(int argc, char const *argv[]) { - int a = 10; + int a = 10; + + char buf[512]; + char *ans = getcwd(buf, sizeof(buf)); + if (ans) { + printf("cwd: %s\n", ans); + } printf("argc=%d\n", argc); // BP_printf + return 0; } Index: lldb/trunk/packages/Python/lldbsuite/test/tools/lldb-mi/syntax/TestMiSyntax.py =================================================================== --- lldb/trunk/packages/Python/lldbsuite/test/tools/lldb-mi/syntax/TestMiSyntax.py +++ lldb/trunk/packages/Python/lldbsuite/test/tools/lldb-mi/syntax/TestMiSyntax.py @@ -97,6 +97,7 @@ # Run all commands simultaneously self.runCmd("-unknown-command") + self.runCmd("-interpreter-exec command help") self.runCmd("-file-exec-and-symbols %s" % self.myexe) self.runCmd("-break-insert -f main") self.runCmd("-gdb-set target-async off") Index: lldb/trunk/tools/lldb-mi/MICmdCmdEnviro.cpp =================================================================== --- lldb/trunk/tools/lldb-mi/MICmdCmdEnviro.cpp +++ lldb/trunk/tools/lldb-mi/MICmdCmdEnviro.cpp @@ -94,6 +94,13 @@ m_cmdData.strMiCmd.c_str(), "SetCurrentPlatformSDKRoot()")); + lldb::SBTarget sbTarget = m_rLLDBDebugSessionInfo.GetTarget(); + if (sbTarget.IsValid()) { + lldb::SBLaunchInfo sbLaunchInfo = sbTarget.GetLaunchInfo(); + sbLaunchInfo.SetWorkingDirectory(strWkDir.c_str()); + sbTarget.SetLaunchInfo(sbLaunchInfo); + } + return bOk; } Index: lldb/trunk/tools/lldb-mi/MICmdCmdGdbSet.h =================================================================== --- lldb/trunk/tools/lldb-mi/MICmdCmdGdbSet.h +++ lldb/trunk/tools/lldb-mi/MICmdCmdGdbSet.h @@ -79,6 +79,7 @@ bool OptionFnPrint(const CMIUtilString::VecString_t &vrWords); bool OptionFnSolibSearchPath(const CMIUtilString::VecString_t &vrWords); bool OptionFnOutputRadix(const CMIUtilString::VecString_t &vrWords); + bool OptionFnDisassemblyFlavor(const CMIUtilString::VecString_t &vrWords); bool OptionFnFallback(const CMIUtilString::VecString_t &vrWords); // Attributes: Index: lldb/trunk/tools/lldb-mi/MICmdCmdGdbSet.cpp =================================================================== --- lldb/trunk/tools/lldb-mi/MICmdCmdGdbSet.cpp +++ lldb/trunk/tools/lldb-mi/MICmdCmdGdbSet.cpp @@ -27,6 +27,7 @@ // Example code if need to implement GDB set other options {"output-radix", &CMICmdCmdGdbSet::OptionFnOutputRadix}, {"solib-search-path", &CMICmdCmdGdbSet::OptionFnSolibSearchPath}, + {"disassembly-flavor", &CMICmdCmdGdbSet::OptionFnDisassemblyFlavor}, {"fallback", &CMICmdCmdGdbSet::OptionFnFallback}}; //++ @@ -399,6 +400,39 @@ //++ //------------------------------------------------------------------------------------ +// Details: Carry out work to complete the GDB set option 'disassembly-flavor' +// to prepare +// and send back information asked for. +// Type: Method. +// Args: vrWords - (R) List of additional parameters used by this option. +// Return: MIstatus::success - Functional succeeded. +// MIstatus::failure - Functional failed. +// Throws: None. +//-- +bool CMICmdCmdGdbSet::OptionFnDisassemblyFlavor( + const CMIUtilString::VecString_t &vrWords) { + // Check we have at least one argument + if (vrWords.size() < 1) { + m_bGbbOptionFnHasError = true; + // m_strGdbOptionFnError = MIRSRC(IDS_CMD_ERR_GDBSET_OPT_SOLIBSEARCHPATH); + return MIstatus::failure; + } + const CMIUtilString &rStrValDisasmFlavor(vrWords[0]); + + lldb::SBDebugger &rDbgr = m_rLLDBDebugSessionInfo.GetDebugger(); + lldb::SBError error = lldb::SBDebugger::SetInternalVariable( + "target.x86-disassembly-flavor", rStrValDisasmFlavor.c_str(), + rDbgr.GetInstanceName()); + if (error.Fail()) { + m_strGdbOptionFnError = error.GetCString(); + return MIstatus::failure; + } + + return MIstatus::success; +} + +//++ +//------------------------------------------------------------------------------------ // Details: Carry out work to complete the GDB set option to prepare and send // back the // requested information. Index: lldb/trunk/tools/lldb-mi/MICmdCmdGdbShow.h =================================================================== --- lldb/trunk/tools/lldb-mi/MICmdCmdGdbShow.h +++ lldb/trunk/tools/lldb-mi/MICmdCmdGdbShow.h @@ -78,6 +78,7 @@ bool OptionFnTargetAsync(const CMIUtilString::VecString_t &vrWords); bool OptionFnPrint(const CMIUtilString::VecString_t &vrWords); bool OptionFnLanguage(const CMIUtilString::VecString_t &vrWords); + bool OptionFnDisassemblyFlavor(const CMIUtilString::VecString_t &vrWords); bool OptionFnFallback(const CMIUtilString::VecString_t &vrWords); // Attributes: Index: lldb/trunk/tools/lldb-mi/MICmdCmdGdbShow.cpp =================================================================== --- lldb/trunk/tools/lldb-mi/MICmdCmdGdbShow.cpp +++ lldb/trunk/tools/lldb-mi/MICmdCmdGdbShow.cpp @@ -13,6 +13,7 @@ #include "lldb/API/SBCompileUnit.h" #include "lldb/API/SBFrame.h" #include "lldb/API/SBLanguageRuntime.h" +#include "lldb/API/SBStringList.h" #include "lldb/API/SBThread.h" // In-house headers: @@ -30,6 +31,7 @@ {"target-async", &CMICmdCmdGdbShow::OptionFnTargetAsync}, {"print", &CMICmdCmdGdbShow::OptionFnPrint}, {"language", &CMICmdCmdGdbShow::OptionFnLanguage}, + {"disassembly-flavor", &CMICmdCmdGdbShow::OptionFnDisassemblyFlavor}, {"fallback", &CMICmdCmdGdbShow::OptionFnFallback}}; //++ @@ -327,6 +329,26 @@ //++ //------------------------------------------------------------------------------------ +// Details: Carry out work to complete the GDB show option 'disassembly-flavor' to prepare +// and send back the requested information. +// Type: Method. +// Args: vrWords - (R) List of additional parameters used by this option. +// Return: MIstatus::success - Function succeeded. +// MIstatus::failure - Function failed. +// Throws: None. +//-- +bool CMICmdCmdGdbShow::OptionFnDisassemblyFlavor(const CMIUtilString::VecString_t &vrWords) { + MIunused(vrWords); + + // Get current disassembly flavor + lldb::SBDebugger &rDbgr = m_rLLDBDebugSessionInfo.GetDebugger(); + m_strValue = lldb::SBDebugger::GetInternalVariableValue("target.x86-disassembly-flavor", + rDbgr.GetInstanceName()).GetStringAtIndex(0); + return MIstatus::success; +} + +//++ +//------------------------------------------------------------------------------------ // Details: Carry out work to complete the GDB show option to prepare and send // back the // requested information. Index: lldb/trunk/tools/lldb-mi/MICmdCmdMiscellanous.cpp =================================================================== --- lldb/trunk/tools/lldb-mi/MICmdCmdMiscellanous.cpp +++ lldb/trunk/tools/lldb-mi/MICmdCmdMiscellanous.cpp @@ -496,14 +496,22 @@ //-- bool CMICmdCmdInterpreterExec::Acknowledge() { if (m_lldbResult.GetOutputSize() > 0) { - CMIUtilString strMsg(m_lldbResult.GetOutput()); - strMsg = strMsg.StripCREndOfLine(); - CMICmnStreamStdout::TextToStdout(strMsg); + const CMIUtilString line(m_lldbResult.GetOutput()); + const bool bEscapeQuotes(true); + CMICmnMIValueConst miValueConst(line.Escape(bEscapeQuotes)); + CMICmnMIOutOfBandRecord miOutOfBandRecord(CMICmnMIOutOfBandRecord::eOutOfBand_ConsoleStreamOutput, miValueConst); + const bool bOk = CMICmnStreamStdout::TextToStdout(miOutOfBandRecord.GetString()); + if (!bOk) + return MIstatus::failure; } if (m_lldbResult.GetErrorSize() > 0) { - CMIUtilString strMsg(m_lldbResult.GetError()); - strMsg = strMsg.StripCREndOfLine(); - CMICmnStreamStderr::LLDBMsgToConsole(strMsg); + const CMIUtilString line(m_lldbResult.GetError()); + const bool bEscapeQuotes(true); + CMICmnMIValueConst miValueConst(line.Escape(bEscapeQuotes)); + CMICmnMIOutOfBandRecord miOutOfBandRecord(CMICmnMIOutOfBandRecord::eOutOfBand_LogStreamOutput, miValueConst); + const bool bOk = CMICmnStreamStdout::TextToStdout(miOutOfBandRecord.GetString()); + if (!bOk) + return MIstatus::failure; } const CMICmnMIResultRecord miRecordResult( Index: lldb/trunk/tools/lldb-mi/MICmdCmdTarget.cpp =================================================================== --- lldb/trunk/tools/lldb-mi/MICmdCmdTarget.cpp +++ lldb/trunk/tools/lldb-mi/MICmdCmdTarget.cpp @@ -123,6 +123,7 @@ // Verify that we have managed to connect successfully lldb::SBStream errMsg; + error.GetDescription(errMsg); if (!process.IsValid()) { SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_INVALID_TARGET_PLUGIN), m_cmdData.strMiCmd.c_str(), Index: lldb/trunk/tools/lldb-mi/MICmnMIOutOfBandRecord.h =================================================================== --- lldb/trunk/tools/lldb-mi/MICmnMIOutOfBandRecord.h +++ lldb/trunk/tools/lldb-mi/MICmnMIOutOfBandRecord.h @@ -65,7 +65,9 @@ eOutOfBand_ThreadSelected, eOutOfBand_TargetModuleLoaded, eOutOfBand_TargetModuleUnloaded, - eOutOfBand_TargetStreamOutput + eOutOfBand_TargetStreamOutput, + eOutOfBand_ConsoleStreamOutput, + eOutOfBand_LogStreamOutput }; // Methods: Index: lldb/trunk/tools/lldb-mi/MICmnMIOutOfBandRecord.cpp =================================================================== --- lldb/trunk/tools/lldb-mi/MICmnMIOutOfBandRecord.cpp +++ lldb/trunk/tools/lldb-mi/MICmnMIOutOfBandRecord.cpp @@ -48,6 +48,10 @@ return "library-unloaded"; case CMICmnMIOutOfBandRecord::eOutOfBand_TargetStreamOutput: return ""; + case CMICmnMIOutOfBandRecord::eOutOfBand_ConsoleStreamOutput: + return ""; + case CMICmnMIOutOfBandRecord::eOutOfBand_LogStreamOutput: + return ""; } assert(false && "unknown CMICmnMIOutofBandRecord::OutOfBand_e"); return NULL; @@ -86,6 +90,10 @@ return "="; case CMICmnMIOutOfBandRecord::eOutOfBand_TargetStreamOutput: return "@"; + case CMICmnMIOutOfBandRecord::eOutOfBand_ConsoleStreamOutput: + return "~"; + case CMICmnMIOutOfBandRecord::eOutOfBand_LogStreamOutput: + return "&"; } assert(false && "unknown CMICmnMIOutofBandRecord::OutOfBand_e"); return NULL;