Commit graph

1353 commits

Author SHA1 Message Date
Simon Marchi
652099717d gdb: remove SYMTAB_OBJFILE macro
Remove the macro, replace with an equivalent method.

Change-Id: I8f9ecd290ad28502e53c1ceca5006ba78bf042eb
2022-02-06 16:03:46 -05:00
Simon Marchi
c615965258 gdb: remove SYMTAB_COMPUNIT macro, add getter/setter
Add a getter and a setter for a symtab's compunit_symtab.  Remove the
corresponding macro and adjust all callers.

For brevity, I chose the name "compunit" instead of "compunit_symtab"
the the field, getter and setter names.  Since we are already in symtab
context, the _symtab suffix seems redundant.

Change-Id: I4b9b731c96e3594f7733e75af1e3d01bc0e4fe92
2022-02-06 15:48:19 -05:00
Tom Tromey
6c92c33953 Convert wrap_here to use integer parameter
I think it only really makes sense to call wrap_here with an argument
consisting solely of spaces.  Given this, it seemed better to me that
the argument be an int, rather than a string.  This patch is the
result.  Much of it was written by a script.
2022-01-26 15:19:13 -07:00
Tom Tromey
d4396e0e97 Reduce explicit use of gdb_stdout
In an earlier version of the pager rewrite series, it was important to
audit unfiltered output calls to see which were truly necessary.

This is no longer necessary, but it still seems like a decent cleanup
to change calls to avoid explicitly passing gdb_stdout.  That is,
rather than using something like fprintf_unfiltered with gdb_stdout,
the code ought to use plain printf_unfiltered instead.

This patch makes this change.  I went ahead and converted all the
_filtered calls I could find, as well, for the same clarity.
2022-01-25 15:22:49 -07:00
Tom Tromey
1475b18b77 Send some error output to gdb_stderr
This changes some code to send some error messages to gdb_stderr
rather than gdb_stdout.
2022-01-25 15:22:49 -07:00
Tom Tromey
de8e4cb3af Move "catch exec" to a new file
The "catch exec" code is reasonably self-contained, and so this patch
moves it out of breakpoint.c (the second largest source file in gdb)
and into a new file, break-catch-exec.c.
2022-01-18 10:34:05 -07:00
Tom Tromey
064f3c6a01 Move "catch fork" to a new file
The "catch fork" code is reasonably self-contained, and so this patch
moves it out of breakpoint.c (the second largest source file in gdb)
and into a new file, break-catch-fork.c.
2022-01-18 10:34:05 -07:00
Tom Tromey
59505f2cec Unify "catch fork" and "catch vfork"
I noticed that "catch fork" and "catch vfork" are nearly identical.
This patch simplifies the code by unifying these two cases.
2022-01-18 10:34:05 -07:00
Tom Tromey
d322d6d69d Move gdb_regex to gdbsupport
This moves the gdb_regex convenience class to gdbsupport.
2022-01-18 10:14:43 -07:00
Tom Tromey
b58f47ab4c Use filtered output in ordinary commands
Many otherwise ordinary commands choose to use unfiltered output
rather than filtered.  I don't think there's any reason for this, so
this changes many such commands to use filtered output instead.

Note that complete_command is not touched due to a comment there
explaining why unfiltered output is believed to be used.
2022-01-05 11:36:33 -07:00
Joel Brobecker
4a94e36819 Automatic Copyright Year update after running gdb/copyright.py
This commit brings all the changes made by running gdb/copyright.py
as per GDB's Start of New Year Procedure.

For the avoidance of doubt, all changes in this commits were
performed by the script.
2022-01-01 19:13:23 +04:00
Simon Marchi
cd0f67f363 gdb: make set_raw_breakpoint static
set_raw_breakpoint is only used in breakpoint.c, make it static.

Change-Id: I7fbeda067685309a30b88aceaf957eff7a28e310
2021-12-07 15:51:10 -05:00
Tom Tromey
8a18382f94 Add "task" keyword to the "watch" command
Breakpoints in gdb can be made specific to an Ada task using the
"task" qualifier.  This patch applies this same idea to watchpoints.
2021-12-02 08:58:22 -07:00
Simon Marchi
c272a98cbf gdb: pass more const target_waitstatus by reference
While working on target_waitstatus changes, I noticed a few places where
const target_waitstatus objects could be passed by reference instead of
by pointers.  And in some cases, places where a target_waitstatus could
be passed as const, but was not.  Convert them as much as possible.

Change-Id: Ied552d464be5d5b87489913b95f9720a5ad50c5a
2021-11-22 13:57:54 -05:00
Andrew Burgess
8579fd136a gdb/gdbsupport: make xstrprintf and xstrvprintf return a unique_ptr
The motivation is to reduce the number of places where unmanaged
pointers are returned from allocation type routines.  All of the
callers are updated.

There should be no user visible changes after this commit.
2021-11-16 17:45:45 +00:00
Kevin Buettner
9c95aea186 Fix PR 28308 - dprintf breakpoints not working when run from script
This commit fixes Bug 28308, titled "Strange interactions with
dprintf and break/commands":

Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=28308

Since creating that bug report, I've found a somewhat simpler way of
reproducing the problem.  I've encapsulated it into the GDB test case
which I've created along with this bug fix.  The name of the new test
is gdb.base/dprintf-execution-x-script.exp, I'll demonstrate the
problem using this test case, though for brevity, I've placed all
relevant files in the same directory and have renamed the files to all
start with 'dp-bug' instead of 'dprintf-execution-x-script'.

The script file, named dp-bug.gdb, consists of the following commands:

dprintf increment, "dprintf in increment(), vi=%d\n", vi
break inc_vi
commands
  continue
end
run

Note that the final command in this script is 'run'.  When 'run' is
instead issued interactively, the  bug does not occur.  So, let's look
at the interactive case first in order to see the correct/expected
output:

$ gdb -q -x dp-bug.gdb dp-bug
... eliding buggy output which I'll discuss later ...
(gdb) run
Starting program: /mesquite2/sourceware-git/f34-master/bld/gdb/tmp/dp-bug
vi=0
dprintf in increment(), vi=0

Breakpoint 2, inc_vi () at dprintf-execution-x-script.c:26
26	in dprintf-execution-x-script.c
vi=1
dprintf in increment(), vi=1

Breakpoint 2, inc_vi () at dprintf-execution-x-script.c:26
26	in dprintf-execution-x-script.c
vi=2
dprintf in increment(), vi=2

Breakpoint 2, inc_vi () at dprintf-execution-x-script.c:26
26	in dprintf-execution-x-script.c
vi=3
[Inferior 1 (process 1539210) exited normally]

In this run, in which 'run' was issued from the gdb prompt (instead
of at the end of the script), there are three dprintf messages along
with three 'Breakpoint 2' messages.  This is the correct output.

Now let's look at the output that I snipped above; this is the output
when 'run' is issued from the script loaded via GDB's -x switch:

$ gdb -q -x dp-bug.gdb dp-bug
Reading symbols from dp-bug...
Dprintf 1 at 0x40116e: file dprintf-execution-x-script.c, line 38.
Breakpoint 2 at 0x40113a: file dprintf-execution-x-script.c, line 26.
vi=0
dprintf in increment(), vi=0

