[PATCH] Remote debugging without a binary (regression)

Luis Machado
2016-02-11T14:19:45Z

cc-ing Gary.

It looks like this is fallout from the changes that were added to make
GDB a bit smarter about locating the binary that is being debugged.

When one attempts to do gdbserver-based debugging in the same
machine/filesystem, there is no problem at all.

If the user wants to have the files transfered over the wire, GDB will
handle it. If the user sets a local sysroot path and doesn't want the
file coming through the wire, GDB will use process information to
attempt to locate the binary in the local filesystem.

Now, considering we have a GDB instance running on a local machine and
a gdbserver instance running on a remote machine with a completely separate
filesystem, having the sysroot set will prevent the file from being
downloaded.

GDB will then attempt to be smart and locate the binary through the path that
is reported by gdbserver. This path is from the remote filesystem though, so
there is a chance this file won't even exist in the local filesystem.

In a normal native session (where we start the process from scratch) this would
result in a "No such file or directory" error. And that is fine, because we
really need a binary to get the process started.

But with a local GDB plus a remote gdbserver on a different filesystem, we will
see the same error and the debugging session will end abruptly, giving the user
no chance of doing some debugging without a symbol file.

--
Remote debugging using some_machine:12345
<some_remote_filesystem_path/gdb.d/gdb.base/break: No such file or directory.
--

I tracked this down to remote_add_inferior and its call to (mainly)
exec_file_locate_attach. This specific function will call other functions
that may throw an error, causing everything to stop dead on its tracks.

The following patch guards such a call to prevent those errors from
disrupting a potential debugging session, and display only a warning.

--
Remote debugging using some_machine:12345
warning: <some_remote_filesystem_path/gdb.d/gdb.base/break: No such file or directory.
--

I tried to come up with a valid testcase that would fail with a local
gdb/gdbserver combination, but it seems GDB is smart enough to recognize
a deleted binary with the help of /proc, thus foiling my attempts.

Any ideas?

gdb/ChangeLog:

2016-02-11 Luis Machado <lgustavo@codesourcery.com>

* remote.c (remote_add_inferior): Guard block that can throw
errors.
---
gdb/remote.c | 30 ++++++++++++++++++++++++++----
1 file changed, 26 insertions(+), 4 deletions(-)

diff --git a/gdb/remote.c b/gdb/remote.c
index 6d56f19..3b63e9f 100644
--- a/gdb/remote.c
+++ b/gdb/remote.c
@@ -1789,10 +1789,32 @@ remote_add_inferior (int fake_pid_p, int pid, int attached,
inf->attach_flag = attached;
inf->fake_pid_p = fake_pid_p;

- /* If no main executable is currently open then attempt to
- open the file that was executed to create this inferior. */
- if (try_open_exec && get_exec_file (0) == NULL)
- exec_file_locate_attach (pid, 1);
+
+ /* exec_file_locate_attach may throw an error if the file cannot be
+ opened either locally or remotely. This happens when, for example,
+ GDB connects to a gdbserver that is running on a different
+ filesystem and the sysroot is set to non-target-based (no "target:").
+
+ Then GDB will neither load the binary from the target nor be able to
+ load a binary from the local filesystem (it may not exist in the local
+ filesystem in the same path as in the remote filesystem).
+
+ Even without a binary, the remote-based debugging session should
+ continue normally instead of ending abruptly. */
+
+ TRY
+ {
+ /* If no main executable is currently open then attempt to
+ open the file that was executed to create this inferior. */
+ if (try_open_exec && get_exec_file (0) == NULL)
+ exec_file_locate_attach (pid, 1);
+ }
+ CATCH (err, RETURN_MASK_ALL)
+ {
+ if (err.message != NULL)
+ warning ("%s", err.message);
+ }
+ END_CATCH

return inf;
}
--
1.9.1