binutils-gdb.git
20 months agox86: drop redundant calculation of EVEX broadcast size
Jan Beulich [Fri, 3 Mar 2023 07:46:13 +0000 (08:46 +0100)]
x86: drop redundant calculation of EVEX broadcast size

In commit a5748e0d8c50 ("x86/Intel: allow MASM representation of
embedded broadcast") I replaced the calculation of i.broadcast.bytes in
check_VecOperands() not paying attention to the immediately following
call to get_broadcast_bytes() doing exactly that (again) first thing.

20 months agogas: default .debug section compression method adjustments
Jan Beulich [Fri, 3 Mar 2023 07:45:54 +0000 (08:45 +0100)]
gas: default .debug section compression method adjustments

While commit b0c295e1b8d0 ("add --enable-default-compressed-debug-
sections-algorithm configure option") adjusted flag_compress_debug's
initializer, it didn't alter the default used when the command line
option was specified with an (optional!) argument. This rendered help
text inconsistent with actual behavior in certain configurations.

As to help text - the default reported there clearly shouldn't be
affected by a possible earlier --compress-debug-sections= option, so
flag_compress_debug can't be used when emitting usage information.

20 months agox86: avoid .byte in testcases where possible
Jan Beulich [Fri, 3 Mar 2023 07:45:12 +0000 (08:45 +0100)]
x86: avoid .byte in testcases where possible

In the course of using the upcoming .insn directive to eliminate various
.byte uses in testcases I've come across these, which needlessly use
more .byte than necessary even without the availability of .insn.

20 months agoTidy type handling in binutils/rdcoff.c
Alan Modra [Fri, 3 Mar 2023 00:45:35 +0000 (11:15 +1030)]
Tidy type handling in binutils/rdcoff.c

There isn't really any good reason for code in rdcoff.c to distinguish
between "basic" types and any other type.  This patch dispenses with
the array reserved for basic types and instead handles all types using
coff_get_slot, simplifying the code.

* rdcoff.c (struct coff_types, coff_slots): Merge.  Delete
coff_slots.
(T_MAX): Delete.
(parse_coff_base_type): Use coff_get_slot to store baseic types.
(coff_get_slot, parse_coff_type, parse_coff_base_type),
(parse_coff_struct_type, parse_coff_enum_type),
(parse_coff_symbol, parse_coff): Pass types as coff_types**.

20 months agobinutils coff type list
Alan Modra [Thu, 2 Mar 2023 22:43:03 +0000 (09:13 +1030)]
binutils coff type list

As for commit 72d225ef9cc7, handle type numbers starting anywhere.

PR 17512
* rdcoff.c (struct coff_slots): Add base_index.
(coff_get_slot): Delete pr17512 excessively large slot check.
Don't allocate entire array from 0 to type number, allocate a
sparse array.

20 months agoAutomatic date update in version.in
GDB Administrator [Fri, 3 Mar 2023 00:00:34 +0000 (00:00 +0000)]
Automatic date update in version.in

20 months agogdb: fix -Wmaybe-uninitialized warning in value.c
Simon Marchi [Thu, 2 Mar 2023 20:26:55 +0000 (15:26 -0500)]
gdb: fix -Wmaybe-uninitialized warning in value.c

Since commit 11470e70ea0d ("gdb: store internalvars in an std::map"), bulding
with -O2, with g++ 11.3.0 on Ubuntu 22.04, I see:

      CXX    value.o
    In constructor ‘internalvar::internalvar(internalvar&&)’,
        inlined from ‘constexpr std::pair<_T1, _T2>::pair(_U1&&, _U2&&) [with _U1 = const char*&; _U2 = internalvar; typename std::enable_if<(std::_PCC<true, _T1, _T2>::_MoveConstructiblePair<_U1, _U2>() && std::_PCC<true, _T1, _T2>::_ImplicitlyMoveConvertiblePair<_U1, _U2>()), bool>::type <anonymous> = true; _T1 = const char*; _T2 = internalvar]’ at /usr/include/c++/11/bits/stl_pair.h:353:35,
        inlined from ‘constexpr std::pair<typename std::__strip_reference_wrapper<typename std::decay<_Tp>::type>::__type, typename std::__strip_reference_wrapper<typename std::decay<_Tp2>::type>::__type> std::make_pair(_T1&&, _T2&&) [with _T1 = const char*&; _T2 = internalvar]’ at /usr/include/c++/11/bits/stl_pair.h:572:72,
        inlined from ‘internalvar* create_internalvar(const char*)’ at /home/smarchi/src/binutils-gdb/gdb/value.c:1933:52:
    /home/smarchi/src/binutils-gdb/gdb/value.c:1831:8: warning: ‘<unnamed>.internalvar::u’ may be used uninitialized [-Wmaybe-uninitialized]
     1831 | struct internalvar
          |        ^~~~~~~~~~~
    /home/smarchi/src/binutils-gdb/gdb/value.c: In function ‘internalvar* create_internalvar(const char*)’:
    /home/smarchi/src/binutils-gdb/gdb/value.c:1933:76: note: ‘<anonymous>’ declared here
     1933 |   auto pair = internalvars.emplace (std::make_pair (name, internalvar (name)));
          |                                                                            ^

This is because the union field internalvar::u is not initialized when
constructing the temporary internalvar object above.  That object is then used
for move-construction, and the (implicit) move constructor copies the
uninitialized bytes of field u over from the temporary object to the new
internalvar object.  The compiler therefore complains that we use uninitialized
bytes.  I don't think it's really a problem, because the internalvar object is
in the `kind == INTERNALVAR_VOID` state, in which the contents of the union is
irrelevant.  Still, mute the warning by default-initializing the union.

Change-Id: I70c392842f35255f50d8e63f4099cb6685366fb7
Reviewed-By: Tom Tromey <tom@tromey.com>
20 months agoHandle half-float in 'x' command
Tom Tromey [Fri, 24 Feb 2023 16:19:32 +0000 (09:19 -0700)]
Handle half-float in 'x' command

Using 'x/hf' should print bytes as float16, but instead it currently
prints as an integer.  I tracked this down to a missing case in
float_type_from_length.

Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30161
Approved-By: Simon Marchi <simon.marchi@efficios.com>
20 months agoFix some value comments
Tom Tromey [Wed, 1 Mar 2023 21:29:28 +0000 (14:29 -0700)]
Fix some value comments

I noticed a very stale comment in valarith.c.  This patch fixes a few
comments in this area.

Reviewed-By: Andrew Burgess <aburgess@redhat.com>
20 months agogdb: LoongArch: Add support for static data member in struct
Hui Li [Thu, 23 Feb 2023 22:47:39 +0000 (06:47 +0800)]
gdb: LoongArch: Add support for static data member in struct

As described in C++ reference [1], static data members are not part
of objects of a given class type. Modified compute_struct_member ()
to ignore static data member so that we can get the expected result.

loongson@linux:~$ cat test.c
#include<stdio.h>
struct struct_01 { static unsigned a; float b;};
unsigned struct_01::a = 66;
struct struct_01 struct_01_val = { 99.00 };
int check_arg_struct(struct struct_01 arg)
  {
    printf("arg.a = %d\n", arg.a);
    printf("arg.b = %f\n", arg.b);
    return 0;
  }
int main()
  {
    check_arg_struct(struct_01_val);
    return 0;
  }
loongson@linux:~$ g++ -g test.c -o test++
loongson@linux:~$ gdb test++

Without this patch:
...
(gdb) start
...
(gdb) p check_arg_struct(struct_01_val)
arg.a = 66
arg.b = 0.000000
$1 = 0

With this patch:
...
(gdb) start
...
(gdb) p check_arg_struct(struct_01_val)
arg.a = 66
arg.b = 99.000000
$1 = 0

[1] https://learn.microsoft.com/en-us/cpp/cpp/static-members-cpp?view=msvc-170

Signed-off-by: Hui Li <lihui@loongson.cn>
Reviewed-By: Tom Tromey <tom@tromey.com>
Signed-off-by: Tiezhu Yang <yangtiezhu@loongson.cn>
20 months agoDon't write zeros to a gap in the output file
Alan Modra [Thu, 2 Mar 2023 09:29:14 +0000 (19:59 +1030)]
Don't write zeros to a gap in the output file

Writing out zeros is counterproductive if a file system supports
sparse files.  A very large gap need not take much actual disk space,
but it usually will if zeros are written.

memory_bseek also supports not writing out zeros in a gap.

* elf.c (write_zeros): Delete.
(assign_file_positions_for_load_sections): Don't call write_zeros.
Comment.

20 months ago[gdb/symtab] Add set/show always-read-ctf on/off
Tom de Vries [Thu, 2 Mar 2023 09:56:40 +0000 (10:56 +0100)]
[gdb/symtab] Add set/show always-read-ctf on/off

[ This is a simplified rewrite of an earlier submission "[RFC][gdb/symtab] Add
maint set symbol-read-order", submitted here (
https://sourceware.org/pipermail/gdb-patches/2022-September/192044.html
). ]

With the test-case included in this patch, we run into:
...
(gdb) file dwarf2-and-ctf
(gdb) print var_ctf^M
'var_ctf' has unknown type; cast it to its declared type^M
...

The problem is that the executable contains both ctf and dwarf2, so the ctf
info (which contains the type information about var_ctf) is ignored.

GDB has support for handling multiple debug formats, but the common use case
for ctf is to be used when dwarf2 is not present, and gdb reflects that,
assuming that by reading ctf in addition there won't be any extra information,
so it's not worth the additional cycles and memory.

Add a new command "set/show always-read-ctf on/off", that when on forces
unconditional reading of ctf, allowing us to do:
...
(gdb) set always-read-ctf on
(gdb) file dwarf2-and-ctf
(gdb) print var_ctf^M
$2 = 2^M
...

The setting is off by default, preserving current behaviour.

A bit of background on the relevance of reading order: the formats have a
priority relationship between them, where reading earlier means lower
priority.  By reading the format with the most detail last, we ensure it has
the highest priority, which makes sure that in case there is overlapping info,
the most detailed info is found.  This explains the current reading order of
mdebug, stabs and dwarf2.

Add the unconditional reading of ctf before dwarf2, because it's less detailed
than dwarf2.  The conditional reading of ctf is still done after the attempt to
read dwarf2, necessarily so because we only know whether there's dwarf2 after
we've tried to read it.

The new command allow us to replace uses of -Wl,--strip-debug added in commit
908a926ec4e ("[gdb/testsuite] Fix ctf test-cases on openSUSE Tumbleweed") by
uses of "set always-read-ctf on", but I've left that for another commit.

Tested on x86_64-linux.

Reviewed-By: Eli Zaretskii <eliz@gnu.org>
Reviewed-By: Tom Tromey <tom@tromey.com>
20 months agogdb: update some copyright years (2022 -> 2023)
Simon Marchi [Wed, 1 Mar 2023 20:09:40 +0000 (15:09 -0500)]
gdb: update some copyright years (2022 -> 2023)

The copyright years in the ROCm files (e.g. solib-rocm.c) are wrong,
they end in 2022 instead of 2023.  I suppose because I posted (or at
least prepared) the patches in 2022 but merged them in 2023, and forgot
to update the year.  I found a bunch of other files that are in the same
situation.  Fix them all up.

Change-Id: Ia55f5b563606c2ba6a89046f22bc0bf1c0ff2e10
Reviewed-By: Tom Tromey <tom@tromey.com>
20 months agoAutomatic date update in version.in
GDB Administrator [Thu, 2 Mar 2023 00:00:37 +0000 (00:00 +0000)]
Automatic date update in version.in

20 months agoUse const for dwarf2_property_baton
Tom Tromey [Wed, 1 Mar 2023 15:03:49 +0000 (08:03 -0700)]
Use const for dwarf2_property_baton

Once a baton is stored in a struct type, it doesn't make sense to
modify it.  This patch constifies the API.

Approved-By: Simon Marchi <simon.marchi@efficios.com>
20 months agoMake gdb property batons type-safe
Tom Tromey [Wed, 1 Mar 2023 14:59:44 +0000 (07:59 -0700)]
Make gdb property batons type-safe

gdbtypes treats dynamic property batons as 'void *', but in actuality
the only users all use dwarf2_property_baton.  This patch changes this
code to be type-safe.  If a new type is needed here, it seems like
that too could be done in a type-safe way.

Approved-By: Simon Marchi <simon.marchi@efficios.com>
20 months agoMore bounds checking in macro_expand
Alan Modra [Wed, 1 Mar 2023 21:42:00 +0000 (08:12 +1030)]
More bounds checking in macro_expand

* macro.c (macro_expand): Ensure input string buffer is not
read past end.

20 months agoUsing .mri in assembly
Alan Modra [Wed, 1 Mar 2023 21:04:40 +0000 (07:34 +1030)]
Using .mri in assembly

Changing mri mode between macro definition and use isn't good.  This
.macro x
.endm
.mri 1
x
leads to a segfault.  Fixed with the following patch, but I suppose
what should really happen is that macros be marked as being mri mode
when defined, and that determine whether the magic NARG parameter be
supplied at expansion.  Nobody has complained about this in 30 years
so I'm not inclined to change gas behaviour to that extent.

* macro.c (macro_expand): Don't segfault in mri mode if NARG
formal isn't found.

20 months agoFix type of check_valid_shift_count parameter
Tom Tromey [Wed, 1 Mar 2023 20:58:50 +0000 (13:58 -0700)]
Fix type of check_valid_shift_count parameter

check_valid_shift_count has an 'int' parameter that really should be
an enum exp_opcode.  This patch makes the change.  Tested by
rebuilding.

20 months agogdb: fix a whitespace issue in solib-rocm.c
Simon Marchi [Wed, 1 Mar 2023 20:21:53 +0000 (15:21 -0500)]
gdb: fix a whitespace issue in solib-rocm.c

Change-Id: I9cd236eaf161fe3a1abf0d212efca47a7149e021

20 months agoFix typo with my email address
Nick Clifton [Wed, 1 Mar 2023 14:38:16 +0000 (14:38 +0000)]
Fix typo with my email address

20 months agoFix btrace regression
Tom Tromey [Wed, 1 Mar 2023 01:43:01 +0000 (18:43 -0700)]
Fix btrace regression

Tom de Vries pointed out that my earlier patch:

    commit 873a185be258ad2552b9579005852815b4da5baf
    Date:   Fri Dec 16 07:56:57 2022 -0700

Don't use struct buffer in handle_qxfer_btrace

regressed gdb.btrace/reconnect.exp.  I didn't notice this because I
did not have libipt installed.

This patch fixes the bug.

Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30169
Tested-By: Bruno Larsen <blarsen@redhat.com>
20 months ago[gdb/testsuite] Add another xfail case in gdb.python/py-record-btrace.exp
Tom de Vries [Wed, 1 Mar 2023 12:44:04 +0000 (13:44 +0100)]
[gdb/testsuite] Add another xfail case in gdb.python/py-record-btrace.exp

I ran into:
...
(gdb) PASS: gdb.python/py-record-btrace.exp: function call: \
  python print(c.prev)
python print(c == c.next.prev)^M
Traceback (most recent call last):^M
  File "<string>", line 1, in <module>^M
AttributeError: 'NoneType' object has no attribute 'prev'^M
Error while executing Python code.^M
(gdb) FAIL: gdb.python/py-record-btrace.exp: function call: \
  python print(c == c.next.prev)
...
due to having only 4 insn instead of 100:
...
python print(len(insn))^M
4^M
...

This could be caused by the same hw bug as we already have an xfail for, so
expand the xfail matching.

Tested on x86_64-linux.

PR testsuite/30185
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30185

Approved-By: Markus T. Metzger <markus.t.metzger@intel.com>
20 months agoCatch overflow in gas s_space
Alan Modra [Wed, 1 Mar 2023 02:28:41 +0000 (12:58 +1030)]
Catch overflow in gas s_space

Also fix an error introduced in 1998 in reporting a zero count for
negative counts.

      * read.c (s_space): Use unsigned multiply, and catch overflow.
      Correct order of tests for invalid repeat counts.  Ensure
      ignored directives don't affect mri_pending_align.

20 months agogas s_fill caused internal error in frag_new
Alan Modra [Wed, 1 Mar 2023 02:20:34 +0000 (12:50 +1030)]
gas s_fill caused internal error in frag_new

Fix an internal error after "non-constant fill count for absolute
section".

* read.c (s_fill): Don't create frags after errors.

20 months agoMemory leak in gas do_repeat
Alan Modra [Wed, 1 Mar 2023 02:18:59 +0000 (12:48 +1030)]
Memory leak in gas do_repeat

* read.c (do_repeat): Free sb on error path.

20 months agoAutomatic date update in version.in
GDB Administrator [Wed, 1 Mar 2023 00:00:36 +0000 (00:00 +0000)]
Automatic date update in version.in

20 months agogdb: add HtabPrinter to gdb-gdb.py.in
Simon Marchi [Thu, 9 Feb 2023 19:50:56 +0000 (14:50 -0500)]
gdb: add HtabPrinter to gdb-gdb.py.in

When debugging GDB, I find it a bit tedious to inspect htab_t objects.
It is possible to find the entries by poking at the fields, but it's
annoying to do each time.  I think a pretty printer would help.  Add a
basic one to gdb-gdb.py.

The pretty printer advertises itself as "array-like", and the result
looks like:

    (top-gdb) p bfcache
    $3 = htab_t with 3 elements = {0x6210003252a0, 0x62100032caa0, 0x62100033baa0}

The htab_t itself doesn't know about the type of pointed objects.  But
it's easy enough to cast the addresses to the right type to use them:

    (top-gdb) print *((btrace_frame_cache *) 0x6210003252a0)
    $6 = {tp = 0x61700002ed80, frame = 0x6210003251e0, bfun = 0x62000000b390}

Change-Id: Ia692e3555fe7a117b7ec087840246b1260a704c6
Reviewed-By: Tom Tromey <tom@tromey.com>
20 months ago[gdb/testsuite] Fix gdb.python/py-breakpoint.exp timeouts
Tom de Vries [Tue, 28 Feb 2023 14:50:23 +0000 (15:50 +0100)]
[gdb/testsuite] Fix gdb.python/py-breakpoint.exp timeouts

On powerpc64le-linux, I run into two timeouts:
...
FAIL: gdb.python/py-breakpoint.exp: test_watchpoints: \
  Test watchpoint write (timeout)
FAIL: gdb.python/py-breakpoint.exp: test_bkpt_internal: \
  Test watchpoint write (timeout)
...

In this case, hw watchpoints are not supported, and using sw watchpoints
is slow.

Most of the time is spent in handling a try-catch, which triggers a malloc.  I
think this bit is more relevant for the "catch throw" part of the test-case,
so fix the timeouts by setting the watchpoints after the try-catch.

Tested on x86_64-linux and powerpc64le-linux.

20 months agoRemove value_in
Tom Tromey [Tue, 28 Feb 2023 14:19:41 +0000 (07:19 -0700)]
Remove value_in

value_in is unused.  From git log, it seems to have been part of the
Chill language, which was removed from gdb eons ago.  This patch
removes the function.  Tested by rebuilding.

20 months ago[gdb/testsuite] Fix gdb.rust/watch.exp on ppc64le
Tom de Vries [Tue, 28 Feb 2023 12:32:23 +0000 (13:32 +0100)]
[gdb/testsuite] Fix gdb.rust/watch.exp on ppc64le

On x86_64-linux, I have:
...
(gdb) watch -location y^M
Hardware watchpoint 2: -location y^M
(gdb) PASS: gdb.rust/watch.exp: watch -location y
...
but on powerpc64le-linux, I run into:
...
(gdb) watch -location y^M
Watchpoint 2: -location y^M
(gdb) FAIL: gdb.rust/watch.exp: watch -location y
...
due to the regexp matching "Hardware watchpoint" but not "Watchpoint":
...
gdb_test "watch -location y" ".*watchpoint .* -location .*"
...

Fix this by making the regexp less restrictive.

Tested on x86_64-linux and powerpc64le-linux.

20 months agogdb: fix mi breakpoint-deleted notifications for thread-specific b/p
Andrew Burgess [Thu, 16 Feb 2023 13:06:29 +0000 (13:06 +0000)]
gdb: fix mi breakpoint-deleted notifications for thread-specific b/p

Background
----------

When a thread-specific breakpoint is deleted as a result of the
specific thread exiting the function remove_threaded_breakpoints is
called which sets the disposition of the breakpoint to
disp_del_at_next_stop and sets the breakpoint number to 0.  Setting
the breakpoint number to zero has the effect of hiding the breakpoint
from the user.  We also print a message indicating that the breakpoint
has been deleted.

It was brought to my attention during a review of another patch[1]
that setting a breakpoints number to zero will suppress the MI
breakpoint-deleted notification for that breakpoint, and indeed, this
can be seen to be true, in delete_breakpoint, if the breakpoint number
is zero, then GDB will not notify the breakpoint_deleted observer.

It seems wrong that a user created, thread-specific breakpoint, will
have a =breakpoint-created notification, but will not have a
=breakpoint-deleted notification.  I suspect that this is a bug.

[1] https://sourceware.org/pipermail/gdb-patches/2023-February/196560.html

The First Problem
-----------------

During my initial testing I wanted to see how GDB handled the
breakpoint after it's number was set to zero.  To do this I created
the testcase gdb.threads/thread-bp-deleted.exp.  This test creates a
worker thread, which immediately exits.  After the worker thread has
exited the main thread spins in a loop.

In GDB I break once the worker thread has been created and place a
thread-specific breakpoint, then use 'continue&' to resume the
inferior in non-stop mode.  The worker thread then exits, but the main
thread never stops - instead it sits in the spin.  I then tried to use
'maint info breakpoints' to see what GDB thought of the
thread-specific breakpoint.

Unfortunately, GDB crashed like this:

  (gdb) continue&
  Continuing.
  (gdb) [Thread 0x7ffff7c5d700 (LWP 1202458) exited]
  Thread-specific breakpoint 3 deleted - thread 2 no longer in the thread list.
  maint info breakpoints
  ... snip some output ...

  Fatal signal: Segmentation fault
  ----- Backtrace -----
  0x5ffb62 gdb_internal_backtrace_1
          ../../src/gdb/bt-utils.c:122
  0x5ffc05 _Z22gdb_internal_backtracev
          ../../src/gdb/bt-utils.c:168
  0x89965e handle_fatal_signal
          ../../src/gdb/event-top.c:964
  0x8997ca handle_sigsegv
          ../../src/gdb/event-top.c:1037
  0x7f96f5971b1f ???
          /usr/src/debug/glibc-2.30-2-gd74461fa34/nptl/../sysdeps/unix/sysv/linux/x86_64/sigaction.c:0
  0xe602b0 _Z15print_thread_idP11thread_info
          ../../src/gdb/thread.c:1439
  0x5b3d05 print_one_breakpoint_location
          ../../src/gdb/breakpoint.c:6542
  0x5b462e print_one_breakpoint
          ../../src/gdb/breakpoint.c:6702
  0x5b5354 breakpoint_1
          ../../src/gdb/breakpoint.c:6924
  0x5b58b8 maintenance_info_breakpoints
          ../../src/gdb/breakpoint.c:7009
  ... etc ...

As the thread-specific breakpoint is set to disp_del_at_next_stop, and
GDB hasn't stopped yet, then the breakpoint still exists in the global
breakpoint list.

The breakpoint will not show in 'info breakpoints' as its number is
zero, but it will show in 'maint info breakpoints'.

As GDB prints the breakpoint, the thread-id for the breakpoint is
printed as part of the 'stop only in thread ...' line.  Printing the
thread-id involves calling find_thread_global_id to convert the global
thread-id into a thread_info*.  Then calling print_thread_id to
convert the thread_info* into a string.

The problem is that find_thread_global_id returns nullptr as the
thread for the thread-specific breakpoint has exited.  The
print_thread_id assumes it will be passed a non-nullptr.  As a result
GDB crashes.

In this commit I've added an assert to print_thread_id (gdb/thread.c)
to check that the pointed passed in is not nullptr.  This assert would
have triggered in the above case before GDB crashed.

MI Notifications: The Dangers Of Changing A Breakpoint's Number
---------------------------------------------------------------

Currently the delete_breakpoint function doesn't trigger the
breakpoint_deleted observer for any breakpoint with the number zero.

There is a comment explaining why this is the case in the code; it's
something about watchpoints.  But I did consider just removing the 'is
the number zero' guard and always triggering the breakpoint_deleted
observer, figuring that I'd then fix the watchpoint issue some other
way.

But I realised this wasn't going to be good enough.  When the MI
notification was delivered the number would be zero, so any frontend
parsing the notifications would not be able to match
=breakpoint-deleted notification to the earlier =breakpoint-created
notification.

What this means is that, at the point the breakpoint_deleted observer
is called, the breakpoint's number must be correct.

MI Notifications: The Dangers Of Delaying Deletion
--------------------------------------------------

The test I used to expose the above crash also brought another problem
to my attention.  In the above test we used 'continue&' to resume,
after which a thread exited, but the inferior didn't stop.  Recreating
the same test in the MI looks like this:

  -break-insert -p 2 main
  ^done,bkpt={number="2",type="breakpoint",disp="keep",...<snip>...}
  (gdb)
  -exec-continue
  ^running
  *running,thread-id="all"
  (gdb)
  ~"[Thread 0x7ffff7c5d700 (LWP 987038) exited]\n"
  =thread-exited,id="2",group-id="i1"
  ~"Thread-specific breakpoint 2 deleted - thread 2 no longer in the thread list.\n"

At this point the we have a single thread left, which is still
running:

  -thread-info
  ^done,threads=[{id="1",target-id="Thread 0x7ffff7c5eb80 (LWP 987035)",name="thread-bp-delet",state="running",core="4"}],current-thread-id="1"
  (gdb)

Notice that we got the =thread-exited notification from GDB as soon as
the thread exited.  We also saw the CLI line from GDB, the line
explaining that breakpoint 2 was deleted.  But, as expected, we didn't
see the =breakpoint-deleted notification.

I say "as expected" because the number was set to zero.  But, even if
the number was not set to zero we still wouldn't see the
notification.  The MI notification is driven by the breakpoint_deleted
observer, which is only called when we actually delete the breakpoint,
which is only done the next time GDB stops.

Now, maybe this is fine.  The notification is delivered a little
late.  But remember, by setting the number to zero the breakpoint will
be hidden from the user, for example, the breakpoint is removed from
the MI's -break-info command output.

This means that GDB is in a position where the breakpoint doesn't show
up in the breakpoint table, but a =breakpoint-deleted notification has
not yet been sent out.  This doesn't seem right to me.

What this means is that, when the thread exits, we should immediately
be sending out the =breakpoint-deleted notification.  We should not
wait for GDB to next stop before sending the notification.

The Solution
------------

My proposed solution is this; in remove_threaded_breakpoints, instead
of setting the disposition to disp_del_at_next_stop and setting the
number to zero, we now just call delete_breakpoint directly.

The notification will now be sent out immediately; as soon as the
thread exits.

As the number has not changed when delete_breakpoint is called, the
notification will have the correct number.

And as the breakpoint is immediately removed from the breakpoint list,
we no longer need to worry about 'maint info breakpoints' trying to
print the thread-id for an exited thread.

My only concern is that calling delete_breakpoint directly seems so
obvious that I wonder why the original patch (that added
remove_threaded_breakpoints) didn't take this approach.  This code was
added in commit 49fa26b0411d, but the commit message offers no clues
to why this approach was taken, and the original email thread offers
no insights either[2].  There are no test regressions after making
this change, so I'm hopeful that this is going to be fine.

[2] https://sourceware.org/pipermail/gdb-patches/2013-September/106493.html

The Complication
----------------

Of course, it couldn't be that simple.

The script gdb.python/py-finish-breakpoint.exp had some regressions
during testing.

The problem was with the FinishBreakpoint.out_of_scope callback
implementation.  This callback is supposed to trigger whenever the
FinishBreakpoint goes out of scope; and this includes when the thread
for the breakpoint exits.

The problem I ran into is the Python FinishBreakpoint implementation.
Specifically, after this change I was loosing some of the out_of_scope
calls.

The problem is that the out_of_scope call (of which I'm interested) is
triggered from the inferior_exit observer.  Before my change the
observers were called in this order:

  thread_exit
  inferior_exit
  breakpoint_deleted

The inferior_exit would trigger the out_of_scope call.

After my change the breakpoint_deleted notification (for
thread-specific breakpoints) occurs earlier, as soon as the
thread-exits, so now the order is:

  thread_exit
  breakpoint_deleted
  inferior_exit

Currently, after the breakpoint_deleted call the Python object
associated with the breakpoint is released, so, when we get to the
inferior_exit observer, there's no longer a Python object to call the
out_of_scope method on.

My solution is to follow the model for how bpfinishpy_pre_stop_hook
and bpfinishpy_post_stop_hook are called, this is done from
gdbpy_breakpoint_cond_says_stop in py-breakpoint.c.

I've now added a new bpfinishpy_pre_delete_hook
gdbpy_breakpoint_deleted in py-breakpoint.c, and from this new hook
function I check and where needed call the out_of_scope method.

With this fix in place I now see the
gdb.python/py-finish-breakpoint.exp test fully passing again.

Testing
-------

Tested on x86-64/Linux with unix, native-gdbserver, and
native-extended-gdbserver boards.

New tests added to covers all the cases I've discussed above.

Approved-By: Pedro Alves <pedro@palves.net>
20 months agogdb/testsuite: fix failure in gdb.mi/mi-pending.exp with extended-remote
Andrew Burgess [Sat, 18 Feb 2023 22:50:52 +0000 (22:50 +0000)]
gdb/testsuite: fix failure in gdb.mi/mi-pending.exp with extended-remote

I currently see this failure when running the gdb.mi/mi-pending.exp
test using the native-extended-remote board:

  -break-insert -f -c x==4 mi-pendshr.c:pendfunc2
  &"No source file named mi-pendshr.c.\n"
  ^done,bkpt={number="2",type="breakpoint",disp="keep",enabled="y",addr="<PENDING>",pending="mi-pendshr.c:pendfunc2",cond="x==4",evaluated-by="host",times="0",original-location="mi-pendshr.c:pendfunc2"}
  (gdb)
  FAIL: gdb.mi/mi-pending.exp: MI pending breakpoint on mi-pendshr.c:pendfunc2 if x==4 (unexpected output)

The failure is caused by the 'evaluated-by="host"' string, which only
appears in the output when the test is run using the
native-extended-remote board.

I could fix this by just updating the pattern in
gdb.mi/mi-pending.exp, but I have instead updated mi-pending.exp to
make more use of the support procs in mi-support.exp.  This did
require making a couple of adjustments to mi-support.exp, but I think
the result is that mi-pending.exp is now easier to read, and I see no
failures with native-extended-remote anymore.

One of the test names has changed after this work, I think the old
test name was wrong - it described a breakpoint as pending when the
breakpoint was not pending, I suspect a copy & paste error.

But there's no changes to what is actually being tested after this
patch.

Approved-By: Pedro Alves <pedro@palves.net>
20 months agogdb/testsuite: introduce is_target_non_stop helper proc
Andrew Burgess [Sat, 18 Feb 2023 20:52:40 +0000 (20:52 +0000)]
gdb/testsuite: introduce is_target_non_stop helper proc

I noticed that several tests included copy & pasted code to run the
'maint show target-non-stop' command, and then switch based on the
result.

In this commit I factor this code out into a helper proc in
lib/gdb.exp, and update all the places I could find that used this
pattern to make use of the helper proc.

There should be no change in what is tested after this commit.

Reviewed-By: Pedro Alves <pedro@palves.net>
20 months agogdb/testsuite introduce foreach_mi_ui_mode helper proc
Andrew Burgess [Fri, 17 Feb 2023 15:19:12 +0000 (15:19 +0000)]
gdb/testsuite introduce foreach_mi_ui_mode helper proc

Introduce foreach_mi_ui_mode, a helper proc which can be used when
tests are going to be repeated once with the MI in the main UI, and
once with the MI on a separate UI.

The proc is used like this:

  foreach_mi_ui_mode VAR {
    # BODY
  }

The BODY will be run twice, once with VAR set to 'main' and once with
VAR set to 'separate', inside BODY we can then change the behaviour
based on the current UI mode.

The point of this proc is that we sometimes shouldn't run the separate
UI tests (when gdb_debug_enabled is true), and this proc hides all
this logic.  If the separate UI mode should not be used then BODY will
be run just once with VAR set to 'main'.

I've updated two tests that can make use of this helper proc.  I'm
going to add another similar test in a later commit.

There should be no change to what is tested with this commit.

Approved-By: Pedro Alves <pedro@palves.net>
20 months agogdb/testsuite: extend the use of mi_clean_restart
Andrew Burgess [Fri, 17 Feb 2023 14:56:39 +0000 (14:56 +0000)]
gdb/testsuite: extend the use of mi_clean_restart

The mi_clean_restart proc calls the mi_gdb_start proc passing no
arguments.

In this commit I add an extra (optional) argument to the
mi_clean_restart proc, and pass this through to mi_gdb_start.

The benefit of this is that we can now use mi_clean_restart when we
also want to pass the 'separate-mi-tty' or 'separate-inferior-tty'
flags to mi_gdb_start, and avoids having to otherwise duplicate the
contents of mi_clean_restart in different tests.

I've updated the obvious places where this new functionality can be
used, and I'm seeing no test regressions.

Reviewed-By: Pedro Alves <pedro@palves.net>
20 months agogdb/testsuite: make more use of mi-support.exp
Andrew Burgess [Fri, 17 Feb 2023 14:33:03 +0000 (14:33 +0000)]
gdb/testsuite: make more use of mi-support.exp

Building on the previous commit, now that the breakpoint related
support functions in lib/mi-support.exp can now help creating the
patterns for thread specific breakpoints, make use of this
functionality for gdb.mi/mi-nsmoribund.exp and gdb.mi/mi-pending.exp.

There should be no changes in what is tested after this commit.

Reviewed-By: Pedro Alves <pedro@palves.net>
20 months agogdb: don't duplicate 'thread' field in MI breakpoint output
Andrew Burgess [Fri, 17 Feb 2023 10:48:06 +0000 (10:48 +0000)]
gdb: don't duplicate 'thread' field in MI breakpoint output

When creating a thread-specific breakpoint with a single location, the
'thread' field would be repeated in the MI output.  This can be seen
in two existing tests gdb.mi/mi-nsmoribund.exp and
gdb.mi/mi-pending.exp, e.g.:

  (gdb)
  -break-insert -p 1 bar
  ^done,bkpt={number="1",type="breakpoint",disp="keep",
      enabled="y",
      addr="0x000000000040110a",func="bar",
      file="/tmp/mi-thread-specific-bp.c",
      fullname="/tmp/mi-thread-specific-bp.c",
      line="32",thread-groups=["i1"],
      thread="1",thread="1",  <================ DUPLICATION!
      times="0",original-location="bar"}

I know we need to be careful when adjusting MI output, but I'm hopeful
in this case, as the field is duplicated, and the field contents are
always identical, that we might get away with removing one of the
duplicates.

The change in GDB is a fairly trivial condition change.

We did have a couple of tests that contained the duplicate fields in
their expected output, but given there was no comment pointing out
this oddity either in the GDB code, or in the test, I suspect this was
more a case of copying whatever output GDB produced and using that as
the expected results.  I've updated these tests to remove the
duplication.

I've update lib/mi-support.exp to provide support for building
breakpoint patterns that contain the thread field, and I've made use
of this in a new test I've added that is just about creating
thread-specific breakpoints and checking the results.  The two tests I
mentioned above as being updated could also use the new
lib/mi-support.exp functionality, but I'm going to do that in a later
patch, this way it is clear what changes I'm actually proposing to
make to the expected output.

As I said, I hope that frontends will be able to handle this change,
but I still think its worth adding a NEWS entry, that way, if someone
runs into problems, there's a chance they can figure out what's going
on.

This should not impact CLI output at all.

Reviewed-By: Eli Zaretskii <eliz@gnu.org>
Approved-By: Pedro Alves <pedro@palves.net>
20 months agogdb: remove an out of date comment about disp_del_at_next_stop
Andrew Burgess [Thu, 16 Feb 2023 19:07:12 +0000 (19:07 +0000)]
gdb: remove an out of date comment about disp_del_at_next_stop

Delete an out of date comment about disp_del_at_next_stop, the comment
says:

  /* NOTE drow/2003-09-08: This state only exists for removing
     watchpoints.  It's not clear that it's necessary...  */

I'm sure this was true when the comment was added, but today the
disp_del_at_next_stop state is not just used for deleting watchpoints,
which leaves us with "It's not clear that it's necessary...", which
doesn't really help at all.

And then this comment is located on one random place where
disp_del_at_next_stop is used, rather than at its definition site.

Lets just delete the comment.

No user visible changes after this commit.

Reviewed-By: Pedro Alves <pedro@palves.net>
20 months ago[Aarch64] Add Binutils support for MEC
Richard Ball [Tue, 28 Feb 2023 10:55:25 +0000 (10:55 +0000)]
[Aarch64] Add Binutils support for MEC

This change supports MEC which is part of RME (Realm Management Extension).

20 months agochew.c printf of intptr_t
Alan Modra [Tue, 28 Feb 2023 00:34:33 +0000 (11:04 +1030)]
chew.c printf of intptr_t

Seen when building binutils with gcc -m32 on x86_64-linux.
chew.c: In function ‘print’:
chew.c:1434:59: warning: format ‘%ld’ expects argument of type ‘long int’, but argument 3 has type ‘intptr_t’ {aka ‘int’} [-Wformat=]
 1434 |     fprintf (stderr, "print: illegal print destination `%ld'\n", *isp);
      |                                                         ~~^      ~~~~
      |                                                           |      |
      |                                                           |      intptr_t {aka int}
      |                                                           long int
      |                                                         %d

* chew.c: Include inttypes.h.
(print): Use PRIdPTR for *isp.

20 months agold: Sort section contributions in PDB files
Mark Harmstone [Mon, 20 Feb 2023 14:10:05 +0000 (14:10 +0000)]
ld: Sort section contributions in PDB files

Microsoft's DIA library, and thus also MSVC and WinDbg, expects section
contributions to be ordered by section number and offset, otherwise it's
unable to resolve line numbers.

20 months agoFree ecoff debug info
Alan Modra [Mon, 27 Feb 2023 11:31:08 +0000 (22:01 +1030)]
Free ecoff debug info

This frees memory associated with the mips ecoff find_nearest_line.

* elfxx-mips.x (free_ecoff_debug): New function, extracted from..
(_bfd_mips_elf_read_ecoff_info): ..here.  Free ext_hdr earlier.
Don't clear already NULL fdr.
(struct mips_elf_find_line): Move earlier.
(_bfd_mips_elf_close_and_cleanup): Call free_ecoff_debug.
(_bfd_mips_elf_find_nearest_line): Likewise on error paths,
and to clean up input_debug when done.

20 months agoAdd some sanity checking in ECOFF lookup_line
Alan Modra [Mon, 27 Feb 2023 04:23:22 +0000 (14:53 +1030)]
Add some sanity checking in ECOFF lookup_line

More anti-fuzzer bounds checking for the ECOFF support.  A lot of this
is in ancient code using "long" for counts and sizes, which is why the
patch uses "(long) ((unsigned long) x + 1) > 0" in a few places.  The
unsigned long cast is so that "x + 1" doesn't trigger ubsan warnings
about signed integer overflow.  It would be a good idea to replace
most of the longs used in binutils with size_t, but that's more than I
care to do for COFF/ECOFF.

* ecofflink.c (mk_fdrtab): Sanity check string offsets.
(lookup_line): Likewise, and symbol indices.

20 months agoAnother PE SEC_HAS_CONTENTS test
Alan Modra [Mon, 27 Feb 2023 04:19:10 +0000 (14:49 +1030)]
Another PE SEC_HAS_CONTENTS test

I'd skipped this one before, thinking "obfd, that's the linker output
bfd so no need to test".  Wrong, this is objcopy output.

* peXXigen.c (_bfd_XX_bfd_copy_private_bfd_data_common): Test
SEC_HAS_CONTENTS before reading section.

20 months agoAutomatic date update in version.in
GDB Administrator [Tue, 28 Feb 2023 00:00:13 +0000 (00:00 +0000)]
Automatic date update in version.in

20 months agoForced quit cases handled by resetting sync_quit_force_run
Kevin Buettner [Mon, 27 Feb 2023 23:11:37 +0000 (16:11 -0700)]
Forced quit cases handled by resetting sync_quit_force_run

During my audit of the use of gdb_exception with regard to QUIT
processing, I found a try/catch in the scoped_switch_fork_info
destructor.

Static analysis found this call path from the destructor to
maybe_quit():

  scoped_switch_fork_info::~scoped_switch_fork_info()
    -> remove_breakpoints()
    -> remove_breakpoint(bp_location*)
    -> remove_breakpoint_1(bp_location*, remove_bp_reason)
    -> memory_validate_breakpoint(gdbarch*, bp_target_info*)
    -> target_read_memory(unsigned long, unsigned char*, long)
    -> target_read(target_ops*, target_object, char const*, unsigned char*, unsigned long, long)
    -> maybe_quit()

Since it's not safe to do a 'throw' from a destructor, we simply
call set_quit_flag and, for gdb_exception_forced_quit, also
set sync_quit_force_run.  This will cause the appropriate
exception to be rethrown at the next QUIT check.

Another case is the try / catch in tui_getc() in tui-io.c.  The
existing catch swallows the exception.  I've added a catch for
'gdb_exception_forced_quit', which also swallows the exception,
but also sets sync_quit_force_run and calls set_quit_flag in
order to restart forced quit processing at the next QUIT check.
This is required because it isn't safe to throw into/through
readline.

Thanks to Pedro Alves for suggesting this idea.

Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=26761
Tested-by: Tom de Vries <tdevries@suse.de>
Approved-By: Pedro Alves <pedro@palves.net>
20 months agoIntroduce set_force_quit_flag and change type of sync_quit_force_run
Kevin Buettner [Mon, 27 Feb 2023 23:11:37 +0000 (16:11 -0700)]
Introduce set_force_quit_flag and change type of sync_quit_force_run

At the moment, handle_sigterm() in event-top.c does the following:

  sync_quit_force_run = 1;
  set_quit_flag ();

This was used several more times in a later patch in this series, so
I'm introducing (at Pedro's suggestion) a new function named
'set_force_quit_flag'.  It simply sets sync_quit_force_run and also
calls set_quit_flag().  I've revised the later patch to call
set_force_quit_flag instead.

I noticed that sync_quit_force_run is declared as an int but is being
used as a bool, so I also changed its type to bool in this commit.

Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=26761
Approved-By: Pedro Alves <pedro@palves.net>
20 months agoQUIT processing w/ explicit throw for gdb_exception_forced_quit
Kevin Buettner [Mon, 27 Feb 2023 23:11:37 +0000 (16:11 -0700)]
QUIT processing w/ explicit throw for gdb_exception_forced_quit

This commit contains changes which have an explicit throw for
gdb_exception_forced_quit, or, in a couple of cases for gdb_exception,
but with a throw following a check to see if 'reason' is
RETURN_FORCED_QUIT.

Most of these are straightforward - it made sense to continue to allow
an existing catch of gdb_exception to also catch gdb_exception_quit;
in these cases, a catch/throw for gdb_exception_forced_quit was added.

There are two cases, however, which deserve a more detailed
explanation.

1) remote_fileio_request in gdb/remote-fileio.c:

