Commit Graph

119858 Commits

Author SHA1 Message Date
Andrew Burgess
6cce025114 gdb: only insert thread-specific breakpoints in the relevant inferior
This commit updates GDB so that thread or inferior specific
breakpoints are only inserted into the program space in which the
specific thread or inferior is running.

In terms of implementation, getting this basically working is easy
enough, now that a breakpoint's thread or inferior field is setup
prior to GDB looking for locations, we can easily use this information
to find a suitable program_space and pass this to as a filter when
creating the sals.

Or we could if breakpoint_ops::create_sals_from_location_spec allowed
us to pass in a filter program_space.

So, this commit extends breakpoint_ops::create_sals_from_location_spec
to take a program_space argument, and uses this to filter the set of
returned sals.  This accounts for about half the change in this patch.

The second set of changes starts from breakpoint_set_thread and
breakpoint_set_inferior, this is called when the thread or inferior
for a breakpoint changes, e.g. from the Python API.

Previously this call would never result in the locations of a
breakpoint changing, after all, locations were inserted in every
program space, and we just use the thread or inferior variable to
decide when we should stop.  Now though, changing a breakpoint's
thread or inferior can mean we need to figure out a new set of
breakpoint locations.

To support this I've added a new breakpoint_re_set_one function, which
is like breakpoint_re_set, but takes a single breakpoint, and just
updates the locations for that one breakpoint.  We only need to call
this function if the program_space in which a breakpoint's thread (or
inferior) is running actually changes.  If the program_space does
change then we call the new breakpoint_re_set_one function passing in
the program_space which should be used to filter the new locations (or
nullptr to indicate we should set locations in all program spaces).
This filter program_space needs to propagate down to all the re_set
methods, this accounts for the remaining half of the changes in this
patch.

There were a couple of existing tests that created thread or inferior
specific breakpoints and then checked the 'info breakpoints' output,
these needed updating.  These were:

  gdb.mi/user-selected-context-sync.exp
  gdb.multi/bp-thread-specific.exp
  gdb.multi/multi-target-continue.exp
  gdb.multi/multi-target-ping-pong-next.exp
  gdb.multi/tids.exp
  gdb.mi/new-ui-bp-deleted.exp
  gdb.multi/inferior-specific-bp.exp
  gdb.multi/pending-bp-del-inferior.exp

I've also added some additional tests to:

  gdb.multi/pending-bp.exp

I've updated the documentation and added a NEWS entry.

Reviewed-By: Eli Zaretskii <eliz@gnu.org>
2024-09-07 21:48:35 +01:00
Andrew Burgess
85eb08c5f0 gdb: don't set breakpoint::pspace in create_breakpoint
I spotted this code within create_breakpoint:

  if ((type_wanted != bp_breakpoint
      && type_wanted != bp_hardware_breakpoint) || thread != -1)
   b->pspace = current_program_space;

this code is only executed when creating a pending breakpoint, and
sets the breakpoint::pspace member variable.

The above code gained the 'thread != -1' clause with this commit:

  commit cc72b2a2da
  Date:   Fri Dec 23 17:06:16 2011 +0000

              Introduce gdb.FinishBreakpoint in Python

While the type_wanted checks were added with this commit:

  commit f8eba3c616
  Date:   Tue Dec 6 18:54:43 2011 +0000

      the "ambiguous linespec" series

Before this breakpoint::pspace was set unconditionally.

If we look at how breakpoint::pspace is used today, some breakpoint
types specifically set this field, either in their constructors, or in
a wrapper function that calls the constructor.  So, the watchpoint
type and its sub-class set this variable, as does the catchpoint type,
and all it's sub-classes.

However, code_breakpoint doesn't specifically set this field within
its constructor, though some sub-classes of
code_breakpoint (ada_catchpoint, exception_catchpoint,
internal_breakpoint, and momentary_breakpoint) do set this field.

When I examine all the places that breakpoint::pspace is used, I
believe that in every place where it is expected that this field is
set, the breakpoint type will be one that specifically sets this
field.

Next, I observe two problems with the existing code.

First, the above code is only hit for pending breakpoints, there's no
equivalent code for non-pending breakpoints.  This opens up the
possibility of GDB entering non-consistent states; if a breakpoint is
first created pending and then later gets a location, the pspace field
will be set, while if the breakpoint is immediately non-pending, then
the pspace field will never be set.

Second, if we look at how breakpoint::pspace is used in the function
breakpoint_program_space_exit, we see that when a program space is
removed, any breakpoint with breakpoint::pspace set to the removed
program space, will be deleted.  This makes sense, but does mean we
need to ensure breakpoint::pspace is only set for breakpoints that
apply to a single program space.

So, if I create a pending dprintf breakpoint (type bp_dprintf) then
the breakpoint::pspace variable will be set even though the dprintf is
not really tied to that one program space.  As a result, when the
matching program space is removed the dprintf is incorrectly removed.

Also, if I create a thread specific breakpoint, then, thanks to the
'thread != -1' clause the wrong program space will be stored in
breakpoint::pspace (the current program space is always used, which
might not be the program space that corresponds to the selected
thread), as a result, the thread specific breakpoint will be deleted
when the matching program space is removed.

If we look at commit cc72b2a2da which added the 'thread != -1'
clause, we can see this change was entirely redundant, the
breakpoint::pspace is also set in bpfinishpy_init after
create_breakpoint has been called.  As such, I think we can safely
drop the 'thread != -1' clause.

For the other problems, I'm proposing to be pretty aggressive - I'd
like to drop the breakpoint::pspace assignment completely from
create_breakpoint.  Having looked at how this variable is used, I
believe that it is already set elsewhere in all the cases that it is
needed.  Maybe this code was needed at one time, but I can't see how
it's needed any more.

There's tests to expose the issues I've spotted with this code, and
there's no regressions in testing.
2024-09-07 21:48:35 +01:00
Andrew Burgess
c6b486755e gdb: parse pending breakpoint thread/task immediately
The initial motivation for this commit was to allow thread or inferior
specific breakpoints to only be inserted within the appropriate
inferior's program-space.  The benefit of this is that inferiors for
which the breakpoint does not apply will no longer need to stop, and
then resume, for such breakpoints.  This commit does not make this
change, but is a refactor to allow this to happen in a later commit.

The problem we currently have is that when a thread-specific (or
inferior-specific) breakpoint is created, the thread (or inferior)
number is only parsed by calling find_condition_and_thread_for_sals.
This function is only called for non-pending breakpoints, and requires
that we know the locations at which the breakpoint will be placed (for
expression checking in case the breakpoint is also conditional).

A consequence of this is that by the time we figure out the breakpoint
is thread-specific we have already looked up locations in all program
spaces.  This feels wasteful -- if we knew the thread-id earlier then
we could reduce the work GDB does by only looking up locations within
the program space for which the breakpoint applies.

Another consequence of how find_condition_and_thread_for_sals is
called is that pending breakpoints don't currently know they are
thread-specific, nor even that they are conditional!  Additionally, by
delaying parsing the thread-id, pending breakpoints can be created for
non-existent threads, this is different to how non-pending
breakpoints are handled, so I can do this:

  $ gdb -q ./gdb/testsuite/outputs/gdb.multi/pending-bp/pending-bp
  Reading symbols from ./gdb/testsuite/outputs/gdb.multi/pending-bp/pending-bp...
  (gdb) break foo thread 99
  Function "foo" not defined.
  Make breakpoint pending on future shared library load? (y or [n]) y
  Breakpoint 1 (foo thread 99) pending.
  (gdb) r
  Starting program: /tmp/gdb/testsuite/outputs/gdb.multi/pending-bp/pending-bp
  [Thread debugging using libthread_db enabled]
  Using host libthread_db library "/lib64/libthread_db.so.1".
  Error in re-setting breakpoint 1: Unknown thread 99.
  [Inferior 1 (process 3329749) exited normally]
  (gdb)

GDB only checked the validity of 'thread 99' at the point the 'foo'
location became non-pending.  In contrast, if I try this:

  $ gdb -q ./gdb/testsuite/outputs/gdb.multi/pending-bp/pending-bp
  Reading symbols from ./gdb/testsuite/outputs/gdb.multi/pending-bp/pending-bp...
  (gdb) break main thread 99
  Unknown thread 99.
  (gdb)

