summaryrefslogtreecommitdiffstats
path: root/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp')
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp289
1 files changed, 68 insertions, 221 deletions
diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
index ec07fbee072..79f77e219d1 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -114,16 +114,13 @@ ProcessGDBRemote::ProcessGDBRemote(Target& target, Listener &listener) :
Process (target, listener),
m_flags (0),
m_stdio_mutex (Mutex::eMutexTypeRecursive),
- m_gdb_comm(),
+ m_gdb_comm(false),
m_debugserver_pid (LLDB_INVALID_PROCESS_ID),
m_debugserver_thread (LLDB_INVALID_HOST_THREAD),
m_last_stop_packet (),
m_register_info (),
m_async_broadcaster ("lldb.process.gdb-remote.async-broadcaster"),
m_async_thread (LLDB_INVALID_HOST_THREAD),
- m_curr_tid (LLDB_INVALID_THREAD_ID),
- m_curr_tid_run (LLDB_INVALID_THREAD_ID),
- m_z0_supported (1),
m_continue_c_tids (),
m_continue_C_tids (),
m_continue_s_tids (),
@@ -430,7 +427,6 @@ ProcessGDBRemote::DoLaunch
ObjectFile * object_file = module->GetObjectFile();
if (object_file)
{
- ArchSpec inferior_arch(module->GetArchitecture());
char host_port[128];
snprintf (host_port, sizeof(host_port), "localhost:%u", get_random_port ());
char connect_url[128];
@@ -439,13 +435,7 @@ ProcessGDBRemote::DoLaunch
// Make sure we aren't already connected?
if (!m_gdb_comm.IsConnected())
{
- error = StartDebugserverProcess (host_port,
- NULL,
- NULL,
- LLDB_INVALID_PROCESS_ID,
- NULL,
- false,
- inferior_arch);
+ error = StartDebugserverProcess (host_port);
if (error.Fail())
return error;
@@ -700,8 +690,6 @@ ProcessGDBRemote::DoAttachToProcessWithID (lldb::pid_t attach_pid)
Error error;
// Clear out and clean up from any current state
Clear();
- const ArchSpec &arch_spec = GetTarget().GetArchitecture();
-
if (attach_pid != LLDB_INVALID_PROCESS_ID)
{
// Make sure we aren't already connected?
@@ -712,13 +700,7 @@ ProcessGDBRemote::DoAttachToProcessWithID (lldb::pid_t attach_pid)
char connect_url[128];
snprintf (connect_url, sizeof(connect_url), "connect://%s", host_port);
- error = StartDebugserverProcess (host_port, // debugserver_url
- NULL, // inferior_argv
- NULL, // inferior_envp
- LLDB_INVALID_PROCESS_ID, // Don't send any attach to pid options to debugserver
- NULL, // Don't send any attach by process name option to debugserver
- false, // Don't send any attach wait_for_launch flag as an option to debugserver
- arch_spec);
+ error = StartDebugserverProcess (host_port);
if (error.Fail())
{
@@ -778,21 +760,12 @@ ProcessGDBRemote::DoAttachToProcessWithName (const char *process_name, bool wait
// Make sure we aren't already connected?
if (!m_gdb_comm.IsConnected())
{
-
- const ArchSpec &arch_spec = GetTarget().GetArchitecture();
-
char host_port[128];
snprintf (host_port, sizeof(host_port), "localhost:%u", get_random_port ());
char connect_url[128];
snprintf (connect_url, sizeof(connect_url), "connect://%s", host_port);
- error = StartDebugserverProcess (host_port, // debugserver_url
- NULL, // inferior_argv
- NULL, // inferior_envp
- LLDB_INVALID_PROCESS_ID, // Don't send any attach to pid options to debugserver
- NULL, // Don't send any attach by process name option to debugserver
- false, // Don't send any attach wait_for_launch flag as an option to debugserver
- arch_spec);
+ error = StartDebugserverProcess (host_port);
if (error.Fail())
{
const char *error_string = error.AsCString();
@@ -925,7 +898,7 @@ ProcessGDBRemote::DoResume ()
if (num_continue_c_tids == num_threads)
{
// All threads are resuming...
- SetCurrentGDBRemoteThreadForRun (-1);
+ m_gdb_comm.SetCurrentThreadForRun (-1);
continue_packet.PutChar ('c');
}
else if (num_continue_c_tids == 1 &&
@@ -934,7 +907,7 @@ ProcessGDBRemote::DoResume ()
num_continue_S_tids == 0 )
{
// Only one thread is continuing
- SetCurrentGDBRemoteThreadForRun (m_continue_c_tids.front());
+ m_gdb_comm.SetCurrentThreadForRun (m_continue_c_tids.front());
continue_packet.PutChar ('c');
}
else
@@ -960,7 +933,7 @@ ProcessGDBRemote::DoResume ()
if (!continue_packet_error)
{
// Add threads continuing with the same signo...
- SetCurrentGDBRemoteThreadForRun (-1);
+ m_gdb_comm.SetCurrentThreadForRun (-1);
continue_packet.Printf("C%2.2x", continue_signo);
}
}
@@ -970,7 +943,7 @@ ProcessGDBRemote::DoResume ()
num_continue_S_tids == 0 )
{
// Only one thread is continuing with signal
- SetCurrentGDBRemoteThreadForRun (m_continue_C_tids.front().first);
+ m_gdb_comm.SetCurrentThreadForRun (m_continue_C_tids.front().first);
continue_packet.Printf("C%2.2x", m_continue_C_tids.front().second);
}
else
@@ -985,7 +958,7 @@ ProcessGDBRemote::DoResume ()
if (num_continue_s_tids == num_threads)
{
// All threads are resuming...
- SetCurrentGDBRemoteThreadForRun (-1);
+ m_gdb_comm.SetCurrentThreadForRun (-1);
continue_packet.PutChar ('s');
}
else if (num_continue_c_tids == 0 &&
@@ -994,7 +967,7 @@ ProcessGDBRemote::DoResume ()
num_continue_S_tids == 0 )
{
// Only one thread is stepping
- SetCurrentGDBRemoteThreadForRun (m_continue_s_tids.front());
+ m_gdb_comm.SetCurrentThreadForRun (m_continue_s_tids.front());
continue_packet.PutChar ('s');
}
else
@@ -1021,7 +994,7 @@ ProcessGDBRemote::DoResume ()
if (!continue_packet_error)
{
// Add threads stepping with the same signo...
- SetCurrentGDBRemoteThreadForRun (-1);
+ m_gdb_comm.SetCurrentThreadForRun (-1);
continue_packet.Printf("S%2.2x", step_signo);
}
}
@@ -1031,7 +1004,7 @@ ProcessGDBRemote::DoResume ()
num_continue_S_tids == 1 )
{
// Only one thread is stepping with signal
- SetCurrentGDBRemoteThreadForRun (m_continue_S_tids.front().first);
+ m_gdb_comm.SetCurrentThreadForRun (m_continue_S_tids.front().first);
continue_packet.Printf("S%2.2x", m_continue_S_tids.front().second);
}
else
@@ -1667,40 +1640,28 @@ ProcessGDBRemote::EnableBreakpoint (BreakpointSite *bp_site)
{
// Try and set hardware breakpoint, and if that fails, fall through
// and set a software breakpoint?
- }
-
- if (m_z0_supported)
- {
- char packet[64];
- const int packet_len = ::snprintf (packet, sizeof(packet), "Z0,%llx,%zx", addr, bp_op_size);
- assert (packet_len + 1 < sizeof(packet));
- StringExtractorGDBRemote response;
- if (m_gdb_comm.SendPacketAndWaitForResponse(packet, packet_len, response, true))
+ if (m_gdb_comm.SupportsGDBStoppointPacket (eBreakpointHardware))
{
- if (response.IsUnsupportedResponse())
- {
- // Disable z packet support and try again
- m_z0_supported = 0;
- return EnableBreakpoint (bp_site);
- }
- else if (response.IsOKResponse())
+ if (m_gdb_comm.SendGDBStoppointTypePacket(eBreakpointHardware, true, addr, bp_op_size) == 0)
{
bp_site->SetEnabled(true);
- bp_site->SetType (BreakpointSite::eExternal);
+ bp_site->SetType (BreakpointSite::eHardware);
return error;
}
- else
- {
- uint8_t error_byte = response.GetError();
- if (error_byte)
- error.SetErrorStringWithFormat("%x packet failed with error: %i (0x%2.2x).\n", packet, error_byte, error_byte);
- }
}
}
- else
+
+ if (m_gdb_comm.SupportsGDBStoppointPacket (eBreakpointSoftware))
{
- return EnableSoftwareBreakpoint (bp_site);
+ if (m_gdb_comm.SendGDBStoppointTypePacket(eBreakpointSoftware, true, addr, bp_op_size) == 0)
+ {
+ bp_site->SetEnabled(true);
+ bp_site->SetType (BreakpointSite::eExternal);
+ return error;
+ }
}
+
+ return EnableSoftwareBreakpoint (bp_site);
}
if (log)
@@ -1731,44 +1692,25 @@ ProcessGDBRemote::DisableBreakpoint (BreakpointSite *bp_site)
{
const size_t bp_op_size = GetSoftwareBreakpointTrapOpcode (bp_site);
- if (bp_site->IsHardware())
- {
- // TODO: disable hardware breakpoint...
- }
- else
+ BreakpointSite::Type bp_type = bp_site->GetType();
+ switch (bp_type)
{
- if (m_z0_supported)
- {
- char packet[64];
- const int packet_len = ::snprintf (packet, sizeof(packet), "z0,%llx,%zx", addr, bp_op_size);
- assert (packet_len + 1 < sizeof(packet));
- StringExtractorGDBRemote response;
- if (m_gdb_comm.SendPacketAndWaitForResponse(packet, packet_len, response, true))
- {
- if (response.IsUnsupportedResponse())
- {
- error.SetErrorString("Breakpoint site was set with Z packet, yet remote debugserver states z packets are not supported.");
- }
- else if (response.IsOKResponse())
- {
- if (log)
- log->Printf ("ProcessGDBRemote::DisableBreakpoint (site_id = %d) addr = 0x%8.8llx -- SUCCESS", site_id, (uint64_t)addr);
- bp_site->SetEnabled(false);
- return error;
- }
- else
- {
- uint8_t error_byte = response.GetError();
- if (error_byte)
- error.SetErrorStringWithFormat("%x packet failed with error: %i (0x%2.2x).\n", packet, error_byte, error_byte);
- }
- }
- }
- else
- {
- return DisableSoftwareBreakpoint (bp_site);
- }
+ case BreakpointSite::eSoftware:
+ error = DisableSoftwareBreakpoint (bp_site);
+ break;
+
+ case BreakpointSite::eHardware:
+ if (m_gdb_comm.SendGDBStoppointTypePacket(eBreakpointSoftware, false, addr, bp_op_size))
+ error.SetErrorToGenericError();
+ break;
+
+ case BreakpointSite::eExternal:
+ if (m_gdb_comm.SendGDBStoppointTypePacket(eBreakpointSoftware, false, addr, bp_op_size))
+ error.SetErrorToGenericError();
+ break;
}
+ if (error.Success())
+ bp_site->SetEnabled(false);
}
else
{
@@ -1869,16 +1811,7 @@ ProcessGDBRemote::DoSignal (int signo)
}
Error
-ProcessGDBRemote::StartDebugserverProcess
-(
- const char *debugserver_url, // The connection string to use in the spawned debugserver ("localhost:1234" or "/dev/tty...")
- char const *inferior_argv[], // Arguments for the inferior program including the path to the inferior itself as the first argument
- char const *inferior_envp[], // Environment to pass along to the inferior program
- lldb::pid_t attach_pid, // If inferior inferior_argv == NULL, and attach_pid != LLDB_INVALID_PROCESS_ID send this pid as an argument to debugserver
- const char *attach_name, // Wait for the next process to launch whose basename matches "attach_name"
- bool wait_for_launch, // Wait for the process named "attach_name" to launch
- const ArchSpec& inferior_arch // The arch of the inferior that we will launch
-)
+ProcessGDBRemote::StartDebugserverProcess (const char *debugserver_url) // The connection string to use in the spawned debugserver ("localhost:1234" or "/dev/tty...")
{
Error error;
if (m_debugserver_pid == LLDB_INVALID_PROCESS_ID)
@@ -1886,8 +1819,9 @@ ProcessGDBRemote::StartDebugserverProcess
// If we locate debugserver, keep that located version around
static FileSpec g_debugserver_file_spec;
- FileSpec debugserver_file_spec;
+ ProcessLaunchInfo launch_info;
char debugserver_path[PATH_MAX];
+ FileSpec &debugserver_file_spec = launch_info.GetExecutableFile();
// Always check to see if we have an environment override for the path
// to the debugserver to use and use it if we do.
@@ -1922,25 +1856,10 @@ ProcessGDBRemote::StartDebugserverProcess
debugserver_file_spec.GetPath (debugserver_path, sizeof(debugserver_path));
m_stdio_communication.Clear();
- posix_spawnattr_t attr;
LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
- Error local_err; // Errors that don't affect the spawning.
- if (log)
- log->Printf ("%s ( path='%s', argv=%p, envp=%p, arch=%s )",
- __FUNCTION__,
- debugserver_path,
- inferior_argv,
- inferior_envp,
- inferior_arch.GetArchitectureName());
- error.SetError( ::posix_spawnattr_init (&attr), eErrorTypePOSIX);
- if (error.Fail() || log)
- error.PutToLog(log.get(), "::posix_spawnattr_init ( &attr )");
- if (error.Fail())
- return error;
-
- Args debugserver_args;
+ Args &debugserver_args = launch_info.GetArguments();
char arg_cstr[PATH_MAX];
// Start args with "debugserver /file/path -r --"
@@ -1968,6 +1887,12 @@ ProcessGDBRemote::StartDebugserverProcess
// debugserver_args.AppendArgument("--log-file=/tmp/debugserver.txt");
// debugserver_args.AppendArgument("--log-flags=0x802e0e");
+ // We currently send down all arguments, attach pids, or attach
+ // process names in dedicated GDB server packets, so we don't need
+ // to pass them as arguments. This is currently because of all the
+ // things we need to setup prior to launching: the environment,
+ // current working dir, file actions, etc.
+#if 0
// Now append the program arguments
if (inferior_argv)
{
@@ -1990,20 +1915,18 @@ ProcessGDBRemote::StartDebugserverProcess
debugserver_args.AppendArgument ("--attach");
debugserver_args.AppendArgument (attach_name);
}
-
- Error file_actions_err;
- posix_spawn_file_actions_t file_actions;
-#if DONT_CLOSE_DEBUGSERVER_STDIO
- file_actions_err.SetErrorString ("Remove this after uncommenting the code block below.");
-#else
- file_actions_err.SetError( ::posix_spawn_file_actions_init (&file_actions), eErrorTypePOSIX);
- if (file_actions_err.Success())
- {
- ::posix_spawn_file_actions_addclose (&file_actions, STDIN_FILENO);
- ::posix_spawn_file_actions_addclose (&file_actions, STDOUT_FILENO);
- ::posix_spawn_file_actions_addclose (&file_actions, STDERR_FILENO);
- }
#endif
+
+ ProcessLaunchInfo::FileAction file_action;
+
+ // Close STDIN, STDOUT and STDERR. We might need to redirect them
+ // to "/dev/null" if we run into any problems.
+ file_action.Close (STDIN_FILENO);
+ launch_info.AppendFileAction (file_action);
+ file_action.Close (STDOUT_FILENO);
+ launch_info.AppendFileAction (file_action);
+ file_action.Close (STDERR_FILENO);
+ launch_info.AppendFileAction (file_action);
if (log)
{
@@ -2012,28 +1935,15 @@ ProcessGDBRemote::StartDebugserverProcess
log->Printf("%s arguments:\n%s", debugserver_args.GetArgumentAtIndex(0), strm.GetData());
}
- error.SetError (::posix_spawnp (&m_debugserver_pid,
- debugserver_path,
- file_actions_err.Success() ? &file_actions : NULL,
- &attr,
- debugserver_args.GetArgumentVector(),
- (char * const*)inferior_envp),
- eErrorTypePOSIX);
-
-
- ::posix_spawnattr_destroy (&attr);
-
- if (file_actions_err.Success())
- ::posix_spawn_file_actions_destroy (&file_actions);
+ error = Host::LaunchProcess(launch_info);
- // We have seen some cases where posix_spawnp was returning a valid
- // looking pid even when an error was returned, so clear it out
- if (error.Fail())
+ if (error.Success ())
+ m_debugserver_pid = launch_info.GetProcessID();
+ else
m_debugserver_pid = LLDB_INVALID_PROCESS_ID;
if (error.Fail() || log)
- error.PutToLog(log.get(), "::posix_spawnp ( pid => %i, path = '%s', file_actions = %p, attr = %p, argv = %p, envp = %p )", m_debugserver_pid, debugserver_path, NULL, &attr, inferior_argv, inferior_envp);
-
+ error.PutToLog(log.get(), "Host::LaunchProcess (launch_info) => pid=%i, path='%s'", m_debugserver_pid, debugserver_path);
}
else
{
@@ -2143,71 +2053,8 @@ ProcessGDBRemote::Initialize()
}
bool
-ProcessGDBRemote::SetCurrentGDBRemoteThread (int tid)
-{
- if (m_curr_tid == tid)
- return true;
-
- char packet[32];
- int packet_len;
- if (tid <= 0)
- packet_len = ::snprintf (packet, sizeof(packet), "Hg%i", tid);
- else
- packet_len = ::snprintf (packet, sizeof(packet), "Hg%x", tid);
- assert (packet_len + 1 < sizeof(packet));
- StringExtractorGDBRemote response;
- if (m_gdb_comm.SendPacketAndWaitForResponse(packet, packet_len, response, false))
- {
- if (response.IsOKResponse())
- {
- m_curr_tid = tid;
- return true;
- }
- }
- return false;
-}
-
-bool
-ProcessGDBRemote::SetCurrentGDBRemoteThreadForRun (int tid)
-{
- if (m_curr_tid_run == tid)
- return true;
-
- char packet[32];
- int packet_len;
- if (tid <= 0)
- packet_len = ::snprintf (packet, sizeof(packet), "Hc%i", tid);
- else
- packet_len = ::snprintf (packet, sizeof(packet), "Hc%x", tid);
-
- assert (packet_len + 1 < sizeof(packet));
- StringExtractorGDBRemote response;
- if (m_gdb_comm.SendPacketAndWaitForResponse(packet, packet_len, response, false))
- {
- if (response.IsOKResponse())
- {
- m_curr_tid_run = tid;
- return true;
- }
- }
- return false;
-}
-
-void
-ProcessGDBRemote::ResetGDBRemoteState ()
-{
- // Reset and GDB remote state
- m_curr_tid = LLDB_INVALID_THREAD_ID;
- m_curr_tid_run = LLDB_INVALID_THREAD_ID;
- m_z0_supported = 1;
-}
-
-
-bool
ProcessGDBRemote::StartAsyncThread ()
{
- ResetGDBRemoteState ();
-
LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
if (log)
OpenPOWER on IntegriCloud