The try block calls do_remote_fileio_request which can (in turn)
call one of the functions in remote_fio_func_map[].  Taking the
first one, remote_fileio_func_open(), we have the following call
path to maybe_quit():

  remote_fileio_func_open(remote_target*, char*)
    -> target_read_memory(unsigned long, unsigned char*, long)
    -> target_read(target_ops*, target_object, char const*, unsigned char*, unsigned long, long)
    -> maybe_quit()

Since there is a path to maybe_quit(), we must ensure that the
catch block is not permitted to swallow a QUIT representing a
SIGTERM.

However, for this case, we must take care not to change the way that
Ctrl-C / SIGINT is handled; we want to send a suitable EINTR reply to
the remote target should that happen.  That being the case, I added a
catch/throw for gdb_exception_forced_quit.  I also did a bit of
rewriting here, adding a catch for gdb_exception_quit in favor of
checking the 'reason' code in the catch block for gdb_exception.

2) mi_execute_command in gdb/mi/mi-main.c:

The try block calls captured_mi_execute_command(); there exists
a call path to maybe_quit():

  captured_mi_execute_command(ui_out*, mi_parse*)
    -> mi_cmd_execute(mi_parse*)
    -> get_current_frame()
    -> get_prev_frame_always_1(frame_info*)
    -> frame_register_unwind_location(frame_info*, int, int*, lval_type*, unsigned long*, int*)
    -> frame_register_unwind(frame_info*, int, int*, int*, lval_type*, unsigned long*, int*, unsigned char*)
    -> value_entirely_available(value*)
    -> value_fetch_lazy(value*)
    -> value_fetch_lazy_memory(value*)
    -> read_value_memory(value*, long, int, unsigned long, unsigned char*, unsigned long)
    -> maybe_quit()