GDB immediately checks if 'thread 99' exists.  I think inconsistencies
like this are confusing, and should be fixed if possible.

In this commit the create_breakpoint function is updated so that the
extra_string, which contains the thread, inferior, task, and/or
condition information, is parsed immediately, even for pending
breakpoints.

Obviously, the condition still can't be validated until the breakpoint
becomes non-pending, but the thread, inferior, and task information
can be pulled from the extra-string, and can be validated early on,
even for pending breakpoints.  The -force-condition flag is also
parsed as part of this early parsing change.

There are a couple of benefits to doing this:

1. Printing of breakpoints is more consistent now.  Consider creating
   a conditional breakpoint before this commit:

    (gdb) set breakpoint pending on
    (gdb) break pendingfunc if (0)
    Function "pendingfunc" not defined.
    Breakpoint 1 (pendingfunc if (0)) pending.
    (gdb) break main if (0)
    Breakpoint 2 at 0x401198: file /tmp/hello.c, line 18.
    (gdb) info breakpoints
    Num     Type           Disp Enb Address            What
    1       breakpoint     keep y   <PENDING>          pendingfunc if (0)
    2       breakpoint     keep y   0x0000000000401198 in main at /tmp/hello.c:18
            stop only if (0)
    (gdb)

   And after this commit:

    (gdb) set breakpoint pending on
    (gdb) break pendingfunc if (0)
    Function "pendingfunc" not defined.
    Breakpoint 1 (pendingfunc) pending.
    (gdb) break main if (0)
    Breakpoint 2 at 0x401198: file /home/andrew/tmp/hello.c, line 18.
    (gdb) info breakpoints
    Num     Type           Disp Enb Address            What
    1       breakpoint     keep y   <PENDING>          pendingfunc
            stop only if (0)
    2       breakpoint     keep y   0x0000000000401198 in main at /home/andrew/tmp/hello.c:18
            stop only if (0)
    (gdb)

   Notice that the display of the condition is now the same for the
   pending and non-pending breakpoints.

   The same is true for the thread, inferior, or task information in
   thread, inferior, or task specific breakpoints; this information is
   displayed on its own line rather than being part of the 'What'
   field.

2. We can check that the thread exists as soon as the pending
   breakpoint is created.  Currently there is a weird difference
   between pending and non-pending breakpoints when creating a
   thread-specific breakpoint.

   A pending thread-specific breakpoint only checks its thread when it
   becomes non-pending, at which point the thread the breakpoint was
   intended for might have exited.  Here's the behaviour before this
   commit:

    (gdb) set breakpoint pending on
    (gdb) break foo thread 2
    Function "foo" not defined.
    Breakpoint 2 (foo thread 2) pending.
    (gdb) c
    Continuing.
    [Thread 0x7ffff7c56700 (LWP 2948835) exited]
    Error in re-setting breakpoint 2: Unknown thread 2.
    [Inferior 1 (process 2948832) exited normally]
    (gdb)

   Notice the 'Error in re-setting breakpoint 2: Unknown thread 2.'
   line, this was triggered when GDB tried to make the breakpoint
   non-pending, and GDB discovers that the thread no longer exists.

   Compare that to the behaviour after this commit:

    (gdb) set breakpoint pending on
    (gdb) break foo thread 2
    Function "foo" not defined.
    Breakpoint 2 (foo) pending.
    (gdb) c
    Continuing.
    [Thread 0x7ffff7c56700 (LWP 2949243) exited]
    Thread-specific breakpoint 2 deleted - thread 2 no longer in the thread list.
    [Inferior 1 (process 2949240) exited normally]
    (gdb)

   Now the behaviour for pending breakpoints is identical to
   non-pending breakpoints, the thread specific breakpoint is removed
   as soon as the thread the breakpoint is associated with exits.

   There is an additional change; when the pending breakpoint is
   created prior to this patch we see this line:

     Breakpoint 2 (foo thread 2) pending.

   While after this patch we get this line:

     Breakpoint 2 (foo) pending.

   Notice that 'thread 2' has disappeared.  This might look like a
   regression, but I don't think it is.  That we said 'thread 2'
   before was just a consequence of the lazy parsing of the breakpoint
   specification, while with this patch GDB understands, and has
   parsed away the 'thread 2' bit of the spec.  If folk think the old
   information was useful then this would be trivial to add back in
   code_breakpoint::say_where.

As a result of this commit the breakpoints 'extra_string' field is now
only used by bp_dprintf type breakpoints to hold the printf format and
arguments.  This string should always be empty for other breakpoint
types.  This allows some cleanup in print_breakpoint_location.

In code_breakpoint::code_breakpoint I've changed an error case into an
assert.  This is because the error is now handled earlier in
create_breakpoint.  As a result we know that by this point, the
extra_string will always be nullptr for anything other than a
bp_dprintf style breakpoint.

The find_condition_and_thread_for_sals function is now no longer
needed, this was previously doing the delayed splitting of the extra
string into thread, task, and condition, but this is now all done in
create_breakpoint, so find_condition_and_thread_for_sals can be
deleted, and the code that calls this in
code_breakpoint::location_spec_to_sals can be removed.  With this
update this code would only ever be reached for bp_dprintf style
breakpoints, and in these cases the extra_string should not contain
anything other than format and args.

The most interesting changes are all in create_breakpoint and in the
new file break-cond-parse.c.  We have a new block of code early on in
create_breakpoint that is responsible for splitting the extra_string
into its component parts by calling create_breakpoint_parse_arg_string
a function in the new break-cond-parse.c file.  This means that some
of the later code can be simplified a little.

The new break-cond-parse.c file implements the splitting up the
extra_string and finding all the parts, as well as some self-tests for
the new function.

Finally, now we know all the breakpoint details, these can be stored
within the breakpoint object if we end up creating a deferred
breakpoint.  Additionally, if we are creating a deferred bp_dprintf we
can parse the extra_string to build the printf command.

The implementation here aims to maintain backwards compatibility as
much as possible, this means that:

  1. We support abbreviations of 'thread', 'task', and 'inferior' in
  some places on the breakpoint line.  The handling of abbreviations
  has (before this patch) been a little weird, so this works:

  (gdb) break *main th 1

  And creates a breakpoint at '*main' for thread 1 only, while this
  does not work:

  (gdb) break main th 1

  In this case GDB will try to find the symbol 'main th 1'.  This
  weirdness exists before and after this patch.

  2. The handling of '-force-condition' is odd, if this flag appears
  immediately after a condition then it will be treated as part of the
  condition, e.g.:

  (gdb) break main if 0 -force-condition
  No symbol "force" in current context.

  But we are fine with these alternatives:

  (gdb) break main if 0 thread 1 -force-condition
  (gdb) break main -force-condition if 0

  Again, this is just a quirk of how the breakpoint line used to be
  parsed, but I've maintained this for backward compatibility.  During
  review it was suggested that -force-condition should become an
  actual breakpoint flag (i.e. only valid after the 'break' command
  but before the function name), and I don't think that would be a
  terrible idea, however, that's not currently a trivial change, and I
  think should be done as a separate piece of work.  For now, this
  patch just maintains the current behaviour.

The implementation works by first splitting the breakpoint condition
string (everything after the location specification) into a list of
tokens, each token has a type and a value. (e.g. we have a THREAD
token where the value is the thread-id string).  The list of tokens is
validated, and in some cases, tokens are merged.  Then the values are
extracted from the remaining token list.

Consider this breakpoint command:

  (gdb) break main thread 1 if argc == 2

The condition string passed to create_breakpoint_parse_arg_string is
going to be 'thread 1 if argc == 2', which is then split into the
tokens:

  { THREAD: "1" } { CONDITION: "argc == 2" }

The thread-id (1) and the condition string 'argc == 2' are extracted
from these tokens and returns back to create_breakpoint.

Now consider this breakpoint command:

  (gdb) break some_function if ( some_var == thread )

Here the user wants a breakpoint if 'some_var' is equal to the
variable 'thread'.  However, when this is initially parsed we will
find these tokens:

  { CONDITION: "( some_var == " } { THREAD: ")" }

