forked from OSchip/llvm-project
Added the ability to set the Platform path for a module through the SBModule
interface. Added a quick way to set the platform though the SBDebugger interface. I will actually an a SBPlatform support soon, but for now this will do. ConnectionFileDescriptor can be passed a url formatted as: "fd://<fd>" where <fd> is a file descriptor in the current process. This is handy if you have services, deamons, or other tools that can spawn processes and give you a file handle. llvm-svn: 130565
This commit is contained in:
parent
3909e037ab
commit
2289fa4820
|
@ -116,6 +116,11 @@ public:
|
|||
|
||||
lldb::SBSourceManager &
|
||||
GetSourceManager ();
|
||||
|
||||
// REMOVE: just for a quick fix, need to expose platforms through
|
||||
// SBPlatform from this class.
|
||||
lldb::SBError
|
||||
SetCurrentPlatform (const char *platform_name);
|
||||
|
||||
// FIXME: Once we get the set show stuff in place, the driver won't need
|
||||
// an interface to the Set/Get UseExternalEditor.
|
||||
|
|
|
@ -36,6 +36,12 @@ public:
|
|||
lldb::SBFileSpec
|
||||
GetFileSpec () const;
|
||||
|
||||
lldb::SBFileSpec
|
||||
GetPlatformFileSpec () const;
|
||||
|
||||
bool
|
||||
SetPlatformFileSpec (const lldb::SBFileSpec &platform_file);
|
||||
|
||||
const uint8_t *
|
||||
GetUUIDBytes () const;
|
||||
|
||||
|
|
|
@ -385,6 +385,8 @@
|
|||
26BD407F135D2AE000237D80 /* FileLineResolver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BD407E135D2ADF00237D80 /* FileLineResolver.cpp */; };
|
||||
26C72C94124322890068DC16 /* SBStream.h in Headers */ = {isa = PBXBuildFile; fileRef = 26C72C93124322890068DC16 /* SBStream.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
26C72C961243229A0068DC16 /* SBStream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26C72C951243229A0068DC16 /* SBStream.cpp */; };
|
||||
26D265A2136B40EE002EEE45 /* SharingPtr.h in Headers */ = {isa = PBXBuildFile; fileRef = 261B5A5311C3F2AD00AABD0A /* SharingPtr.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
26D265BC136B4269002EEE45 /* lldb-public.h in Headers */ = {isa = PBXBuildFile; fileRef = 26651A14133BEC76005B64B7 /* lldb-public.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
26D5E15F135BAEA2006EA0A7 /* OptionGroupArchitecture.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26D5E15E135BAEA2006EA0A7 /* OptionGroupArchitecture.cpp */; };
|
||||
26D5E163135BB054006EA0A7 /* OptionGroupPlatform.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26D5E162135BB054006EA0A7 /* OptionGroupPlatform.cpp */; };
|
||||
26DC6A171337FE8000FF7998 /* liblldb-core.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 2689FFCA13353D7A00698AC0 /* liblldb-core.a */; };
|
||||
|
@ -2639,6 +2641,8 @@
|
|||
2617447A11685869005ADD65 /* SBType.h in Headers */,
|
||||
9A19A6AF1163BBB200E0D453 /* SBValue.h in Headers */,
|
||||
9A357583116CFDEE00E8ED2F /* SBValueList.h in Headers */,
|
||||
26D265A2136B40EE002EEE45 /* SharingPtr.h in Headers */,
|
||||
26D265BC136B4269002EEE45 /* lldb-public.h in Headers */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include "lldb/API/SBBroadcaster.h"
|
||||
#include "lldb/API/SBCommandInterpreter.h"
|
||||
#include "lldb/API/SBCommandReturnObject.h"
|
||||
#include "lldb/API/SBError.h"
|
||||
#include "lldb/API/SBEvent.h"
|
||||
#include "lldb/API/SBFrame.h"
|
||||
#include "lldb/API/SBInputReader.h"
|
||||
|
@ -811,3 +812,22 @@ SBDebugger::GetID()
|
|||
return m_opaque_sp->GetID();
|
||||
return LLDB_INVALID_UID;
|
||||
}
|
||||
|
||||
|
||||
SBError
|
||||
SBDebugger::SetCurrentPlatform (const char *platform_name)
|
||||
{
|
||||
SBError sb_error;
|
||||
if (m_opaque_sp)
|
||||
{
|
||||
PlatformSP platform_sp (Platform::Create (platform_name, sb_error.ref()));
|
||||
|
||||
if (platform_sp)
|
||||
{
|
||||
bool make_selected = true;
|
||||
m_opaque_sp->GetPlatformList().Append (platform_sp, make_selected);
|
||||
}
|
||||
}
|
||||
return sb_error;
|
||||
}
|
||||
|
||||
|
|
|
@ -71,6 +71,52 @@ SBModule::GetFileSpec () const
|
|||
return file_spec;
|
||||
}
|
||||
|
||||
lldb::SBFileSpec
|
||||
SBModule::GetPlatformFileSpec () const
|
||||
{
|
||||
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
|
||||
|
||||
SBFileSpec file_spec;
|
||||
if (m_opaque_sp)
|
||||
file_spec.SetFileSpec(m_opaque_sp->GetPlatformFileSpec());
|
||||
|
||||
if (log)
|
||||
{
|
||||
log->Printf ("SBModule(%p)::GetPlatformFileSpec () => SBFileSpec(%p)",
|
||||
m_opaque_sp.get(), file_spec.get());
|
||||
}
|
||||
|
||||
return file_spec;
|
||||
|
||||
}
|
||||
|
||||
bool
|
||||
SBModule::SetPlatformFileSpec (const lldb::SBFileSpec &platform_file)
|
||||
{
|
||||
bool result = false;
|
||||
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
|
||||
|
||||
if (m_opaque_sp)
|
||||
{
|
||||
m_opaque_sp->SetPlatformFileSpec(*platform_file);
|
||||
result = true;
|
||||
}
|
||||
|
||||
if (log)
|
||||
{
|
||||
log->Printf ("SBModule(%p)::SetPlatformFileSpec (SBFileSpec(%p (%s%s%s)) => %i",
|
||||
m_opaque_sp.get(),
|
||||
platform_file.get(),
|
||||
platform_file->GetDirectory().GetCString(),
|
||||
platform_file->GetDirectory() ? "/" : "",
|
||||
platform_file->GetFilename().GetCString(),
|
||||
result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
const uint8_t *
|
||||
SBModule::GetUUIDBytes () const
|
||||
{
|
||||
|
|
|
@ -183,126 +183,74 @@ SBTarget::Launch
|
|||
if (getenv("LLDB_LAUNCH_FLAG_DISABLE_ASLR"))
|
||||
launch_flags |= eLaunchFlagDisableASLR;
|
||||
|
||||
static const char *g_launch_tty = NULL;
|
||||
static bool g_got_launch_tty = false;
|
||||
if (!g_got_launch_tty)
|
||||
StateType state = eStateInvalid;
|
||||
sb_process.SetProcess (m_opaque_sp->GetProcessSP());
|
||||
if (sb_process.IsValid())
|
||||
{
|
||||
// Get the LLDB_LAUNCH_FLAG_LAUNCH_IN_TTY only once
|
||||
g_got_launch_tty = true;
|
||||
g_launch_tty = ::getenv ("LLDB_LAUNCH_FLAG_LAUNCH_IN_TTY");
|
||||
if (g_launch_tty)
|
||||
{
|
||||
// LLDB_LAUNCH_FLAG_LAUNCH_IN_TTY is a path to a terminal to reuse
|
||||
// if the first character is '/', else it is a boolean value.
|
||||
if (g_launch_tty[0] != '/')
|
||||
{
|
||||
if (Args::StringToBoolean(g_launch_tty, false, NULL))
|
||||
g_launch_tty = "";
|
||||
else
|
||||
g_launch_tty = NULL;
|
||||
}
|
||||
}
|
||||
state = sb_process->GetState();
|
||||
|
||||
if (sb_process->IsAlive() && state != eStateConnected)
|
||||
{
|
||||
if (state == eStateAttaching)
|
||||
error.SetErrorString ("process attach is in progress");
|
||||
else
|
||||
error.SetErrorString ("a process is already being debugged");
|
||||
sb_process.Clear();
|
||||
return sb_process;
|
||||
}
|
||||
}
|
||||
|
||||
// if ((launch_flags & eLaunchFlagLaunchInTTY) || g_launch_tty)
|
||||
// {
|
||||
// ArchSpec arch (m_opaque_sp->GetArchitecture ());
|
||||
//
|
||||
// Module *exe_module = m_opaque_sp->GetExecutableModule().get();
|
||||
// if (exe_module)
|
||||
// {
|
||||
// char exec_file_path[PATH_MAX];
|
||||
// exe_module->GetFileSpec().GetPath(exec_file_path, sizeof(exec_file_path));
|
||||
// if (exe_module->GetFileSpec().Exists())
|
||||
// {
|
||||
// // Make a new argument vector
|
||||
// std::vector<const char *> exec_path_plus_argv;
|
||||
// // Append the resolved executable path
|
||||
// exec_path_plus_argv.push_back (exec_file_path);
|
||||
//
|
||||
// // Push all args if there are any
|
||||
// if (argv)
|
||||
// {
|
||||
// for (int i = 0; argv[i]; ++i)
|
||||
// exec_path_plus_argv.push_back(argv[i]);
|
||||
// }
|
||||
//
|
||||
// // Push a NULL to terminate the args.
|
||||
// exec_path_plus_argv.push_back(NULL);
|
||||
//
|
||||
//
|
||||
// const char *tty_name = NULL;
|
||||
// if (g_launch_tty && g_launch_tty[0] == '/')
|
||||
// tty_name = g_launch_tty;
|
||||
//
|
||||
// lldb::pid_t pid = Host::LaunchInNewTerminal (tty_name,
|
||||
// &exec_path_plus_argv[0],
|
||||
// envp,
|
||||
// working_directory,
|
||||
// &arch,
|
||||
// true,
|
||||
// launch_flags & eLaunchFlagDisableASLR);
|
||||
//
|
||||
// if (pid != LLDB_INVALID_PROCESS_ID)
|
||||
// {
|
||||
// sb_process = AttachToProcessWithID(listener, pid, error);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// error.SetErrorStringWithFormat("failed to launch process in terminal");
|
||||
// }
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// error.SetErrorStringWithFormat("executable doesn't exist: \"%s\"", exec_file_path);
|
||||
// }
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// error.SetErrorStringWithFormat("invalid executable");
|
||||
// }
|
||||
// }
|
||||
// else
|
||||
if (state == eStateConnected)
|
||||
{
|
||||
// If we are already connected, then we have already specified the
|
||||
// listener, so if a valid listener is supplied, we need to error out
|
||||
// to let the client know.
|
||||
if (listener.IsValid())
|
||||
{
|
||||
error.SetErrorString ("process is connected and already has a listener, pass empty listener");
|
||||
sb_process.Clear();
|
||||
return sb_process;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (listener.IsValid())
|
||||
sb_process.SetProcess (m_opaque_sp->CreateProcess (listener.ref()));
|
||||
else
|
||||
sb_process.SetProcess (m_opaque_sp->CreateProcess (m_opaque_sp->GetDebugger().GetListener()));
|
||||
}
|
||||
|
||||
if (sb_process.IsValid())
|
||||
if (sb_process.IsValid())
|
||||
{
|
||||
if (getenv("LLDB_LAUNCH_FLAG_DISABLE_STDIO"))
|
||||
launch_flags |= eLaunchFlagDisableSTDIO;
|
||||
|
||||
error.SetError (sb_process->Launch (argv, envp, launch_flags, stdin_path, stdout_path, stderr_path, working_directory));
|
||||
if (error.Success())
|
||||
{
|
||||
|
||||
if (getenv("LLDB_LAUNCH_FLAG_DISABLE_STDIO"))
|
||||
launch_flags |= eLaunchFlagDisableSTDIO;
|
||||
// We we are stopping at the entry point, we can return now!
|
||||
if (stop_at_entry)
|
||||
return sb_process;
|
||||
|
||||
|
||||
error.SetError (sb_process->Launch (argv, envp, launch_flags, stdin_path, stdout_path, stderr_path, working_directory));
|
||||
if (error.Success())
|
||||
// Make sure we are stopped at the entry
|
||||
StateType state = sb_process->WaitForProcessToStop (NULL);
|
||||
if (state == eStateStopped)
|
||||
{
|
||||
// We we are stopping at the entry point, we can return now!
|
||||
if (stop_at_entry)
|
||||
return sb_process;
|
||||
|
||||
// Make sure we are stopped at the entry
|
||||
StateType state = sb_process->WaitForProcessToStop (NULL);
|
||||
if (state == eStateStopped)
|
||||
// resume the process to skip the entry point
|
||||
error.SetError (sb_process->Resume());
|
||||
if (error.Success())
|
||||
{
|
||||
// resume the process to skip the entry point
|
||||
error.SetError (sb_process->Resume());
|
||||
if (error.Success())
|
||||
{
|
||||
// If we are doing synchronous mode, then wait for the
|
||||
// process to stop yet again!
|
||||
if (m_opaque_sp->GetDebugger().GetAsyncExecution () == false)
|
||||
sb_process->WaitForProcessToStop (NULL);
|
||||
}
|
||||
// If we are doing synchronous mode, then wait for the
|
||||
// process to stop yet again!
|
||||
if (m_opaque_sp->GetDebugger().GetAsyncExecution () == false)
|
||||
sb_process->WaitForProcessToStop (NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
error.SetErrorString ("unable to create lldb_private::Process");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
error.SetErrorString ("unable to create lldb_private::Process");
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
|
@ -97,6 +97,46 @@ ConnectionFileDescriptor::Connect (const char *s, Error *error_ptr)
|
|||
{
|
||||
return SocketConnect (s + strlen("connect://"), error_ptr);
|
||||
}
|
||||
else if (strstr(s, "fd://"))
|
||||
{
|
||||
// Just passing a native file descriptor within this current process
|
||||
// that is already opened (possibly from a service or other source).
|
||||
s += strlen ("fd://");
|
||||
bool success = false;
|
||||
m_fd = Args::StringToSInt32 (s, -1, 0, &success);
|
||||
if (success)
|
||||
{
|
||||
// We have what looks to be a valid file descriptor, but we
|
||||
// should make it is. We currently are doing this by trying to
|
||||
// get the flags from the file descriptor and making sure it
|
||||
// isn't a bad fd. We also need to enable non blocking mode for
|
||||
// the fd if it already isn't.
|
||||
errno = 0;
|
||||
int flags = ::fcntl (m_fd, F_GETFL, 0);
|
||||
if (flags == -1 || errno == EBADF)
|
||||
{
|
||||
if (error_ptr)
|
||||
error_ptr->SetErrorStringWithFormat ("stale file descriptor: %s", s);
|
||||
m_fd = -1;
|
||||
return eConnectionStatusError;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((flags & O_NONBLOCK) == 0)
|
||||
{
|
||||
flags |= O_NONBLOCK;
|
||||
::fcntl (m_fd, F_SETFL, flags);
|
||||
}
|
||||
m_should_close_fd = true;
|
||||
return eConnectionStatusSuccess;
|
||||
}
|
||||
}
|
||||
|
||||
if (error_ptr)
|
||||
error_ptr->SetErrorStringWithFormat ("invalid file descriptor: \"fd://%s\"", s);
|
||||
m_fd = -1;
|
||||
return eConnectionStatusError;
|
||||
}
|
||||
else if (strstr(s, "file://"))
|
||||
{
|
||||
// file:///PATH
|
||||
|
|
|
@ -352,14 +352,7 @@ ProcessGDBRemote::DoConnectRemote (const char *remote_url)
|
|||
if (error.Fail())
|
||||
return error;
|
||||
|
||||
if (strncmp (remote_url, "connect://", strlen ("connect://")) == 0)
|
||||
{
|
||||
error = ConnectToDebugserver (remote_url);
|
||||
}
|
||||
else
|
||||
{
|
||||
error.SetErrorStringWithFormat ("unsupported remote url: %s", remote_url);
|
||||
}
|
||||
error = ConnectToDebugserver (remote_url);
|
||||
|
||||
if (error.Fail())
|
||||
return error;
|
||||
|
|
|
@ -2065,8 +2065,10 @@ Process::Launch
|
|||
Module *exe_module = m_target.GetExecutableModule().get();
|
||||
if (exe_module)
|
||||
{
|
||||
char exec_file_path[PATH_MAX];
|
||||
exe_module->GetFileSpec().GetPath(exec_file_path, sizeof(exec_file_path));
|
||||
char local_exec_file_path[PATH_MAX];
|
||||
char platform_exec_file_path[PATH_MAX];
|
||||
exe_module->GetFileSpec().GetPath(local_exec_file_path, sizeof(local_exec_file_path));
|
||||
exe_module->GetPlatformFileSpec().GetPath(platform_exec_file_path, sizeof(platform_exec_file_path));
|
||||
if (exe_module->GetFileSpec().Exists())
|
||||
{
|
||||
if (PrivateStateThreadIsValid ())
|
||||
|
@ -2089,7 +2091,7 @@ Process::Launch
|
|||
// Make a new argument vector
|
||||
std::vector<const char *> exec_path_plus_argv;
|
||||
// Append the resolved executable path
|
||||
exec_path_plus_argv.push_back (exec_file_path);
|
||||
exec_path_plus_argv.push_back (platform_exec_file_path);
|
||||
|
||||
// Push all args if there are any
|
||||
if (argv)
|
||||
|
@ -2156,7 +2158,7 @@ Process::Launch
|
|||
}
|
||||
else
|
||||
{
|
||||
error.SetErrorStringWithFormat("File doesn't exist: '%s'.\n", exec_file_path);
|
||||
error.SetErrorStringWithFormat("File doesn't exist: '%s'.\n", local_exec_file_path);
|
||||
}
|
||||
}
|
||||
return error;
|
||||
|
|
Loading…
Reference in New Issue