That being the case, we can't allow the exception handler (catch block)
to swallow a gdb_exception_quit for SIGTERM.  However, it does seem
reasonable to output the exception via the mi interface so that some
suitable message regarding SIGTERM might be printed; therefore, I
check the exception's 'reason' field for RETURN_FORCED_QUIT and
do a throw for this case.

Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=26761
Tested-by: Tom de Vries <tdevries@suse.de>
Approved-By: Pedro Alves <pedro@palves.net>
20 months agoGuile QUIT processing updates
Kevin Buettner [Mon, 27 Feb 2023 23:11:37 +0000 (16:11 -0700)]
Guile QUIT processing updates

This commit contains QUIT processing updates for GDB's Guile support.
As with the Python updates, we don't want to permit this code to
swallow the exception, gdb_exception_forced_quit, which is associated
with GDB receiving a SIGTERM.

I've adopted the same solution that I used for Python; whereever
a gdb_exception is caught in try/catch code in the Guile extension
language support, a catch for gdb_exception_forced_quit has been
added; this catch block will simply call quit_force(), which will
cause the necessary cleanups to occur followed by GDB exiting.

Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=26761
Tested-by: Tom de Vries <tdevries@suse.de>
Approved-By: Pedro Alves <pedro@palves.net>
20 months agoPython QUIT processing updates
Kevin Buettner [Mon, 27 Feb 2023 23:11:37 +0000 (16:11 -0700)]
Python QUIT processing updates