This is a consequence of how we have to try and figure out the
contents of the 'if' condition without actually parsing the
expression; parsing the expression requires that we know the location
in order to lookup the variables by name, and this can't be done for
pending breakpoints (their location isn't known yet), and one of the
points of this work is that we extract things like thread-id for
pending breakpoints.

And so, it is in this case that token merging takes place.  We check
if the value of a token appearing immediately after the CONDITION
token looks valid.  In this case, does ')' look like a valid
thread-id.  Clearly, in this case ')' does not, and so me merge the
THREAD token into the condition token, giving:

  { CONDITION: "( some_var == thread )" }

Which is what we want.

I'm sure that we might still be able to come up with some edge cases
where the parser makes the wrong choice.  I think long term the best
way to work around these would be to move the thread, inferior, task,
and -force-condition flags to be "real" command options for the break
command.  I am looking into doing this, but can't guarantee if/when
that work would be completed, so this patch should be reviewed assume
that the work will never arrive (though I hope it will).

Reviewed-By: Eli Zaretskii <eliz@gnu.org>
2024-09-07 21:48:35 +01:00
Andrew Burgess
5a7cfbb424 gdb: create new is_thread_id helper function
This is a refactoring commit that splits the existing parse_thread_id
function into two parts, and then adds a new is_thread_id function.

The core of parse_thread_id is split into parse_thread_id_1, which is
responsible for actually parsing a thread-id.  Then parse_thread_id is
responsible for taking a parsed thread-id and validating that it
references an actually existing inferior thread.

The new is_thread_id function also uses parse_thread_id_1, but doesn't
actually check that the inferior thread exists, instead, this new
function simply checks that a string looks like a thread-id.

This commit does not add a use for is_thread_id, this will be added in
the next commit.

This is a refactoring commit, there should be no user visible changes
after this commit.
2024-09-07 21:48:34 +01:00
Andrew Burgess
3debc0b348 gdb: add another overload of startswith
We already have one overload of the startswith function that takes a
std::string_view for both arguments.  A later patch in this series is
going to be improved by having an overload that takes one argument as
a std::string_view and the other argument as a plain 'char *'.

This commit adds the new overload, but doesn't make use of it (yet).
There should be no user visible changes after this commit.
2024-09-07 21:48:34 +01:00
Andrew Burgess
4764e22161 gdb: make breakpoint_debug_printf global
This commit makes breakpoint_debug_printf available outside of
breakpoint.c.  In a later commit I'll want to use this macro from
another file.

This is just a refactor, there should be no user visible changes after
this commit.
2024-09-07 21:48:34 +01:00
Tom Tromey
26d23d8e02 Remove tui_refresh_cmd_win
tui_refresh_cmd_win is no longer needed and can be replaced with a
call to the refresh_window method.
2024-09-07 14:23:04 -06:00
Tom Tromey
a35cc8ff85 Remove tui_wrefresh
This removes tui_wrefresh, moving the code into refresh_window.  We
remove tui_norefresh_window as well, because now the command window's
refresh_window has to do what tui_wrefresh previously did.
2024-09-07 14:23:04 -06:00
Tom Tromey
d3acf3d759 Rename tui_suppress_output
This patch renames tui_suppress_output to the more descriptive
tui_batch_rendering.  This code was never really correct, and was
based on a misunderstanding of the curses API.  The updated comments
describe the intended use of this class.

This also removes the erroneous tui_win_info::no_refresh.
wnoutrefresh does not prevent any output; rather, it copies from one
curses buffer to another but (unlike woutrefresh) without then
flushing to the screen.

tui_batch_rendering now works in the correct way: calling doupdate in
the destructor of the outermost instance, thus batching all screen
output until that point.

The patch adds instantiations of tui_batch_rendering to various spots,
to make sure it is active when refreshing.
2024-09-07 14:23:04 -06:00
Tom Tromey
8f934adf59 Clean up refreshing in TUI register window
This patch rearranges the TUI register window code a bit, removing a
call to tui_wrefresh and hoisting the calls to refresh_window to "more
outer" spots.

Reviewed-By: Alexandra Petlanova Hajkova <ahajkova@redhat.com>
2024-09-07 14:23:04 -06:00
Andrew Burgess
03ad29c86c gdb: 'target ...' commands now expect quoted/escaped filenames
This commit changes the 'target ...' commands that accept a filename
to take a quoted or escaped filename rather than a literal filename.

What this means in practice is that if you are specifying a filename
that contains no white space or quote characters, then nothing should
change, e.g.:

  target exec /path/to/some/file

works both before and after this commit.

However, if a user wishes to specify a file containing white space
then either the entire filename needs to be quoted, or the special
white space needs to be escaped.  Before this patch a user could
write:

  target exec /path/to a file/containing spaces

But after this commit the user would have to choose one of:

  target exec "/path/to a file/containing spaces"

or

  target exec /path/to\ a\ file/containing\ spaces

Obviously this is a potentially breaking change.  The benefit of
making this change is consistency.  Commands that take multiple
arguments (one of which is a filename) or in the future, commands that
take filename options, will always need to use quoted/escaped
filenames, so converting all unquoted filename commands to use quoting
or escaping makes the UI more consistent.

Additionally (though this is probably not a common problem), GDB
strips trailing white space from commands that the user enters.  As
such it is not possible to reference any file that ends in white space
unless the quoting / escaping style is used.  Though I suspect very
few users run into this problem!

The downside obviously is that this is a UI breaking change.

Reviewed-By: Eli Zaretskii <eliz@gnu.org>
2024-09-07 20:28:59 +01:00
Andrew Burgess
e454ae416a gdb: allow quoted filenames for commands that have custom completion
This commit changes how GDB processes command arguments for the
following commands:

  compile file
  maint print c-tdesc
  save gdb-index

After this commit these commands will now expect their single filename
argument to be (optionally) quoted if it contains any special
characters (e.g. whit space or quotes).

If the filename does not contain any special characters then nothing
changes.  As an example:

   (gdb) save gdb-index /path/to/some/directory/

will work before and after this patch.  However, if the directory
name contains a white space then before this patch a user would write:

  (gdb) save gdb-index /path/to some/directory/

But this will now fail as GDB will consider this as two arguments,
'/path/to' and 'some/directory/'.  To pass this single directory name
a user must now do one of these:

  (gdb) save gdb-index "/path/to some/directory/"
  (gdb) save gdb-index '/path/to some/directory/'
  (gdb) save gdb-index /path/to\ some/directory/

This brings these commands into line with commands like 'file' and
'symbol-file', which have supported quoted filenames for a while.

The motivation for this change is to make handling of filename
arguments consistent throughout GDB.  We can't move to all commands
taking non-quoted filenames as the non-quoted style only allows for a
single argument.  Additionally, the non-quoted style doesn't allow for
filenames that end in white space (though this is probably pretty
rare).  So, if we want to have consistency the only choice is to move
towards supporting quote filenames.

Reviewed-By: Eli Zaretskii <eliz@gnu.org>
2024-09-07 20:28:59 +01:00
Andrew Burgess
d552429eda gdb: add remove-symbol-file command completion
The 'remove-symbol-file' command doesn't currently offer command
completion.  This commit addresses this.

The 'remove-symbol-file' uses gdb_argv to split its command arguments,
this means that the filename the command expects can be quoted.

However, the 'remove-symbol-file' command is a little weird in that it
also has a '-a' option, if this option is passed then the command
expects not a filename, but an address.

Currently the remove_symbol_file_command function splits the command
args using gdb_argv, checks for a '-a' flag by looking at the first
argument value, and then expects the filename or address to occupy a
single entry in the gdb_argv array.

The first thing I do is handle the '-a' flag using GDB's option
system.  I model this option as a flag_option_def (a boolean option).

I've dropped the use of gdb_argv and instead use the new(ish) function
extract_single_filename_arg, which was added a couple of commits back,
to parse the filename argument (when '-a' is not given).

If '-a' is given the the remove-symbol-file command expects an address
rather than a filename.  As we previously split the arguments using
gdb_argv this meant the address needed to appear as a single
argument.  So a user could write:

  (gdb) remove-symbol-file 0x1234

Or they could write:

  (gdb) remove-symbol-file some_function

Both of these would work fine.  But a user could not write:

  (gdb) remove-symbol-file some_function + 0x1000

As only the 'some_function' part would be processed.  Now the user
could do this:

  (gdb) remove-symbol-file "some_function + 0x1000"

By enclosing the address expression in quotes this would be handled as
a single argument.  However, this is a little weird, that's not how
commands like 'print' or 'x' work.  Also this functionality was
neither documented, or tested.

And so, in this commit, by removing the use of gdb_argv I bring the
'remove-symbol-file' command inline with GDB's other commands that
take an expression, the quotes are no longer needed.

Usually in a completer we call 'complete_options', but don't actually
capture the option values.  But for remove-symbol-file I do.  This
allows me to spot when the '-a' option has been given, I can then
complete the rest of the command line as either a filename or an
expression.

Reviewed-By: Eli Zaretskii <eliz@gnu.org>
2024-09-07 20:28:59 +01:00
Andrew Burgess
1be3b2e82f gdb: extend completion of quoted filenames to work in brkchars phase
Up to this point filename completion for possibly quoted filenames has
always been handled during the second (non-brkchars) phase of
completion.  This works fine for commands that only want to complete
on a single filename argument.

In a later commit though I need to perform completion of a quoted
filename argument during the first (brkchars) phase of completion.
This will allow me to add a custom completer that completes both
command options and arguments for a command (remove-symbol-file) that
takes a possibly quoted filename argument.

This commit doesn't add the remove-symbol-file completer, this commit
is just about putting support for that in place.

To achieve this I've added the new function
advance_to_filename_maybe_quoted_complete_word_point, which is unused
in this commit.  I've then had to extend some other functions in order
to extract the quoting state during the brkchars phase.

As this commit doesn't use the new functionality, the important thing
at this point is that I've not regressed the existing filename
completion (or any of the other completion).  The next commit in this
series will make use of the new functionality, and will include
tests.

There should be no user visible changes after this commit.
2024-09-07 20:28:59 +01:00
Andrew Burgess
1217ae6726 gdb: new extract_single_filename_arg helper function
This commit is in preparation for the next few commits, this commit
adds a new function extract_single_filename_arg.

This new function will be used to convert GDB commands that expect a
single filename argument to have these commands take a possibly quoted
or escaped string.

There's no use of the new function in this commit, for that see the
following commits.
2024-09-07 20:28:58 +01:00
Andrew Burgess
67b8e30af9 gdb: implement readline rl_directory_rewrite_hook callback
Implement the readline rl_directory_rewrite_hook callback function,
this is used when readline needs to offer completions from within a
directory.  The important thing is that this function should remove
any escaping, this allows GDB to correctly offer completions in
situations like this:

  (gdb) file /tmp/directory\ with\ spaces/<TAB><TAB>

Note the escaping in 'directory\ with\ spaces'.  Without the
rl_directory_rewrite_hook callback readline will try to open a
directory literally called '/tmp/directory\ with\ spaces' which
obviously doesn't exist.

There are tests added to cover this new functionality.
2024-09-07 20:28:58 +01:00
Andrew Burgess
8f87fcb1da gdb: improve gdb_rl_find_completion_word for quoted words
The function gdb_rl_find_completion_word is very similar to the
readline function _rl_find_completion_word, but was either an older
version of that function, or was trimmed when copying to remove code
which was considered unnecessary.

We maintain this copy because the _rl_find_completion_word function is
not part of the public readline API, and we need to replicate the
functionality of that function as part of the 'complete' command.

Within gdb_rl_find_completion_word when looking for the completion
word, if we don't find a unclosed quoted string (which would become
the completion word) then we scan backwards looking for a word break
character.  For example, given:

  (gdb) complete file /tmp/foo