Breakpoint 2, inc_vi () at dprintf-execution-x-script.c:26
26	dprintf-execution-x-script.c: No such file or directory.
vi=1

Breakpoint 2, inc_vi () at dprintf-execution-x-script.c:26
26	in dprintf-execution-x-script.c
vi=2

Breakpoint 2, inc_vi () at dprintf-execution-x-script.c:26
26	in dprintf-execution-x-script.c
vi=3
[Inferior 1 (process 1539175) exited normally]

In the output shown above, only the first dprintf message is printed.
The 2nd and 3rd dprintf messages are missing!  However, all three
'Breakpoint 2...' messages are still printed.

Why does this happen?

bpstat_do_actions_1() in gdb/breakpoint.c contains the following
comment and code near the start of the function:

  /* Avoid endless recursion if a `source' command is contained
     in bs->commands.  */
  if (executing_breakpoint_commands)
    return 0;

  scoped_restore save_executing
    = make_scoped_restore (&executing_breakpoint_commands, 1);

Also, as described by this comment prior to the 'async' field
in 'struct ui' in top.h, the main UI starts off in sync mode
when processing command line arguments:

  /* True if the UI is in async mode, false if in sync mode.  If in
     sync mode, a synchronous execution command (e.g, "next") does not
     return until the command is finished.  If in async mode, then
     running a synchronous command returns right after resuming the
     target.  Waiting for the command's completion is later done on
     the top event loop.  For the main UI, this starts out disabled,
     until all the explicit command line arguments (e.g., `gdb -ex
     "start" -ex "next"') are processed.  */

This combination of things, the state of the static global
'executing_breakpoint_commands' plus the state of the async
field in the main UI causes this behavior.

This is a backtrace after hitting the dprintf breakpoint for
the second time when doing 'run' from the script file, i.e.
non-interactively:

Thread 1 "gdb" hit Breakpoint 3, bpstat_do_actions_1 (bsp=0x7fffffffc2b8)
    at /ironwood1/sourceware-git/f34-master/bld/../../worktree-master/gdb/breakpoint.c:4431
4431	  if (executing_breakpoint_commands)

 #0  bpstat_do_actions_1 (bsp=0x7fffffffc2b8)
     at gdb/breakpoint.c:4431
 #1  0x00000000004d8bc6 in dprintf_after_condition_true (bs=0x1538090)
     at gdb/breakpoint.c:13048
 #2  0x00000000004c5caa in bpstat_stop_status (aspace=0x116dbc0, bp_addr=0x40116e, thread=0x137f450, ws=0x7fffffffc718,
     stop_chain=0x1538090) at gdb/breakpoint.c:5498
 #3  0x0000000000768d98 in handle_signal_stop (ecs=0x7fffffffc6f0)
     at gdb/infrun.c:6172
 #4  0x00000000007678d3 in handle_inferior_event (ecs=0x7fffffffc6f0)
     at gdb/infrun.c:5662
 #5  0x0000000000763cd5 in fetch_inferior_event ()
     at gdb/infrun.c:4060
 #6  0x0000000000746d7d in inferior_event_handler (event_type=INF_REG_EVENT)
     at gdb/inf-loop.c:41
 #7  0x00000000007a702f in handle_target_event (error=0, client_data=0x0)
     at gdb/linux-nat.c:4207
 #8  0x0000000000b8cd6e in gdb_wait_for_event (block=block@entry=0)
     at gdbsupport/event-loop.cc:701
 #9  0x0000000000b8d032 in gdb_wait_for_event (block=0)
     at gdbsupport/event-loop.cc:597
 #10 gdb_do_one_event () at gdbsupport/event-loop.cc:212
 #11 0x00000000009d19b6 in wait_sync_command_done ()
     at gdb/top.c:528
 #12 0x00000000009d1a3f in maybe_wait_sync_command_done (was_sync=0)
     at gdb/top.c:545
 #13 0x00000000009d2033 in execute_command (p=0x7fffffffcb18 "", from_tty=0)
     at gdb/top.c:676
 #14 0x0000000000560d5b in execute_control_command_1 (cmd=0x13b9bb0, from_tty=0)
     at gdb/cli/cli-script.c:547
 #15 0x000000000056134a in execute_control_command (cmd=0x13b9bb0, from_tty=0)
     at gdb/cli/cli-script.c:717
 #16 0x00000000004c3bbe in bpstat_do_actions_1 (bsp=0x137f530)
     at gdb/breakpoint.c:4469
 #17 0x00000000004c3d40 in bpstat_do_actions ()
     at gdb/breakpoint.c:4533
 #18 0x00000000006a473a in command_handler (command=0x1399ad0 "run")
     at gdb/event-top.c:624
 #19 0x00000000009d182e in read_command_file (stream=0x113e540)
     at gdb/top.c:443
 #20 0x0000000000563697 in script_from_file (stream=0x113e540, file=0x13bb0b0 "dp-bug.gdb")
     at gdb/cli/cli-script.c:1642
 #21 0x00000000006abd63 in source_gdb_script (extlang=0xc44e80 <extension_language_gdb>, stream=0x113e540,
     file=0x13bb0b0 "dp-bug.gdb") at gdb/extension.c:188
 #22 0x0000000000544400 in source_script_from_stream (stream=0x113e540, file=0x7fffffffd91a "dp-bug.gdb",
     file_to_open=0x13bb0b0 "dp-bug.gdb")
     at gdb/cli/cli-cmds.c:692
 #23 0x0000000000544557 in source_script_with_search (file=0x7fffffffd91a "dp-bug.gdb", from_tty=1, search_path=0)
     at gdb/cli/cli-cmds.c:750
 #24 0x00000000005445cf in source_script (file=0x7fffffffd91a "dp-bug.gdb", from_tty=1)
     at gdb/cli/cli-cmds.c:759
 #25 0x00000000007cf6d9 in catch_command_errors (command=0x5445aa <source_script(char const*, int)>,
     arg=0x7fffffffd91a "dp-bug.gdb", from_tty=1, do_bp_actions=false)
     at gdb/main.c:523
 #26 0x00000000007cf85d in execute_cmdargs (cmdarg_vec=0x7fffffffd1b0, file_type=CMDARG_FILE, cmd_type=CMDARG_COMMAND,
     ret=0x7fffffffd18c) at gdb/main.c:615
 #27 0x00000000007d0c8e in captured_main_1 (context=0x7fffffffd3f0)
     at gdb/main.c:1322
 #28 0x00000000007d0eba in captured_main (data=0x7fffffffd3f0)
     at gdb/main.c:1343
 #29 0x00000000007d0f25 in gdb_main (args=0x7fffffffd3f0)
     at gdb/main.c:1368
 #30 0x00000000004186dd in main (argc=5, argv=0x7fffffffd508)
     at gdb/gdb.c:32