See the previous patches in this series for the motivation behind
these changes.

This commit contains updates to Python's QUIT handling.  Ideally, we'd
like to throw gdb_exception_forced_quit through the extension
language; I made an attempt to do this for gdb_exception_quit in an
earlier version of this patch, but Pedro pointed out that it is
(almost certainly) not safe to do so.

Still, we definitely don't want to swallow the exception representing
a SIGTERM for GDB, nor do we want to force modules written in the
extension language to have to explicitly handle this case.  Since the
idea is for GDB to cleanup and quit for this exception, we'll simply
call quit_force() just as if the gdb_exception_forced_quit propagation
had managed to make it back to the top level.

Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=26761
Tested-by: Tom de Vries <tdevries@suse.de>
Approved-By: Pedro Alves <pedro@palves.net>
20 months agoCatch gdb_exception_error instead of gdb_exception (in many places)
Kevin Buettner [Mon, 27 Feb 2023 23:11:37 +0000 (16:11 -0700)]
Catch gdb_exception_error instead of gdb_exception (in many places)

As described in the previous commit for this series, I became
concerned that there might be instances in which a QUIT (due to either
a SIGINT or SIGTERM) might not cause execution to return to the top
level.  In some (though very few) instances, it is okay to not
propagate the exception for a Ctrl-C / SIGINT, but I don't think that
it is ever okay to swallow the exception caused by a SIGTERM.
Allowing that to happen would definitely be a deviation from the
current behavior in which GDB exits upon receipt of a SIGTERM.

I looked at all cases where an exception handler catches a
gdb_exception.  Handlers which did NOT need modification were those
which satisifed one or more of the following conditions:

  1) There is no call path to maybe_quit() in the try block.  I used a
     static analysis tool to help make this determination.  In
     instances where the tool didn't provide an answer of "yes, this
     call path can result in maybe_quit() being called", I reviewed it
     by hand.

  2) The catch block contains a throw for conditions that it
     doesn't want to handle; these "not handled" conditions
     must include the quit exception and the new "forced quit" exception.

  3) There was (also) a catch for gdb_exception_quit.

Any try/catch blocks not meeting the above conditions could
potentially swallow a QUIT exception.

My first thought was to add catch blocks for gdb_exception_quit and
then rethrow the exception.  But Pedro pointed out that this can be
handled without adding additional code by simply catching
gdb_exception_error instead.  That's what this patch series does.

There are some oddball cases which needed to be handled differently,
plus the extension languages, but those are handled in later patches.

Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=26761
Tested-by: Tom de Vries <tdevries@suse.de>
Approved-by: Pedro Alves <pedro@palves.net>
20 months agoHandle gdb SIGTERM by throwing / catching gdb_exception_force_quit
Kevin Buettner [Mon, 27 Feb 2023 23:11:37 +0000 (16:11 -0700)]
Handle gdb SIGTERM by throwing / catching gdb_exception_force_quit

When a GDB process receives the SIGTERM signal, handle_sigterm() in
event-top.c is called.  The global variable 'sync_quit_force_run' is
set by this signal handler.  It does some other things too, but the
setting of this global is the important bit for the SIGTERM part of
this discussion.

GDB will periodically check to see whether a Ctrl-C or SIGTERM has
been received.  This is performed via use of the QUIT macro in
GDB's code.  QUIT is defined to invoke maybe_quit(), which will be
periodically called during any lengthy operation.  This is supposed to
ensure that the user won't have to wait too long for a Ctrl-C or
SIGTERM to be acted upon.

When a Ctrl-C / SIGINT is received, quit_handler() will decide whether
to pass the SIGINT onto the inferior or to call quit() which causes
gdb_exception_quit to be thrown.  This exception (usually) propagates
to the top level.  Control is then returned to the top level event
loop.

At the moment, SIGTERM is handled very differently.  Instead of
throwing an exception, quit_force() is called.  This does eventually
cause GDB to exit(), but prior to that happening, the inferiors
are killed or detached and other target related cleanup occurs.
As shown in this discussion between Pedro Alves and myself...

https://sourceware.org/pipermail/gdb-patches/2021-July/180802.html
https://sourceware.org/pipermail/gdb-patches/2021-July/180902.html
https://sourceware.org/pipermail/gdb-patches/2021-July/180903.html

...we found that it is possible for inferior_ptid and current_thread_
to get out of sync.  When that happens, the "current_thread_ != nullptr"
assertion in inferior_thread() can fail resulting in a GDB internal
error.

Pedro recommended that we "let the normal quit exception propagate all
the way to the top level, and then have the top level call quit_force
if sync_quit_force_run is set."  However, after the v2 series for this
patch set, we tweaked that idea by introducing a new exception for
handling SIGTERM.

This commit implements the obvious part of Pedro's suggestion:
Instead of calling quit_force from quit(), throw_forced_quit() is now
called instead.  This causes the new exception 'gdb_exception_forced_quit'
to be thrown.

At the top level, I changed catch_command_errors() and captured_main()
to catch gdb_exception_forced_quit and then call quit_force() from the
catch block.  I also changed start_event_loop() to also catch
gdb_exception_forced_quit; while we could also call quit_force() from
that catch block, it's sufficient to simply rethrow the exception
since it'll be caught by the newly added code in captured_main().

Making these changes fixed the failure / regression that I was seeing
for gdb.base/gdb-sigterm.exp when run on a machine with glibc-2.34.
However, there are many other paths back to the top level which this
test case does not test.  I did an audit of all of the try / catch
code in GDB in which calls in the try-block might (eventually) call
QUIT.  I found many cases where gdb_exception_quit and the new
gdb_exception_forced_quit will be swallowed.  (When using GDB, have
you ever hit Ctrl-C and not have it do anything; if so, it could be
due to a swallowed gdb_exception_quit in one of the cases I've
identified.)  The rest of the patches in this series deal with this
concern.

Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=26761
Tested-by: Tom de Vries <tdevries@suse.de>
Approved-by: Pedro Alves <pedro@palves.net>
20 months agoIntroduce gdb_exception_forced_quit
Kevin Buettner [Mon, 27 Feb 2023 23:11:37 +0000 (16:11 -0700)]
Introduce gdb_exception_forced_quit

This commit adds a new exception 'gdb_exception_forced_quit', reason
code 'REASON_FORCED_QUIT', return mask 'RETURN_MASK_FORCED_QUIT', and
a wrapper for throwing the exception, throw_forced_quit().

The addition of this exception plus supporting code will allow us to
recognize that a SIGTERM has been received by GDB and then propagate
recognition of that fact to the upper levels of GDB where it can be
correctly handled.  At the moment, when GDB receives a SIGTERM, it
will attempt to exit via a series of calls from the QUIT checking
code.  However, before it can exit, it must do various cleanups, such
as killing or detaching all inferiors.  Should these cleanups be
attempted while GDB is executing very low level code, such as reading
target memory from within ps_xfer_memory(), it can happen that some of
GDB's state is out of sync with regard to the cleanup code's
expectations.  In the case just mentioned, it's been observed that
inferior_ptid and the current_thread_ are not in sync; this triggers
an assert / internal error.

This commit only introduces the exception plus supporting machinery;
changes which use this new exception are in later commits in this
series.

Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=26761
Tested-by: Tom de Vries <tdevries@suse.de>
Approved-by: Pedro Alves <pedro@palves.net>
20 months agoFix value chain use-after-free
Tom Tromey [Wed, 8 Feb 2023 20:59:36 +0000 (13:59 -0700)]
Fix value chain use-after-free

Hannes filed a bug showing a crash, where a pretty-printer written in
Python could cause a use-after-free.  He sent a patch, but I thought a
different approach was needed.

In a much earlier patch (see bug #12533), we changed the Python code
to release new values from the value chain when constructing a
gdb.Value.  The rationale for this is that if you write a command that
does a lot of computations in a loop, all the values will be kept live
by the value chain, resulting in gdb using a large amount of memory.

However, suppose a value is passed to Python from some code in gdb
that needs to use the value after the call into Python.  In this
scenario, value_to_value_object will still release the value -- and
because gdb code doesn't generally keep strong references to values (a
consequence of the ancient decision to use the value chain to avoid
memory management), this will result in a use-after-free.

This scenario can happen, as it turns out, when a value is passed to
Python for pretty-printing.  Now, normally this route boxes the value
via value_to_value_object_no_release, avoiding the problematic release
from the value chain.  However, if you then call Value.cast, the
underlying value API might return the same value, when is then
released from the chain.

This patch fixes the problem by changing how value boxing is done.
value_to_value_object no longer removes a value from the chain.
Instead, every spot in gdb that might construct new values uses a
scoped_value_mark to ensure that the requirements of bug #12533 are
met.  And, because incoming values aren't ever released from the chain
(the Value.cast one comes earlier on the chain than the
scoped_value_mark), the bug can no longer occur.  (Note that many
spots in the Python layer already take this approach, so not many
places needed to be touched.)

In the future I think we should replace the use of raw "value *" with
value_ref_ptr pretty much everywhere.  This will ensure lifetime
safety throughout gdb.