There is no unclosed quoted string so we end up scanning backwards
from the end looking for a word break character.  In this case the
space after 'file' and before '/tmp/foo' is found, so '/tmp/foo'
becomes the completion word.

However, given this:

  (gdb) complete file /tmp/foo\"

There is still no unclosed quoted string, however, when we can
backwards the '"' (double quotes) are treated as a word break
character, and so we end up using the empty string as the completion
word.

The readline function _rl_find_completion_word avoids this mistake by
using the rl_char_is_quoted_p hook.  This function will return true
for the double quote character as it is preceded by a backslash.  An
earlier commit in this series supplied a rl_char_is_quoted_p function
for the filename completion case, however, gdb_rl_find_completion_word
doesn't call rl_char_is_quoted_p so this doesn't help for the
'complete' case.

In this commit I've copied the code to call rl_char_is_quoted_p from
_rl_find_completion_word into gdb_rl_find_completion_word.

This half solves the problem.  In the case:

  (gdb) complete file /tmp/foo\"

We do now try to complete on the string '/tmp/foo\"', however, when we
reach filename_completer we call back into readline to actually
perform filename completion.  However, at this point the WORD variable
points to a string that still contains the backslash.  The backslash
isn't part of the actual filename, that's just an escape character.

Our expectation is that readline will remove the backslash when
looking for matching filenames.  However, readline contains an
optimisation to avoid unnecessary work trying to remove escape
characters.

The readline variable rl_completion_found_quote is set in the readline
function gen_completion_matches before the generation of completion
matches.  This variable is set to true (non-zero) if there is (or
might be) escape characters within the completion word.

The function rl_filename_completion_function, which generates the
filename matches, only removes escape characters when
rl_completion_found_quote is true.  When GDB generates completions
through readline (e.g. tab completion) then rl_completion_found_quote
is set correctly.

But when we use the 'complete' command we don't pass through readline,
and so gen_completion_matches is never called and
rl_completion_found_quote is not set.  In this case when we call
rl_filename_completion_function readline doesn't remove the escapes
from the completion word, and so in our case above, readline looks for
completions of the exact filename '/tmp/foo\"', that is, the filename
including the backslash.

To work around this problem I've added a new flag to our function
gdb_rl_find_completion_word which is set true when we find any quoting
or escaping.  This matches what readline does.

Then in the 'complete' function we can set rl_completion_found_quote
prior to generating completion matches.

With this done the 'complete' command now works correctly when trying
to complete filenames that contain escaped word break characters.  The
tests have been updated accordingly.
2024-09-07 20:28:58 +01:00
Andrew Burgess
f2f866c6ca gdb: apply escaping to filenames in 'complete' results
Building on the mechanism added in the previous commit(s), this commit
applies escaping to filenames in the 'complete' command output.
Consider a file: /tmp/xxx/aa"bb -- that is a filename that contains a
double quote, currently the 'complete' command output looks like this:

  (gdb) complete file /tmp/xxx/a
  file /tmp/xxx/aa"bb

Notice that the double quote in the output is not escaped.  If we
passed this same output back to GDB then the double quote will be
treated as the start of a string.

After this commit then the output looks like this:

  (gdb) complete file /tmp/xxx/a
  file /tmp/xxx/aa\"bb

The double quote is now escaped.  If we feed this output back to GDB
then GDB will treat this as a single filename that contains a double
quote, exactly what we want.

To achieve this I've done a little refactoring, splitting out the core
of gdb_completer_file_name_quote, and then added a new call from the
filename_match_formatter function.

There are updates to the tests to cover this new functionality.
2024-09-07 20:28:58 +01:00
Andrew Burgess
2bebc9ee27 gdb: add match formatter mechanism for 'complete' command output
This commit solves a problem that existed prior to the previous
commit, but the previous commit made more common.

When completing a filename with the 'complete' command GDB will always
add a trailing quote character, even if the completion is a directory
name, in which case it would be better if the trailing quote was not
added.  Consider:

  (gdb) complete file '/tmp/xx
  file '/tmp/xxx/'

The completion offered here is really only a partial completion, we've
completed up to the end of the next directory name, but, until we have
a filename then the completion is not finished and the trailing quote
should not be added.

This would match the readline behaviour, e.g.:

  (gdb) file '/tmp/xx<TAB>
  (gdb) file '/tmp/xxx/

In this case readline completes the directory name, but doesn't add
the trailing quote character.

Remember that the 'complete' command is intended for tools like
e.g. emacs in order that they can emulate GDB's standard readline
completion when implementing a CLI of their own.  As such, not adding
the trailing quote in this case matches the readline behaviour, and
seems like the right way to go.