There are two frames for bpstat_do_actions_1(), one at frame #16 and
the other at frame #0.  The one at frame #16 is processing the actions
for Breakpoint 2, which is a 'continue'.  The one at frame #0 is attempting
to process the dprintf breakpoint action.  However, at this point,
the value of 'executing_breakpoint_commands' is 1, forcing an early
return, i.e. prior to executing the command(s) associated with the dprintf
breakpoint.

For the sake of comparison, this is what the stack looks like when hitting
the dprintf breakpoint for the second time when issuing the 'run'
command from the GDB prompt.

Thread 1 "gdb" hit Breakpoint 3, bpstat_do_actions_1 (bsp=0x7fffffffccd8)
    at /ironwood1/sourceware-git/f34-master/bld/../../worktree-master/gdb/breakpoint.c:4431
4431	  if (executing_breakpoint_commands)

 #0  bpstat_do_actions_1 (bsp=0x7fffffffccd8)
     at gdb/breakpoint.c:4431
 #1  0x00000000004d8bc6 in dprintf_after_condition_true (bs=0x16b0290)
     at gdb/breakpoint.c:13048
 #2  0x00000000004c5caa in bpstat_stop_status (aspace=0x116dbc0, bp_addr=0x40116e, thread=0x13f0e60, ws=0x7fffffffd138,
     stop_chain=0x16b0290) at gdb/breakpoint.c:5498
 #3  0x0000000000768d98 in handle_signal_stop (ecs=0x7fffffffd110)
     at gdb/infrun.c:6172
 #4  0x00000000007678d3 in handle_inferior_event (ecs=0x7fffffffd110)
     at gdb/infrun.c:5662
 #5  0x0000000000763cd5 in fetch_inferior_event ()
     at gdb/infrun.c:4060
 #6  0x0000000000746d7d in inferior_event_handler (event_type=INF_REG_EVENT)
     at gdb/inf-loop.c:41
 #7  0x00000000007a702f in handle_target_event (error=0, client_data=0x0)
     at gdb/linux-nat.c:4207
 #8  0x0000000000b8cd6e in gdb_wait_for_event (block=block@entry=0)
     at gdbsupport/event-loop.cc:701
 #9  0x0000000000b8d032 in gdb_wait_for_event (block=0)
     at gdbsupport/event-loop.cc:597
 #10 gdb_do_one_event () at gdbsupport/event-loop.cc:212
 #11 0x00000000007cf512 in start_event_loop ()
     at gdb/main.c:421
 #12 0x00000000007cf631 in captured_command_loop ()
     at gdb/main.c:481
 #13 0x00000000007d0ebf in captured_main (data=0x7fffffffd3f0)
     at gdb/main.c:1353
 #14 0x00000000007d0f25 in gdb_main (args=0x7fffffffd3f0)
     at gdb/main.c:1368
 #15 0x00000000004186dd in main (argc=5, argv=0x7fffffffd508)
     at gdb/gdb.c:32

This relatively short backtrace is due to the current UI's async field
being set to 1.

Yet another thing to be aware of regarding this problem is the
difference in the way that commands associated to dprintf breakpoints
versus regular breakpoints are handled.  While they both use a command
list associated with the breakpoint, regular breakpoints will place
the commands to be run on the bpstat chain constructed in
bp_stop_status().  These commands are run later on.  For dprintf
breakpoints, commands are run via the 'after_condition_true' function
pointer directly from bpstat_stop_status().  (The 'commands' field in
the bpstat is cleared in dprintf_after_condition_true().  This
prevents the dprintf commands from being run again later on when other
commands on the bpstat chain are processed.)

Another thing that I noticed is that dprintf breakpoints are the only
type of breakpoint which use 'after_condition_true'.  This suggests
that one possible way of fixing this problem, that of making dprintf
breakpoints work more like regular breakpoints, probably won't work.
(I must admit, however, that my understanding of this code isn't
complete enough to say why.  I'll trust that whoever implemented it
had a good reason for doing it this way.)

The comment referenced earlier regarding 'executing_breakpoint_commands'
states that the reason for checking this variable is to avoid
potential endless recursion when a 'source' command appears in
bs->commands.  We know that a dprintf command is constrained to either
1) execution of a GDB printf command, 2) an inferior function call of
a printf-like function, or 3) execution of an agent-printf command.
Therefore, infinite recursion due to a 'source' command cannot happen
when executing commands upon hitting a dprintf breakpoint.

I chose to fix this problem by having dprintf_after_condition_true()
directly call execute_control_commands().  This means that it no
longer attempts to go through bpstat_do_actions_1() avoiding the
infinite recursion check for potential 'source' commands on the
command chain.  I think it simplifies this code a little bit too, a
definite bonus.

Summary:

	* breakpoint.c (dprintf_after_condition_true): Don't call
	bpstat_do_actions_1().  Call execute_control_commands()
	instead.
2021-11-09 20:27:53 -07:00
Simon Marchi
313f3b21cb gdb: remove bpstat typedef, rename bpstats to bpstat
I don't find that the bpstat typedef, which hides a pointer, is
particularly useful.  In fact, it confused me many times, and I just see
it as something to remember that adds cognitive load.  Also, with C++,
we might want to be able to pass bpstats objects by const-reference, not
necessarily by pointer.

So, remove the bpstat typedef and rename struct bpstats to bpstat (since
it represents one bpstat, it makes sense that it is singular).

Change-Id: I52e763b6e54ee666a9e045785f686d37b4f5f849
2021-11-08 16:39:14 -05:00
Simon Marchi
f54bdb6d27 gdb: add add_setshow_prefix_cmd
There's a common pattern to call add_basic_prefix_cmd and
add_show_prefix_cmd to add matching set and show commands.  Add the
add_setshow_prefix_cmd function to factor that out and use it at a few
places.

Change-Id: I6e9e90a30e9efb7b255bf839cac27b85d7069cfd
2021-10-28 10:44:18 -04:00
Simon Marchi
50888e42dc gdb: change functions returning value contents to use gdb::array_view
The bug fixed by this [1] patch was caused by an out-of-bounds access to
a value's content.  The code gets the value's content (just a pointer)
and then indexes it with a non-sensical index.

This made me think of changing functions that return value contents to
return array_views instead of a plain pointer.  This has the advantage
that when GDB is built with _GLIBCXX_DEBUG, accesses to the array_view
are checked, making bugs more apparent / easier to find.

This patch changes the return types of these functions, and updates
callers to call .data() on the result, meaning it's not changing
anything in practice.  Additional work will be needed (which can be done
little by little) to make callers propagate the use of array_view and
reap the benefits.

[1] https://sourceware.org/pipermail/gdb-patches/2021-September/182306.html

Change-Id: I5151f888f169e1c36abe2cbc57620110673816f3
2021-10-25 14:51:44 -04:00
Simon Marchi
183be22290 gdb, gdbserver: make target_waitstatus safe
I stumbled on a bug caused by the fact that a code path read
target_waitstatus::value::sig (expecting it to contain a gdb_signal
value) while target_waitstatus::kind was TARGET_WAITKIND_FORKED.  This
meant that the active union field was in fact
target_waitstatus::value::related_pid, and contained a ptid.  The read
signal value was therefore garbage, and that caused GDB to crash soon
after.  Or, since that GDB was built with ubsan, this nice error
message:

    /home/simark/src/binutils-gdb/gdb/linux-nat.c:1271:12: runtime error: load of value 2686365, which is not a valid value for type 'gdb_signal'