The test case in this patch comes from Hannes' original patch.  I only
made a trivial ("require") change to it.  However, while this fails
for him, I can't make it fail on this machine; nevertheless, he tried
my patch and reported the bug as being fixed.

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

20 months agoRemove infrun_thread_thread_exit observer
Pedro Alves [Wed, 16 Nov 2022 17:01:44 +0000 (17:01 +0000)]
Remove infrun_thread_thread_exit observer

After the previous patches, I believe this observer isn't necessary
anymore for anything.  Remove it.

Change-Id: Idb33fb6b6f55589c8c523a92169b3ca95a23d0b9

20 months agoall-stop "follow-fork parent" and selecting another thread
Pedro Alves [Fri, 25 Nov 2022 16:20:22 +0000 (16:20 +0000)]
all-stop "follow-fork parent" and selecting another thread

With:

 - catch a fork in thread 1
 - select thread 2
 - set follow-fork child
 - next

... follow_fork notices that thread 1 had last stopped for a fork
which hasn't been followed yet, and because thread 1 is not the
current thread, GDB aborts the execution command, presenting the stop
in thread 1.

That makes sense, as only the forking thread (thread 1) survives in
the child, so better stop and let the user decide how to proceed.

However, with:

 - catch a fork in thread 1
 - select thread 2
 - set follow-fork parent << note difference here
 - next

... GDB does the same: follow_fork notices that thread 1 had last
stopped for a fork which hasn't been followed yet, and because thread
1 is not the current thread, GDB aborts the execution command,
presenting the stop in thread 1.

Aborting/stopping in this case doesn't make sense to me.  As we're
following the parent, thread 2 will still continue to exist in the
parent.  What the child does after we've followed the parent shouldn't
matter -- it can go on running free, be detached, etc., depending on
"set schedule-multiple", "set detach-on-fork", etc.  That does not
influence the execution command that the user issued for the parent
thread.

So this patch changes GDB in that direction -- in follow_fork, if
following the parent, and we've switched threads meanwhile, switch
back to the unfollowed thread, follow it (stay with the parent), and
don't abort/stop.  If we're following a fork (as opposed to vfork),
then switch back again to the thread that the user was trying to
resume.  If following a vfork, however, stay with the vforking-thread
selected, as we will need to see a vfork_done event first, before we
can resume any other thread.

As I was working on this, I managed to end up calling target_resume
for a solo-thread resume (to collect the vfork_done event), with
scope_ptid pointing at the vfork parent thread, and inferior_ptid
pointing to the vfork child.  For a solo-thread resume, the scope_ptid
argument to target_resume must the same as inferior_ptid.  The mistake
was caught by the assertion in target_resume, like so:

...
  [infrun] resume_1: step=0, signal=GDB_SIGNAL_0, trap_expected=0, current thread [1722839.1722839.0] at 0x5555555553c3
  [infrun] do_target_resume: resume_ptid=1722839.1722939.0, step=0, sig=GDB_SIGNAL_0
../../src/gdb/target.c:2661: internal-error: target_resume: Assertion `inferior_ptid.matches (scope_ptid)' failed.
...

but I think it doesn't hurt to catch such a mistake earlier, hence the
change in internal_resume_ptid.

Change-Id: I896705506a16d2488b1bfb4736315dd966f4e412

20 months agoMake follow_fork not rely on get_last_target_status
Pedro Alves [Thu, 17 Nov 2022 18:25:36 +0000 (18:25 +0000)]
Make follow_fork not rely on get_last_target_status

Currently, if

  - you're in all-stop mode,
  - the inferior last stopped because of a fork catchpoint,

when you next resume the program, gdb checks whether it had last
stopped for a fork/vfork, and if so,

 a) if the current thread is the one that forked, gdb follows the
   parent/child, depending on "set follow-fork" mode.

 b) if the current thread is some other thread (because you switched
   threads meanwhile), gdb switches back to that thread, gdb follows
   the parent/child, and stops the resumption command.

There's a problem in b), however -- if you have "set schedule-multiple
off", which is the default, or "set scheduler-locking on", gdb will
still switch back to the forking thread, even if you didn't want to
resume it.  For example, with:

  (gdb) catch fork
  (gdb) c
  * thread 1 stops for fork
  (gdb) thread 2
  (gdb) set scheduler-locking on
  (gdb) c

gdb switches back to thread 1, and follows the fork.

Or with:

  (gdb) add-inferior -exec prog
  (gdb) inferior 2
  (gdb) start
  (gdb) inferior 1
  (gdb) catch fork
  (gdb) c
  * thread 1.1 stops for fork
  (gdb) inferior 2
  (gdb) set schedule-multiple off # this is the default
  (gdb) c

gdb switches back to thread 1.1, and follows the fork.

Another issue is that, because follow_fork relies on
get_last_target_status to find the thread that has a pending fork, it
is possible to confuse it.  For example, "run" or "start" call
init_wait_for_inferior, which clears the last target status, so this:

  (gdb) catch fork
  (gdb) c
  * thread 1 stops for fork
  (gdb) add-inferior -exec prog
  (gdb) inferior 2
  (gdb) start
  (gdb) set follow-fork child
  (gdb) inferior 1
  (gdb) n

... does not follow to the fork child of inferior 1, because the
get_last_target_status call in follow_fork doesn't return a
TARGET_WAITKIND_FORKED.  Thanks to Simon for this example.

All of the above are fixed by this patch.  It changes follow_fork to
not look at get_last_target_status, but to instead iterate over the
set of threads that the user is resuming, and find the one that has a
pending_follow kind of fork/vfork.

gdb.base/foll-fork.exp is augmented to exercise the last "start"
scenario described above.  The other cases will be exercised in the
testcase added by the following patch.

Change-Id: Ifcca77e7b2456277387f40660ef06cec2b93b97e

20 months agoImprove "info program"
Pedro Alves [Thu, 17 Nov 2022 23:21:04 +0000 (23:21 +0000)]
Improve "info program"

With gdb.base/catch-follow-exec.exp, we currently see:

~~~~~~~~~~~~~~~
 (gdb)
 continue
 Continuing.
 process 693251 is executing new program: /usr/bin/ls
 [New inferior 2]
 [New process 693251]
 [Switching to process 693251]

 Thread 2.1 "ls" hit Catchpoint 2 (exec'd /usr/bin/ls), 0x00007ffff7fd0100 in _start () from /lib64/ld-linux-x86-64.so.2
 (gdb)
 info prog
 No selected thread.
~~~~~~~~~~~~~~~

Note the "No selected thread" output.  That is totally bogus, because
there _is_ a selected thread.  What GDB really means, is that it can't
find the thread that had the latest (user-visible) stop.  And that
happens because "info program" gets that info from
get_last_target_status, and the last target status has been cleared.

However, GDB also checks if there is a selected thread, here:

  if (ptid == null_ptid || ptid == minus_one_ptid)
    error (_("No selected thread."));

.. the null_ptid part.  That is also bogus, because what matters is
the thread that last reported a stop, not the current thread:

 - in all-stop mode, "info program" displays info about the last stop.
   That may have happened on a thread different from the selected
   thread.

 - in non-stop mode, because all threads are controlled individually,
   "info program" shows info about the last stop of the selected
   thread.

The current code already behaves this way, though in a poor way.  This
patch reimplements it, such that the all-stop version now finds the
thread that last reported an event via the 'previous_thread' strong
reference.  Being a strong reference means that if that thread has
exited since the event was reported, 'previous_thread' will still
point to it, so we can say that the thread exited meanwhile.

The patch also extends "info program" output a little, to let the user
know which thread we are printing info for.  For example, for the
gdb.base/catch-follow-exec.exp case we shown above, we now get:

 (gdb) info prog
 Last stopped for thread 2.1 (process 710867).
 Using the running image of child process 710867.
 Program stopped at 0x7ffff7fd0100.
 It stopped at breakpoint 2.
 Type "info stack" or "info registers" for more information.
 (gdb)

while in non-stop mode, we get:

 (gdb) info prog
 Selected thread 2.1 (process 710867).
 Using the running image of child process 710867.
 Program stopped at 0x7ffff7fd0100.
 It stopped at breakpoint 2.
 Type "info stack" or "info registers" for more information.
 (gdb)

In both cases, the first line of output is new.

The existing code considered these running/exited cases as an error,
but I think that that's incorrect, since this is IMO just plain
execution info as well.  So the patch makes those cases regular
prints, not errors.

If the thread is running, we get, in non-stop mode:

 (gdb) info prog
 Selected thread 2.1 (process 710867).
 Selected thread is running.

... and in all-stop:

 (gdb) info prog
 Last stopped for thread 2.1 (process 710867).
 Thread is now running.

If the thread has exited, we get, in non-stop mode:

 (gdb) info prog
 Selected thread 2.1 (process 710867).
 Selected thread has exited.

... and in all-stop:

 (gdb) info prog
 Last stopped for thread 2.1 (process 710867).
 Thread has since exited.

The gdb.base/info-program.exp testcase was much extended to test
all-stop/non-stop and single-threaded/multi-threaded.

Change-Id: I51d9d445f772d872af3eead3449ad4aa445781b1

20 months agoConvert previous_inferior_ptid to strong reference to thread_info
Pedro Alves [Thu, 17 Nov 2022 23:08:58 +0000 (23:08 +0000)]
Convert previous_inferior_ptid to strong reference to thread_info

I originally wrote this patch, because while working on some other
patch, I spotted a regression in the
gdb.multi/multi-target-no-resumed.exp.exp testcase.  Debugging the
issue, I realized that the problem was related to how I was using
previous_inferior_ptid to look up the thread the user had last
selected.  The problem is that previous_inferior_ptid alone doesn't
tell you which target that ptid is from, and I was just always using
the current target, which was incorrect.  Two different targets may
have threads with the same ptid.

I decided to fix this by replacing previous_inferior_ptid with a
strong reference to the thread, called previous_thread.

I have since found a new motivation for this change -- I would like to
tweak "info program" to not rely on get_last_target_status returning a
ptid that still exists in the thread list.  With both the follow_fork
changes later in this series, and the step-over-thread-exit changes,
that can happen, as we'll delete threads and not clear the last
waitstatus.

A new update_previous_thread function is added that can be used to
update previous_thread from inferior_ptid.  This must be called in
several places that really want to get rid of previous_thread thread,
and reset the thread id counter, otherwise we get regressions like
these:

  (gdb) info threads -gid
    Id   GId  Target Id                               Frame
 - * 1    1    Thread 2974541.2974541 "tids-gid-reset" main () at src/gdb/testsuite/gdb.multi/tids-gid-reset.c:21
 - (gdb) PASS: gdb.multi/tids-gid-reset.exp: single-inferior: after restart: info threads -gid
 + * 1    2    Thread 2958361.2958361 "tids-gid-reset" main () at src/gdb/testsuite/gdb.multi/tids-gid-reset.c:21
 + (gdb) FAIL: gdb.multi/tids-gid-reset.exp: single-inferior: after restart: info threads -gid

and:

  Core was generated by `build/gdb/testsuite/outputs/gdb.reverse/sigall-precsave/si'.
  Program terminated with signal SIGTRAP, Trace/breakpoint trap.
  #0  gen_ABRT () at src/gdb/testsuite/gdb.reverse/sigall-reverse.c:398
  398      kill (getpid (), SIGABRT);
 +[Current thread is 1 (LWP 2662066)]
  Restored records from core file build/gdb/testsuite/outputs/gdb.reverse/sigall-precsave/sigall.precsave.
  #0  gen_ABRT () at src/gdb/testsuite/gdb.reverse/sigall-reverse.c:398
  398      kill (getpid (), SIGABRT);

  continue
  Continuing.

 -Program received signal SIGABRT, Aborted.
 +Thread 1 received signal SIGABRT, Aborted.
  0x00007ffff7dfd55b in kill () at ../sysdeps/unix/syscall-template.S:78
  78     ../sysdeps/unix/syscall-template.S: No such file or directory.
 -(gdb) PASS: gdb.reverse/sigall-precsave.exp: sig-test-1: get signal ABRT
 +(gdb) FAIL: gdb.reverse/sigall-precsave.exp: sig-test-1: get signal ABRT

I.e., GDB was failing to restart the thread counter back to 1, because
the previous_thread thread was being help due to the strong reference.

Tested on GNU/Linux native, gdbserver and gdbserver + "maint set
target-non-stop on".

gdb/ChangeLog:
yyyy-mm-dd  Pedro Alves  <pedro@palves.net>

* infcmd.c (kill_command, detach_command, disconnect_command):
Call update_previous_thread.
* infrun.c (previous_inferior_ptid): Delete.
(previous_thread): New.
(update_previous_thread): New.
(proceed, init_wait_for_inferior): Call update_previous_thread.
(normal_stop): Adjust to compare previous_thread and
inferior_thread.  Call update_previous_thread.
* infrun.h (update_previous_thread): Declare.
* target.c (target_pre_inferior, target_preopen): Call
update_previous_thread.

Change-Id: I42779a1ee51a996fa1e8f6e1525c6605dbfd42c7

20 months agoTweak "Using the running image of ..." output
Pedro Alves [Sat, 3 Dec 2022 16:20:51 +0000 (16:20 +0000)]
Tweak "Using the running image of ..." output

Currently, "info files" and "info program" on a few native targets
show:

 (gdb) info files
 Symbols from "/home/pedro/gdb/tests/threads".
 Native process:
 Using the running image of child Thread 0x7ffff7d89740 (LWP 1097968).
  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 ...

 (gdb) info program
 Using the running image of child Thread 0x7ffff7d89740 (LWP 1097968).
  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 Program stopped at 0x555555555278.
 ...

This patch changes them to:

 (gdb) info files
 Symbols from "/home/pedro/gdb/tests/threads".
 Native process:
 Using the running image of child process 1097968.
                                  ^^^^^^^^^^^^^^^
 ...

 (gdb) info program
 Using the running image of child process 1097968.
                                  ^^^^^^^^^^^^^^^
 Program stopped at 0x555555555278.
 ...

... which I think makes a lot more sense in this context.  The "info
program" manual entry even says:

  "Display information about the status of your program: whether it is
   running or not, what process it is, and why it stopped."
                        ^^^^^^^^^^^^^

