summaryrefslogtreecommitdiffstats
path: root/lldb/source/Plugins/Process/gdb-remote
diff options
context:
space:
mode:
authorTodd Fiala <todd.fiala@gmail.com>2014-10-11 21:42:09 +0000
committerTodd Fiala <todd.fiala@gmail.com>2014-10-11 21:42:09 +0000
commit75f47c3a5d8fa1f3f7f492af58199d34f10f26ed (patch)
tree9897488a36cba6200867d738e554ecbbac64a62d /lldb/source/Plugins/Process/gdb-remote
parent3c1e1e949895fbe29b7f5b0ca4708243c261e807 (diff)
downloadbcm5719-llvm-75f47c3a5d8fa1f3f7f492af58199d34f10f26ed.tar.gz
bcm5719-llvm-75f47c3a5d8fa1f3f7f492af58199d34f10f26ed.zip
llgs: fixes to PTY/gdb-remote inferior stdout/stderr handling, logging addtions.
With this change, both local-process llgs and remote-target llgs stdout/stderr handling from inferior work correctly. Several log lines have been added around PTY and stdout/stderr redirection logic on the lldb client side. Regarding remote llgs execution, see the following: With these changes, remote llgs with $O now works properly: $ lldb (lldb) platform select remote-linux (lldb) target create ~/some/inferior/exe (lldb) gdb-remote {some-target}:{port} (lldb) run The sequence above will correctly redirect stdout/stderr over gdb-remote $O, as is needed for remote debugging. That sequence assumes there is a lldb-gdbserver exe running on the target with {some-host}:{port}. You can replace the gdb-remote command with a '(lldb) platform connect connect://{target-ip}:{target-port}'. If you do this and have a lldb-platform running on the remote end, it will go ahead and launch llgs for lldb for each target instance that is run/attached. For local debugging with llgs, the following sequence also works, and uses local PTYs instead to avoid $O and extra gdb-remote messages: $ lldb (lldb) settings set platform.plugin.linux.use-llgs true (lldb) target create ~/some/inferior/exe (lldb) run The above will run the inferior using llgs on the local host, and will use PTYs rather than $O redirection. This change also removes the logging that happened after the fork but before the exec when llgs is launching a new inferior process. Some aspect of the file handling during that portion of code would not do the right thing with log handling. We might want to go back later and have that communicate over a pipe from the child to parent to pass along any messages that previously were logged in that section of code. llvm-svn: 219578
Diffstat (limited to 'lldb/source/Plugins/Process/gdb-remote')
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp55
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h7
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp81
3 files changed, 122 insertions, 21 deletions
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp
index 5ecf3cc476b..2e0cdd410e5 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp
@@ -483,6 +483,27 @@ GDBRemoteCommunicationServer::LaunchProcess ()
return LaunchPlatformProcess ();
}
+bool
+GDBRemoteCommunicationServer::ShouldRedirectInferiorOutputOverGdbRemote (const lldb_private::ProcessLaunchInfo &launch_info) const
+{
+ // Retrieve the file actions specified for stdout and stderr.
+ auto stdout_file_action = launch_info.GetFileActionForFD (STDOUT_FILENO);
+ auto stderr_file_action = launch_info.GetFileActionForFD (STDERR_FILENO);
+
+ // If neither stdout and stderr file actions are specified, we're not doing anything special, so
+ // assume we want to redirect stdout/stderr over gdb-remote $O messages.
+ if ((stdout_file_action == nullptr) && (stderr_file_action == nullptr))
+ {
+ // Send stdout/stderr over the gdb-remote protocol.
+ return true;
+ }
+
+ // Any other setting for either stdout or stderr implies we are either suppressing
+ // it (with /dev/null) or we've got it set to a PTY. Either way, we don't want the
+ // output over gdb-remote.
+ return false;
+}
+
lldb_private::Error
GDBRemoteCommunicationServer::LaunchProcessForDebugging ()
{
@@ -507,20 +528,34 @@ GDBRemoteCommunicationServer::LaunchProcessForDebugging ()
return error;
}
- // Setup stdout/stderr mapping from inferior.
- auto terminal_fd = m_debugged_process_sp->GetTerminalFileDescriptor ();
- if (terminal_fd >= 0)
+ // Handle mirroring of inferior stdout/stderr over the gdb-remote protocol as needed.
+ // llgs local-process debugging may specify PTYs, which will eliminate the need to reflect inferior
+ // stdout/stderr over the gdb-remote protocol.
+ if (ShouldRedirectInferiorOutputOverGdbRemote (m_process_launch_info))
{
if (log)
- log->Printf ("ProcessGDBRemoteCommunicationServer::%s setting inferior STDIO fd to %d", __FUNCTION__, terminal_fd);
- error = SetSTDIOFileDescriptor (terminal_fd);
- if (error.Fail ())
- return error;
+ log->Printf ("GDBRemoteCommunicationServer::%s pid %" PRIu64 " setting up stdout/stderr redirection via $O gdb-remote commands", __FUNCTION__, m_debugged_process_sp->GetID ());
+
+ // Setup stdout/stderr mapping from inferior to $O
+ auto terminal_fd = m_debugged_process_sp->GetTerminalFileDescriptor ();
+ if (terminal_fd >= 0)
+ {
+ if (log)
+ log->Printf ("ProcessGDBRemoteCommunicationServer::%s setting inferior STDIO fd to %d", __FUNCTION__, terminal_fd);
+ error = SetSTDIOFileDescriptor (terminal_fd);
+ if (error.Fail ())
+ return error;
+ }
+ else
+ {
+ if (log)
+ log->Printf ("ProcessGDBRemoteCommunicationServer::%s ignoring inferior STDIO since terminal fd reported as %d", __FUNCTION__, terminal_fd);
+ }
}
else
{
if (log)
- log->Printf ("ProcessGDBRemoteCommunicationServer::%s ignoring inferior STDIO since terminal fd reported as %d", __FUNCTION__, terminal_fd);
+ log->Printf ("GDBRemoteCommunicationServer::%s pid %" PRIu64 " skipping stdout/stderr redirection via $O: inferior will communicate over client-provided file descriptors", __FUNCTION__, m_debugged_process_sp->GetID ());
}
printf ("Launched '%s' as process %" PRIu64 "...\n", m_process_launch_info.GetArguments ().GetArgumentAtIndex (0), m_process_launch_info.GetProcessID ());
@@ -3757,7 +3792,7 @@ GDBRemoteCommunicationServer::Handle_z (StringExtractorGDBRemote &packet)
}
// Parse out software or hardware breakpoint requested.
- packet.SetFilePos (strlen("Z"));
+ packet.SetFilePos (strlen("z"));
if (packet.GetBytesLeft() < 1)
return SendIllFormedResponse(packet, "Too short z packet, missing software/hardware specifier");
@@ -3797,7 +3832,7 @@ GDBRemoteCommunicationServer::Handle_z (StringExtractorGDBRemote &packet)
if (want_breakpoint)
{
- // Try to set the breakpoint.
+ // Try to clear the breakpoint.
const Error error = m_debugged_process_sp->RemoveBreakpoint (breakpoint_addr);
if (error.Success ())
return SendOKResponse ();
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h
index e1008f4a01f..ab911cd5dd8 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h
@@ -152,8 +152,6 @@ public:
//------------------------------------------------------------------
/// Specify the program to launch and its arguments.
///
- /// The LaunchProcess () command can be executed to do the lauching.
- ///
/// @param[in] args
/// The command line to launch.
///
@@ -170,8 +168,6 @@ public:
//------------------------------------------------------------------
/// Specify the launch flags for the process.
///
- /// The LaunchProcess () command can be executed to do the lauching.
- ///
/// @param[in] launch_flags
/// The launch flags to use when launching this process.
///
@@ -543,6 +539,9 @@ private:
void
ClearProcessSpecificData ();
+ bool
+ ShouldRedirectInferiorOutputOverGdbRemote (const lldb_private::ProcessLaunchInfo &launch_info) const;
+
//------------------------------------------------------------------
// For GDBRemoteCommunicationServer only
//------------------------------------------------------------------
diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
index d2dc2465e8d..fe99706969c 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -748,8 +748,12 @@ ProcessGDBRemote::WillLaunchOrAttach ()
Error
ProcessGDBRemote::DoLaunch (Module *exe_module, ProcessLaunchInfo &launch_info)
{
+ Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
Error error;
+ if (log)
+ log->Printf ("ProcessGDBRemote::%s() entered", __FUNCTION__);
+
uint32_t launch_flags = launch_info.GetFlags().Get();
const char *stdin_path = NULL;
const char *stdout_path = NULL;
@@ -776,10 +780,21 @@ ProcessGDBRemote::DoLaunch (Module *exe_module, ProcessLaunchInfo &launch_info)
stderr_path = file_action->GetPath();
}
+ if (log)
+ {
+ if (stdin_path || stdout_path || stderr_path)
+ log->Printf ("ProcessGDBRemote::%s provided with STDIO paths via launch_info: stdin=%s, stdout=%s, stdout=%s",
+ __FUNCTION__,
+ stdin_path ? stdin_path : "<null>",
+ stdout_path ? stdout_path : "<null>",
+ stderr_path ? stderr_path : "<null>");
+ else
+ log->Printf ("ProcessGDBRemote::%s no STDIO paths given via launch_info", __FUNCTION__);
+ }
+
// ::LogSetBitMask (GDBR_LOG_DEFAULT);
// ::LogSetOptions (LLDB_LOG_OPTION_THREADSAFE | LLDB_LOG_OPTION_PREPEND_TIMESTAMP | LLDB_LOG_OPTION_PREPEND_PROC_AND_THREAD);
// ::LogSetLogFile ("/dev/stdout");
- Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
ObjectFile * object_file = exe_module->GetObjectFile();
if (object_file)
@@ -816,6 +831,13 @@ ProcessGDBRemote::DoLaunch (Module *exe_module, ProcessLaunchInfo &launch_info)
if (stderr_path == NULL)
stderr_path = slave_name;
+
+ if (log)
+ log->Printf ("ProcessGDBRemote::%s adjusted STDIO paths for local platform (IsHost() is true) using slave: stdin=%s, stdout=%s, stdout=%s",
+ __FUNCTION__,
+ stdin_path ? stdin_path : "<null>",
+ stdout_path ? stdout_path : "<null>",
+ stderr_path ? stderr_path : "<null>");
}
// Set STDIN to /dev/null if we want STDIO disabled or if either
@@ -833,7 +855,14 @@ ProcessGDBRemote::DoLaunch (Module *exe_module, ProcessLaunchInfo &launch_info)
if (disable_stdio || (stderr_path == NULL && (stdin_path || stdout_path)))
stderr_path = "/dev/null";
- if (stdin_path)
+ if (log)
+ log->Printf ("ProcessGDBRemote::%s final STDIO paths after all adjustments: stdin=%s, stdout=%s, stdout=%s",
+ __FUNCTION__,
+ stdin_path ? stdin_path : "<null>",
+ stdout_path ? stdout_path : "<null>",
+ stderr_path ? stderr_path : "<null>");
+
+ if (stdin_path)
m_gdb_comm.SetSTDIN (stdin_path);
if (stdout_path)
m_gdb_comm.SetSTDOUT (stdout_path);
@@ -1025,18 +1054,38 @@ ProcessGDBRemote::DidLaunchOrAttach (ArchSpec& process_arch)
// prefer that over the Host information as it will be more specific
// to our process.
- if (m_gdb_comm.GetProcessArchitecture().IsValid())
- process_arch = m_gdb_comm.GetProcessArchitecture();
+ const ArchSpec &remote_process_arch = m_gdb_comm.GetProcessArchitecture();
+ if (remote_process_arch.IsValid())
+ {
+ process_arch = remote_process_arch;
+ if (log)
+ log->Printf ("ProcessGDBRemote::%s gdb-remote had process architecture, using %s %s",
+ __FUNCTION__,
+ process_arch.GetArchitectureName () ? process_arch.GetArchitectureName () : "<null>",
+ process_arch.GetTriple().getTriple ().c_str() ? process_arch.GetTriple().getTriple ().c_str() : "<null>");
+ }
else
+ {
process_arch = m_gdb_comm.GetHostArchitecture();
+ if (log)
+ log->Printf ("ProcessGDBRemote::%s gdb-remote did not have process architecture, using gdb-remote host architecture %s %s",
+ __FUNCTION__,
+ process_arch.GetArchitectureName () ? process_arch.GetArchitectureName () : "<null>",
+ process_arch.GetTriple().getTriple ().c_str() ? process_arch.GetTriple().getTriple ().c_str() : "<null>");
+ }
if (process_arch.IsValid())
{
ArchSpec &target_arch = GetTarget().GetArchitecture();
-
if (target_arch.IsValid())
{
- // If the remote host is ARM and we have apple as the vendor, then
+ if (log)
+ log->Printf ("ProcessGDBRemote::%s analyzing target arch, currently %s %s",
+ __FUNCTION__,
+ target_arch.GetArchitectureName () ? target_arch.GetArchitectureName () : "<null>",
+ target_arch.GetTriple().getTriple ().c_str() ? target_arch.GetTriple().getTriple ().c_str() : "<null>");
+
+ // If the remote host is ARM and we have apple as the vendor, then
// ARM executables and shared libraries can have mixed ARM architectures.
// You can have an armv6 executable, and if the host is armv7, then the
// system will load the best possible architecture for all shared libraries
@@ -1047,6 +1096,11 @@ ProcessGDBRemote::DidLaunchOrAttach (ArchSpec& process_arch)
process_arch.GetTriple().getVendor() == llvm::Triple::Apple)
{
GetTarget().SetArchitecture (process_arch);
+ if (log)
+ log->Printf ("ProcessGDBRemote::%s remote process is ARM/Apple, setting target arch to %s %s",
+ __FUNCTION__,
+ process_arch.GetArchitectureName () ? process_arch.GetArchitectureName () : "<null>",
+ process_arch.GetTriple().getTriple ().c_str() ? process_arch.GetTriple().getTriple ().c_str() : "<null>");
}
else
{
@@ -1065,7 +1119,14 @@ ProcessGDBRemote::DidLaunchOrAttach (ArchSpec& process_arch)
target_triple.setEnvironment (remote_triple.getEnvironment());
}
}
+
}
+
+ if (log)
+ log->Printf ("ProcessGDBRemote::%s final target arch after adjustments for remote architecture: %s %s",
+ __FUNCTION__,
+ target_arch.GetArchitectureName () ? target_arch.GetArchitectureName () : "<null>",
+ target_arch.GetTriple().getTriple ().c_str() ? target_arch.GetTriple().getTriple ().c_str() : "<null>");
}
else
{
@@ -1094,7 +1155,12 @@ ProcessGDBRemote::DoAttachToProcessWithID (lldb::pid_t attach_pid)
Error
ProcessGDBRemote::DoAttachToProcessWithID (lldb::pid_t attach_pid, const ProcessAttachInfo &attach_info)
{
+ Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
Error error;
+
+ if (log)
+ log->Printf ("ProcessGDBRemote::%s()", __FUNCTION__);
+
// Clear out and clean up from any current state
Clear();
if (attach_pid != LLDB_INVALID_PROCESS_ID)
@@ -1117,13 +1183,14 @@ ProcessGDBRemote::DoAttachToProcessWithID (lldb::pid_t attach_pid, const Process
if (error.Success())
{
m_gdb_comm.SetDetachOnError(attach_info.GetDetachOnError());
-
+
char packet[64];
const int packet_len = ::snprintf (packet, sizeof(packet), "vAttach;%" PRIx64, attach_pid);
SetID (attach_pid);
m_async_broadcaster.BroadcastEvent (eBroadcastBitAsyncContinue, new EventDataBytes (packet, packet_len));
}
}
+
return error;
}
OpenPOWER on IntegriCloud