To achieve this, I've added a new function pointer member variable
completion_result::m_match_formatter.  This contains a pointer to a
callback function which is used by the 'complete' command to format
each result.

The default behaviour of this callback function is to just append the
quote character (the character from before the completion string) to
the end of the completion result.  This matches the current behaviour.

However, for filename completion we override the default value of
m_match_formatter, this new function checks if the completion result
is a directory or not.  If the completion result is a directory then
the closing quote is not added, instead we add a trailing '/'
character.

The code to add a trailing '/' character already exists within the
filename_completer function.  This is no longer needed in this
location, instead this code is moved into the formatter callback.

Tests are updated to handle the changes in functionality, this removes
an xfail added in the previous commit.
2024-09-07 20:28:58 +01:00
Andrew Burgess
bbbfe4af4f gdb: simplify completion_result::print_matches
Simplify completion_result::print_matches by removing one of the code
paths.  Now, every time we call ::print_matches we always add the
trailing quote.

Previously, when using the 'complete' command, if there was only one
result then trailing quote was added in ::build_completion_result, but
when we had multiple results the trailing quote was added in
::print_matches.  As a consequence, ::print_matches had to understand
not to add the trailing quote for the single result case.

After this commit we don't add the trailing quote in
::build_completion_result, instead ::print_matches always adds the
trailing quote, which makes ::print_matches simpler.

However, there is a slight problem.  When completion is being driven
by readline, and not by the 'complete' command, we still need to
manually add the trailing quote in the single result case, and as the
printing is done by readline we can't add the quote at the time of
printing, and so, in ::build_completion_result, we still add the
trailing quote, but only when completion is being done for readline.

And this does cause a small problem.  When completing a filename, if
the completion results in a directory name then, when using the
'complete' command, GDB should not be adding a trailing quote.  For
example, if we have the file /tmp/xxx/foo.c, then what we should see
is this:

  (gdb) complete file '/tmp/xx
  file 'tmp/xxx/

But what we actually see after this commit is this:

  (gdb) complete file '/tmp/xx
  file 'tmp/xxx/'

Previously we didn't get the trailing quote in this case, as when
there is only a single result, the quote was added in
::build_completion_result, and for filename completion, GDB didn't
know what the quote character was in ::build_completion_result, so no
quote was added.  Now that the trailing quote is always added in
::print_matches, and GDB does know the quote character at this point,
so we are now getting the trailing quote, which is not correct.

This is a regression, but really, GDB is now broken in a consistent
way, if we create the file /tmp/xxa/bar.c, then previously if we did
this:

  (gdb) complete file '/tmp/xx
  file '/tmp/xxa/'
  file '/tmp/xxx/'

Notice how we get the trailing quote in this case, this is the before
patch behaviour, and is also wrong.

A later commit will fix things so that the trailing quote is not added
in this filename completion case, but for now I'm going to accept this
small regression.

This change in behaviour caused some failures in one of the completion
tests, I've tweaked the test case to expect the trailing quote as part
of this commit, but will revert this in a later commit in this series.

I've also added an extra test for when the 'complete' command does
complete to a single complete filename, in which case the trailing
quote is expected.
2024-09-07 20:28:58 +01:00
Andrew Burgess
1d1df75397 gdb: move display of completion results into completion_result class
This commit moves the printing of the 'complete' command results out
of the 'complete_command' function.  The printing is now done in a new
member function 'completion_result::print_matches'.  At this point,
this is entirely a refactor.

The motivation for this refactor is how 'complete' should print the
completion of filename arguments.  In some cases the filename results
need to have escaping added to the output.  This escaping needs to be
done immediately prior to printing the result as adding too early will
result in multiple 'complete' results potentially being sorted
incorrectly.  See the subsequent commits for more details.

There should be no user visible changes after this commit.

Approved-By: Tom Tromey <tom@tromey.com>
2024-09-07 20:28:58 +01:00
Andrew Burgess
3503687591 gdb: improve escaping when completing filenames
This improves quoting and escaping when completing filenames for
commands that allow filenames to be quoted and escaped.

I've struggled a bit trying to split this series into chunks.  There's
a lot of dependencies between different parts of the completion
system, and trying to get this working correctly is pretty messy.

This first step is really about implementing 3 readline hooks:

  rl_char_is_quoted_p
    - Is a particular character quoted within readline's input buffer?
  rl_filename_dequoting_function
    - Remove quoting characters from a filename.
  rl_filename_quoting_function
    - Add quoting characters to a filename.

See 'info readline' for full details, but with these hooks connected
up, readline (on behalf of GDB) should do a better job inserting
backslash escapes when completing filenames.

There's still a bunch of stuff that doesn't work after this commit,
mostly around the 'complete' command which of course doesn't go
through readline, so doesn't benefit from all of these new functions
yet, I'll add some of this in a later commit.

Tab completion is now slightly improved though, it is possible to
tab-complete a filename that includes a double or single quote, either
in an unquoted string or within a string surrounded by single or
double quotes, backslash escaping is used when necessary.

There are some additional tests to cover the new functionality.
2024-09-07 20:28:58 +01:00
Andrew Burgess
dc22ab49e9 gdb: deprecated filename_completer and associated functions
Following on from the previous commit, this commit marks the old
unquoted filename completion related functions as deprecated.

The aim of doing this is to make it more obvious to someone adding a
new command that they should not be using the older unquoted style
filename argument handling.

I split this change from the previous to make for an easier review.
This commit touches more files, but is _just_ function renaming.
Check out gdb/completer.{c,h} for what has been renamed.  All the
other files have just been updated to use the new names.

There should be no user visible changes after this commit.
2024-09-07 20:28:58 +01:00
Andrew Burgess
4076f962e8 gdb: split apart two different types of filename completion
Unfortunately we have two different types of filename completion in
GDB.

The majority of commands have what I call unquoted filename
completion, this is for commands like 'set logging file ...', 'target
core ...', and 'add-auto-load-safe-path ...'.  For these commands
everything after the command name (that is not a command option) is
treated as a single filename.  If the filename contains white space
then this does not need to be escaped, nor does the filename need to
be quoted.  In fact, the filename argument is not de-quoted, and does
not have any escaping removed, so if a user does try to add such
things, they will be treated as part of the filename.  As an example:

  (gdb) target core "/path/that contains/some white space"

Will look for a directory calls '"' (double quotes) in the local
directory.

A small number of commands do de-quote and remove escapes from
filename arguments.  These command accept what I call quoted and
escaped filenames.  Right now these are the commands that specify the
file for GDB to debug, so:

  file
  exec-file
  symbol-file
  add-symbol-file
  remove-symbol-file

As an example of this in action:

  (gdb) file "/path/that contains/some white space"

In this case GDB would load the file:

  /path/that contains/some white space

Current filename completion always assumes that filenames can be
quoted, though escaping doesn't work in completion right now.  But the
assumption that quoting is allowed is clearly wrong.

This commit splits filename completion into two.  The existing
filename_completer is retained, and is used for unquoted filenames.  A
second filename_maybe_quoted_completer is added which can be used for
completing quoted filenames.

The filename completion test has been extended to cover more cases.
As part of the extended testing I need to know the character that
should be used to separate filenames within a path.  For this TCL 8.6+
has $::tcl_platform(pathSeparator).  To support older versions of TCL
I've added some code to testsuite/lib/gdb.exp.

You might notice that after this commit the completion for unquoted
files is all done in the brkchars phase, that is the function
filename_completer_handle_brkchars calculates the completions and
marks the completion_tracker as using a custom word point.  The reason
for this is that we don't want to break on white space for this
completion, but if we rely on readline to find the completion word,
readline will consider the entire command line, and with no white
space in the word break character set, readline will end up using the
entire command line as the word to complete.

For now at least, the completer for quoted filenames does generate its
completions during the completion phase, though this is going to
change in a later commit.
2024-09-07 20:28:57 +01:00
Andrew Burgess
8358d39b4f gdb: unify build-id to objfile lookup code
There are 3 places where we currently call debuginfod_exec_query to
lookup an objfile for a given build-id.