This change affects ptrace targets, procfs targets, and Windows.

Approved-By: Simon Marchi <simon.marchi@efficios.com>
Change-Id: I6aab061ff494a84ba3398cf98fd49efd7a6ec1ca

20 months agogdb: make-target-delegates.py: add type annotations
Simon Marchi [Mon, 27 Feb 2023 01:14:03 +0000 (20:14 -0500)]
gdb: make-target-delegates.py: add type annotations

Fixes all warnings given by pyright.

Change-Id: I480521bfc62960c4eccd9d32c886392b05a1ddaa
Reviewed-By: Tom Tromey <tom@tromey.com>
Reviewed-By: Andrew Burgess <aburgess@redhat.com>
20 months agogdb: make-target-delegates.py: add Entry type
Simon Marchi [Mon, 27 Feb 2023 01:14:02 +0000 (20:14 -0500)]
gdb: make-target-delegates.py: add Entry type

Add the Entry type and use it in the `entries` map, rather than using an
ad-hoc str -> str map that comes from the re.match.  This will make it
easier to make typing work in a subsequent patch, but it also helps
readers know what attributes exist for entries, which is not clear
currently.

Change-Id: I5b58dee1ed7ae85987b99bd417e641ede718624c
Reviewed-By: Tom Tromey <tom@tromey.com>
Reviewed-By: Andrew Burgess <aburgess@redhat.com>
20 months agogdb: make-target-delegates.py: make one string raw
Simon Marchi [Mon, 27 Feb 2023 01:14:01 +0000 (20:14 -0500)]
gdb: make-target-delegates.py: make one string raw

Fixes the following flake8 warning:

  make-target-delegates.py:36:39: W605 invalid escape sequence '\s'

Change-Id: I25eeb296f55765e17e5217a2d1e49018f63a3acd
Reviewed-By: Tom Tromey <tom@tromey.com>
Reviewed-By: Andrew Burgess <aburgess@redhat.com>
20 months agogdb: gdbarch*.py, copyright.py: add type annotations
Simon Marchi [Mon, 27 Feb 2023 01:14:00 +0000 (20:14 -0500)]
gdb: gdbarch*.py, copyright.py: add type annotations

Add type annotations to gdbarch*.py to fix all errors shown by pyright.
There is one change in copyright.py too, to fix this one:

    /home/simark/src/binutils-gdb/gdb/gdbarch.py
      /home/simark/src/binutils-gdb/gdb/gdbarch.py:206:13 - error: Type of "copyright" is partially unknown
        Type of "copyright" is "(tool: Unknown, description: Unknown) -> str" (reportUnknownMemberType)

Change-Id: Ia109b53e267f6e2f5bd79a1288d0d5c9508c9ac4
Reviewed-By: Tom Tromey <tom@tromey.com>
Reviewed-By: Andrew Burgess <aburgess@redhat.com>
20 months agogdb: split gdbarch component types to gdbarch_types.py
Simon Marchi [Mon, 27 Feb 2023 01:13:59 +0000 (20:13 -0500)]
gdb: split gdbarch component types to gdbarch_types.py

Editing gdbarch-components.py is not an experience in an editor that is
minimally smart about Python.  Because gdbarch-components.py is read and
exec'd by gdbarch.py, it doesn't import the  Info / Method / Function /
Value types.  And because these types are defined in gdbarch.py, it
can't import them, as that would make a cyclic dependency.

Solve this by introducing a third file, gdbarch_types.py, to define
these types.  Make gdbarch.py and gdbarch-components.py import it.
Also, replace the read & exec of gdbarch-components.py by a regular
import.  For this to work though, gdbarch-components.py needs to be
renamed to gdbarch_components.py.

Change-Id: Ibe994d56ef9efcc0698b3ca9670d4d9bf8bbb853
Reviewed-By: Tom Tromey <tom@tromey.com>
Reviewed-By: Andrew Burgess <aburgess@redhat.com>
20 months agogdb: pyproject.toml: set pyright typeCheckingMode = "strict"
Simon Marchi [Mon, 27 Feb 2023 01:13:58 +0000 (20:13 -0500)]
gdb: pyproject.toml: set pyright typeCheckingMode = "strict"

While working on other projects, I found the pyright type checker very
helpful when editing Python code.  I don't think I have to explain the
advantages of type checking to a crowd used to C/C++.

Setting typeCheckingMode to "strict" makes pyright flag a bit more type
issues than the default of "basic".

Change-Id: I38818ec59f7f73c2ab020cc9226286cdd485abc7
Reviewed-By: Tom Tromey <tom@tromey.com>
Reviewed-By: Andrew Burgess <aburgess@redhat.com>
20 months agogdb: gdbarch.py: remove Info.__init__
Simon Marchi [Mon, 27 Feb 2023 01:13:57 +0000 (20:13 -0500)]
gdb: gdbarch.py: remove Info.__init__

Info.__init__ currently assigns `self.predicate = None`.  This was
helpful to ensure that all component types had a `predicate` attribute.
The generator code could then avoid having code like "if the component
is anything but Info, use predicate".  Since the previous commit, all
component types have a predicate attribute which defaults to False.  We
can therefore remove the assignment in Info.__init__, and in turn remove
Info.__init__.  We however need to make the printer parameter of
_Component.__init__ optional, as Info don't need a printer.

Change-Id: I611edeca9cc9837eb49dddfe038595e1ff3b7239
Reviewed-By: Andrew Burgess <aburgess@redhat.com>
20 months agogdb: gdbarch.py: spell out parameters of _Component.__init__
Simon Marchi [Mon, 27 Feb 2023 01:13:56 +0000 (20:13 -0500)]
gdb: gdbarch.py: spell out parameters of _Component.__init__

The way _Component uses kwargs is handy to save a few characters, but it
doesn't play well with static analysis.  When editing gdbarch.py, my
editor (which uses pylance under the hood) knows nothing about the
properties of components.  So it's full of squiggly lines, and typing
analysis (which I find really helpful) doesn't work.  I therefore think
it would be better to spell out the parameters.

Change-Id: Iaf561beb0d0fbe170ce1c79252a291e0945e1830
Reviewed-By: Tom Tromey <tom@tromey.com>
Reviewed-By: Andrew Burgess <aburgess@redhat.com>
20 months agogdb: reformat Python files with black 23.1.0
Simon Marchi [Mon, 27 Feb 2023 01:13:55 +0000 (20:13 -0500)]
gdb: reformat Python files with black 23.1.0

Change-Id: Ie8ec8870a16d71c5858f5d08958309d23c318302
Reviewed-By: Tom Tromey <tom@tromey.com>
Reviewed-By: Andrew Burgess <aburgess@redhat.com>
20 months agogdb: remove invalid / dead code from gdbarch.py
Simon Marchi [Mon, 27 Feb 2023 01:13:54 +0000 (20:13 -0500)]
gdb: remove invalid / dead code from gdbarch.py

My editor flagged that the variable `c` (in the lines removed by this
patch) was unknown.  I guess it ends up working because there is a `c`
variable in the global scope.  I tried putting `assert False` inside
that if, and it is not hit, showing that we never enter this if.  So,
remove it.  There is no change in the generated files.

Change-Id: Id3b9f67719e88cada7c6fde673c8d7842ab13617
Reviewed-By: Tom Tromey <tom@tromey.com>
Reviewed-By: Andrew Burgess <aburgess@redhat.com>
20 months agoFix crash with "finish" in Rust
Tom Tromey [Thu, 9 Feb 2023 19:12:42 +0000 (12:12 -0700)]
Fix crash with "finish" in Rust

PR rust/30090 points out that a certain "finish" in a Rust program
will cause gdb to crash.  This happens due to some confusion about
field indices in rust_language::print_enum.  The fix is to use
value_primitive_field so that the correct type can be passed; other
spots in rust-lang.c already do this.

Note that the enclosed test case comes with an xfail.  This is needed
because for this function, rustc doesn't follow the platform ABI.

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

20 months agoRemove old GNU indent directives
Tom Tromey [Wed, 8 Feb 2023 18:26:24 +0000 (11:26 -0700)]
Remove old GNU indent directives

Now that gdb_indent.sh has been removed, I think it makes sense to
also remove the directives intended for GNU indent.

20 months agoHandle range types in ax-gdb.c
Tom Tromey [Wed, 4 Jan 2023 16:36:59 +0000 (09:36 -0700)]
Handle range types in ax-gdb.c

A range type can usually be treated the same as its underlying integer
type, at least for the purposes of agent expressions.  This patch
arranges for range types to be handled this way in ax-gdb.c, letting a
somewhat larger subset of Ada expressions be compiled.

20 months agoImplement some agent expressions for Ada
Tom Tromey [Wed, 21 Dec 2022 18:52:37 +0000 (11:52 -0700)]
Implement some agent expressions for Ada

Ada historically has not implemented agent expressions, and some Ada
constructs probably cannot reasonably be converted to agent
expressions.  However, a subset of simple operations can be, and this
patch represents a first step in that direction.

On one internal AdaCore test case, this improves the performance of a
conditional breakpoint from 5 minutes to 5 seconds.

The main tricky part in this patch is ensuring the converted
expressions detect the cases that will not work.  This is done by
examining the code in the corresponding evaluation methods.

20 months agoRegenerate Linux syscall group info
Pedro Alves [Fri, 24 Feb 2023 18:58:31 +0000 (18:58 +0000)]
Regenerate Linux syscall group info

This commit makes use of the new script to regenerate the Linux
syscall group info against strace git hash
e88e5e9ae6da68f22d15f9be3193b1412ac9aa02.

Like so:

 $ cd gdb/syscalls/
 $ ./update-linux-defaults.sh ~/strace.git/
 Generating linux-defaults.xml.in
 $ make
 for f in aarch64-linux.xml amd64-linux.xml arm-linux.xml bfin-linux.xml \
          i386-linux.xml mips-n32-linux.xml mips-n64-linux.xml \
  mips-o32-linux.xml ppc64-linux.xml ppc-linux.xml s390-linux.xml \
  s390x-linux.xml sparc64-linux.xml sparc-linux.xml; do \
   xsltproc --output $f apply-defaults.xsl $f.in; \
 done

The result is that a lot more syscalls end up assigned to groups.
Some lose their group info, but that just mirrors what strace does.

The gdb/syscalls/linux-defaults.xml.in file shows a large diff because
the new version is ASCII sorted, while the current version was
somewhat (but not consistently) sorted by "family" of syscalls.