Despite being a large-ish change, I think it would be nice to make
target_waitstatus safe against that kind of bug.  As already done
elsewhere (e.g. dynamic_prop), validate that the type of value read from
the union matches what is supposed to be the active field.

 - Make the kind and value of target_waitstatus private.
 - Make the kind initialized to TARGET_WAITKIND_IGNORE on
   target_waitstatus construction.  This is what most users appear to do
   explicitly.
 - Add setters, one for each kind.  Each setter takes as a parameter the
   data associated to that kind, if any.  This makes it impossible to
   forget to attach the associated data.
 - Add getters, one for each associated data type.  Each getter
   validates that the data type fetched by the user matches the wait
   status kind.
 - Change "integer" to "exit_status", "related_pid" to "child_ptid",
   just because that's more precise terminology.
 - Fix all users.

That last point is semi-mechanical.  There are a lot of obvious changes,
but some less obvious ones.  For example, it's not possible to set the
kind at some point and the associated data later, as some users did.
But in any case, the intent of the code should not change in this patch.

This was tested on x86-64 Linux (unix, native-gdbserver and
native-extended-gdbserver boards).  It was built-tested on x86-64
FreeBSD, NetBSD, MinGW and macOS.  The rest of the changes to native
files was done as a best effort.  If I forgot any place to update in
these files, it should be easy to fix (unless the change happens to
reveal an actual bug).

Change-Id: I0ae967df1ff6e28de78abbe3ac9b4b2ff4ad03b7
2021-10-21 16:13:56 -04:00
Tom Tromey
6f781ee300 Use unique_xmalloc_ptr in breakpoint
This changes struct breakpoint to use unique_xmalloc_ptr in a couple
of spots, removing a bit of manual memory management.
2021-10-20 11:00:32 -06:00
Tom Tromey
23d6ee6405 Use unique_xmalloc_ptr in bp_location
This changes struct bp_location to use a unique_xmalloc_ptr, removing
a bit of manual memory management.
2021-10-20 11:00:32 -06:00
Tom Tromey
a4c50be3d6 Use unique_xmalloc_ptr in watchpoint
This changes struct watchpoint to use unique_xmalloc_ptr in a couple
of places, removing a bit of manual memory management.
2021-10-20 11:00:31 -06:00
Tom Tromey
5c1146d2de Use unique_xmalloc_ptr in exec_catchpoint
This changes struct exec_catchpoint to use a unique_xmalloc_ptr,
removing a bit of manual memory management.
2021-10-20 11:00:31 -06:00
Tom Tromey
b00577cd7b Use unique_xmalloc_ptr in solib_catchpoint
This changes struct solib_catchpoint to use a unique_xmalloc_ptr,
removing a bit of manual memory management.
2021-10-20 11:00:31 -06:00
Simon Marchi
e0700ba44c gdb: make string-like set show commands use std::string variable
String-like settings (var_string, var_filename, var_optional_filename,
var_string_noescape) currently take a pointer to a `char *` storage
variable (typically global) that holds the setting's value.  I'd like to
"mordernize" this by changing them to use an std::string for storage.

An obvious reason is that string operations on std::string are often
easier to write than with C strings.  And they avoid having to do any
manual memory management.

Another interesting reason is that, with `char *`, nullptr and an empty
string often both have the same meaning of "no value".  String settings
are initially nullptr (unless initialized otherwise).  But when doing
"set foo" (where `foo` is a string setting), the setting now points to
an empty string.  For example, solib_search_path is nullptr at startup,
but points to an empty string after doing "set solib-search-path".  This
leads to some code that needs to check for both to check for "no value".
Or some code that converts back and forth between NULL and "" when
getting or setting the value.  I find this very error-prone, because it
is very easy to forget one or the other.  With std::string, we at least
know that the variable is not "NULL".  There is only one way of
representing an empty string setting, that is with an empty string.

I was wondering whether the distinction between NULL and "" would be
important for some setting, but it doesn't seem so.  If that ever
happens, it would be more C++-y and self-descriptive to use
optional<string> anyway.

Actually, there's one spot where this distinction mattered, it's in
init_history, for the test gdb.base/gdbinit-history.exp.  init_history
sets the history filename to the default ".gdb_history" if it sees that
the setting was never set - if history_filename is nullptr.  If
history_filename is an empty string, it means the setting was explicitly
cleared, so it leaves it as-is.  With the change to std::string, this
distinction doesn't exist anymore.  This can be fixed by moving the code
that chooses a good default value for history_filename to
_initialize_top.  This is ran before -ex commands are processed, so an
-ex command can then clear that value if needed (what
gdb.base/gdbinit-history.exp tests).

Another small improvement, in my opinion is that we can now easily
give string parameters initial values, by simply initializing the global
variables, instead of xstrdup-ing it in the _initialize function.

In Python and Guile, when registering a string-like parameter, we
allocate (with new) an std::string that is owned by the param_smob (in
Guile) and the parmpy_object (in Python) objects.

This patch started by changing all relevant add_setshow_* commands to
take an `std::string *` instead of a `char **` and fixing everything
that failed to build.  That includes of course all string setting
variable and their uses.

string_option_def now uses an std::string also, because there's a
connection between options and settings (see
add_setshow_cmds_for_options).

The add_path function in source.c is really complex and twisted, I'd
rather not try to change it to work on an std::string right now.
Instead, I added an overload that copies the std:string to a `char *`
and back.  This means more copying, but this is not used in a hot path
at all, so I think it is acceptable.

Change-Id: I92c50a1bdd8307141cdbacb388248e4e4fc08c93
Co-authored-by: Lancelot SIX <lsix@lancelotsix.com>
2021-10-03 17:53:16 +01:00
Simon Marchi
25558938d0 gdb: change thread_info::name to unique_xmalloc_ptr, add helper function
This started out as changing thread_info::name to a unique_xmalloc_ptr.
That showed that almost all users of that field had the same logic to
get a thread's name: use thread_info::name if non-nullptr, else ask the
target.  Factor out this logic in a new thread_name free function.  Make
the field private (rename to m_name) and add some accessors.

Change-Id: Iebdd95f4cd21fbefc505249bd1d05befc466a2fc
2021-09-24 17:25:55 -04:00
Andrew Burgess
611841bb1a gdb: make thread_info::executing private
Rename thread_info::executing to thread_info::m_executing, and make it
private.  Add a new get/set member functions, and convert GDB to make
use of these.

The only real change of interest in this patch is in thread.c where I
have deleted the helper function set_executing_thread, and now just
use the new set function thread_info::set_executing.  However, the old
helper function set_executing_thread included some code to reset the
thread's stop_pc, so I moved this code into the new function
thread_info::set_executing.  However, I don't believe there is
anywhere that this results in a change of behaviour, previously the
executing flag was always set true through a call to
set_executing_thread anyway.
2021-09-07 12:44:08 +01:00
Simon Marchi
9fe3819e83 gdb: remove breakpoint_find_if
Remove breakpoint_find_if, replace its sole usage with using
all_breakpoints directly instead.  At the same time, change return
types to use bool.