In one of these places we first call build_id_to_exec_bfd which also
looks up an objfile given a build-id, but this function looks on disk
for a symlink in the .build-id/ sub-directory (within the
debug-file-directory).

I can't think of any reason why we shouldn't call build_id_to_exec_bfd
before every call to debuginfod_exec_query.

So, in this commit I have added a new function in build-id.c,
find_objfile_by_build_id, this function calls build_id_to_exec_bfd,
and if that fails, then calls debuginfod_exec_query.

Everywhere we call debuginfod_exec_query is updated to call the new
function, and in locate_exec_from_corefile_build_id, the existing call
to build_id_to_exec_bfd is removed as calling find_objfile_by_build_id
does this for us.

One slight weird thing is in core_target::build_file_mappings, here we
call find_objfile_by_build_id which returns a gdb_bfd_ref_ptr for the
opened file, however we immediately reopen the file as "binary".  The
reason for this is that all the bfds opened in ::build_file_mappings
need to be opened as "binary" (see the function comments for why).

I did consider passing a target type into find_objfile_by_build_id,
which could then be forwarded to build_id_to_exec_bfd and used to open
the BFD as "binary", however, if you follow the call chain you'll end
up in build_id_to_debug_bfd_1, where we actually open the bfd.  Notice
in here that we call build_id_verify to double check the build-id of
the file we found, this requires that the bfd not be opened as
"binary".

What this means is that we always have to first open the bfd using the
gnutarget target type (for the build-id check), and then we would have
to reopen it as "binary".  There seems little point pushing the reopen
logic into find_objfile_by_build_id, so we just do this in the
::build_file_mappings function.

I've extended the tests to cover the two cases which actually changed
in this commit.
2024-09-07 20:28:57 +01:00
Andrew Burgess
fa826a4bbe gdb: improve shared library build-id check for core-files
When GDB opens a core file, in 'core_target::build_file_mappings ()',
we collection information about the files that are mapped into the
core file, specifically, the build-id and the DT_SONAME attribute for
the file, which will be set for some shared libraries.

We then cache the DT_SONAME to build-id information on the core file
bfd object in the function set_cbfd_soname_build_id.

Later, when we are loading the shared libraries for the core file, we
can use the library's file name to look in the DT_SONAME to build-id
map, and, if we find a matching entry, we can use the build-id to
validate that we are loading the correct shared library.

This works OK, but has some limitations: not every shared library will
have a DT_SONAME attribute.  Though it is good practice to add such an
attribute, it's not required.  A library without this attribute will
not have its build-id checked, which can lead to GDB loading the wrong
shared library.

What I want to do in this commit is to improve GDB's ability to use
the build-ids extracted in core_target::build_file_mappings to both
validate the shared libraries being loaded, and then to use these
build-ids to potentially find (via debuginfod) the shared library.

To do this I propose making the following changes to GDB:

(1) Rather than just recording the DT_SONAME to build-id mapping in
set_cbfd_soname_build_id, we should also record, the full filename to
build-id mapping, and also the memory ranges to build-id mapping for
every memory range covered by every mapped file.

(2) Add a new callback solib_ops::find_solib_addr.  This callback
takes a solib object and returns an (optional) address within the
inferior that is part of this library.  We can use this address to
find a mapped file using the stored memory ranges which will increase
the cases in which a match can be found.

(3) Move the mapped file record keeping out of solib.c and into
corelow.c.  Future commits will make use of this information from
other parts of GDB.  This information was never solib specific, it
lived in the solib.c file because that was the only user of the data,
but really, the data is all about the core file, and should be stored
in core_target, other parts of GDB can then query this data as needed.

Now, when we load a shared library for a core file, we do the
following lookups:

  1. Is the exact filename of the shared library found in the filename
  to build-id map?  If so then use this build-id for validation.

  2. Find an address within the shared library using ::find_solib_addr
  and then look for an entry in the mapped address to build-id map.
  If an entry is found then use this build-id.

  3. Finally, look in the soname to build-id map.  If an entry is
  found then use this build-id.

The addition of step #2 here means that GDB is now far more likely to
find a suitable build-id for a shared library.  Having acquired a
build-id the existing code for using debuginfod to lookup a shared
library object can trigger more often.

On top of this, we also create a build-id to filename map.  This is
useful as often a shared library is implemented as a symbolic link to
the actual shared library file.  The mapped file information is stored
based on the actual, real file name, while the shared library
information holds the original symbolic link file name.

If when loading the shared library, we find the symbolic link has
disappeared, we can use the build-id to file name map to check if the
actual file is still around, if it is (and if the build-id matches)
then we can fall back to use that file.  This is another way in which
we can slightly increase the chances that GDB will find the required
files when loading a core file.

Adding all of the above required pretty much a full rewrite of the
existing set_cbfd_soname_build_id function and the corresponding
get_cbfd_soname_build_id function, so I have taken the opportunity to
move the information caching out of solib.c and into corelow.c where
it is now accessed through the function core_target_find_mapped_file.

At this point the benefit of this move is not entirely obvious, though
I don't think the new location is significantly worse than where it
was originally.  The benefit though is that the cached information is
no longer tied to the shared library loading code.

I already have a second set of patches (not in this series) that make
use of this caching from elsewhere in GDB.  I've not included those
patches in this series as this series is already pretty big, but even
if those follow up patches don't arrive, I think the new location is
just as good as the original location.

Rather that caching the information within the core file BFD via the
registry mechanism, the information used for the mapped file lookup is
now stored within the core_file target directly.
2024-09-07 20:28:57 +01:00
Andrew Burgess
a47a679c76 gdb/corefile: improve file backed mapping handling
This commit improves how GDB handles file backed mappings within a
core file, specifically, this is a restructuring of the function
core_target::build_file_mapping.

The primary motivation for this commit was to put in place the
infrastructure to support the next commit in this series, but this
commit does itself make some improvements.

Currently in core_target::build_file_mapping we use
gdbarch_read_core_file_mappings to iterate over the mapped regions
within a core file.

For each region a callback is invoked which is passed details of the
mapping; the file the mapping is from, the offset into the file, and
the address range at which the mapping exists.  We are also passed the
build-id for the mapped file in some cases.

We are only told the build-id for the mapped region which actually
contains the ELF header of the mapped file.  Other regions of the same
mapped ELF will not have the build-id passed to the callback.

Within core_target::build_file_mapping, in the per-region callback, we
try to find the mapped file based on its filename.  If the file can't
be found, and if we have a build-id then we'll ask debuginfod to
download the file.

However we find the file, we cache the opened bfd object, which is
good.  Subsequent mappings from the same file will not have a build-id
set, but by that point we already have a cached open bfd object, so
the lack of build-id is irrelevant.

The problem with the above is that if we find a matching file based on
the filename, then we accept that file, even if we have a build-id,
and the build-id doesn't match.

Currently, the mapped region processing is done in a single pass, we
call gdbarch_read_core_file_mappings, and for each mapping, as we see
it, we create the data structures needed to represent that mapping.

In this commit, I will change this to a two phase process.  In the
first phase the mappings are grouped together based on the name of the
mapped file.  At the end of phase one we have a 'struct mapped_file',
a new struct, for each mapped file.  This struct associates an
optional build-id with a list of mapped regions.

In the second phase we try to find the file using its filename.  If
the file is found, and the 'struct mapped_file' has a build-id, then
we'll compare the build-id with the file we found.  This allows us to
reject on-disk files which have changed since the core file was
created.

If no suitable file was found (either no file found, or a build-id
mismatch) then we can use debuginfod to potentially download a
suitable file.

  NOTE: In the future we could potentially add additional sanity
  checks here, for example, if a data-file is mapped, and has no
  build-id, we can estimate a minimum file size based on the expected
  mappings.  If the file we find is not big enough then we can reject
  the on-disk file.  But I don't know how useful this would actually
  be, so I've not done that for now.

Having found (or not) a suitable file then we can create the data
structures for each mapped region just as we did before.

The new functionality here is the extra build-id check, and the
possibility of rejecting an on-disk file if the build-id doesn't
match.

This change could have been done within the existing single phase
approach I think, however, in the next approach I need to have all the
mapped regions associated with the expected build-id, and the new two
phase structure allows me to do that, this is the reason for such an
extensive rewrite in this commit.