If I sort the old file and diff against the new, the difference is
like this:

     <syscall name="accept4" groups="network"/>
     <syscall name="accept" groups="network"/>
     <syscall name="access" groups="file"/>
     <syscall name="acct" groups="file"/>
  -  <syscall name="arch_prctl" groups="process"/>
     <syscall name="bind" groups="network"/>
  +  <syscall name="bpf" groups="descriptor"/>
     <syscall name="break" groups="memory"/>
     <syscall name="brk" groups="memory"/>
  +  <syscall name="bsd43_fstatfs" groups="descriptor"/>
  +  <syscall name="bsd43_fstat" groups="descriptor"/>
  +  <syscall name="bsd43_killpg" groups="process"/>
  +  <syscall name="bsd43_kill" groups="process"/>
  +  <syscall name="bsd43_lstat" groups="file"/>
  +  <syscall name="bsd43_madvise" groups="memory"/>
  +  <syscall name="bsd43_mincore" groups="memory"/>
  +  <syscall name="bsd43_mmap" groups="descriptor,memory"/>
  +  <syscall name="bsd43_mprotect" groups="memory"/>
  +  <syscall name="bsd43_mremap" groups="memory"/>
  +  <syscall name="bsd43_munmap" groups="memory"/>
  +  <syscall name="bsd43_oldfstat" groups="descriptor"/>
  +  <syscall name="bsd43_oldstat" groups="file"/>
  +  <syscall name="bsd43_quotactl" groups="file"/>
  +  <syscall name="bsd43_sbreak" groups="memory"/>
  +  <syscall name="bsd43_sbrk" groups="memory"/>
  +  <syscall name="bsd43_statfs" groups="file"/>
  +  <syscall name="bsd43_stat" groups="file"/>
  +  <syscall name="cacheflush" groups="memory"/>
     <syscall name="chdir" groups="file"/>
     <syscall name="chmod" groups="file"/>
     <syscall name="chown32" groups="file"/>
     <syscall name="chown" groups="file"/>
     <syscall name="chroot" groups="file"/>
  +  <syscall name="clone2" groups="process"/>
  +  <syscall name="clone3" groups="process"/>
     <syscall name="clone" groups="process"/>
     <syscall name="close" groups="descriptor"/>
     <syscall name="connect" groups="network"/>
  +  <syscall name="copy_file_range" groups="descriptor"/>
     <syscall name="creat" groups="descriptor,file"/>
     <syscall name="dup2" groups="descriptor"/>
     <syscall name="dup3" groups="descriptor"/>
  @@ -28,14 +52,17 @@
     <syscall name="epoll_create1" groups="descriptor"/>
     <syscall name="epoll_create" groups="descriptor"/>
     <syscall name="epoll_ctl" groups="descriptor"/>
  +  <syscall name="epoll_pwait2" groups="descriptor"/>
     <syscall name="epoll_pwait" groups="descriptor"/>
     <syscall name="epoll_wait" groups="descriptor"/>
     <syscall name="eventfd2" groups="descriptor"/>
     <syscall name="eventfd" groups="descriptor"/>
  +  <syscall name="execveat" groups="descriptor,file,process"/>
     <syscall name="execve" groups="file,process"/>
     <syscall name="execv" groups="file,process"/>
     <syscall name="exit_group" groups="process"/>
     <syscall name="exit" groups="process"/>
  +  <syscall name="faccessat2" groups="descriptor,file"/>
     <syscall name="faccessat" groups="descriptor,file"/>
     <syscall name="fadvise64_64" groups="descriptor"/>
     <syscall name="fadvise64" groups="descriptor"/>
  @@ -57,7 +84,11 @@
     <syscall name="flock" groups="descriptor"/>
     <syscall name="fork" groups="process"/>
     <syscall name="fremovexattr" groups="descriptor"/>
  +  <syscall name="fsconfig" groups="descriptor,file"/>
     <syscall name="fsetxattr" groups="descriptor"/>
  +  <syscall name="fsmount" groups="descriptor"/>
  +  <syscall name="fsopen" groups="descriptor"/>
  +  <syscall name="fspick" groups="descriptor,file"/>
     <syscall name="fstat64" groups="descriptor"/>
     <syscall name="fstatat64" groups="descriptor,file"/>
     <syscall name="fstatfs64" groups="descriptor"/>
  @@ -72,16 +103,26 @@
     <syscall name="getdents" groups="descriptor"/>
     <syscall name="get_mempolicy" groups="memory"/>
     <syscall name="getpeername" groups="network"/>
  +  <syscall name="getpmsg" groups="network"/>
     <syscall name="getsockname" groups="network"/>
     <syscall name="getsockopt" groups="network"/>
     <syscall name="getxattr" groups="file"/>
  -  <syscall name="inotify_add_watch" groups="descriptor"/>
  +  <syscall name="inotify_add_watch" groups="descriptor,file"/>
     <syscall name="inotify_init1" groups="descriptor"/>
     <syscall name="inotify_init" groups="descriptor"/>
     <syscall name="inotify_rm_watch" groups="descriptor"/>
     <syscall name="ioctl" groups="descriptor"/>
  +  <syscall name="io_destroy" groups="memory"/>
  +  <syscall name="io_setup" groups="memory"/>
  +  <syscall name="io_uring_enter" groups="descriptor,signal"/>
  +  <syscall name="io_uring_register" groups="descriptor,memory"/>
  +  <syscall name="io_uring_setup" groups="descriptor"/>
     <syscall name="ipc" groups="ipc"/>
  -  <syscall name="kill" groups="signal"/>
  +  <syscall name="kexec_file_load" groups="descriptor"/>
  +  <syscall name="kill" groups="signal,process"/>
  +  <syscall name="landlock_add_rule" groups="descriptor"/>
  +  <syscall name="landlock_create_ruleset" groups="descriptor"/>
  +  <syscall name="landlock_restrict_self" groups="descriptor"/>
     <syscall name="lchown32" groups="file"/>
     <syscall name="lchown" groups="file"/>
     <syscall name="lgetxattr" groups="file"/>
  @@ -98,19 +139,31 @@
     <syscall name="lstat" groups="file"/>
     <syscall name="madvise" groups="memory"/>
     <syscall name="mbind" groups="memory"/>
  +  <syscall name="memfd_create" groups="descriptor"/>
  +  <syscall name="memfd_secret" groups="descriptor"/>
     <syscall name="migrate_pages" groups="memory"/>
     <syscall name="mincore" groups="memory"/>
     <syscall name="mkdirat" groups="descriptor,file"/>
     <syscall name="mkdir" groups="file"/>
     <syscall name="mknodat" groups="descriptor,file"/>
     <syscall name="mknod" groups="file"/>
  +  <syscall name="mlock2" groups="memory"/>
     <syscall name="mlockall" groups="memory"/>
     <syscall name="mlock" groups="memory"/>
     <syscall name="mmap2" groups="descriptor,memory"/>
     <syscall name="mmap" groups="descriptor,memory"/>
  +  <syscall name="mount_setattr" groups="descriptor,file"/>
     <syscall name="mount" groups="file"/>
  +  <syscall name="move_mount" groups="descriptor,file"/>
     <syscall name="move_pages" groups="memory"/>
     <syscall name="mprotect" groups="memory"/>
  +  <syscall name="mq_getsetattr" groups="descriptor"/>
  +  <syscall name="mq_notify" groups="descriptor"/>
  +  <syscall name="mq_open" groups="descriptor"/>
  +  <syscall name="mq_timedreceive" groups="descriptor"/>
  +  <syscall name="mq_timedreceive_time64" groups="descriptor"/>
  +  <syscall name="mq_timedsend" groups="descriptor"/>
  +  <syscall name="mq_timedsend_time64" groups="descriptor"/>
     <syscall name="mremap" groups="memory"/>
     <syscall name="msgctl" groups="ipc"/>
     <syscall name="msgget" groups="ipc"/>
  @@ -126,45 +179,98 @@
     <syscall name="oldfstat" groups="descriptor"/>
     <syscall name="oldlstat" groups="file"/>
     <syscall name="oldstat" groups="file"/>
  +  <syscall name="oldumount" groups="file"/>
  +  <syscall name="openat2" groups="descriptor,file"/>
     <syscall name="openat" groups="descriptor,file"/>
     <syscall name="open_by_handle_at" groups="descriptor"/>
     <syscall name="open" groups="descriptor,file"/>
  +  <syscall name="open_tree" groups="descriptor,file"/>
  +  <syscall name="osf_fstatfs64" groups="descriptor"/>
  +  <syscall name="osf_fstatfs" groups="descriptor"/>
  +  <syscall name="osf_fstat" groups="descriptor"/>
  +  <syscall name="osf_lstat" groups="file"/>
  +  <syscall name="osf_mincore" groups="memory"/>
  +  <syscall name="osf_mremap" groups="memory"/>
  +  <syscall name="osf_old_fstat" groups="descriptor"/>
  +  <syscall name="osf_old_killpg" groups="process"/>
  +  <syscall name="osf_old_lstat" groups="file"/>
  +  <syscall name="osf_old_stat" groups="file"/>
  +  <syscall name="osf_sbrk" groups="memory"/>
  +  <syscall name="osf_select" groups="descriptor"/>
  +  <syscall name="osf_shmat" groups="ipc,memory"/>
  +  <syscall name="osf_sigprocmask" groups="signal"/>
  +  <syscall name="osf_statfs64" groups="file"/>
  +  <syscall name="osf_statfs" groups="file"/>
  +  <syscall name="osf_stat" groups="file"/>
  +  <syscall name="osf_utimes" groups="file"/>
  +  <syscall name="osf_wait4" groups="process"/>
     <syscall name="pause" groups="signal"/>
     <syscall name="perf_event_open" groups="descriptor"/>
  +  <syscall name="pidfd_getfd" groups="descriptor"/>
  +  <syscall name="pidfd_open" groups="descriptor"/>
  +  <syscall name="pidfd_send_signal" groups="descriptor,signal,process"/>
     <syscall name="pipe2" groups="descriptor"/>
     <syscall name="pipe" groups="descriptor"/>
     <syscall name="pivot_root" groups="file"/>
  +  <syscall name="pkey_mprotect" groups="memory"/>
     <syscall name="poll" groups="descriptor"/>
  +  <syscall name="posix_fstatfs" groups="descriptor"/>
  +  <syscall name="posix_fstat" groups="descriptor"/>
  +  <syscall name="posix_kill" groups="process"/>
  +  <syscall name="posix_lstat" groups="file"/>
  +  <syscall name="posix_madvise" groups="memory"/>
  +  <syscall name="posix_mmap" groups="descriptor,memory"/>
  +  <syscall name="posix_munmap" groups="memory"/>
  +  <syscall name="posix_sbreak" groups="memory"/>
  +  <syscall name="posix_SGI_madvise" groups="memory"/>
  +  <syscall name="posix_SGI_mmap" groups="descriptor,memory"/>
  +  <syscall name="posix_SGI_mprotect" groups="memory"/>
  +  <syscall name="posix_SGI_msync" groups="memory"/>
  +  <syscall name="posix_SGI_munmap" groups="memory"/>
  +  <syscall name="posix_statfs" groups="file"/>
  +  <syscall name="posix_stat" groups="file"/>
     <syscall name="ppoll" groups="descriptor"/>
  +  <syscall name="ppoll_time64" groups="descriptor"/>
     <syscall name="pread64" groups="descriptor"/>
     <syscall name="pread" groups="descriptor"/>
  +  <syscall name="preadv2" groups="descriptor"/>
     <syscall name="preadv" groups="descriptor"/>
  +  <syscall name="process_madvise" groups="descriptor"/>
  +  <syscall name="process_mrelease" groups="descriptor"/>
     <syscall name="pselect6" groups="descriptor"/>
  +  <syscall name="pselect6_time64" groups="descriptor"/>
  +  <syscall name="putpmsg" groups="network"/>
     <syscall name="pwrite64" groups="descriptor"/>
     <syscall name="pwrite" groups="descriptor"/>
  +  <syscall name="pwritev2" groups="descriptor"/>
     <syscall name="pwritev" groups="descriptor"/>
  +  <syscall name="quotactl_fd" groups="descriptor"/>
     <syscall name="quotactl" groups="file"/>
     <syscall name="readahead" groups="descriptor"/>
     <syscall name="readdir" groups="descriptor"/>
  -  <syscall name="read" groups="descriptor"/>
     <syscall name="readlinkat" groups="descriptor,file"/>
     <syscall name="readlink" groups="file"/>
  +  <syscall name="read" groups="descriptor"/>
     <syscall name="readv" groups="descriptor"/>
     <syscall name="recvfrom" groups="network"/>
  -  <syscall name="recv" groups="network"/>
  +  <syscall name="recvmmsg_time64" groups="network"/>
     <syscall name="recvmmsg" groups="network"/>
     <syscall name="recvmsg" groups="network"/>
  +  <syscall name="recv" groups="network"/>
     <syscall name="remap_file_pages" groups="memory"/>
     <syscall name="removexattr" groups="file"/>
  +  <syscall name="renameat2" groups="descriptor,file"/>
     <syscall name="renameat" groups="descriptor,file"/>
     <syscall name="rename" groups="file"/>
  +  <syscall name="riscv_flush_icache" groups="memory"/>
     <syscall name="rmdir" groups="file"/>
     <syscall name="rt_sigaction" groups="signal"/>
     <syscall name="rt_sigpending" groups="signal"/>
     <syscall name="rt_sigprocmask" groups="signal"/>
  -  <syscall name="rt_sigqueueinfo" groups="signal"/>
  +  <syscall name="rt_sigqueueinfo" groups="signal,process"/>
     <syscall name="rt_sigreturn" groups="signal"/>
     <syscall name="rt_sigsuspend" groups="signal"/>
  +  <syscall name="rt_sigtimedwait_time64" groups="signal"/>
     <syscall name="rt_sigtimedwait" groups="signal"/>
     <syscall name="rt_tgsigqueueinfo" groups="process,signal"/>
     <syscall name="select" groups="descriptor"/>
  @@ -172,12 +278,14 @@
     <syscall name="semget" groups="ipc"/>
     <syscall name="semop" groups="ipc"/>
     <syscall name="semtimedop" groups="ipc"/>
  +  <syscall name="semtimedop_time64" groups="ipc"/>
     <syscall name="sendfile64" groups="descriptor,network"/>
     <syscall name="sendfile" groups="descriptor,network"/>
  -  <syscall name="send" groups="network"/>
     <syscall name="sendmmsg" groups="network"/>
     <syscall name="sendmsg" groups="network"/>
  +  <syscall name="send" groups="network"/>
     <syscall name="sendto" groups="network"/>
  +  <syscall name="set_mempolicy_home_node" groups="memory"/>
     <syscall name="set_mempolicy" groups="memory"/>
     <syscall name="setns" groups="descriptor"/>
     <syscall name="setsockopt" groups="network"/>
  @@ -198,38 +306,78 @@
     <syscall name="sigreturn" groups="signal"/>
     <syscall name="sigsuspend" groups="signal"/>
     <syscall name="socketcall" groups="descriptor"/>
  -  <syscall name="socket" groups="network"/>
     <syscall name="socketpair" groups="network"/>
  +  <syscall name="socket" groups="network"/>
     <syscall name="splice" groups="descriptor"/>
     <syscall name="ssetmask" groups="signal"/>
     <syscall name="stat64" groups="file"/>
     <syscall name="statfs64" groups="file"/>
     <syscall name="statfs" groups="file"/>
     <syscall name="stat" groups="file"/>
  +  <syscall name="statx" groups="descriptor,file"/>
  +  <syscall name="svr4_fstatfs" groups="descriptor"/>
  +  <syscall name="svr4_fstat" groups="descriptor"/>
  +  <syscall name="svr4_fstatvfs" groups="descriptor"/>
  +  <syscall name="svr4_fxstat" groups="descriptor"/>
  +  <syscall name="svr4_kill" groups="process"/>
  +  <syscall name="svr4_lstat" groups="file"/>
  +  <syscall name="svr4_lxstat" groups="file"/>
  +  <syscall name="svr4_mincore" groups="memory"/>
  +  <syscall name="svr4_mmap" groups="descriptor,memory"/>
  +  <syscall name="svr4_mprotect" groups="memory"/>
  +  <syscall name="svr4_munmap" groups="memory"/>
  +  <syscall name="svr4_sbreak" groups="memory"/>
  +  <syscall name="svr4_statfs" groups="file"/>
  +  <syscall name="svr4_stat" groups="file"/>
  +  <syscall name="svr4_statvfs" groups="file"/>
  +  <syscall name="svr4_xstat" groups="file"/>
     <syscall name="swapoff" groups="file"/>
     <syscall name="swapon" groups="file"/>
     <syscall name="symlinkat" groups="descriptor,file"/>
     <syscall name="symlink" groups="file"/>
  +  <syscall name="sync_file_range2" groups="descriptor"/>
     <syscall name="sync_file_range" groups="descriptor"/>
     <syscall name="syncfs" groups="descriptor"/>
  +  <syscall name="sysv_brk" groups="memory"/>
  +  <syscall name="sysv_fstatfs" groups="descriptor"/>
  +  <syscall name="sysv_fstat" groups="descriptor"/>
  +  <syscall name="sysv_fstatvfs" groups="descriptor"/>
  +  <syscall name="sysv_fxstat" groups="descriptor"/>
  +  <syscall name="sysv_kill" groups="process"/>
  +  <syscall name="sysv_lstat" groups="file"/>
  +  <syscall name="sysv_lxstat" groups="file"/>
  +  <syscall name="sysv_madvise" groups="memory"/>
  +  <syscall name="sysv_mmap64" groups="descriptor,memory"/>
  +  <syscall name="sysv_mmap" groups="descriptor,memory"/>
  +  <syscall name="sysv_mprotect" groups="memory"/>
  +  <syscall name="sysv_msync" groups="memory"/>
  +  <syscall name="sysv_munmap" groups="memory"/>
  +  <syscall name="sysv_quotactl" groups="file"/>
  +  <syscall name="sysv_statfs" groups="file"/>
  +  <syscall name="sysv_stat" groups="file"/>
  +  <syscall name="sysv_statvfs" groups="file"/>
  +  <syscall name="sysv_xstat" groups="file"/>
     <syscall name="tee" groups="descriptor"/>
  -  <syscall name="tgkill" groups="signal"/>
  +  <syscall name="tgkill" groups="signal,process"/>
     <syscall name="timerfd_create" groups="descriptor"/>
  +  <syscall name="timerfd_gettime64" groups="descriptor"/>
     <syscall name="timerfd_gettime" groups="descriptor"/>
  -  <syscall name="timerfd" groups="descriptor"/>
  +  <syscall name="timerfd_settime64" groups="descriptor"/>
     <syscall name="timerfd_settime" groups="descriptor"/>
  -  <syscall name="tkill" groups="signal"/>
  +  <syscall name="timerfd" groups="descriptor"/>
  +  <syscall name="tkill" groups="signal,process"/>
     <syscall name="truncate64" groups="file"/>
     <syscall name="truncate" groups="file"/>
     <syscall name="umount2" groups="file"/>
     <syscall name="umount" groups="file"/>
     <syscall name="unlinkat" groups="descriptor,file"/>
     <syscall name="unlink" groups="file"/>
  -  <syscall name="unshare" groups="process"/>
     <syscall name="uselib" groups="file"/>
  -  <syscall name="utime" groups="file"/>
  +  <syscall name="userfaultfd" groups="descriptor"/>
     <syscall name="utimensat" groups="descriptor,file"/>
  +  <syscall name="utimensat_time64" groups="descriptor,file"/>
     <syscall name="utimes" groups="file"/>
  +  <syscall name="utime" groups="file"/>
     <syscall name="vfork" groups="process"/>
     <syscall name="vmsplice" groups="descriptor"/>
     <syscall name="wait4" groups="process"/>

