Index: include/lldb/API/SBTarget.h =================================================================== --- include/lldb/API/SBTarget.h +++ include/lldb/API/SBTarget.h @@ -272,6 +272,9 @@ lldb::SBFileSpec GetExecutable(); + void AppendImageSearchPath(const char *from, const char *to, + lldb::SBError &error); + bool AddModule(lldb::SBModule &module); lldb::SBModule AddModule(const char *path, const char *triple, Index: lit/lit.cfg =================================================================== --- lit/lit.cfg +++ lit/lit.cfg @@ -56,7 +56,10 @@ # Register substitutions config.substitutions.append(('%python', config.python_executable)) -debugserver = lit.util.which('debugserver', lldb_tools_dir) +if platform.system() in ['Darwin']: + debugserver = lit.util.which('debugserver', lldb_tools_dir) +else: + debugserver = lit.util.which('lldb-server', lldb_tools_dir) lldb = "%s -S %s/lit-lldb-init" % (lit.util.which('lldb', lldb_tools_dir), config.test_source_root) @@ -91,7 +94,10 @@ config.substitutions.append(('%lldb', lldb)) if debugserver is not None: - config.substitutions.append(('%debugserver', debugserver)) + if platform.system() in ['Darwin']: + config.substitutions.append(('%debugserver', debugserver)) + else: + config.substitutions.append(('%debugserver', debugserver + ' gdbserver')) for pattern in [r"\bFileCheck\b", r"\blldb-test\b", Index: lit/tools/lldb-mi/target/inputs/main.c =================================================================== --- /dev/null +++ lit/tools/lldb-mi/target/inputs/main.c @@ -0,0 +1,4 @@ +int main(void) { + int x = 0; + return x; +} Index: lit/tools/lldb-mi/target/inputs/target-select-so-path.py =================================================================== --- /dev/null +++ lit/tools/lldb-mi/target/inputs/target-select-so-path.py @@ -0,0 +1,39 @@ +#!/usr/bin/env python2 + +import os +import sys +import subprocess + + +hostname = 'localhost' + +(r, w) = os.pipe() +args = sys.argv +# Get debugserver, lldb-mi and FileCheck executables' paths with arguments. +debugserver = ' '.join([args[1], '--pipe', str(w), hostname + ':0']) +lldbmi = args[2] +test_file = args[3] +filecheck = 'FileCheck ' + test_file + +# Run debugserver, lldb-mi and FileCheck. +debugserver_proc = subprocess.Popen(debugserver.split()) +lldbmi_proc = subprocess.Popen(lldbmi, stdin=subprocess.PIPE, + stdout=subprocess.PIPE, shell=True) +filecheck_proc = subprocess.Popen(filecheck, stdin=lldbmi_proc.stdout, + shell=True) + +# Get a tcp port chosen by debugserver. +# The number quite big to get lldb-server's output and to not hang. +bytes_to_read = 10 +port_bytes = os.read(r, bytes_to_read) +port = str(port_bytes.decode('utf-8').strip('\x00')) + +with open(test_file, 'r') as f: + # Replace '$PORT' with a free port number and pass + # test's content to lldb-mi. + lldbmi_proc.stdin.write(f.read().replace('$PORT', port)) + lldbmi_proc.wait() + filecheck_proc.wait() + +debugserver_proc.kill() +exit(filecheck_proc.returncode) Index: lit/tools/lldb-mi/target/lit.local.cfg =================================================================== --- /dev/null +++ lit/tools/lldb-mi/target/lit.local.cfg @@ -0,0 +1 @@ +config.suffixes = ['.test'] Index: lit/tools/lldb-mi/target/target-select-so-path.test =================================================================== --- /dev/null +++ lit/tools/lldb-mi/target/target-select-so-path.test @@ -0,0 +1,25 @@ +# UNSUPPORTED: windows +# +# RUN: %cc -o %t %p/inputs/main.c -g +# RUN: python %p/inputs/target-select-so-path.py "%debugserver" "%lldbmi %t" %s + +# Test that -target-select command can hook up a path +# added by gdb-set solib-search-path. + +# Check that we have a valid target created via file-exec-and-symbols. +# CHECK: ^done + +-interpreter-exec console "target modules search-paths list" +# CHECK ^done + +-gdb-set solib-search-path /example/dir +# CHECK: ^done + +-target-select remote localhost:$PORT +# CHECK: ^connected + +-interpreter-exec console "target modules search-paths list" +# CHECK: ~"[0] \".\" -> \"/example/dir\"\n" +# CHECK-NEXT: ^done + +-gdb-exit Index: scripts/interface/SBTarget.i =================================================================== --- scripts/interface/SBTarget.i +++ scripts/interface/SBTarget.i @@ -373,6 +373,11 @@ lldb::SBFileSpec GetExecutable (); + void + AppendImageSearchPath (const char *from, + const char *to, + SBError &error); + bool AddModule (lldb::SBModule &module); Index: source/API/SBTarget.cpp =================================================================== --- source/API/SBTarget.cpp +++ source/API/SBTarget.cpp @@ -1457,6 +1457,28 @@ return false; } +void SBTarget::AppendImageSearchPath(const char *from, const char *to, + lldb::SBError &error) { + TargetSP target_sp(GetSP()); + if (!target_sp) { + error.SetErrorString("invalid target"); + return; + } + const ConstString csFrom(from), csTo(to); + if (csFrom && csTo) { + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); + if (log) + log->Printf("SBTarget(%p)::%s: '%s' -> '%s'", + static_cast(target_sp.get()), __FUNCTION__, + from, to); + target_sp->GetImageSearchPathList().Append(csFrom, csTo, true); + } else + if (csFrom) + error.SetErrorString(" path can't be empty"); + else + error.SetErrorString(" path can't be empty"); +} + lldb::SBModule SBTarget::AddModule(const char *path, const char *triple, const char *uuid_cstr) { return AddModule(path, triple, uuid_cstr, NULL); Index: tools/lldb-mi/MICmdCmdTarget.cpp =================================================================== --- tools/lldb-mi/MICmdCmdTarget.cpp +++ tools/lldb-mi/MICmdCmdTarget.cpp @@ -10,9 +10,8 @@ // Overview: CMICmdCmdTargetSelect implementation. // Third Party Headers: -#include "lldb/API/SBCommandInterpreter.h" -#include "lldb/API/SBCommandReturnObject.h" #include "lldb/API/SBStream.h" +#include "lldb/API/SBError.h" // In-house headers: #include "MICmdArgValNumber.h" @@ -52,7 +51,7 @@ // Return: None. // Throws: None. //-- -CMICmdCmdTargetSelect::~CMICmdCmdTargetSelect() {} +CMICmdCmdTargetSelect::~CMICmdCmdTargetSelect() = default; //++ //------------------------------------------------------------------------------------ @@ -93,16 +92,17 @@ CMICmnLLDBDebugSessionInfo &rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance()); + lldb::SBTarget target = rSessionInfo.GetTarget(); - // Check we have a valid target - // Note: target created via 'file-exec-and-symbols' command - if (!rSessionInfo.GetTarget().IsValid()) { + // Check we have a valid target. + // Note: target created via 'file-exec-and-symbols' command. + if (!target.IsValid()) { SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_INVALID_TARGET_CURRENT), m_cmdData.strMiCmd.c_str())); return MIstatus::failure; } - // Verify that we are executing remotely + // Verify that we are executing remotely. const CMIUtilString &rRemoteType(pArgType->GetValue()); if (rRemoteType != "remote") { SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_INVALID_TARGET_TYPE), @@ -111,33 +111,25 @@ return MIstatus::failure; } - // Create a URL pointing to the remote gdb stub + // Create a URL pointing to the remote gdb stub. const CMIUtilString strUrl = CMIUtilString::Format("connect://%s", pArgParameters->GetValue().c_str()); - // Ask LLDB to connect to the target port - const char *pPlugin("gdb-remote"); lldb::SBError error; - lldb::SBProcess process = rSessionInfo.GetTarget().ConnectRemote( + // Ask LLDB to connect to the target port. + const char *pPlugin("gdb-remote"); + lldb::SBProcess process = target.ConnectRemote( rSessionInfo.GetListener(), strUrl.c_str(), pPlugin, error); - // Verify that we have managed to connect successfully - lldb::SBStream errMsg; - error.GetDescription(errMsg); + // Verify that we have managed to connect successfully. if (!process.IsValid()) { SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_INVALID_TARGET_PLUGIN), m_cmdData.strMiCmd.c_str(), - errMsg.GetData())); - return MIstatus::failure; - } - if (error.Fail()) { - SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_CONNECT_TO_TARGET), - m_cmdData.strMiCmd.c_str(), - errMsg.GetData())); + error.GetCString())); return MIstatus::failure; } - // Set the environment path if we were given one + // Set the environment path if we were given one. CMIUtilString strWkDir; if (rSessionInfo.SharedDataRetrieve( rSessionInfo.m_constStrSharedDataKeyWkDir, strWkDir)) { @@ -150,28 +142,13 @@ } } - // Set the shared object path if we were given one + // Set the shared object path if we were given one. CMIUtilString strSolibPath; if (rSessionInfo.SharedDataRetrieve( - rSessionInfo.m_constStrSharedDataSolibPath, strSolibPath)) { - lldb::SBDebugger &rDbgr = rSessionInfo.GetDebugger(); - lldb::SBCommandInterpreter cmdIterpreter = rDbgr.GetCommandInterpreter(); - - CMIUtilString strCmdString = CMIUtilString::Format( - "target modules search-paths add . %s", strSolibPath.c_str()); - - lldb::SBCommandReturnObject retObj; - cmdIterpreter.HandleCommand(strCmdString.c_str(), retObj, false); + rSessionInfo.m_constStrSharedDataSolibPath, strSolibPath)) + target.AppendImageSearchPath(".", strSolibPath.c_str(), error); - if (!retObj.Succeeded()) { - SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_FNFAILED), - m_cmdData.strMiCmd.c_str(), - "target-select")); - return MIstatus::failure; - } - } - - return MIstatus::success; + return HandleSBError(error); } //++