There's a new test that exercises GDB's ability to find mapped files
via the build-id, and this downloading from debuginfod.
2024-09-07 20:28:57 +01:00
Andrew Burgess
522875f679 gdb/corefile: don't pretend unavailable sections are readable
When GDB opens a core file the bfd library processes the core file and
creates sections within the bfd object to represent each of the
segments within the core file.

GDB then creates two target_section lists, m_core_section_table and
m_core_file_mappings, these, along with m_core_unavailable_mappings,
are used by GDB to implement core_target::xfer_partial; this is the
function used when GDB tries to read memory from a core file inferior.

The m_core_section_table list represents sections within the core file
itself.  The sections in this list can be split into two groups based
on whether the section has the SEC_HAS_CONTENTS flag set or not.

Sections (from the core file) that have the SEC_HAS_CONTENTS flag had
their contents copied into the core file when the core file was
created.  These correspond to writable sections within the original
inferior (the inferior for which the core file was created).

Sections (from the core file) that do not have the SEC_HAS_CONTENTS
flag will not have had their contents copied into the core file when
it was created.  These sections correspond to read-only sections
mapped from a file (possibly the initial executable, or possibly some
other file) in the original inferior.  The expectation is that the
contents of these sections can still be found by looking in the file
that was originally mapped.

The m_core_file_mappings list is created when GDB parses the mapped
file list in the core file.  Every mapped region will be covered by
entries in the m_core_section_table list (see above), but for
read-only mappings the entry in m_core_section_table will not have the
SEC_HAS_CONTENTS flag set.  As GDB parses the mapped file list, if the
file that was originally mapped can be found, then GDB creates an
entry in the m_core_file_mappings list which represents the region
of the file that was mapped into the original inferior.

However, GDB only creates entries in m_core_file_mappings if it is
able to find the correct on-disk file to open.  If the file can't be
found then an entry is added to m_core_unavailable_mappings instead.

If is the handling m_core_unavailable_mappings which I think is
currently not completely correct.

When a read lands within an m_core_unavailable_mappings region we
currently forward the read to the exec file stratum.  The reason for
this is this: when GDB read the mapped file list, if the executable
file could not be found at the expected path then mappings within the
executable will end up in the m_core_unavailable_mappings list.

However, the user might provide the executable to GDB from a different
location.  If this happens then forwarding the read to the exec file
stratum might give a result.

But, if the exec file stratum does not resolve the access then
currently we continue through ::xfer_partial, the next step of which
is to handle m_core_section_table entries that don't have the
SEC_HAS_CONTENTS flag set.  Every m_core_unavailable_mappings entry
will naturally have an m_core_section_table without the
SEC_HAS_CONTENTS flag set, and so we treat the unavailable mapping as
zero initialised memory and return all zeros.

It is this fall through behaviour that I think is wrong.  If a read
falls in an unavailable region, and the exec file stratum cannot help,
then I think the access should fail.

To achieve this goal I have removed the xfer_memory_via_mappings
helper function and moved its content inline into ::xfer_partial.
Now, if an access is within an m_core_unavailable_mappings region, and
the exec file stratum doesn't help, we immediately return with an
error.

The reset of ::xfer_partial is unchanged, I've extended some comments
in the area that I have changed to (I hope) explain better what's
going on.

There's a new test that covers the new functionality, an inferior maps
a file and generates a core file.  We then remove the mapped file,
load the core file and try to read from the mapped region.  The
expectation is that GDB should give an error rather than claiming that
the region is full of zeros.
2024-09-07 20:28:57 +01:00
Xin Wang
9a33a0b9c6 Not append rela for absolute symbol
LoongArch: Not append rela for absolute symbol

Use la.global to get absolute symbol like la.abs.
la.global put address of a global symbol into a got
entry and append a rela for it, which will be used
to relocate by dynamic linker. Dynamic linker should
not relocate for got entry of absolute symbol as it
stores symval not symbol's address.
2024-09-07 10:07:13 +08:00
Xin Wang
2bbe107902 Add macros to get opcode of instructions approriately
LoongArch: Add macros to get opcode and register of instructions appropriately

Currently, we get opcode of an instruction by manipulate the binary with
it's mask, it's a bit of a pain. Now a macro is defined to do this and a
macro to get the RD and RJ registers which is applicable to most instructions
of LoongArch are added.
2024-09-07 10:06:03 +08:00
GDB Administrator
4723415cda Automatic date update in version.in 2024-09-07 00:00:27 +00:00
Vladimir Mezentsev
a35d8973e5 Rename gp-* man pages to gprofng-* man pages
gprofng/ChangeLog
2024-09-05  Vladimir Mezentsev  <vladimir.mezentsev@oracle.com>.

	* doc/gp-archive.texi: Rename to doc/gprofng-archive.texi.
	* doc/gp-collect-app.texi: Rename to doc/gprofng-collect-app.texi.
	* doc/gp-display-html.texi: Rename to doc/gprofng-display-html.texi.
	* doc/gp-display-src.texi: Rename to doc/gprofng-display-src.texi.
	* doc/gp-display-text.texi: Rename to doc/gprofng-display-text.texi.
	* doc/gp-macros.texi: Add new macros.
	* doc/gprofng.texi: Rename man pages.
	* doc/gprofng_ug.texi: Likewise.
	* doc/Makefile.am: Likewise.
	* doc/Makefile.in: Rebuild.
2024-09-06 14:21:54 -07:00
Tom Tromey
d2f6771173 Fix 'catch exception' with -flto
A user noticed that when an Ada program (including the runtime) is
compiled with -flto, then "catch exception" does not work -- even
though setting the equivalent breakpoint by hand does work.

Looking into this, it turns out that GCC puts the exception functions
from the Ada runtime into a CU that uses the C language, not Ada.
Then, when trying to look up the relevant symbol,
lookup_name_info::search_name_hash uses the "verbatim" form of the
symbol name (like "<__gnat_debug_raise_exception>") rather than the
"<>"-less form, causing the symbol not to be found.

This patch fixes the problem in two steps.

First, lookup_name_info::search_name_hash is changed to use the same
hack that language_defn::get_symbol_name_matcher uses.  That is, when
the current language is Ada, verbatim-mode lookups are special-cased.
(This is a bit unfortunate; perhaps a better long term approach would
be to promote verbatim mode to a fundamental mode of
lookup_name_info.)

Second, although the above fixes the problem in the Ada language mode,
the code still fails in other languages.  However, due to the way
these lookups are coded in ada-lang.c, I think it makes sense to
temporarily set the current language to Ada in
create_ada_exception_catchpoint.

Tested on x86-64 Fedora 38.

A new test case that mimics the -flto scenario is included.

Reviewed-By: Alexandra Petlanova Hajkova <ahajkova@redhat.com>
2024-09-06 12:31:50 -06:00
Tom Tromey
6a4eb277b7 Clear Ada symbol cache
This patch changes "maint flush symbol-cache" to also flush the
Ada-specific symbol cache.  This can be helpful when working on the
Ada code.

Approved-By: Tom de Vries <tdevries@suse.de>
2024-09-06 11:08:41 -06:00
Tom Tromey
d767b870c4 Test -fgnat-encodings=all in tagged_access.exp
While working on a longer series, I needed to make sure this
particular test kept working with -fgnat-encodings=all, so this patch
adds it to the test.
2024-09-06 10:31:53 -06:00
Tom Tromey
a63b3b2f74 Introduce and use foreach_gnat_encoding
gnat-llvm does not support the -fgnat-encodings flag.  This patch
prepares gdb's Ada tests to handle this situation by introducing a new
foreach_gnat_encoding.  A subsequent patch may change this to support
gnat-llvm; meanwhile this is a little cleaner anyway.
2024-09-06 10:22:13 -06:00
Bernd Edlinger
f83ca9c7cc Fix the build-id option for GCC default configuration
It is possible that the compiler is configured to do
so automatically, but at least for GCC the configure option
--enable-linker-build-id is not enabled by default.
So the option -Wl,--build-id should be used regardless
of which compiler is used.