Change-Id: I679d59d42fb2a914bf7a99e4c558e9696e5adff1

20 months agoAutogenerate gdb/syscalls/linux-defaults.xml.in (groups) from strace sources
Pedro Alves [Fri, 24 Feb 2023 18:58:31 +0000 (18:58 +0000)]
Autogenerate gdb/syscalls/linux-defaults.xml.in (groups) from strace sources

I noticed that "catch syscall group:process" doesn't catch clone3,
while it does catch clone.

The catch syscall group information is recorded in the
gdb/syscalls/linux-defaults.xml.in file, which says:

  <!-- The group field information was based on strace.  -->

So I looked at the strace sources, to confirm that clone3 is in fact
recorded in the "process" group there too, and to check what other
syscalls might be missing groups.

After some digging, I found that strace records the group info in C
arrays, with entries like:
...
[ 61] = { 4, TP, SEN(wait4), "wait4" },
[ 62] = { 2, TS|TP, SEN(kill), "kill" },
[ 63] = { 1, 0, SEN(uname), "uname" },
...

You can see the current master's table for Linux x86-64 here:

  https://github.com/strace/strace/blob/e88e5e9ae6da68f22d15f9be3193b1412ac9aa02/src/linux/x86_64/syscallent.h

The column with TS|TP above is what defines each syscall's groups.  So
I wrote a script that extracts this information and generates
linux-defaults.xml.in.

Approved-By: Simon Marchi <simon.marchi@efficios.com>
Change-Id: I679d59d42fb2a914bf7a99e4c558e9696e5adff1

20 months agogas/testsuite: adjust another test for case insensitive file systems
Clément Chigot [Mon, 27 Feb 2023 12:57:12 +0000 (13:57 +0100)]
gas/testsuite: adjust another test for case insensitive file systems

As 1fafeaac8503eea2f61c3a35f0eef183b7e7cc65, "line.s" and "Line.s" are
identical in case insensitive file systems. Thus, gas doesn't trigger
an input file switch.

gas/ChangeLog:

        * testsuite/gas/elf/dwarf-5-macro.s: Change Line.s to Line2.s.

20 months agogdb: don't treat empty enums as flag enums
Andrew Burgess [Mon, 20 Feb 2023 13:14:55 +0000 (13:14 +0000)]
gdb: don't treat empty enums as flag enums

In C++ it is possible to use an empty enum as a strong typedef.  For
example, a user could write:

  enum class my_type : unsigned char {};

Now my_type can be used like 'unsigned char' except the compiler will
not allow implicit conversion too and from the native 'unsigned char'
type.

This is used in the standard library for things like std::byte.

Currently, when GDB prints a value of type my_type, it looks like
this:

  (gdb) print my_var
  $1 = (unknown: 0x4)

Which isn't great.  This gets worse when we consider something like:

  std::vector<my_type> vec;

When using a pretty-printer, this could look like this:

  std::vector of length 2, capacity 2 = {(unknown: 0x2), (unknown: 0x4)}

Clearly not great.  This is described in PR gdb/30148.

The problem here is in dwarf2/read.c, we assume all enums are flag
enums unless we find an enumerator with a non-flag like value.
Clearly an empty enum contains no non-flag values, so we assume the
enum is a flag enum.

I propose adding an extra check here; that is, an empty enum should
never be a flag enum.

With this the above cases look more like:

  (gdb) print my_var
  $1 = 4

and:

  std::vector of length 2, capacity 2 = {2, 4}

Which look much better.

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

Reviewed-By: Tom Tromey <tom@tromey.com>
20 months agoDo not change the timestamp when updating the gas asconfig file.
Benson Muite [Mon, 27 Feb 2023 13:35:49 +0000 (13:35 +0000)]
Do not change the timestamp when updating the gas asconfig file.

 PR 28909 * doc/local.mk (asconfig.texi): Use "cp -p" to preserve timestamps. * Makefile.in: Regenerate.

20 months agoFix missing "Core was generated by" when loading a x32 corefile.
Felix Willgerodt [Mon, 27 Feb 2023 13:01:06 +0000 (13:01 +0000)]
Fix missing "Core was generated by" when loading a x32 corefile.

20 months agoUpdated Serbian translations for gold, gprof and opcodes sub-directories
Nick Clifton [Mon, 27 Feb 2023 12:50:31 +0000 (12:50 +0000)]
Updated Serbian translations for gold, gprof and opcodes sub-directories

20 months agogdb/testsuite: Improve testing of GDB's completion functions
Bruno Larsen [Tue, 21 Feb 2023 16:10:31 +0000 (17:10 +0100)]
gdb/testsuite: Improve testing of GDB's completion functions

When looking at some failures of gdb.linespec/cp-completion-aliases.exp,
I noticed that when a completion test will fail, it always fails with a
timeout.  This is because most completion tests use gdb_test_multiple
and only add a check for the correct output.  This commit adds new
options for both, tab and command completion.

For command completion, the new option will check if the prompt was
printed, and fail in this case. This is enough to know that the test has
failed because the check comes after the PASS path. For tab completion,
we have to check if GDB outputted more than just the input line, because
sometimes GDB would have printed a partial line before finishing with
the correct completion.

Approved-By: Tom Tromey <tom@tromey.com>
20 months agogdb, python: do minor modernization in execute_gdb_command
Tankut Baris Aktemur [Mon, 27 Feb 2023 09:28:40 +0000 (10:28 +0100)]
gdb, python: do minor modernization in execute_gdb_command

Use nullptr instead of NULL and boolify two local variables in
execute_gdb_command.

Approved-By: Tom Tromey <tom@tromey.com>
20 months agoAutomatic date update in version.in
GDB Administrator [Mon, 27 Feb 2023 00:00:09 +0000 (00:00 +0000)]
Automatic date update in version.in

20 months agoRemove expand_symtab_containing_pc
Tom Tromey [Sun, 26 Feb 2023 16:49:02 +0000 (09:49 -0700)]
Remove expand_symtab_containing_pc

The function expand_symtab_containing_pc is unused; remove it.
Tested by rebuilding.

21 months agoAutomatic date update in version.in
GDB Administrator [Sun, 26 Feb 2023 00:00:19 +0000 (00:00 +0000)]
Automatic date update in version.in

21 months agogdb/amd64: replace xmalloc/alloca with gdb::byte_vector
Andrew Burgess [Thu, 23 Feb 2023 10:34:39 +0000 (10:34 +0000)]
gdb/amd64: replace xmalloc/alloca with gdb::byte_vector

Replace a couple of uses of xmalloc and alloc with a gdb::byte_vector
local variable instead.

There should be no user visible changes after this commit.

Reviewed-By: Tom Tromey <tom@tromey.com>
21 months agoopcodes/m68k: enable libopcodes styling for GDB
Andrew Burgess [Sat, 25 Feb 2023 10:16:34 +0000 (10:16 +0000)]
opcodes/m68k: enable libopcodes styling for GDB

The following commit added libopcodes styling for m68k:

  commit c22ff449275c91e4842bb10c650e83c572580f65
  Date:   Tue Feb 14 18:07:19 2023 +0100

      opcodes: style m68k disassembler output

but didn't set disassemble_info::created_styled_output in
disassemble.c, which is needed in order for GDB to start using the
libopcodes based styling.

This commit fixes this small oversight.  GDB now styles correctly.

21 months agoAutomatic date update in version.in
GDB Administrator [Sat, 25 Feb 2023 00:00:12 +0000 (00:00 +0000)]
Automatic date update in version.in

21 months agogdbserver/linux-low.cc: Fix a typo in ternary operator
Khem Raj [Thu, 23 Feb 2023 00:28:22 +0000 (16:28 -0800)]
gdbserver/linux-low.cc: Fix a typo in ternary operator

Signed-off-by: Khem Raj <raj.khem@gmail.com>
21 months agoRemove struct buffer
Tom Tromey [Fri, 16 Dec 2022 19:50:29 +0000 (12:50 -0700)]
Remove struct buffer

I've long wanted to remove 'struct buffer', and thanks to Simon's
earlier patch, I was finally able to do so.  My feeling has been that
gdb already has several decent structures available for growing
strings: std::string of course, but also obstack and even objalloc
from BFD and dyn-string from libiberty.  The previous patches in this
series removed all the uses of struct buffer, so this one can remove
the code and the remaining #includes.

21 months agoDon't use struct buffer in top.c
Tom Tromey [Fri, 16 Dec 2022 19:53:20 +0000 (12:53 -0700)]
Don't use struct buffer in top.c

This changes top.c to use std::string rather than struct buffer.  Like
the event-top.c change, this is not completely ideal in that it
requires a copy of the string.

21 months agoDon't use struct buffer in event-top.c
Tom Tromey [Fri, 16 Dec 2022 19:45:40 +0000 (12:45 -0700)]
Don't use struct buffer in event-top.c

This changes event-top.c to use std::string rather than struct buffer.
This isn't completely ideal, in that it requires a copy of the string
to be made.

21 months agoDon't use struct buffer in handle_qxfer_threads
Tom Tromey [Fri, 16 Dec 2022 14:59:52 +0000 (07:59 -0700)]
Don't use struct buffer in handle_qxfer_threads

This changes handle_qxfer_threads, in gdbserver, to use std::string
rather than struct buffer.

21 months agoDon't use struct buffer in handle_qxfer_btrace
Tom Tromey [Fri, 16 Dec 2022 14:56:57 +0000 (07:56 -0700)]
Don't use struct buffer in handle_qxfer_btrace

This changes handle_qxfer_btrace and handle_qxfer_btrace_conf, in
gdbserver, to use std::string rather than struct buffer.

21 months agoDon't use struct buffer in handle_qxfer_traceframe_info
Tom Tromey [Fri, 16 Dec 2022 14:49:01 +0000 (07:49 -0700)]
Don't use struct buffer in handle_qxfer_traceframe_info

This changes handle_qxfer_traceframe_info, in gdbserver, to use
std::string rather than struct buffer.

21 months agoRemove struct buffer from tracefile-tfile.c
Tom Tromey [Fri, 16 Dec 2022 14:42:47 +0000 (07:42 -0700)]
Remove struct buffer from tracefile-tfile.c

This changes tracefile-tfile.c to use std::string rather than struct
buffer.

21 months agoWrite the DWARF index in the background
Tom Tromey [Wed, 13 Apr 2022 17:25:53 +0000 (11:25 -0600)]
Write the DWARF index in the background

The new DWARF cooked indexer interacts poorly with the DWARF index
cache.  In particular, the cache will require gdb to wait for the
cooked index to be finalized.  As this happens in the foreground, it
means that users with this setting enabled will see a slowdown.

This patch changes gdb to write the cache entry a worker thread.  (As
usual, in the absence of threads, this work is simply done immediately
in the main thread.)

Some care is taken to ensure that this can't crash, and that gdb will
not exit before the task is complete.

To avoid use-after-free problems, the DWARF per-BFD object explicitly
waits for the index cache task to complete.

To avoid gdb exiting early, an exit observer is used to wait for all
such pending tasks.

In normal use, neither of these waits will be very visible.  For users
using "-batch" to pre-generate the index, though, it would be.
However I don't think there is much to be done about this, as it was
the status quo ante.

21 months agoOnly use the per-BFD object to write a DWARF index
Tom Tromey [Wed, 13 Apr 2022 17:21:20 +0000 (11:21 -0600)]
Only use the per-BFD object to write a DWARF index

The DWARF index does not need access to the objfile or per-objfile
objects when writing -- it's entirely based on the objfile-independent
per-BFD data.

This patch implements this idea by changing the entire API to only be
passed the per-BFD object.  This simplifies some lifetime reasoning
for the next patch.

This patch removes some code that ensures that the BFD came from a
file.  It seems to me that checking for the existence of a build-id is
good enough for the index cache.