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:
Greg Clayton 2011-04-30 01:09:13 +00:00
parent 3909e037ab
commit 2289fa4820
9 changed files with 180 additions and 116 deletions

View File

@ -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.

View File

@ -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;

View File

@ -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;
};

View File

@ -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;
}

View File

@ -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
{

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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;