Change-Id: I9ec392236b4804b362d16ab563330b9c07311106
2021-08-31 09:55:31 -04:00
Patrick Monnerat
bd7ccaa983 Notify observer of breakpoint auto-disabling
As breakpoint_modified observer is currently notified upon breakpoint stop
before handling auto-disabling when enable count is reached, the observer
is never notified of the disabling.

The problem affects:
- The MI interpreter enabled= value when reporting =breakpoint-modified
- A Python event handler for breakpoint_modified using the "enabled"
  member of its parameter
- insight: breakpoint GUI window is not properly updated upon auto-disable

This patch moves the observer notification after the auto-disabling
code and implements corresponding tests for the MI and Python cases.

Fixes https://sourceware.org/bugzilla/show_bug.cgi?id=23336

Change-Id: I0c50df4789334071e5390cb46b3ca0d4a7f83c61
2021-08-16 11:10:19 -04:00
Simon Marchi
5538b03c98 gdb: remove cmd_list_element::function::sfunc
I don't understand what the sfunc function type in
cmd_list_element::function is for.  Compared to cmd_simple_func_ftype,
it has an extra cmd_list_element parameter, giving the callback access
to the cmd_list_element for the command being invoked.  This allows
registering the same callback with many commands, and alter the behavior
using the cmd_list_element's context.

From the comment in cmd_list_element, it sounds like at some point it
was the callback function type for set and show functions, hence the
"s".  But nowadays, it's used for many more commands that need to access
the cmd_list_element object (see add_catch_command for example).

I don't really see the point of having sfunc at all, since do_sfunc is
just a trivial shim that changes the order of the arguments.  All
commands using sfunc could just as well set cmd_list_element::func to
their callback directly.

Therefore, remove the sfunc field in cmd_list_element and everything
that goes with it.  Rename cmd_const_sfunc_ftype to cmd_func_ftype and
use it for cmd_list_element::func, as well as for the add_setshow
commands.

Change-Id: I1eb96326c9b511c293c76996cea0ebc51c70fac0
2021-07-23 15:38:54 -04:00
Simon Marchi
1edb66d856 gdb: make thread_info::suspend private, add getters / setters
A following patch will want to take some action when a pending wait
status is set on or removed from a thread.  Add a getter and a setter on
thread_info for the pending waitstatus, so that we can add some code in
the setter later.

The thing is, the pending wait status field is in the
thread_suspend_state, along with other fields that we need to backup
before and restore after the thread does an inferior function call.
Therefore, make the thread_suspend_state member private
(thread_info::suspend becomes thread_info::m_suspend), and add getters /
setters for all of its fields:

 - pending wait status
 - stop signal
 - stop reason
 - stop pc

For the pending wait status, add the additional has_pending_waitstatus
and clear_pending_waitstatus methods.

I think this makes the thread_info interface a bit nicer, because we
now access the fields as:

  thread->stop_pc ()

rather than

  thread->suspend.stop_pc

The stop_pc field being in the `suspend` structure is an implementation
detail of thread_info that callers don't need to be aware of.

For the backup / restore of the thread_suspend_state structure, add
save_suspend_to and restore_suspend_from methods.  You might wonder why
`save_suspend_to`, as opposed to a simple getter like

  thread_suspend_state &suspend ();

I want to make it clear that this is to be used only for backing up and
restoring the suspend state, _not_ to access fields like:

  thread->suspend ()->stop_pc

Adding some getters / setters allows adding some assertions.  I find
that this helps understand how things are supposed to work.  Add:

 - When getting the pending status (pending_waitstatus method), ensure
   that there is a pending status.
 - When setting a pending status (set_pending_waitstatus method), ensure
   there is no pending status.

