This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] Remote debugging without a binary (regression)


On 02/12/2016 08:31 AM, Gary Benson wrote:
Luis Machado wrote:
On 02/11/2016 02:35 PM, Gary Benson wrote:
Luis Machado wrote:
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.

I don't have any fundamental objection to your patch but I'm not
really sure I understand what's going on here.  You have the
sysroot set to some path that does not exist?  What are you trying
to do and what are you expecting to be able to do?  What did GDB
do before?

No. The sysroot being anything other than "target:" is needed is
order to prevent gdbserver from transfering the files over (too
slow). Plus, i'm not loading any symbol file on GDB's side.

So i'm trying to connect to a gdbserver running on a remote system
with a separate filesystem. gdbserver will now report the full path
to the binary on the remote end via the new qXfer:exec-file packet,
even if i force the sysroot to be empty.

In summary, GDB (running on a local machine) is attempting to use
that path provided by qXfer:exec-file to open a symbol file that
only exists on the remote end's filesystem, not in the local
filesystem where GDB is running.

If GDB fails to locate that file, it will drop the connection due to
a error that is thrown from within exec_file_locate_attach and its
callees.

The correct behavior is for GDB to ignore the lack of a symbol file
and carry on connecting to the remote target, allowing a symbol-less
debugging session.

Does that make it clear?

I'm getting there, but I have a couple more questions:

1) What exactly are you setting sysroot to?  Is it:
     - the empty string
     - a directory full of shared libraries but not the main executable
     - an empty directory
     - a non-existent directory?


It doesn't matter, as long as it is not "target:", meaning we really don't want to load files using the help of gdbserver.

2) What exactly is the error being thrown within exec_file_locate_attach?


The one i mentioned above:

<some_remote_filesystem_path>/gdb.d/gdb.base/break: No such file or directory.

This comes from exec_file_attach. In my specific case above, this is thrown from gdb/exec.c:268, a call to perror_with_name.

          if (scratch_chan < 0)
            perror_with_name (filename);

It seems this was introduced with commit 1b6e6f5c7ffba559a681d11852acf38ef48dceff, with the addition of a call to exec_file_locate_attach from within remote_add_inferior.

That unguarded call to exec_file_locate_attach doesn't look safe since its callees can throw errors and potentially disrupt a connection attempt.

FWIW I tried this (both on the same machine):


Doing so with both on the same machine/filesystem will not reproduce the problem, as i mentioned in my original post. GDB and gdbserver need to be on separate filesystems.

   gdbserver :9999 /bin/ls
   gdb -q -ex "set sysroot /whatever" -ex "target remote :9999"

and got this:

   Reading symbols from /bin/ls...(no debugging symbols found)...done.

which I think is an error: the sysroot is being ignored.


Isn't it being ignored because GDB managed to figure out the path and successfully open the symbol file?

If it should honor the sysroot in that case, that looks like a different problem than the one i was originally chasing. There may be more bugs. :-)

Once again, I have no fundamental problem with your patch, but I want
to make sure we're not papering over some deeper issue.

Thanks,
Gary



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]