Approved-By: Tom de Vries <tdevries@suse.de>
2024-09-06 16:32:16 +02:00
Shahab Vahedi
237df762d7 bfd: Fix GCC warning when CFLAGS="-Og" is used
This patch initializes the "op" variable in skip_cfa_op() function
of bfd/elf-eh-frame.c to "0" at its declaration point to avoid the
"maybe-uninitialized" warning.

Building binutils on a system with GCC version 13.2.0 and a configure
command that sets the optimization level to "-Og" leads to a build
failure because of a warning being treated as an error:
---------------------------------------------------------------------
$ ./configure CFLAGS="-Og"
$ make
  ...
  CC       elf-eh-frame.lo
  /src/gdb/bfd/elf-eh-frame.c: In function 'skip_cfa_op':
  /src/gdb/bfd/elf-eh-frame.c:354:33: error: 'op' may be used
    uninitialized [-Werror=maybe-uninitialized]
  354 |   switch (op & 0xc0 ? op & 0xc0 : op)
      |           ~~~~~~~~~~~~~~~~~~~~~~^~~~
  /src/gdb/bfd/elf-eh-frame.c:348:12: note: 'op' was declared here
  348 |   bfd_byte op;
      |            ^~
  cc1: all warnings being treated as errors
  ...
---------------------------------------------------------------------

The relevant code snippet related to this warning looks like:
---------------------------------------------------------------------
  static inline bool
  read_byte (bfd_byte **iter, bfd_byte *end, unsigned char *result)
  {
    if (*iter >= end)
      return false;
    *result = *((*iter)++);
    return true;
  }

  static bool
  skip_cfa_op (bfd_byte **iter, bfd_byte *end,...)
  {
    bfd_byte op;

    if (!read_byte (iter, end, &op))
      return false;

    switch (op & 0xc0 ? op & 0xc0 : op)
    ...
  }
---------------------------------------------------------------------

This warning probably happens because "-Og" results in GCC not
inlining the "read_byte()" function. Therefore, GCC treats its
invocation inside "skip_cfa_op()" like a black box and that ends
in the aforementioned warning.

Acknowledgement:
  Lancelot Six -- for coming with the idea behind this fix.
  Jan Beulich  -- for reviewing.

bfd/ChangeLog:
	* elf-eh-frame.c (skip_cfa_op): Initialize the "op" variable.
2024-09-06 08:36:32 +02:00
Jan Beulich
4eb59a5243 x86/APX: use D for 2-operand CFCMOVcc
There's no need to have 30 redundant templates when we can easily take
care of the operand swapping like we do for various other insns.
2024-09-06 08:35:42 +02:00
Jan Beulich
6b8ed67d6e x86/APX: optimize certain reg-only CFCMOVcc forms
Along the lines of 2513312930 ("x86/APX: apply NDD-to-legacy
transformation to further CMOVcc forms") these can similarly be
converted to the shorter legacy-encoded CMOVcc.
2024-09-06 08:35:07 +02:00
Jan Beulich
a844415db8 bfd/PE: correct SizeOfImage calculation
We don't really want to align the last section's size to object
alignment (when that section may itself not be aligned as much), we want
image size to be a multiple thereof.
2024-09-06 08:34:24 +02:00
Jan Beulich
f12eb19e17 x86: templatize VNNI templates
Reduce redundancy, in preparation of the addition of further counterparts
for AVX10.2.
2024-09-06 08:33:47 +02:00
GDB Administrator
9772824e0e Automatic date update in version.in 2024-09-06 00:00:15 +00:00
Mark Harmstone
897a57a126 bfd/pdb: fix -Wmaybe-uninitialized warning
Initialize stream0_start to fix spurious -Wmaybe-uninitialized warning
on some versions of gcc.
2024-09-05 09:58:47 +01:00
Alan Modra
8a72d8924a PR32136, Use-of-uninitialized-memory in evax_bfd_print_image
PR 32136
	 * vms-alpha.c (evax_bfd_print_image): Sanity check various string
	 lengths.
2024-09-05 16:14:03 +09:30
Thiago Jung Bauermann
43af2e08dc gdbserver: aarch64: Fix expedited registers list
Since this commit:

  commit a8651ef518
  CommitDate: Fri Jun 14 14:47:38 2024 +0100

      gdb/aarch64: prevent crash from in process agent

gdbserver isn't sending expedited registers with its stop reply packets
anymore.  The problem is with how the constructor of the
expedited_registers std::vector is called:

The intent of the expedited_registers initialization in
aarch64_linux_read_description is to create a vector with capacity for 6
elements, but that's not how the std::vector constructor works.

Instead it creates a vector pre-populated with 6 elements initialized
with the default value for the type of the elements, and thus the first
6 elements are null pointers.  The actual expedited registers are added
starting at the 7th element.

This causes init_target_desc to consider that the expedite_regs list is
empty, since it stops checking at the first nullptr element.  The end
result is that gdbserver doesn't send any expedited registers to GDB in
its stop replies.

Fix by not specifying an element count when declaring the vector.

Tested for regressions on aarch64-linux-gnu native-extended-remote.

Approved-By: Andrew Burgess <aburgess@redhat.com>
2024-09-05 01:02:51 -03:00
Lulu Cai
88327cbcd0 LoongArch: Fixed ABI v1.00 TLS dynamic relocation generation bug
Commit "b67a17aa7c0c478a" modified the logic of allocating dynamic
relocation space for TLS GD/IE, but only modified the logic of
generation dynamic relocations for TLS GD/IE in ABI v2.00. When
linking an object file of ABI v1.00 with bfd ld of ABI v2.00, it
will cause an assertion failure.

Modified the dynamic relocation generation logic of TLS GD/IE
in ABI v1.00 to be consistent with ABI v2.00.
2024-09-05 11:48:44 +08:00
GDB Administrator
9adad97491 Automatic date update in version.in 2024-09-05 00:00:11 +00:00
Vladimir Mezentsev
b79c457ca0 Fix 32097 Warnings when building gprofng with Clang
gprofng/ChangeLog
2024-09-03  Vladimir Mezentsev  <vladimir.mezentsev@oracle.com>.

	PR gprofng/32097
	* common/hwcdrv.c: Fix -Wempty-body warnings.
	* common/hwcentry.h: Fix -Wdeprecated-non-prototype warnings.
	* common/hwctable.c: Fix -Wdeprecated-non-prototype warnings.
	* libcollector/collector.c: Likewise.
	* libcollector/collector.h: Likewise.
	* libcollector/collectorAPI.c: Likewise.
	* libcollector/dispatcher.c: Likewise.
	* libcollector/iotrace.c: Likewise.
	* libcollector/libcol_util.c: Fix -Wunused-but-set-variable warnings.
	* libcollector/libcol_util.h: Remove unused declarations.
	* libcollector/linetrace.c: Fix -Wdeprecated-non-prototype warnings.
	* src/BaseMetricTreeNode.h: Fix -Wunused-private-field warnings.
	* src/Dbe.cc: Fix -Wself-assign warnings.
	* src/DbeSession.cc: Fix -Wunused-but-set-variable warnings.
	* src/Disasm.cc: Fix -Wunused-const-variable warnings.
	* src/Experiment.cc: Fix -Wunused-private-field warnings.
	* src/HashMap.h: Fix -Wself-assign warnings.
	* src/IOActivity.h: Fix -Wunused-private-field warnings.
	* src/collctrl.cc: Fix -Wself-assign, -Wparentheses-equality warnings.
	* src/collctrl.h: Fix -Wunused-private-field warnings.
	* src/collector_module.h: Fix -Wdeprecated-non-prototype warnings.
	* src/gp-display-src.cc: Fix -Wunused-private-field warnings.
	* src/gp-print.h: Fix -Wheader-guard warnings.
	* src/hwc_intel_icelake.h: Fix -Winitializer-overrides warnings.
	* src/util.cc: Fix -Wunused-but-set-variable warnings.
2024-09-04 13:49:21 -07:00
Tom Tromey
82d6a9e5b4 Improve comments in dwarf2/parent-map.h
I noticed that the comments for class parent_map aren't very clear.
This patch attempts to fix this, and also clarifies a point on
parent_map_map::add_map.

Approved-By: Simon Marchi <simon.marchi@efficios.com>
2024-09-04 12:05:45 -06:00