There is one case I found where this wasn't true - in
remote_target::process_initial_stop_replies - which needed adjustments
to respect that contract.  I think it's because
process_initial_stop_replies is kind of (ab)using the
thread_info::suspend::waitstatus to store some statuses temporarily, for
its internal use (statuses it doesn't intent on leaving pending).

process_initial_stop_replies pulls out stop replies received during the
initial connection using target_wait.  It always stores the received
event in `evthread->suspend.waitstatus`.  But it only sets
waitstatus_pending_p, if it deems the event interesting enough to leave
pending, to be reported to the core:

      if (ws.kind != TARGET_WAITKIND_STOPPED
	  || ws.value.sig != GDB_SIGNAL_0)
	evthread->suspend.waitstatus_pending_p = 1;

It later uses this flag a bit below, to choose which thread to make the
"selected" one:

      if (selected == NULL
	  && thread->suspend.waitstatus_pending_p)
	selected = thread;

And ultimately that's used if the user-visible mode is all-stop, so that
we print the stop for that interesting thread:

  /* In all-stop, we only print the status of one thread, and leave
     others with their status pending.  */
  if (!non_stop)
    {
      thread_info *thread = selected;
      if (thread == NULL)
	thread = lowest_stopped;
      if (thread == NULL)
	thread = first;

      print_one_stopped_thread (thread);
    }

But in any case (all-stop or non-stop), print_one_stopped_thread needs
to access the waitstatus value of these threads that don't have a
pending waitstatus (those that had TARGET_WAITKIND_STOPPED +
GDB_SIGNAL_0).  This doesn't work with the assertions I've
put.

So, change the code to only set the thread's wait status if it is an
interesting one that we are going to leave pending.  If the thread
stopped due to a non-interesting event (TARGET_WAITKIND_STOPPED +
GDB_SIGNAL_0), don't store it.  Adjust print_one_stopped_thread to
understand that if a thread has no pending waitstatus, it's because it
stopped with TARGET_WAITKIND_STOPPED + GDB_SIGNAL_0.

The call to set_last_target_status also uses the pending waitstatus.
However, given that the pending waitstatus for the thread may have been
cleared in print_one_stopped_thread (and that there might not even be a
pending waitstatus in the first place, as explained above), it is no
longer possible to do it at this point.  To fix that, move the call to
set_last_target_status in print_one_stopped_thread.  I think this will
preserve the existing behavior, because set_last_target_status is
currently using the current thread's wait status.  And the current
thread is the last one for which print_one_stopped_thread is called.  So
by calling set_last_target_status in print_one_stopped_thread, we'll get
the same result.  set_last_target_status will possibly be called
multiple times, but only the last call will matter.  It just means
possibly more calls to set_last_target_status, but those are cheap.

Change-Id: Iedab9653238eaf8231abcf0baa20145acc8b77a7
2021-07-12 20:46:53 -04:00
Simon Marchi
7846f3aa61 gdb: add setter / getter for thread_info resumed state
A following patch will want to do things when a thread's resumed state
changes.  Make the `resumed` field private (renamed to `m_resumed`) and
add a getter and a setter for it.  The following patch in question will
therefore be able to add some code to the setter.

Change-Id: I360c48cc55a036503174313261ce4e757d795319
2021-07-12 20:46:52 -04:00
Simon Marchi
9be259865c gdb: introduce iterator_range, remove next_adapter
I was always a bit confused by next_adapter, because it kind of mixes
the element type and the iterator type.  In reality, it is not much more
than a class that wraps two iterators (begin and end).  However, it
assumes that:

 - you can construct the begin iterator by passing a pointer to the
   first element of the iterable
 - you can default-construct iterator to make the end iterator

I think that by generalizing it a little bit, we can re-use it at more
places.

Rename it to "iterator_range".  I think it describes a bit better: it's
a range made by wrapping a begin and end iterator.  Move it to its own
file, since it's not related to next_iterator anymore.

iterator_range has two constructors.  The variadic one, where arguments
are forwarded to construct the underlying begin iterator.  The end
iterator is constructed through default construction.  This is a
generalization of what we have today.

There is another constructor which receives already constructed begin
and end iterators, useful if the end iterator can't be obtained by
default-construction.  Or, if you wanted to make a range that does not
end at the end of the container, you could pass any iterator as the
"end".

This generalization allows removing some "range" classes, like
all_inferiors_range.  These classes existed only to pass some arguments
when constructing the begin iterator.  With iterator_range, those same
arguments are passed to the iterator_range constructed and then
forwarded to the constructed begin iterator.

There is a small functional difference in how iterator_range works
compared to next_adapter.  next_adapter stored the pointer it received
as argument and constructeur an iterator in the `begin` method.
iterator_range constructs the begin iterator and stores it as a member.
Its `begin` method returns a copy of that iterator.

With just iterator_range, uses of next_adapter<foo> would be replaced
with:

  using foo_iterator = next_iterator<foo>;
  using foo_range = iterator_range<foo_iterator>;

However, I added a `next_range` wrapper as a direct replacement for
next_adapter<foo>.  IMO, next_range is a slightly better name than
next_adapter.

The rest of the changes are applications of this new class.

gdbsupport/ChangeLog:

	* next-iterator.h (class next_adapter): Remove.
	* iterator-range.h: New.

gdb/ChangeLog:

	* breakpoint.h (bp_locations_range): Remove.
	(bp_location_range): New.
	(struct breakpoint) <locations>: Adjust type.
	(breakpoint_range): Use iterator_range.
	(tracepoint_range): Use iterator_range.
	* breakpoint.c (breakpoint::locations): Adjust return type.
	* gdb_bfd.h (gdb_bfd_section_range): Use iterator_range.
	* gdbthread.h (all_threads_safe): Pass argument to
	all_threads_safe_range.
	* inferior-iter.h (all_inferiors_range): Use iterator_range.
	(all_inferiors_safe_range): Use iterator_range.
	(all_non_exited_inferiors_range): Use iterator_range.
	* inferior.h (all_inferiors, all_non_exited_inferiors): Pass
	inferior_list as argument.
	* objfiles.h (struct objfile) <compunits_range>: Remove.
	<compunits>: Return compunit_symtab_range.
	* progspace.h (unwrapping_objfile_iterator)
	<unwrapping_objfile_iterator>: Take parameter by value.
	(unwrapping_objfile_range): Use iterator_range.
	(struct program_space) <objfiles_range>: Define with "using".
	<objfiles>: Adjust.
	<objfiles_safe_range>: Define with "using".
	<objfiles_safe>: Adjust.
	<solibs>: Return so_list_range, define here.
	* progspace.c (program_space::solibs): Remove.
	* psymtab.h (class psymtab_storage) <partial_symtab_iterator>:
	New.
	<partial_symtab_range>: Use iterator_range.
	* solist.h (so_list_range): New.
	* symtab.h (compunit_symtab_range):
	New.
	(symtab_range): New.
	(compunit_filetabs): Change to a function.
	* thread-iter.h (inf_threads_range,
	inf_non_exited_threads_range, safe_inf_threads_range,
	all_threads_safe_range): Use iterator_range.
	* top.h (ui_range): New.
	(all_uis): Use ui_range.

Change-Id: Ib7a9d2a3547f45f01aa1c6b24536ba159db9b854
2021-07-06 15:02:05 -04:00
Simon Marchi
0f8e203412 gdb: add context getter/setter to cmd_list_element
Straightforward replacement of get_cmd_context / set_cmd_context with
cmd_list_element methods.

gdb/ChangeLog:

	* cli/cli-decode.h (struct cmd_list_element) <set_context,
	context>: New.
	<context>: Rename to...
	<m_context>: ... this.
	* cli/cli-decode.c (set_cmd_context, get_cmd_context): Remove.
	* command.h (set_cmd_context, get_cmd_context): Remove, use
	cmd_list_element::set_context and cmd_list_element::context
	everywhere instead.

Change-Id: I5016b0079014e3f17d1aa449ada7954473bf2b5d
2021-06-25 21:35:40 -04:00
Andrew Burgess
80dc83fd0e gdb/remote: handle target dying just before a stepi
I randomly hit a situation where gdbserver crashed immediately before
I issued a 'stepi' to GDB, it turns out that this causes GDB itself to
crash.

What happens is that as part of the stepi we try to insert some
breakpoints into the inferior, so from insert_breakpoints we figure
out what we want to insert, then, eventually, try to send some packets
to the remote to get the breakpoints inserted.

It is only at this point that GDB realises that the target has gone
away.  This causes GDB to then enter this call stack:

  unpush_and_perror
    remote_unpush_target
      generic_mourn_inferior
        breakpoint_init_inferior
          delete_breakpoint
            update_global_location_list

So, we realise the target is gone and so delete the breakpoints
associated with that target.

GDB then throws a TARGET_CLOSE_ERROR from unpush_and_error.

This error is caught in insert_breakpoints where we then try to print
a nice error saying something like:

  Cannot insert breakpoint %d: some error text here...

To fill in the '%d' we try to read properties of the breakpoint
object.

Which was deleted due to the delete_breakpoint call above.

And so GDB dies...

My proposal in this commit is that, should we catch a
TARGET_CLOSE_ERROR in insert_breakpoints, then we just rethrow the
error.

This will cause the main event loop to print something like:

  Remote connection closed

Which I think is fine, I don't think the user will care much which
particular breakpoint GDB was operating on when the connection closed,
just knowing that the connection closed should be enough I think.

I initially added a test to 'gdb.server/server-kill.exp' for this
issue, however, my first attempt was not good enough, the test was
passing even without my fix.

Turns out that the server-kill.exp test actually kills the PID of the
inferior, not the PID of the server.  This means that gdbserver is
actually able to send a packet to GDB saying that the inferior has
exited prior to gdbserver itself shutting down.  This extra
information was enough to prevent the bug I was seeing manifest.

So, I have extended server-kill.exp to run all of the tests twice, the
first time we still kill the inferior.  On the second run we hard kill
the gdbserver itself, this prevents the server from sending anything
to GDB before it exits.

My new test is only expected to fail in this second mode of
operation (killing gdbserver itself), and without my fix, that is what
I see.

gdb/ChangeLog:

	* breakpoint.c (insert_bp_location): If we catch a
	TARGET_CLOSE_ERROR just rethrow it, the breakpoints might have
	been deleted.

gdb/testsuite/ChangeLog:

	* gdb.server/server-kill.exp: Introduce global kill_pid_of, and
	make use of this in prepare to select which pid we should kill.
	Run all the tests twice with a different kill_pid_of value.
	(prepare): Make use of kill_pid_of.
	(test_stepi): New proc.
2021-06-22 10:03:02 +01:00
Andrew Burgess
b4b3e2dee2 gdb: avoid premature dummy frame garbage collection
Consider the following chain of events:

  * GDB is performing an inferior call, and

  * the inferior calls longjmp, and

  * GDB detects that the longjmp has completed, stops, and enters
    check_longjmp_breakpoint_for_call_dummy (in breakpoint.c), and

  * GDB tries to unwind the stack in order to check that the dummy
    frame (setup for the inferior call) is still on the stack, but

  * The unwind fails, possibly due to missing debug information, so

  * GDB incorrectly concludes that the inferior has longjmp'd past the
    dummy frame, and so deletes the dummy frame, including the dummy
    frame breakpoint, but then

  * The inferior continues, and eventually returns to the dummy frame,
    which is usually (always?) on the stack, the inferior starts
    trying to execute the random contents of the stack, this results
    in undefined behaviour.

This situation is already warned about in the comment on the function
check_longjmp_breakpoint_for_call_dummy where we say:

   You should call this function only at places where it is safe to currently
   unwind the whole stack.  Failed stack unwind would discard live dummy
   frames.

The warning here is fine, the problem is that, even though we call the
function from a location within GDB where we hope to be able to
unwind, sometime the state of the inferior means that the unwind will
not succeed.

This commit tries to improve the situation by adding the following
additional check; when GDB fails to find the dummy frame on the stack,
instead of just assuming that the dummy frame can be garbage
collected, first find the stop_reason for the last frame on the stack.
If this stop_reason indicates that the stack unwinding may have failed
then we assume that the dummy frame is still in use.  However, if the
last frame's stop_reason indicates that the stack unwind completed
successfully then we can be confident that the dummy frame is no
longer in use, and we garbage collect it.

Tested on x86-64 GNU/Linux.

gdb/ChangeLog:

	* breakpoint.c (check_longjmp_breakpoint_for_call_dummy): Add
	check for why the backtrace stopped.

gdb/testsuite/ChangeLog:

	* gdb.base/premature-dummy-frame-removal.c: New file.
	* gdb.base/premature-dummy-frame-removal.exp: New file.
	* gdb.base/premature-dummy-frame-removal.py: New file.

Change-Id: I8f330cfe0f3f33beb3a52a36994094c4abada07e
2021-06-01 09:23:34 +01:00
Simon Marchi
24b21115f5 gdb: fix tab after space indentation issues
I spotted some indentation issues where we had some spaces followed by
tabs at beginning of line, that I wanted to fix.  So while at it, I did
a quick grep to find and fix all I could find.

gdb/ChangeLog:

	* Fix tab after space indentation issues throughout.

Change-Id: I1acb414dd9c593b474ae2b8667496584df4316fd
2021-05-27 15:18:49 -04:00
Simon Marchi
01add95bed gdb: fix some indentation issues
I wrote a small script to spot a pattern of indentation mistakes I saw
happened in breakpoint.c.  And while at it I ran it on all files and
fixed what I found.  No behavior changes intended, just indentation and
addition / removal of curly braces.

gdb/ChangeLog:

	* Fix some indentation mistakes throughout.

gdbserver/ChangeLog:

	* Fix some indentation mistakes throughout.

Change-Id: Ia01990c26c38e83a243d8f33da1d494f16315c6e
2021-05-27 15:01:28 -04:00
Simon Marchi
055c879fcf gdb: remove iterate_over_bp_locations function
Remove it, change users (well, a single one) to use all_bp_locations.
This requires moving all_bp_locations to breakpoint.h to expose it.

gdb/ChangeLog:

	* breakpoint.h (iterate_over_bp_locations): Remove.  Update
	users to use all_bp_locations.
	(all_bp_locations): New.
	* breakpoint.c (all_bp_locations): Make non-static.
	(iterate_over_bp_locations): Remove.

Change-Id: Iaf1f716d6c2c5b2975579b3dc113a86f5d0975be
2021-05-27 14:58:38 -04:00
Simon Marchi
240edef62f gdb: remove iterate_over_breakpoints function
Now that we have range functions that let us use ranged for loops, we
can remove iterate_over_breakpoints in favor of those, which are easier
to read and write.  This requires exposing the declaration of
all_breakpoints and all_breakpoints_safe in breakpoint.h, as well as the
supporting types.

Change some users of iterate_over_breakpoints to use all_breakpoints,
when they don't need to delete the breakpoint, and all_breakpoints_safe
otherwise.

gdb/ChangeLog:

	* breakpoint.h (iterate_over_breakpoints): Remove.  Update
	callers to use all_breakpoints or all_breakpoints_safe.
	(breakpoint_range, all_breakpoints, breakpoint_safe_range,
	all_breakpoints_safe): Move here.
	* breakpoint.c (all_breakpoints, all_breakpoints_safe): Make
	non-static.
	(iterate_over_breakpoints): Remove.
	* python/py-finishbreakpoint.c (bpfinishpy_detect_out_scope_cb):
	Return void.
	* python/py-breakpoint.c (build_bp_list): Add comment, reverse
	return value logic.
	* guile/scm-breakpoint.c (bpscm_build_bp_list): Return void.

Change-Id: Idde764a1f577de0423e4f2444a7d5cdb01ba5e48
2021-05-27 14:58:37 -04:00
Simon Marchi
e0d9a27040 gdb: add all_bp_locations_at_addr function
Add the all_bp_locations_at_addr function, which returns a range of all
breakpoint locations at exactly the given address.  This lets us
replace:

  bp_location *loc, **loc2p, *locp;
  ALL_BP_LOCATIONS_AT_ADDR (loc2p, locp, address)
    {
      loc = *loc2p;

      // use loc
    }

with

  for (bp_location *loc : all_bp_locations_at_addr (address))
    {
      // use loc
    }

The all_bp_locations_at_addr returns a bp_locations_at_addr_range
object, which is really just a wrapper around two std::vector iterators
representing the beginning and end of the interesting range.  These
iterators are found when constructing the bp_locations_at_addr_range
object using std::equal_range, which seems a perfect fit for this use
case.

One thing I noticed about the current ALL_BP_LOCATIONS_AT_ADDR is that
if you call it with a NULL start variable, that variable gets filled in
and can be re-used for subsequent iterations.  This avoids the cost of
finding the start of the interesting range again for the subsequent
iterations.  This happens in build_target_command_list, for example.
The same effect can be achieved by storing the range in a local
variable, it can be iterated on multiple times.

Note that the original comment over ALL_BP_LOCATIONS_AT_ADDR says:

    Iterates through locations with address ADDRESS for the currently
    selected program space.

I don't see anything restricting the iteration to a given program space,
as we iterate over all bp_locations, which as far as I know contains all
breakpoint locations, regardless of the program space.  So I just
dropped that part of the comment.

gdb/ChangeLog:

	* breakpoint.c (get_first_locp_gte_addr): Remove.
	(ALL_BP_LOCATIONS_AT_ADDR): Remove.  Replace all uses with
	all_bp_locations_at_addr.
	(struct bp_locations_at_addr_range): New.
	(all_bp_locations_at_addr): New.
	(bp_locations_compare_addrs): New.

Change-Id: Icc8c92302045c47a48f507b7f1872bdd31d4ba59
2021-05-27 14:58:37 -04:00
Simon Marchi
48d7020b7f gdb: add all_bp_locations function
Add the all_bp_locations function to replace the ALL_BP_LOCATIONS macro.
For simplicity, all_bp_locations simply returns a const reference to the
bp_locations vector.  But the callers just treat it as a range to
iterate on, so if we ever change the breakpoint location storage, we can
change the all_bp_locations function to return some other range type,
and the callers won't need to be changed.

gdb/ChangeLog:

	* breakpoint.c (ALL_BP_LOCATIONS): Remove, update users to use
	all_bp_locations.
	(all_bp_locations): New.

Change-Id: Iae71a1ba135c1a5bcdb4658bf3cf9793f0e9f81c
2021-05-27 14:58:37 -04:00
Simon Marchi
5d51cd5d14 gdb: make bp_locations an std::vector
Change the type of the global location list, bp_locations, to be an
std::vector.

Adjust the users to deal with that, mostly in an obvious way by using
.data() and .size().  The user where it's slightly less obvious is
update_global_location_list.  There, we std::move the old location list
out of the global vector into a local variable.  The code to fill the
new location list gets simpler, as it's now simply using .push_back(),
no need to count the locations beforehand.

In the rest of update_global_location_list, the code is adjusted to work
with indices instead of `bp_location **`, to iterate on the location
list.  I believe it's a bit easier to understand this way.  But more
importantly, when we build with _GLIBCXX_DEBUG, the operator[] of the
vector does bound checking, so we will know if we ever access past a
vector size (which we won't if we access by raw pointer).  I think that
work can further be done to make that function easier to understand,
notably find better names than "loc" and "loc2" for variables, but
that's work for later.

gdb/ChangeLog:

	* breakpoint.c (bp_locations): Change to std::vector, update all
	users.
	(bp_locations_count): Remove.
	(update_global_location_list): Change to work with indices
	rather than bp_location**.

Change-Id: I193ce40f84d5dc930fbab8867cf946e78ff0df0b
2021-05-27 14:58:37 -04:00
Simon Marchi
40cb8ca539 gdb: add breakpoint::locations method
Add the breakpoint::locations method, which returns a range that can be
used to iterate over a breakpoint's locations.  This shortens

  for (bp_location *loc = b->loc; loc != nullptr; loc = loc->next)

into

  for (bp_location *loc : b->locations ())

Change all the places that I found that could use it.

gdb/ChangeLog:

	* breakpoint.h (bp_locations_range): New.
	(struct breakpoint) <locations>: New.  Use where possible.

Change-Id: I1ba2f7d93d57e544e1f8609124587dcf2e1da037
2021-05-27 14:58:37 -04:00
Simon Marchi
f6d17b2b1c gdb: add all_tracepoints function
Same idea as the previous patches, but to replace the ALL_TRACEPOINTS
macro.  Define a new filtered_iterator that only keeps the breakpoints
for which is_tracepoint returns true (just like the macro did).

I would have like to make it so tracepoint_range yields some
`tracepoint *` instead of some `breakpoint *`, that would help simplify
the callers, who wouldn't have to do the cast themselves.  But I didn't
find an obvious way to do it.  It can always be added later.

It turns out there is already an all_tracepoints function, which returns
a vector containing all the breakpoints that are tracepoint.  Remove it,
most users will just work seamlessly with the new function.  The
exception is start_tracing, which iterated multiple times on the vector.
Adapt this one so it iterates multiple times on the returned range.

Since the existing users of all_tracepoints are outside of breakpoint.c,
this requires defining all_tracepoints and a few supporting types in
breakpoint.h.  So, move breakpoint_iterator from breakpoint.c to
breakpoint.h.

gdb/ChangeLog:

	* breakpoint.h (all_tracepoints): Remove.
	(breakpoint_iterator): Move here.
	(struct tracepoint_filter): New.
	(tracepoint_iterator): New.
	(tracepoint_range): New.
	(all_tracepoints): New.
	* breakpoint.c (ALL_TRACEPOINTS): Remove, replace all users with
	all_tracepoints.
	(breakpoint_iterator): Move to header.
	(all_tracepoints): New.
	* tracepoint.c (start_tracing): Adjust.

Change-Id: I76b1bba4215dbec7a03846c568368aeef7f1e05a
2021-05-27 14:58:36 -04:00
Simon Marchi
1428b37afb gdb: add all_breakpoints_safe function
Same as the previous patch, but intended to replace the
ALL_BREAKPOINTS_SAFE macro, which allows deleting the current breakpoint
while iterating.  The new range type simply wraps the range added by the
previous patch with basic_safe_range.

I didn't remove the ALL_BREAKPOINTS_SAFE macro, because there is one
spot where it's more tricky to remove, in the
check_longjmp_breakpoint_for_call_dummy function.  More thought it
needed for this one.

gdb/ChangeLog:

	* breakpoint.c (breakpoint_safe_range): New.
	(all_breakpoints_safe): New.  Use instead of
	ALL_BREAKPOINTS_SAFE where possible.

Change-Id: Ifccab29f135e1f85700e3697ed60f0b643c7682f
2021-05-27 14:58:36 -04:00
Simon Marchi
43892fdfa1 gdb: add all_breakpoints function
Introduce the all_breakpoints function, which returns a range that can
be used to iterate on breakpoints.  Replace all uses of the
ALL_BREAKPOINTS macro with this.

In one instance, I could replace the breakpoint iteration with a call to
get_breakpoint.

gdb/ChangeLog:

	* breakpoint.c (ALL_BREAKPOINTS): Remove, replace all uses with
	all_breakpoints.
	(breakpoint_iterator): New.
	(breakpoint_range): New.
	(all_breakpoints): New.

Change-Id: I229595bddad7c9100b179a9dd56b04b8c206e86c
2021-05-27 14:58:36 -04:00
Simon Marchi
5e84b7eefb gdb: remove add_alias_cmd overload that accepts a string
Same idea as previous patch, but for add_alias_cmd.  Remove the overload
that accepts the target command as a string (the target command name),
leaving only the one that takes the cmd_list_element.

gdb/ChangeLog:

	* command.h (add_alias_cmd): Accept target as
	cmd_list_element.  Update callers.

Change-Id: I546311f411e9e7da9302322d6ffad4e6c56df266
2021-05-27 14:00:08 -04:00
Simon Marchi
e0f25bd971 gdb: make add_info_alias accept target as a cmd_list_element
Same idea as previous patch, but for add_info_alias.

gdb/ChangeLog:

	* command.h (add_info_alias): Accept target as
	cmd_list_element.  Update callers.

Change-Id: If830d423364bf42d7bea5ac4dd3a81adcfce6f7a
2021-05-27 14:00:07 -04:00