- Maintenance script qa.sh (bsc#1221763):

* Remove yama ptrace_scope == 1 kfails.

OBS-URL: https://build.opensuse.org/package/show/devel:gcc/gdb?expand=0&rev=451
This commit is contained in:
2025-04-03 13:13:04 +00:00
committed by Git OBS Bridge
commit 9a9cd521a2
133 changed files with 34667 additions and 0 deletions

23
.gitattributes vendored Normal file
View File

@@ -0,0 +1,23 @@
## Default LFS
*.7z filter=lfs diff=lfs merge=lfs -text
*.bsp filter=lfs diff=lfs merge=lfs -text
*.bz2 filter=lfs diff=lfs merge=lfs -text
*.gem filter=lfs diff=lfs merge=lfs -text
*.gz filter=lfs diff=lfs merge=lfs -text
*.jar filter=lfs diff=lfs merge=lfs -text
*.lz filter=lfs diff=lfs merge=lfs -text
*.lzma filter=lfs diff=lfs merge=lfs -text
*.obscpio filter=lfs diff=lfs merge=lfs -text
*.oxt filter=lfs diff=lfs merge=lfs -text
*.pdf filter=lfs diff=lfs merge=lfs -text
*.png filter=lfs diff=lfs merge=lfs -text
*.rpm filter=lfs diff=lfs merge=lfs -text
*.tbz filter=lfs diff=lfs merge=lfs -text
*.tbz2 filter=lfs diff=lfs merge=lfs -text
*.tgz filter=lfs diff=lfs merge=lfs -text
*.ttf filter=lfs diff=lfs merge=lfs -text
*.txz filter=lfs diff=lfs merge=lfs -text
*.whl filter=lfs diff=lfs merge=lfs -text
*.xz filter=lfs diff=lfs merge=lfs -text
*.zip filter=lfs diff=lfs merge=lfs -text
*.zst filter=lfs diff=lfs merge=lfs -text

1
.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
.osc

117
README.qa Normal file
View File

@@ -0,0 +1,117 @@
I. LOCAL QA.
0. Notes.
Note that the configs are hardcoded in the script. F.i. atm SLE-11 is not
included, because the config is unresolvable on devel:gcc/gdb. Also Leap
15.2 is not included because of 'remote error: unknown repository type
UNDEFINED"'.
The script tries to keep disk usage low by removing the buildroot after each
build, but that requires sudo rights, so the first thing the script does is
ask for sudo authentication.
1. Cleanup.
Do:
...
$ bash qa-local.sh 1
...
2. Build.
Do:
...
$ bash qa-local.sh 2
...
This builds gdb for each x86_64 config, without running the testsuite.
I did a timing run on my laptop (with 6 configs) and got:
...
real 66m17.689s
user 149m31.925s
sys 12m25.359s
...
so for a dual-core/4-SMT CPU, it's ~1h5m.
3. Build & test.
Do:
...
$ bash qa-local.sh 3
...
This builds gdb and produces test results for each x86_64 config.
I did a timing run on my laptop (with 6 configs) and got:
...
real 285m9.679s
user 683m16.769s
sys 133m58.287s
...
so for a dual-core/4-SMT CPU, it's ~4h45m.
The resulting testlogs (with 6 configs) is 1.4GB.
4. Verify.
Do:
...
$ bash qa-local.sh 4
...
This verifies the test results for each x86_64 config, using the qa.sh script.
5. Cleanup.
Do:
...
$ rm -Rf tmp-qa-local
...
l
I. REMOTE QA.
1. Cleanup.
Do:
...
$ bash qa-remote.sh 1
...
2. Get test results.
Do:
...
$ bash qa-remote.sh 2
...
This downloads the remote test results.
3. Verify.
Do:
...
$ bash qa-remote.sh 3 <m>
...
with m running from 1 to 5.
This verifies the test results, using the qa.sh script.
4. Cleanup.
Do:
...
$ rm -Rf tmp-qa-remote
...

24
_constraints Normal file
View File

@@ -0,0 +1,24 @@
<constraints>
<overwrite>
<conditions>
<arch>ppc64</arch>
<arch>ppc64le</arch>
</conditions>
<hardware>
<disk>
<size unit="G">4</size>
</disk>
</hardware>
</overwrite>
<overwrite>
<conditions>
<arch>x86_64</arch>
</conditions>
<hardware>
<disk>
<size unit="G">8</size>
</disk>
</hardware>
</overwrite>
</constraints>

3
_multibuild Normal file
View File

@@ -0,0 +1,3 @@
<multibuild>
<package>testsuite</package>
</multibuild>

View File

@@ -0,0 +1,100 @@
From 89cf6ba4a207f5342db58d9e43178ae516cc220e Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Wed, 15 Jan 2025 17:02:00 +0100
Subject: [PATCH 23/46] Add dwarf_expr_piece.op
Add a new field "dwarf_location_atom op" to dwarf_expr_piece to keep track of
which dwarf_location_atom caused a dwarf_expr_piece to be added.
This is used in the following patch.
Tested on s390x-linux.
Approved-By: Tom Tromey <tom@tromey.com>
---
gdb/dwarf2/expr.c | 10 ++++++----
gdb/dwarf2/expr.h | 6 +++++-
2 files changed, 11 insertions(+), 5 deletions(-)
diff --git a/gdb/dwarf2/expr.c b/gdb/dwarf2/expr.c
index cb80dbf60b1..03107f90575 100644
--- a/gdb/dwarf2/expr.c
+++ b/gdb/dwarf2/expr.c
@@ -1198,13 +1198,15 @@ dwarf_expr_context::stack_empty_p () const
/* Add a new piece to the dwarf_expr_context's piece list. */
void
-dwarf_expr_context::add_piece (ULONGEST size, ULONGEST offset)
+dwarf_expr_context::add_piece (ULONGEST size, ULONGEST offset,
+ enum dwarf_location_atom op)
{
dwarf_expr_piece &p = this->m_pieces.emplace_back ();
p.location = this->m_location;
p.size = size;
p.offset = offset;
+ p.op = op;
if (p.location == DWARF_VALUE_LITERAL)
{
@@ -2169,7 +2171,7 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr,
/* Record the piece. */
op_ptr = safe_read_uleb128 (op_ptr, op_end, &size);
- add_piece (8 * size, 0);
+ add_piece (8 * size, 0, op);
/* Pop off the address/regnum, and reset the location
type. */
@@ -2187,7 +2189,7 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr,
/* Record the piece. */
op_ptr = safe_read_uleb128 (op_ptr, op_end, &size);
op_ptr = safe_read_uleb128 (op_ptr, op_end, &uleb_offset);
- add_piece (size, uleb_offset);
+ add_piece (size, uleb_offset, op);
/* Pop off the address/regnum, and reset the location
type. */
@@ -2389,7 +2391,7 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr,
pointer, then make a pieced value. This is ok because we can't
have implicit pointers in contexts where pieces are invalid. */
if (this->m_location == DWARF_VALUE_IMPLICIT_POINTER)
- add_piece (8 * this->m_addr_size, 0);
+ add_piece (8 * this->m_addr_size, 0, DW_OP_implicit_pointer);
this->m_recursion_depth--;
gdb_assert (this->m_recursion_depth >= 0);
diff --git a/gdb/dwarf2/expr.h b/gdb/dwarf2/expr.h
index b02cc531640..957c58f30c4 100644
--- a/gdb/dwarf2/expr.h
+++ b/gdb/dwarf2/expr.h
@@ -24,6 +24,7 @@
#include "leb128.h"
#include "dwarf2/call-site.h"
+#include "dwarf2.h"
struct dwarf2_per_objfile;
@@ -54,6 +55,9 @@ enum dwarf_value_location
/* A piece of an object, as recorded by DW_OP_piece or DW_OP_bit_piece. */
struct dwarf_expr_piece
{
+ /* The DWARF operation for which the piece was created. */
+ enum dwarf_location_atom op;
+
enum dwarf_value_location location;
union
@@ -208,7 +212,7 @@ struct dwarf_expr_context
struct type *address_type () const;
void push (struct value *value, bool in_stack_memory);
bool stack_empty_p () const;
- void add_piece (ULONGEST size, ULONGEST offset);
+ void add_piece (ULONGEST size, ULONGEST offset, enum dwarf_location_atom op);
void execute_stack_op (const gdb_byte *op_ptr, const gdb_byte *op_end);
void pop ();
struct value *fetch (int n);
--
2.43.0

View File

@@ -0,0 +1,220 @@
From 29b185c531fcd933da62142debcb088321be7c4c Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Wed, 15 Jan 2025 17:02:00 +0100
Subject: [PATCH 24/46] Add gdbarch_dwarf2_reg_piece_offset hook
In rw_pieced_value, when reading/writing part of a register, DW_OP_piece and
DW_OP_bit_piece are handled the same, but the standard tells us:
- DW_OP_piece: if the piece is located in a register, but does not occupy the
entire register, the placement of the piece within that register is defined
by the ABI.
- DW_OP_bit_piece: if the location is a register, the offset is from the least
significant bit end of the register.
Add a new hook gdbarch_dwarf2_reg_piece_offset that allows us to define the
ABI-specific behaviour for DW_OP_piece.
The default implementation of the hook is the behaviour of DW_OP_bit_piece, so
there should not be any functional changes.
Tested on s390x-linux.
Approved-By: Tom Tromey <tom@tromey.com>
---
gdb/dwarf2/expr.c | 31 +++++++++++++++++++++++++------
gdb/findvar.c | 18 ++++++++++++++++++
gdb/gdbarch-gen.h | 8 ++++++++
gdb/gdbarch.c | 22 ++++++++++++++++++++++
gdb/gdbarch_components.py | 16 ++++++++++++++++
gdb/value.h | 2 ++
6 files changed, 91 insertions(+), 6 deletions(-)
diff --git a/gdb/dwarf2/expr.c b/gdb/dwarf2/expr.c
index 03107f90575..ece713ee7cd 100644
--- a/gdb/dwarf2/expr.c
+++ b/gdb/dwarf2/expr.c
@@ -211,14 +211,33 @@ rw_pieced_value (value *v, value *from, bool check_optimized)
ULONGEST reg_bits = 8 * register_size (arch, gdb_regnum);
int optim, unavail;
- if (gdbarch_byte_order (arch) == BFD_ENDIAN_BIG
- && p->offset + p->size < reg_bits)
+ if (p->offset + p->size < reg_bits)
{
- /* Big-endian, and we want less than full size. */
- bits_to_skip += reg_bits - (p->offset + p->size);
+ /* We want less than full size. */
+
+ if (p->op == DW_OP_piece)
+ {
+ gdb_assert (p->offset == 0);
+
+ /* If the piece is located in a register, but does not
+ occupy the entire register, the placement of the piece
+ within that register is defined by the ABI. */
+ bits_to_skip
+ += 8 * gdbarch_dwarf2_reg_piece_offset (arch, gdb_regnum,
+ p->size / 8);
+ }
+ else if (p->op == DW_OP_bit_piece)
+ {
+ /* If the location is a register, the offset is from the
+ least significant bit end of the register. */
+ if (gdbarch_byte_order (arch) == BFD_ENDIAN_BIG)
+ bits_to_skip += reg_bits - (p->offset + p->size);
+ else
+ bits_to_skip += p->offset;
+ }
+ else
+ error (_("Don't know how to get part of implicit pointer"));
}
- else
- bits_to_skip += p->offset;
this_size = bits_to_bytes (bits_to_skip, this_size_bits);
buffer.resize (this_size);
diff --git a/gdb/findvar.c b/gdb/findvar.c
index df4ab1a28b9..3b20974474a 100644
--- a/gdb/findvar.c
+++ b/gdb/findvar.c
@@ -541,6 +541,24 @@ default_value_from_register (gdbarch *gdbarch, type *type, int regnum,
return value;
}
+/* Default implementation of gdbarch_dwarf2_reg_piece_offset. Implements
+ DW_OP_bits_piece for DW_OP_piece. */
+
+ULONGEST
+default_dwarf2_reg_piece_offset (gdbarch *gdbarch, int gdb_regnum, ULONGEST size)
+{
+ ULONGEST reg_size = register_size (gdbarch, gdb_regnum);
+ gdb_assert (size <= reg_size);
+ if (reg_size == size)
+ return 0;
+
+ if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
+ return reg_size - size;
+
+ return 0;
+}
+
+
/* VALUE must be an lval_register value. If regnum is the value's
associated register number, and len the length of the value's type,
read one or more registers in VALUE's frame, starting with register REGNUM,
diff --git a/gdb/gdbarch-gen.h b/gdb/gdbarch-gen.h
index b982fd7cd09..2e20a9dbccd 100644
--- a/gdb/gdbarch-gen.h
+++ b/gdb/gdbarch-gen.h
@@ -430,6 +430,14 @@ typedef struct value * (gdbarch_value_from_register_ftype) (struct gdbarch *gdba
extern struct value * gdbarch_value_from_register (struct gdbarch *gdbarch, struct type *type, int regnum, const frame_info_ptr &this_frame);
extern void set_gdbarch_value_from_register (struct gdbarch *gdbarch, gdbarch_value_from_register_ftype *value_from_register);
+/* For a DW_OP_piece located in a register, but not occupying the
+ entire register, return the placement of the piece within that
+ register as defined by the ABI. */
+
+typedef ULONGEST (gdbarch_dwarf2_reg_piece_offset_ftype) (struct gdbarch *gdbarch, int regnum, ULONGEST size);
+extern ULONGEST gdbarch_dwarf2_reg_piece_offset (struct gdbarch *gdbarch, int regnum, ULONGEST size);
+extern void set_gdbarch_dwarf2_reg_piece_offset (struct gdbarch *gdbarch, gdbarch_dwarf2_reg_piece_offset_ftype *dwarf2_reg_piece_offset);
+
typedef CORE_ADDR (gdbarch_pointer_to_address_ftype) (struct gdbarch *gdbarch, struct type *type, const gdb_byte *buf);
extern CORE_ADDR gdbarch_pointer_to_address (struct gdbarch *gdbarch, struct type *type, const gdb_byte *buf);
extern void set_gdbarch_pointer_to_address (struct gdbarch *gdbarch, gdbarch_pointer_to_address_ftype *pointer_to_address);
diff --git a/gdb/gdbarch.c b/gdb/gdbarch.c
index 58e9ebbdc59..ed5b5859277 100644
--- a/gdb/gdbarch.c
+++ b/gdb/gdbarch.c
@@ -109,6 +109,7 @@ struct gdbarch
gdbarch_register_to_value_ftype *register_to_value = nullptr;
gdbarch_value_to_register_ftype *value_to_register = nullptr;
gdbarch_value_from_register_ftype *value_from_register = default_value_from_register;
+ gdbarch_dwarf2_reg_piece_offset_ftype *dwarf2_reg_piece_offset = default_dwarf2_reg_piece_offset;
gdbarch_pointer_to_address_ftype *pointer_to_address = unsigned_pointer_to_address;
gdbarch_address_to_pointer_ftype *address_to_pointer = unsigned_address_to_pointer;
gdbarch_integer_to_address_ftype *integer_to_address = nullptr;
@@ -371,6 +372,7 @@ verify_gdbarch (struct gdbarch *gdbarch)
/* Skip verify of value_from_register, invalid_p == 0 */
/* Skip verify of pointer_to_address, invalid_p == 0 */
/* Skip verify of address_to_pointer, invalid_p == 0 */
+ /* Skip verify of dwarf2_reg_piece_offset, invalid_p == 0. */
/* Skip verify of integer_to_address, has predicate. */
/* Skip verify of return_value, invalid_p == 0 */
if ((gdbarch->return_value_as_value == default_gdbarch_return_value) == (gdbarch->return_value == nullptr))
@@ -783,6 +785,9 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file)
gdb_printf (file,
"gdbarch_dump: value_from_register = <%s>\n",
host_address_to_string (gdbarch->value_from_register));
+ gdb_printf (file,
+ "gdbarch_dump: dwarf2_reg_piece_offset = <%s>\n",
+ host_address_to_string (gdbarch->dwarf2_reg_piece_offset));
gdb_printf (file,
"gdbarch_dump: pointer_to_address = <%s>\n",
host_address_to_string (gdbarch->pointer_to_address));
@@ -2573,6 +2578,23 @@ set_gdbarch_value_from_register (struct gdbarch *gdbarch,
gdbarch->value_from_register = value_from_register;
}
+ULONGEST
+gdbarch_dwarf2_reg_piece_offset (struct gdbarch *gdbarch, int regnum, ULONGEST size)
+{
+ gdb_assert (gdbarch != NULL);
+ gdb_assert (gdbarch->dwarf2_reg_piece_offset != NULL);
+ if (gdbarch_debug >= 2)
+ gdb_printf (gdb_stdlog, "gdbarch_dwarf2_reg_piece_offset called\n");
+ return gdbarch->dwarf2_reg_piece_offset (gdbarch, regnum, size);
+}
+
+void
+set_gdbarch_dwarf2_reg_piece_offset (struct gdbarch *gdbarch,
+ gdbarch_dwarf2_reg_piece_offset_ftype dwarf2_reg_piece_offset)
+{
+ gdbarch->dwarf2_reg_piece_offset = dwarf2_reg_piece_offset;
+}
+
CORE_ADDR
gdbarch_pointer_to_address (struct gdbarch *gdbarch, struct type *type, const gdb_byte *buf)
{
diff --git a/gdb/gdbarch_components.py b/gdb/gdbarch_components.py
index 4006380076d..4a228b5d27c 100644
--- a/gdb/gdbarch_components.py
+++ b/gdb/gdbarch_components.py
@@ -829,6 +829,22 @@ allocate and return a struct value with all value attributes
invalid=False,
)
+Method(
+ comment="""
+For a DW_OP_piece located in a register, but not occupying the
+entire register, return the placement of the piece within that
+register as defined by the ABI.
+""",
+ type="ULONGEST",
+ name="dwarf2_reg_piece_offset",
+ params=[
+ ("int", "regnum"),
+ ("ULONGEST", "size")
+ ],
+ predefault="default_dwarf2_reg_piece_offset",
+ invalid=False,
+)
+
Method(
type="CORE_ADDR",
name="pointer_to_address",
diff --git a/gdb/value.h b/gdb/value.h
index 9d7e88d9433..47df66e0961 100644
--- a/gdb/value.h
+++ b/gdb/value.h
@@ -1128,6 +1128,8 @@ extern value *default_value_from_register (gdbarch *gdbarch, type *type,
int regnum,
const frame_info_ptr &this_frame);
+extern ULONGEST default_dwarf2_reg_piece_offset (gdbarch *gdbarch, int regnum, ULONGEST size);
+
extern struct value *value_from_register (struct type *type, int regnum,
const frame_info_ptr &frame);
--
2.43.0

11
baselibs.conf Normal file
View File

@@ -0,0 +1,11 @@
gdb
+/usr/bin/gdb -> /usr/bin/gdb<extension>
# kill package for i586 32bit
targetarch x86_64 block!
prereq -glibc-x86
gdbserver
+/usr/bin/gdbserver -> /usr/bin/gdbserver<extension>
provides "gdb-<targettype>:/usr/bin/gdbserver<extension>"
# kill package for i586 32bit
targetarch x86_64 block!
prereq -glibc-x86

46
clean.sh Normal file
View File

@@ -0,0 +1,46 @@
#!/bin/sh
dryrun=false
while [ $# -gt 0 ]; do
case $1 in
-dryrun|--dryrun|-dry-run|--dry-run)
dryrun=true
;;
*)
echo "Don't know how to handle arg: $1"
exit 1
esac
shift
done
first=true
for f in *.patch; do
if grep -q "^Patch.*[ \t]$f" gdb.spec; then
continue
fi
if $dryrun; then
if $first; then
echo "Patches not mentioned in gdb.spec:"
fi
first=false
echo "$f"
continue
fi
( set -x; osc remove -f "$f" )
done
files=$(echo ./*~)
if [ "$files" != "./*~" ]; then
if $dryrun; then
echo "Backup files:"
echo "$files"
else
for f in $files; do
( set -x; rm -f "$f" )
done
fi
fi

View File

@@ -0,0 +1,144 @@
From 0ac8e9af3cd6713f4b230e9e335e1398c3161210 Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Fri, 10 Jan 2025 21:25:53 +0100
Subject: [PATCH 26/46] Fix gdb.ada/O2_float_param.exp on s390x-linux
With test-case gdb.ada/O2_float_param.exp on s390x-linux, I get:
...
(gdb) frame^M
#0 callee.increment (val=99.0, val@entry=<error reading variable: \
register has not been saved in frame>, msg=...) at callee.adb:19^M
19 procedure Increment (Val : in out Float; Msg: String) is^M
(gdb) FAIL: $exp: scenario=all: frame
...
The frame command calls read_frame_arg to get:
- the current value of val, and
- the value of val at function entry.
The first scenario succeeds, and the second scenario fails.
For context and contrast, let's also investigate the first scenario: getting
the current value of val.
Function parameter val:
...
<2><b51>: Abbrev Number: 4 (DW_TAG_formal_parameter)
<b52> DW_AT_name : val
<b58> DW_AT_type : <0xb86>
<b5c> DW_AT_location : 0xab (location list)
...
has location list:
...
000000ab 0000000001002928 0000000001002967
(DW_OP_reg16 (f0))
000000be 0000000001002967 0000000001002968
(DW_OP_reg24 (f8))
000000d1 0000000001002968 0000000001002974
(DW_OP_GNU_regval_type: 24 (f8) <0xb29>;
DW_OP_GNU_const_type: <0xb29> 4 byte block: 3f 80 0 0 ; DW_OP_plus;
DW_OP_stack_value)
000000ef 0000000001002974 0000000001002982
(DW_OP_GNU_entry_value: (DW_OP_GNU_regval_type: 16 (f0) <0xb29>);
DW_OP_GNU_const_type: <0xb29> 4 byte block: 3f 80 0 0 ; DW_OP_plus;
DW_OP_stack_value)
0000010f <End of list>
...
and since we're stopped at address 0x1002928:
...
(gdb) print $pc
$1 = (access procedure) 0x1002928 <callee.increment>
...
we get the value from dwarf register 16.
The s390x ABI [1] specifies that dwarf register 16 maps onto 8-byte register
f0 or 16-byte register v0 (where f0 is part of v0), and in this case (because
the v0 register is available) s390_dwarf_reg_to_regnum maps it to v0.
Val is only 4 bytes:
...
(gdb) ptype val
type = <4-byte float>
...
and s390_value_from_register takes care to get the value from the correct part
of v0.
The value of v0 is found in the prologue cache, and the value of parameter val
is printed.
Now the second scenario: getting the value of val at function entry.
FWIW, since we're stopped at function entry, we could simply return the same
value, reading the same register, but that's currently not implemented [2].
Instead we start from the fact that val is in dwarf reg 16 at function entry,
and then use call site information:
...
<4><cf7>: Abbrev Number: 13 (DW_TAG_GNU_call_site)
<cf8> DW_AT_low_pc : 0x1002a46
<d00> DW_AT_abstract_origin: <0xdda>
<5><d04>: Abbrev Number: 12 (DW_TAG_GNU_call_site_parameter)
<d05> DW_AT_location : 1 byte block: 60 (DW_OP_reg16 (f0))
<d07> DW_AT_GNU_call_site_value: 3 byte block: f5 18 2d \
(DW_OP_GNU_regval_type: 24 (f8) <0xc42>)
<5><d0b>: Abbrev Number: 12 (DW_TAG_GNU_call_site_parameter)
...
to conclude that the value we're looking for is in dwarf reg 24, which
s390_dwarf_reg_to_regnum maps to v8.
As before, s390_value_from_register takes care to get the value from the
correct part of v8.
However, v8 is not available in the prologue cache, and we take a different
path and end up in s390_unwind_pseudo_register, where v8 and similar
(regnum_is_vxr_full) is unhandled, and we get:
...
return value::allocate_optimized_out (type);
...
which eventually causes the "error reading variable: register has not been
saved in frame".
Fix this by handling the regnum_is_vxr_full case in
s390_unwind_pseudo_register, similar to how that is done in
s390_pseudo_register_read.
Tested on s390x-linux.
This also fixes test-case gdb.base/savedregs.exp.
[1] https://github.com/IBM/s390x-abi
[2] https://sourceware.org/pipermail/gdb-patches/2024-September/211589.html
---
gdb/s390-tdep.c | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/gdb/s390-tdep.c b/gdb/s390-tdep.c
index a7c58b37276..31730296ef1 100644
--- a/gdb/s390-tdep.c
+++ b/gdb/s390-tdep.c
@@ -2332,6 +2332,22 @@ s390_unwind_pseudo_register (const frame_info_ptr &this_frame, int regnum)
return value_cast (type, val);
}
+ if (regnum_is_vxr_full (tdep, regnum))
+ {
+ struct value *val = value::allocate_register (this_frame, regnum);
+
+ int reg = regnum - tdep->v0_full_regnum;
+ struct value *val1
+ = frame_unwind_register_value (this_frame, S390_F0_REGNUM + reg);
+ struct value *val2
+ = frame_unwind_register_value (this_frame, S390_V0_LOWER_REGNUM + reg);
+
+ val1->contents_copy (val, 0, 0, 8);
+ val2->contents_copy (val, 8, 0, 8);
+
+ return value_cast (type, val);
+ }
+
return value::allocate_optimized_out (type);
}
--
2.43.0

View File

@@ -0,0 +1,188 @@
From de696a57729423bf643e530fdb638dff6cf3c08b Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Sat, 4 Jan 2025 11:31:02 +0100
Subject: [PATCH 21/46] Fix gdb.base/finish-pretty.exp on s390x
On s390x-linux, with test-case gdb.base/finish-pretty.exp I ran into:
...
(gdb) finish
Run till exit from #0 foo () at finish-pretty.c:28
main () at finish-pretty.c:40
40 return v.a + v.b;
Value returned has type: struct s. Cannot determine contents
(gdb) FAIL: $exp: finish foo prettyprinted function result
...
The function being finished is foo, which returns a value of type struct s.
The ABI [1] specifies:
- that the value is returned in a storage buffer allocated by the caller, and
- that the address of this buffer is passed as a hidden argument in r2.
GDB fails to print the value when finishing foo, because it doesn't know the
address of the buffer.
Implement the gdbarch_get_return_buf_addr hook for s390x to fix this.
This is based on ppc_sysv_get_return_buf_addr, the only other implementation
of gdbarch_get_return_buf_addr. For readability I've factored out
dwarf_reg_on_entry.
There is one difference with ppc_sysv_get_return_buf_addr: only
NO_ENTRY_VALUE_ERROR is caught. If this patch is approved, I intend to submit
a follow-up patch to fix this in ppc_sysv_get_return_buf_addr as well.
The hook is not guaranteed to work, because it attempts to get the value r2
had at function entry.
The hook can be called after function entry, and the ABI doesn't guarantee
that r2 is the same throughout the function.
Using -fvar-tracking adds debug information, which allows the hook to succeed
more often, and indeed after adding this to the test-case, it passes.
Do likewise in one more test-case.
Tested on s390x-linux.
Fixes:
- gdb.ada/finish-large.exp
- gdb.base/finish-pretty.exp
- gdb.base/retval-large-struct.exp
- gdb.cp/non-trivial-retval.exp
- gdb.ada/array_return.exp
AFAICT, I've also enabled the hook for s390 and from the ABI I get the
impression that it should work, but I haven't been able to test it.
[1] https://github.com/IBM/s390x-abi
---
gdb/s390-tdep.c | 58 ++++++++++++++++++++++++
gdb/testsuite/gdb.ada/array_return.exp | 8 +++-
gdb/testsuite/gdb.base/finish-pretty.exp | 8 +++-
3 files changed, 72 insertions(+), 2 deletions(-)
diff --git a/gdb/s390-tdep.c b/gdb/s390-tdep.c
index 4844b7e9bc8..4e7dce70c12 100644
--- a/gdb/s390-tdep.c
+++ b/gdb/s390-tdep.c
@@ -40,6 +40,7 @@
#include "trad-frame.h"
#include "value.h"
#include "inferior.h"
+#include "dwarf2/loc.h"
#include "features/s390-linux32.c"
#include "features/s390x-linux64.c"
@@ -2119,6 +2120,62 @@ s390_return_value (struct gdbarch *gdbarch, struct value *function,
return rvc;
}
+/* Try to get the value of DWARF_REG in FRAME at function entry. If successful,
+ return it as value of type VAL_TYPE. */
+
+static struct value *
+dwarf_reg_on_entry (int dwarf_reg, struct type *val_type,
+ const frame_info_ptr &frame)
+{
+ enum call_site_parameter_kind kind = CALL_SITE_PARAMETER_DWARF_REG;
+ union call_site_parameter_u kind_u = { .dwarf_reg = dwarf_reg };
+
+ try
+ {
+ return value_of_dwarf_reg_entry (val_type, frame, kind, kind_u);
+ }
+ catch (const gdb_exception_error &e)
+ {
+ if (e.error == NO_ENTRY_VALUE_ERROR)
+ return nullptr;
+
+ throw;
+ }
+}
+
+/* Both the 32-bit and 64-bit ABIs specify that values of some types are
+ returned in a storage buffer provided by the caller. Return the address of
+ that storage buffer, if possible. Implements the
+ gdbarch_get_return_buf_addr hook. */
+
+static CORE_ADDR
+s390_get_return_buf_addr (struct type *val_type,
+ const frame_info_ptr &cur_frame)
+{
+ /* The address of the storage buffer is provided as a hidden argument in
+ register r2. */
+ int dwarf_reg = 2;
+
+ /* The ABI does not guarantee that the register will not be changed while
+ executing the function. Hence, it cannot be assumed that it will still
+ contain the address of the storage buffer when execution reaches the end
+ of the function.
+
+ Attempt to determine the value on entry using the DW_OP_entry_value DWARF
+ entries. This requires compiling the user program with -fvar-tracking. */
+ struct value *val_on_entry
+ = dwarf_reg_on_entry (dwarf_reg, lookup_pointer_type (val_type), cur_frame);
+
+ if (val_on_entry == nullptr)
+ {
+ warning ("Cannot determine the function return value.\n"
+ "Try compiling with -fvar-tracking.");
+ return 0;
+ }
+
+ return value_as_address (val_on_entry);
+}
+
/* Frame unwinding. */
/* Implement the stack_frame_destroyed_p gdbarch method. */
@@ -7183,6 +7240,7 @@ s390_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
set_gdbarch_dummy_id (gdbarch, s390_dummy_id);
set_gdbarch_frame_align (gdbarch, s390_frame_align);
set_gdbarch_return_value (gdbarch, s390_return_value);
+ set_gdbarch_get_return_buf_addr (gdbarch, s390_get_return_buf_addr);
/* Frame handling. */
/* Stack grows downward. */
diff --git a/gdb/testsuite/gdb.ada/array_return.exp b/gdb/testsuite/gdb.ada/array_return.exp
index c6edee11f17..d1fc2ac2c98 100644
--- a/gdb/testsuite/gdb.ada/array_return.exp
+++ b/gdb/testsuite/gdb.ada/array_return.exp
@@ -19,7 +19,13 @@ require allow_ada_tests
standard_ada_testfile p
-if {[gdb_compile_ada "${srcfile}" "${binfile}" executable {debug}] != ""} {
+set opts {}
+lappend opts debug
+if { [have_fvar_tracking] } {
+ lappend opts "additional_flags=-fvar-tracking"
+}
+
+if {[gdb_compile_ada "${srcfile}" "${binfile}" executable $opts] != ""} {
return -1
}
diff --git a/gdb/testsuite/gdb.base/finish-pretty.exp b/gdb/testsuite/gdb.base/finish-pretty.exp
index 44f3340f41c..0b6bea6681d 100644
--- a/gdb/testsuite/gdb.base/finish-pretty.exp
+++ b/gdb/testsuite/gdb.base/finish-pretty.exp
@@ -18,7 +18,13 @@
standard_testfile
-if { [prepare_for_testing "failed to prepare" $testfile $srcfile] } {
+set opts {}
+lappend opts debug
+if { [have_fvar_tracking] } {
+ lappend opts "additional_flags=-fvar-tracking"
+}
+
+if { [prepare_for_testing "failed to prepare" $testfile $srcfile $opts] } {
return -1
}
--
2.43.0

View File

@@ -0,0 +1,187 @@
From 1d761604714b32883d2bbc4a5f274fc3e2c668fe Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Thu, 9 Jan 2025 14:32:19 +0100
Subject: [PATCH 22/46] Fix gdb.base/readnever.exp on s390x
On s390x-linux, I run into:
...
(gdb) backtrace
#0 0x000000000100061a in fun_three ()
#1 0x000000000100067a in fun_two ()
#2 0x000003fffdfa9470 in ?? ()
Backtrace stopped: frame did not save the PC
(gdb) FAIL: gdb.base/readnever.exp: backtrace
...
This is really due to a problem handling the fun_three frame. When generating
a backtrace from fun_two, everying looks ok:
...
$ gdb -readnever -q -batch outputs/gdb.base/readnever/readnever \
-ex "b fun_two" \
-ex run \
-ex bt
...
#0 0x0000000001000650 in fun_two ()
#1 0x00000000010006b6 in fun_one ()
#2 0x00000000010006ee in main ()
...
For reference the frame info with debug info (without -readnever) looks like this:
...
$ gdb -q -batch outputs/gdb.base/readnever/readnever \
-ex "b fun_three" \
-ex run \
-ex "info frame"
...
Stack level 0, frame at 0x3fffffff140:
pc = 0x1000632 in fun_three (readnever.c:20); saved pc = 0x100067a
called by frame at 0x3fffffff1f0
source language c.
Arglist at 0x3fffffff140, args: a=10, b=49 '1', c=0x3fffffff29c
Locals at 0x3fffffff140, Previous frame's sp in v0
...
But with -readnever, like this instead:
...
Stack level 0, frame at 0x0:
pc = 0x100061a in fun_three; saved pc = 0x100067a
called by frame at 0x3fffffff140
Arglist at 0xffffffffffffffff, args:
Locals at 0xffffffffffffffff, Previous frame's sp in r15
...
An obvious difference is the "Previous frame's sp in" v0 vs. r15.
Looking at the code:
...
0000000001000608 <fun_three>:
1000608: b3 c1 00 2b ldgr %f2,%r11
100060c: b3 c1 00 0f ldgr %f0,%r15
1000610: e3 f0 ff 50 ff 71 lay %r15,-176(%r15)
1000616: b9 04 00 bf lgr %r11,%r15
...
it becomes clear what is going on. This is an unusual prologue.
Rather than saving r11 (frame pointer) and r15 (stack pointer) to stack,
instead they're saved into call-clobbered floating point registers.
[ For reference, this is the prologue of fun_two:
...
0000000001000640 <fun_two>:
1000640: eb bf f0 58 00 24 stmg %r11,%r15,88(%r15)
1000646: e3 f0 ff 50 ff 71 lay %r15,-176(%r15)
100064c: b9 04 00 bf lgr %r11,%r15
...
where the first instruction stores registers r11 to r15 to stack. ]
Gdb fails to properly analyze the prologue, which causes the problems getting
the frame info.
Fix this by:
- adding handling of the ldgr insn [1] in s390_analyze_prologue, and
- recognizing the insn as saving a register in
s390_prologue_frame_unwind_cache.
This gets us instead:
...
Stack level 0, frame at 0x0:
pc = 0x100061a in fun_three; saved pc = 0x100067a
called by frame at 0x3fffffff1f0
Arglist at 0xffffffffffffffff, args:
Locals at 0xffffffffffffffff, Previous frame's sp in f0
...
and:
...
(gdb) backtrace^M
#0 0x000000000100061a in fun_three ()^M
#1 0x000000000100067a in fun_two ()^M
#2 0x00000000010006b6 in fun_one ()^M
#3 0x00000000010006ee in main ()^M
(gdb) PASS: gdb.base/readnever.exp: backtrace
...
Tested on s390x-linux.
PR tdep/32417
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32417
Approved-By: Andreas Arnez <arnez@linux.ibm.com>
[1] https://www.ibm.com/support/pages/sites/default/files/2021-05/SA22-7871-10.pdf
---
gdb/s390-tdep.c | 39 +++++++++++++++++++++++++++++++++++++++
gdb/s390-tdep.h | 1 +
2 files changed, 40 insertions(+)
diff --git a/gdb/s390-tdep.c b/gdb/s390-tdep.c
index 4e7dce70c12..2609b42f797 100644
--- a/gdb/s390-tdep.c
+++ b/gdb/s390-tdep.c
@@ -855,6 +855,11 @@ s390_analyze_prologue (struct gdbarch *gdbarch,
|| is_rre (insn64, op_lgr, &r1, &r2))
data->gpr[r1] = data->gpr[r2];
+ /* LDGR r1, r2 --- load from register to floating-point register
+ (64-bit version). */
+ else if (is_rre (insn64, op_ldgr, &r1, &r2))
+ data->fpr[r1] = data->gpr[r2];
+
/* L r1, d2(x2, b2) --- load. */
/* LY r1, d2(x2, b2) --- load (long-displacement version). */
/* LG r1, d2(x2, b2) --- load (64-bit version). */
@@ -2542,6 +2547,40 @@ s390_prologue_frame_unwind_cache (const frame_info_ptr &this_frame,
&& data.fpr_slot[i] != 0)
info->saved_regs[S390_F0_REGNUM + i].set_addr (cfa - data.fpr_slot[i]);
+ /* Handle this type of prologue:
+ ldgr %f2,%r11
+ ldgr %f0,%r15
+ where call-clobbered floating point registers are used as register save
+ slots. */
+ for (i = 0; i < S390_NUM_FPRS; i++)
+ {
+ int fpr = S390_F0_REGNUM + i;
+
+ /* Check that fpr is a call-clobbered register. */
+ if (s390_register_call_saved (gdbarch, fpr))
+ continue;
+
+ /* Check that fpr contains the value of a register at function
+ entry. */
+ if (data.fpr[i].kind != pvk_register)
+ continue;
+
+ int entry_val_reg = data.fpr[i].reg;
+
+ /* Check that entry_val_reg is a call-saved register. */
+ if (!s390_register_call_saved (gdbarch, entry_val_reg))
+ continue;
+
+ /* In the prologue, we've copied:
+ - the value of a call-saved register (entry_val_reg) at function
+ entry, to
+ - a call-clobbered floating point register (fpr).
+
+ Heuristic: assume that makes the floating point register a register
+ save slot, leaving the value constant throughout the function. */
+ info->saved_regs[entry_val_reg].set_realreg (fpr);
+ }
+
/* Function return will set PC to %r14. */
info->saved_regs[S390_PSWA_REGNUM] = info->saved_regs[S390_RETADDR_REGNUM];
diff --git a/gdb/s390-tdep.h b/gdb/s390-tdep.h
index 10f775f468f..b098d735a13 100644
--- a/gdb/s390-tdep.h
+++ b/gdb/s390-tdep.h
@@ -82,6 +82,7 @@ enum
op1_lgfi = 0xc0, op2_lgfi = 0x01,
op_lr = 0x18,
op_lgr = 0xb904,
+ op_ldgr = 0xb3c1,
op_l = 0x58,
op1_ly = 0xe3, op2_ly = 0x58,
op1_lg = 0xe3, op2_lg = 0x04,
--
2.43.0

View File

@@ -0,0 +1,143 @@
From 69e165afa3d45cfac89ed6be298ac6465c84c0fd Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Wed, 15 Jan 2025 17:02:00 +0100
Subject: [PATCH 25/46] Fix gdb.base/store.exp on s390x
On s390x-linux, I get:
...
(gdb) print l^M
$29 = 0^M
(gdb) FAIL: gdb.base/store.exp: var doublest l; print old l, expecting -1
...
So, we're in wack_doublest trying to print l, which is a copy of parameter u:
...
register doublest l = u, r = v;
...
which does have the expected value:
...
(gdb) p u
$1 = -1
...
which is a long double, 16 bytes and looks like this:
...
(gdb) p /x u
$3 = 0xbfff0000000000000000000000000000
...
Parameter u is passed in two registers:
...
<2><6a5>: Abbrev Number: 15 (DW_TAG_formal_parameter)
<6a6> DW_AT_name : v
<69e> DW_AT_location : 6 byte block: 50 93 8 51 93 8 \
(DW_OP_reg0 (r0); DW_OP_piece: 8; DW_OP_reg1 (r1); DW_OP_piece: 8)
...
and indeed we find the msw in r0 and the lsw in r1:
...
(gdb) p /x $r0
$4 = 0xbfff000000000000
(gdb) p /x $r1
$5 = 0x0
(gdb)
...
Likewise, variable l consists of two registers:
...
<2><6b5>: Abbrev Number: 13 (DW_TAG_variable)
<6b6> DW_AT_name : l
<6be> DW_AT_location : 6 byte block: 68 93 8 69 93 8 \
(DW_OP_reg24 (f8); DW_OP_piece: 8; DW_OP_reg25 (f10); DW_OP_piece: 8)
...
and we find the same values there:
...
(gdb) p /x $f8
$6 = 0xbfff000000000000
(gdb) p /x $f10
$7 = 0x0
...
So, we get the expected results when fetching the value from two gprs, but not
when fetching the value from two fprs.
When fetching the values from the two fprs, we stumble upon a particularity of
the DWARF register numbers as defined by the s390x ABI [1]: dwarf register 24
maps to both floating-point register f8 (8 bytes), and vector register v8
(16 bytes).
In s390_dwarf_reg_to_regnum, it's determined which of the two is chosen, and
if available vector registers are preferred over floating-point registers, so
v8 is chosen, and used to fetch the value.
Since the size of the DW_OP_piece is 8 bytes, and the register size is 16
bytes, this bit in rw_pieced_value is activated:
...
/* If the piece is located in a register, but does not
occupy the entire register, the placement of the piece
within that register is defined by the ABI. */
bits_to_skip
+= 8 * gdbarch_dwarf2_reg_piece_offset (arch, gdb_regnum,
p->size / 8);
...
but since the default implemention default_dwarf2_reg_piece_offset does not
match the s390x ABI, we get the wrong answer.
This is a known problem, see FOSDEM 2018 presentation "DWARF Pieces And Other
DWARF Location Woes" [2].
Fix this by adding s390_dwarf2_reg_piece_offset, roughly implementing the same
logic as in s390_value_from_register.
Tested on s390x-linux.
Approved-By: Tom Tromey <tom@tromey.com>
[1] https://github.com/IBM/s390x-abi
[2] https://archive.fosdem.org/2018/schedule/event/dwarfpieces
---
gdb/s390-tdep.c | 23 +++++++++++++++++++++++
1 file changed, 23 insertions(+)
diff --git a/gdb/s390-tdep.c b/gdb/s390-tdep.c
index 2609b42f797..a7c58b37276 100644
--- a/gdb/s390-tdep.c
+++ b/gdb/s390-tdep.c
@@ -1260,6 +1260,28 @@ s390_value_from_register (gdbarch *gdbarch, type *type, int regnum,
return value;
}
+/* Implementation of the gdbarch_dwarf2_reg_piece_offset hook. */
+
+static ULONGEST
+s390_dwarf2_reg_piece_offset (gdbarch *gdbarch, int gdb_regnum, ULONGEST size)
+{
+ s390_gdbarch_tdep *tdep = gdbarch_tdep<s390_gdbarch_tdep> (gdbarch);
+
+ /* Floating point register. */
+ if (gdb_regnum >= S390_F0_REGNUM && gdb_regnum <= S390_F15_REGNUM)
+ return 0;
+
+ /* Vector register, v0 - v15. */
+ if (regnum_is_vxr_full (tdep, gdb_regnum))
+ return 0;
+
+ /* Vector register, v16 - v31. */
+ if (gdb_regnum >= S390_V16_REGNUM && gdb_regnum <= S390_V31_REGNUM)
+ return 0;
+
+ return default_dwarf2_reg_piece_offset (gdbarch, gdb_regnum, size);
+}
+
/* Implement pseudo_register_name tdesc method. */
static const char *
@@ -7259,6 +7281,7 @@ s390_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
set_gdbarch_stab_reg_to_regnum (gdbarch, s390_dwarf_reg_to_regnum);
set_gdbarch_dwarf2_reg_to_regnum (gdbarch, s390_dwarf_reg_to_regnum);
set_gdbarch_value_from_register (gdbarch, s390_value_from_register);
+ set_gdbarch_dwarf2_reg_piece_offset (gdbarch, s390_dwarf2_reg_piece_offset);
/* Pseudo registers. */
set_gdbarch_pseudo_register_read (gdbarch, s390_pseudo_register_read);
--
2.43.0

View File

@@ -0,0 +1,97 @@
From 6775ce3f5e936a50d883abfb60cafa80f8b76cf6 Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Tue, 10 Dec 2024 11:53:31 +0100
Subject: [PATCH 19/46] Fix gdb.dap/step-out.exp on s390x
With test-case gdb.dap/step-out.exp on s390x-linux, I get:
...
>>> {"seq": 7, "type": "request", "command": "scopes", "arguments": {"frameId": 0}}
Content-Length: 569^M
^M
{"request_seq": 7, "type": "response", "command": "scopes", "body": {"scopes": [{"variablesReference": 1, "name": "Locals", "presentationHint": "locals", "expensive": false, "namedVariables": 1, "line": 35, "source": {"name": "step-out.c", "path": "/home/vries/gdb/src/gdb/testsuite/gdb.dap/step-out.c"}}, {"variablesReference": 2, "name": "Registers", "presentationHint": "registers", "expensive": false, "namedVariables": 114, "line": 35, "source": {"name": "step-out.c", "path": "/home/vries/gdb/src/gdb/testsuite/gdb.dap/step-out.c"}}]}, "success": true, "seq": 21}PASS: gdb.dap/step-out.exp: get scopes success
FAIL: gdb.dap/step-out.exp: three scopes
...
The problem is that the test-case expects three scopes:
...
lassign $scopes scope reg_scope return_scope
...
but the return_scope is missing because this doesn't work:
...
$ gdb -q -batch outputs/gdb.dap/step-out/step-out \
-ex "b function_breakpoint_here" \
-ex run \
-ex finish
...
Value returned has type: struct result. Cannot determine contents
...
This is likely caused by a problem in gdb, but there's nothing wrong the DAP
support.
Fix this by:
- allowing two scopes, and
- declaring the tests of return_scope unsupported.
Tested on s390x-linux.
Approved-By: Tom Tromey <tom@tromey.com>
---
gdb/testsuite/gdb.dap/step-out.exp | 42 ++++++++++++++++--------------
1 file changed, 23 insertions(+), 19 deletions(-)
diff --git a/gdb/testsuite/gdb.dap/step-out.exp b/gdb/testsuite/gdb.dap/step-out.exp
index 757f4ebdaca..491eaf71197 100644
--- a/gdb/testsuite/gdb.dap/step-out.exp
+++ b/gdb/testsuite/gdb.dap/step-out.exp
@@ -59,24 +59,28 @@ set scopes [dap_check_request_and_response "get scopes" scopes \
[format {o frameId [i %d]} $frame_id]]
set scopes [dict get [lindex $scopes 0] body scopes]
-gdb_assert {[llength $scopes] == 2} "two scopes"
-
-lassign $scopes scope reg_scope
-gdb_assert {[dict get $scope name] == "Locals"} "scope is locals"
-gdb_assert {[dict get $scope presentationHint] == "locals"} \
- "locals presentation hint"
-gdb_assert {[dict get $scope namedVariables] == 2} "two vars in scope"
-
-set num [dict get $scope variablesReference]
-set refs [lindex [dap_check_request_and_response "fetch arguments" \
- "variables" \
- [format {o variablesReference [i %d]} $num]] \
- 0]
-set varlist [lindex [dict get $refs body variables] 0]
-
-gdb_assert {[dict get $varlist variablesReference] > 0} \
- "variable has children"
-gdb_assert {[dict get $varlist name] == "(return)"} \
- "variable is return value"
+gdb_assert {[llength $scopes] == 2 || [llength $scopes] == 3} "two or three scopes"
+lassign $scopes scope reg_scope return_scope
+
+set test "scope is locals"
+if { $return_scope == "" } {
+ unsupported $test
+} else {
+ gdb_assert {[dict get $scope presentationHint] == "locals"} \
+ "locals presentation hint"
+ gdb_assert {[dict get $scope namedVariables] == 2} "two vars in scope"
+
+ set num [dict get $scope variablesReference]
+ set refs [lindex [dap_check_request_and_response "fetch arguments" \
+ "variables" \
+ [format {o variablesReference [i %d]} $num]] \
+ 0]
+ set varlist [lindex [dict get $refs body variables] 0]
+
+ gdb_assert {[dict get $varlist variablesReference] > 0} \
+ "variable has children"
+ gdb_assert {[dict get $varlist name] == "(return)"} \
+ "variable is return value"
+}
dap_shutdown
--
2.43.0

View File

@@ -0,0 +1,56 @@
From 2ccefe53891d9c1393853f5179f8e8046c95a6ce Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Wed, 19 Jun 2024 10:04:22 +0200
Subject: [PATCH 17/46] Fix gdb.dwarf2/shortpiece.exp on s390x
On s390x-linux, I run into:
...
(gdb) p (short []) s1^M
$3 = {0, 1, 0, <optimized out>}^M
(gdb) FAIL: gdb.dwarf2/shortpiece.exp: p (short []) s1
...
while this is expected:
...
(gdb) p (short []) s1^M
$3 = {1, 0, 0, <optimized out>}^M
(gdb) PASS: gdb.dwarf2/shortpiece.exp: p (short []) s1
...
The type of s1 is:
...
(gdb) ptype s1
type = struct S {
myint a;
myushort b;
}
...
so the difference is due the fact that viewing an int as two shorts gives
different results depending on the endianness.
Fix this by allowing both results.
Tested on x86_64-linux and s390x-linux.
Approved-By: Tom Tromey <tom@tromey.com>
---
gdb/testsuite/gdb.dwarf2/shortpiece.exp | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/gdb/testsuite/gdb.dwarf2/shortpiece.exp b/gdb/testsuite/gdb.dwarf2/shortpiece.exp
index f7ff805de7c..4fcdfcae57a 100644
--- a/gdb/testsuite/gdb.dwarf2/shortpiece.exp
+++ b/gdb/testsuite/gdb.dwarf2/shortpiece.exp
@@ -138,7 +138,9 @@ gdb_test "p s2" \
# This test verifies that GDB can print a pieced value casted to a
# different type.
gdb_test "p (int \[\]) s1" " = \\{1, <optimized out>\\}"
-gdb_test "p (short \[\]) s1" " = \\{1, 0, 0, <optimized out>\\}"
+set re_little [string_to_regexp "{1, 0, 0, <optimized out>}"]
+set re_big [string_to_regexp "{0, 1, 0, <optimized out>}"]
+gdb_test {p (short []) s1} " = ($re_little|$re_big)"
# Test for correct output if the size of the original object is not a
# multiple of the array's element size.
--
2.43.0

View File

@@ -0,0 +1,23 @@
Fix gdb.mi/new-ui-mi-sync.exp
---
gdb/testsuite/gdb.mi/new-ui-mi-sync.exp | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/gdb/testsuite/gdb.mi/new-ui-mi-sync.exp b/gdb/testsuite/gdb.mi/new-ui-mi-sync.exp
index 887bd60abcd..18072d4e668 100644
--- a/gdb/testsuite/gdb.mi/new-ui-mi-sync.exp
+++ b/gdb/testsuite/gdb.mi/new-ui-mi-sync.exp
@@ -83,7 +83,11 @@ proc do_test {sync_command} {
# in the separate MI UI. Note the "run" variant usually triggers
# =thread-group-started/=thread-created/=library-loaded as well.
with_spawn_id $gdb_main_spawn_id {
- gdb_test "add-inferior" "Added inferior 2 on connection .*"
+ gdb_test_multiple "add-inferior" "" {
+ -re "\r\nAdded inferior 2 on connection .*\[\r\n\]+$gdb_prompt " {
+ pass $gdb_test_name
+ }
+ }
}
# Interrupt the program.

View File

@@ -0,0 +1,25 @@
From 388654c78086e5240fec47260e47d1deff4af43d Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Thu, 6 Feb 2025 13:27:57 +0100
Subject: [PATCH 43/46] fixup-gdb-6.5-gcore-buffer-limit-test.patch
---
gdb/testsuite/gdb.base/gcore-excessive-memory.exp | 2 ++
1 file changed, 2 insertions(+)
diff --git a/gdb/testsuite/gdb.base/gcore-excessive-memory.exp b/gdb/testsuite/gdb.base/gcore-excessive-memory.exp
index 31cf88ce78a..1ef595923ad 100644
--- a/gdb/testsuite/gdb.base/gcore-excessive-memory.exp
+++ b/gdb/testsuite/gdb.base/gcore-excessive-memory.exp
@@ -14,6 +14,8 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+require can_spawn_for_attach
+
if {[use_gdb_stub]} {
untested "skipping test because of use_gdb_stub"
return -1
--
2.43.0

View File

@@ -0,0 +1,26 @@
From a7d9abecbc24e3d68746ea5b905eba11913980e1 Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Tue, 25 Mar 2025 17:15:01 +0100
Subject: [PATCH 2/2] fixup-gdb-add-rpm-suggestion-script.patch
---
gdb/python/lib/gdb/command/rpm-suggestions.py | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/gdb/python/lib/gdb/command/rpm-suggestions.py b/gdb/python/lib/gdb/command/rpm-suggestions.py
index bb049bc66e7..066ce98d947 100644
--- a/gdb/python/lib/gdb/command/rpm-suggestions.py
+++ b/gdb/python/lib/gdb/command/rpm-suggestions.py
@@ -510,8 +510,7 @@ class rpm_suggestion_build_id_mode(gdb.Parameter):
# The 'info rpm-suggestions' command.
class rpm_suggestion_info(gdb.Command):
- """Relist any RPM installation suggestions that have been made
- since the executable was last changed."""
+ """Relist any RPM installation suggestions that have been made since the executable was last changed."""
def __init__(self):
super().__init__("info rpm-suggestions", gdb.COMMAND_NONE, gdb.COMPLETE_NONE)
--
2.43.0

BIN
gdb-15.2.tar.bz2 (Stored with Git LFS) Normal file

Binary file not shown.

View File

@@ -0,0 +1,268 @@
From FEDORA_PATCHES Mon Sep 17 00:00:00 2001
From: Andrew Cagney <cagney@gnu.org>
Date: Fri, 27 Oct 2017 21:07:50 +0200
Subject: gdb-6.3-gstack-20050411.patch
;; Add a wrapper script to GDB that implements pstack using the
;; --readnever option.
;;=push
2004-11-23 Andrew Cagney <cagney@redhat.com>
* Makefile.in (uninstall-gstack, install-gstack): New rules, add
to install and uninstall.
* gstack.sh, gstack.1: New files.
diff --git a/gdb/Makefile.in b/gdb/Makefile.in
--- a/gdb/Makefile.in
+++ b/gdb/Makefile.in
@@ -2071,7 +2071,7 @@ info install-info clean-info dvi install-dvi pdf install-pdf html install-html:
install: all
@$(MAKE) $(FLAGS_TO_PASS) install-only
-install-only: $(CONFIG_INSTALL)
+install-only: install-gstack $(CONFIG_INSTALL)
transformed_name=`t='$(program_transform_name)'; \
echo gdb | sed -e "$$t"` ; \
if test "x$$transformed_name" = x; then \
@@ -2121,7 +2121,25 @@ install-guile:
install-python:
$(SHELL) $(srcdir)/../mkinstalldirs $(DESTDIR)$(GDB_DATADIR)/python/gdb
-uninstall: force $(CONFIG_UNINSTALL)
+GSTACK=gstack
+.PHONY: install-gstack
+install-gstack:
+ transformed_name=`t='$(program_transform_name)'; \
+ echo $(GSTACK) | sed -e "$$t"` ; \
+ if test "x$$transformed_name" = x; then \
+ transformed_name=$(GSTACK) ; \
+ else \
+ true ; \
+ fi ; \
+ $(SHELL) $(srcdir)/../mkinstalldirs $(DESTDIR)$(bindir) ; \
+ $(INSTALL_PROGRAM) $(srcdir)/$(GSTACK).sh \
+ $(DESTDIR)$(bindir)/$$transformed_name$(EXEEXT) ; \
+ : $(SHELL) $(srcdir)/../mkinstalldirs \
+ $(DESTDIR)$(man1dir) ; \
+ : $(INSTALL_DATA) $(srcdir)/gstack.1 \
+ $(DESTDIR)$(man1dir)/$$transformed_name.1
+
+uninstall: force uninstall-gstack $(CONFIG_UNINSTALL)
transformed_name=`t='$(program_transform_name)'; \
echo gdb | sed -e $$t` ; \
if test "x$$transformed_name" = x; then \
@@ -2152,6 +2170,28 @@ uninstall: force $(CONFIG_UNINSTALL)
rm -f $(DESTDIR)$(bindir)/$$transformed_name
@$(MAKE) DO=uninstall "DODIRS=$(SUBDIRS)" $(FLAGS_TO_PASS) subdir_do
+.PHONY: uninstall-gstack
+uninstall-gstack:
+ transformed_name=`t='$(program_transform_name)'; \
+ echo $(GSTACK) | sed -e $$t` ; \
+ if test "x$$transformed_name" = x; then \
+ transformed_name=$(GSTACK) ; \
+ else \
+ true ; \
+ fi ; \
+ rm -f $(DESTDIR)$(bindir)/$$transformed_name$(EXEEXT) \
+ $(DESTDIR)$(man1dir)/$$transformed_name.1
+
+# The C++ name parser can be built standalone for testing.
+test-cp-name-parser.o: cp-name-parser.c
+ $(COMPILE) -DTEST_CPNAMES cp-name-parser.c
+ $(POSTCOMPILE)
+
+test-cp-name-parser$(EXEEXT): test-cp-name-parser.o $(LIBIBERTY)
+ $(ECHO_CXXLD) $(CC_LD) $(INTERNAL_LDFLAGS) \
+ -o test-cp-name-parser$(EXEEXT) test-cp-name-parser.o \
+ $(LIBIBERTY)
+
# We do this by grepping through sources. If that turns out to be too slow,
# maybe we could just require every .o file to have an initialization routine
# of a given name (top.o -> _initialize_top, etc.).
diff --git a/gdb/gstack.sh b/gdb/gstack.sh
new file mode 100644
--- /dev/null
+++ b/gdb/gstack.sh
@@ -0,0 +1,43 @@
+#!/bin/sh
+
+if test $# -ne 1; then
+ echo "Usage: `basename $0 .sh` <process-id>" 1>&2
+ exit 1
+fi
+
+if test ! -r /proc/$1; then
+ echo "Process $1 not found." 1>&2
+ exit 1
+fi
+
+# GDB doesn't allow "thread apply all bt" when the process isn't
+# threaded; need to peek at the process to determine if that or the
+# simpler "bt" should be used.
+
+backtrace="bt"
+if test -d /proc/$1/task ; then
+ # Newer kernel; has a task/ directory.
+ if test `/bin/ls /proc/$1/task | /usr/bin/wc -l` -gt 1 2>/dev/null ; then
+ backtrace="thread apply all bt"
+ fi
+elif test -f /proc/$1/maps ; then
+ # Older kernel; go by it loading libpthread.
+ if /bin/grep -e libpthread /proc/$1/maps > /dev/null 2>&1 ; then
+ backtrace="thread apply all bt"
+ fi
+fi
+
+GDB=${GDB:-gdb}
+
+# Run GDB, strip out unwanted noise.
+# --readnever is no longer used since .gdb_index is now in use.
+$GDB --quiet -nx $GDBARGS /proc/$1/exe $1 <<EOF 2>&1 |
+set width 0
+set height 0
+set pagination no
+$backtrace
+EOF
+/bin/sed -n \
+ -e 's/^\((gdb) \)*//' \
+ -e '/^#/p' \
+ -e '/^Thread/p'
diff --git a/gdb/testsuite/gdb.base/gstack.c b/gdb/testsuite/gdb.base/gstack.c
new file mode 100644
--- /dev/null
+++ b/gdb/testsuite/gdb.base/gstack.c
@@ -0,0 +1,43 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2005, 2007, 2008, 2009 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+
+void
+func (void)
+{
+ const char msg[] = "looping\n";
+
+ /* Use the most simple notification not to get caught by attach on exiting
+ the function. */
+ write (1, msg, strlen (msg));
+
+ for (;;);
+}
+
+int
+main (void)
+{
+ alarm (60);
+ nice (100);
+
+ func ();
+
+ return 0;
+}
diff --git a/gdb/testsuite/gdb.base/gstack.exp b/gdb/testsuite/gdb.base/gstack.exp
new file mode 100644
--- /dev/null
+++ b/gdb/testsuite/gdb.base/gstack.exp
@@ -0,0 +1,84 @@
+# Copyright (C) 2012 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+set testfile gstack
+set executable ${testfile}
+set binfile [standard_output_file $executable]
+if {[build_executable ${testfile} ${executable} "" {debug}] == -1} {
+ return -1
+}
+
+set test "spawn inferior"
+set command "${binfile}"
+set res [remote_spawn host $command];
+if { $res < 0 || $res == "" } {
+ perror "Spawning $command failed."
+ fail $test
+ return
+}
+
+# The spawn id of the test inferior.
+set test_spawn_id $res
+
+set use_gdb_stub 1
+set pid [exp_pid -i $res]
+gdb_expect {
+ -re "looping\r\n" {
+ pass $test
+ }
+ eof {
+ fail "$test (eof)"
+ return
+ }
+ timeout {
+ fail "$test (timeout)"
+ return
+ }
+}
+
+# Testcase uses the most simple notification not to get caught by attach on
+# exiting the function. Still we could retry the gstack command if we fail.
+
+set test "spawn gstack"
+set command "sh -c GDB=$GDB\\ GDBARGS=-data-directory\\\\\\ $GDB_DATA_DIRECTORY\\ sh\\ ${srcdir}/../gstack.sh\\ $pid\\;echo\\ GSTACK-END"
+set res [remote_spawn host $command];
+if { $res < 0 || $res == "" } {
+ perror "Spawning $command failed."
+ fail $test
+}
+
+set gdb_spawn_id $res
+
+gdb_test_multiple "" $test {
+ -re "^#0 +(0x\[0-9a-f\]+ in )?\\.?func \\(\\) at \[^\r\n\]*\r\n#1 +0x\[0-9a-f\]+ in \\.?main \\(\\) at \[^\r\n\]*\r\nGSTACK-END\r\n\$" {
+ pass $test
+ }
+}
+
+gdb_test_multiple "" "gstack exits" {
+ eof {
+ set result [wait -i $gdb_spawn_id]
+ verbose $result
+
+ gdb_assert { [lindex $result 2] == 0 } "gstack exits with no error"
+ gdb_assert { [lindex $result 3] == 0 } "gstack's exit status is 0"
+
+ remote_close host
+ clear_gdb_spawn_id
+ }
+}
+
+# Kill the test inferior.
+kill_wait_spawned_process $test_spawn_id

View File

@@ -0,0 +1,247 @@
From FEDORA_PATCHES Mon Sep 17 00:00:00 2001
From: Fedora GDB patches <invalid@email.com>
Date: Fri, 27 Oct 2017 21:07:50 +0200
Subject: gdb-6.3-mapping-zero-inode-test.patch
;; Test GCORE for shmid 0 shared memory mappings.
;;=fedoratest: But it is broken anyway, sometimes the case being tested is not reproducible.
diff --git a/gdb/testsuite/gdb.base/gcore-shmid0.c b/gdb/testsuite/gdb.base/gcore-shmid0.c
new file mode 100644
--- /dev/null
+++ b/gdb/testsuite/gdb.base/gcore-shmid0.c
@@ -0,0 +1,128 @@
+/* Copyright 2007, 2009 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or (at
+ your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+/*
+ * Test GDB's handling of gcore for mapping with a name but zero inode.
+ */
+
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#include <stdio.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <assert.h>
+#include <time.h>
+
+/* The same test running in a parallel testsuite may steal us the zero SID,
+ even if we never get any EEXIST. Just try a while. */
+
+#define TIMEOUT_SEC 10
+
+static volatile int v;
+
+static void
+initialized (void)
+{
+ v++;
+}
+
+static void
+unresolved (void)
+{
+ v++;
+}
+
+int
+main (void)
+{
+ int sid;
+ unsigned int *addr = (void *) -1L;
+ int attempt, round = 0;
+ time_t ts_start, ts;
+
+ if (time (&ts_start) == (time_t) -1)
+ {
+ printf ("time (): %m\n");
+ exit (1);
+ }
+
+ /* The generated SID will cycle with an increment of 32768, attempt until it
+ * wraps to 0. */
+
+ for (attempt = 0; addr == (void *) -1L; attempt++)
+ {
+ /* kernel-2.6.25-8.fc9.x86_64 just never returns the value 0 by
+ shmget(2). shmget returns SID range 0..1<<31 in steps of 32768,
+ 0x1000 should be enough but wrap the range it to be sure. */
+
+ if (attempt > 0x21000)
+ {
+ if (time (&ts) == (time_t) -1)
+ {
+ printf ("time (): %m\n");
+ exit (1);
+ }
+
+ if (ts >= ts_start && ts < ts_start + TIMEOUT_SEC)
+ {
+ attempt = 0;
+ round++;
+ continue;
+ }
+
+ printf ("Problem is not reproducible on this kernel (attempt %d, "
+ "round %d)\n", attempt, round);
+ unresolved ();
+ exit (1);
+ }
+
+ sid = shmget ((key_t) rand (), 0x1000, IPC_CREAT | IPC_EXCL | 0777);
+ if (sid == -1)
+ {
+ if (errno == EEXIST)
+ continue;
+
+ printf ("shmget (%d, 0x1000, IPC_CREAT): errno %d\n", 0, errno);
+ exit (1);
+ }
+
+ /* Use SID only if it is 0, retry it otherwise. */
+
+ if (sid == 0)
+ {
+ addr = shmat (sid, NULL, SHM_RND);
+ if (addr == (void *) -1L)
+ {
+ printf ("shmat (%d, NULL, SHM_RND): errno %d\n", sid,
+ errno);
+ exit (1);
+ }
+ }
+ if (shmctl (sid, IPC_RMID, NULL) != 0)
+ {
+ printf ("shmctl (%d, IPC_RMID, NULL): errno %d\n", sid, errno);
+ exit (1);
+ }
+ }
+
+ initialized ();
+
+ return 0;
+}
diff --git a/gdb/testsuite/gdb.base/gcore-shmid0.exp b/gdb/testsuite/gdb.base/gcore-shmid0.exp
new file mode 100644
--- /dev/null
+++ b/gdb/testsuite/gdb.base/gcore-shmid0.exp
@@ -0,0 +1,101 @@
+# Copyright 2007, 2009 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+# Test GDB's handling of gcore for mapping with a name but zero inode.
+
+if { [prepare_for_testing gcore-shmid0.exp gcore-shmid0] } {
+ return -1
+}
+
+# Does this gdb support gcore?
+set test "help gcore"
+gdb_test_multiple $test $test {
+ -re "Undefined command: .gcore.*$gdb_prompt $" {
+ # gcore command not supported -- nothing to test here.
+ unsupported "gdb does not support gcore on this target"
+ return -1;
+ }
+ -re "Save a core file .*$gdb_prompt $" {
+ pass $test
+ }
+}
+
+if { ! [ runto_main ] } then {
+ untested gcore-shmid0.exp
+ return -1
+}
+
+gdb_breakpoint "initialized"
+gdb_breakpoint "unresolved"
+
+set oldtimeout $timeout
+set timeout [expr $oldtimeout + 120]
+
+set test "Continue to initialized."
+gdb_test_multiple "continue" $test {
+ -re "Breakpoint .*, initialized .* at .*\r\n$gdb_prompt $" {
+ pass $test
+ }
+ -re "Breakpoint .*, unresolved .* at .*\r\n$gdb_prompt $" {
+ set timeout $oldtimeout
+ unsupported $test
+ return -1
+ }
+}
+set timeout $oldtimeout
+
+set escapedfilename [string_to_regexp [standard_output_file gcore-shmid0.test]]
+
+set test "save a corefile"
+gdb_test_multiple "gcore [standard_output_file gcore-shmid0.test]" $test {
+ -re "Saved corefile ${escapedfilename}\[\r\n\]+$gdb_prompt $" {
+ pass $test
+ }
+ -re "Can't create a corefile\[\r\n\]+$gdb_prompt $" {
+ unsupported $test
+ }
+}
+
+# Be sure to remove the handle first.
+# But it would get removed even on a kill by GDB as the handle is already
+# deleted, just it is still attached.
+gdb_continue_to_end "finish"
+
+set test "core-file command"
+gdb_test_multiple "core-file [standard_output_file gcore-shmid0.test]" $test {
+ -re ".* program is being debugged already.*y or n. $" {
+ # gdb_load may connect us to a gdbserver.
+ send_gdb "y\n"
+ exp_continue;
+ }
+ -re "Core was generated by .*\r\n\#0 .*\\\(\\\).*\r\n$gdb_prompt $" {
+ # The filename does not fit there anyway so do not check it.
+ pass $test
+ }
+ -re ".*registers from core file: File in wrong format.* $" {
+ fail "core-file command (could not read registers from core file)"
+ }
+}
+
+set test "backtrace"
+gdb_test_multiple "bt" $test {
+ -re "#0 *initialized \\\(\\\) at .*#1 .* main \\\(.*$gdb_prompt $" {
+ pass $test
+ }
+ -re "#0 *initialized \\\(\\\) at .*Cannot access memory at address .*$gdb_prompt $" {
+ fail $test
+ }
+}

View File

@@ -0,0 +1,107 @@
From FEDORA_PATCHES Mon Sep 17 00:00:00 2001
From: Fedora GDB patches <invalid@email.com>
Date: Fri, 27 Oct 2017 21:07:50 +0200
Subject: gdb-6.5-bz218379-ppc-solib-trampoline-test.patch
;; Test sideeffects of skipping ppc .so libs trampolines (BZ 218379).
;;=fedoratest
https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=218379
diff --git a/gdb/testsuite/gdb.base/step-over-trampoline.c b/gdb/testsuite/gdb.base/step-over-trampoline.c
new file mode 100644
--- /dev/null
+++ b/gdb/testsuite/gdb.base/step-over-trampoline.c
@@ -0,0 +1,28 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2006 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Please email any bugs, comments, and/or additions to this file to:
+ bug-gdb@prep.ai.mit.edu */
+
+#include <stdio.h>
+
+int main (void)
+{
+ puts ("hello world");
+ return 0;
+}
diff --git a/gdb/testsuite/gdb.base/step-over-trampoline.exp b/gdb/testsuite/gdb.base/step-over-trampoline.exp
new file mode 100644
--- /dev/null
+++ b/gdb/testsuite/gdb.base/step-over-trampoline.exp
@@ -0,0 +1,59 @@
+# Copyright 2006 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+if {[use_gdb_stub]} {
+ untested "skipping test because of use_gdb_stub"
+ return -1
+}
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+set testfile step-over-trampoline
+set srcfile ${testfile}.c
+set binfile [standard_output_file ${testfile}]
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
+ untested "Couldn't compile test program"
+ return -1
+}
+
+# Get things started.
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+# For C programs, "start" should stop in main().
+
+gdb_test "start" \
+ "main \\(\\) at .*$srcfile.*" \
+ "start"
+
+# main () at hello2.c:5
+# 5 puts("hello world\n");
+# (gdb) next
+# 0x100007e0 in call___do_global_ctors_aux ()
+
+gdb_test_multiple "next" "invalid `next' output" {
+ -re "\nhello world.*return 0;.*" {
+ pass "stepped over"
+ }
+ -re " in call___do_global_ctors_aux \\(\\).*" {
+ fail "stepped into trampoline"
+ }
+}

View File

@@ -0,0 +1,154 @@
From FEDORA_PATCHES Mon Sep 17 00:00:00 2001
From: Fedora GDB patches <invalid@email.com>
Date: Fri, 27 Oct 2017 21:07:50 +0200
Subject: gdb-6.5-gcore-buffer-limit-test.patch
;; Test gcore memory and time requirements for large inferiors.
;;=fedoratest
diff --git a/gdb/testsuite/gdb.base/gcore-excessive-memory.c b/gdb/testsuite/gdb.base/gcore-excessive-memory.c
new file mode 100644
--- /dev/null
+++ b/gdb/testsuite/gdb.base/gcore-excessive-memory.c
@@ -0,0 +1,37 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2008 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Please email any bugs, comments, and/or additions to this file to:
+ bug-gdb@prep.ai.mit.edu */
+
+#include <unistd.h>
+#include <stdlib.h>
+
+#define MEGS 64
+
+int main()
+{
+ void *mem;
+
+ mem = malloc (MEGS * 1024ULL * 1024ULL);
+
+ for (;;)
+ sleep (1);
+
+ return 0;
+}
diff --git a/gdb/testsuite/gdb.base/gcore-excessive-memory.exp b/gdb/testsuite/gdb.base/gcore-excessive-memory.exp
new file mode 100644
--- /dev/null
+++ b/gdb/testsuite/gdb.base/gcore-excessive-memory.exp
@@ -0,0 +1,99 @@
+# Copyright 2008 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+if {[use_gdb_stub]} {
+ untested "skipping test because of use_gdb_stub"
+ return -1
+}
+
+set testfile gcore-excessive-memory
+set srcfile ${testfile}.c
+set shfile [standard_output_file ${testfile}-gdb.sh]
+set corefile [standard_output_file ${testfile}.core]
+set binfile [standard_output_file ${testfile}]
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
+ untested "Couldn't compile test program"
+ return -1
+}
+
+set f [open "|getconf PAGESIZE" "r"]
+gets $f pagesize
+close $f
+
+set pid_of_bin [eval exec $binfile &]
+sleep 2
+
+# Get things started.
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+set pid_of_gdb [exp_pid -i [board_info host fileid]]
+
+gdb_test "attach $pid_of_bin" "Attaching to .*" "attach"
+gdb_test "up 99" "in main .*" "verify we can get to main"
+
+proc memory_v_pages_get {} {
+ global pid_of_gdb pagesize
+ set fd [open "/proc/$pid_of_gdb/statm"]
+ gets $fd line
+ close $fd
+ # number of pages of virtual memory
+ scan $line "%d" drs
+ return $drs
+}
+
+set pages_found [memory_v_pages_get]
+
+# It must be definitely less than `MEGS' of `gcore-excessive-memory.c'.
+set mb_gcore_reserve 4
+verbose -log "pages_found = $pages_found, mb_gcore_reserve = $mb_gcore_reserve"
+set kb_found [expr $pages_found * $pagesize / 1024]
+set kb_permit [expr $kb_found + 1 * 1024 + $mb_gcore_reserve * 1024]
+verbose -log "kb_found = $kb_found, kb_permit = $kb_permit"
+
+# Create the ulimit wrapper.
+set f [open $shfile "w"]
+puts $f "#! /bin/sh"
+puts $f "ulimit -v $kb_permit"
+puts $f "exec $GDB \"\$@\""
+close $f
+remote_exec host "chmod +x $shfile"
+
+gdb_exit
+set GDBold $GDB
+set GDB "$shfile"
+gdb_start
+set GDB $GDBold
+
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+set pid_of_gdb [exp_pid -i [board_info host fileid]]
+
+gdb_test "attach $pid_of_bin" "Attaching to .*" "attach"
+gdb_test "up 99" "in main .*" "verify we can get to main"
+
+verbose -log "kb_found before gcore = [expr [memory_v_pages_get] * $pagesize / 1024]"
+
+gdb_test "gcore $corefile" "Saved corefile \[^\n\r\]*" "Save the core file"
+
+verbose -log "kb_found after gcore = [expr [memory_v_pages_get] * $pagesize / 1024]"
+
+# Cleanup.
+exec kill -9 $pid_of_bin

View File

@@ -0,0 +1,40 @@
From 4aaa960916b069dd82a293bf0e876dbc8710801e Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Wed, 26 Mar 2025 10:25:38 +0100
Subject: [PATCH 4/4] gdb-6.6-buildid-locate-tests-suse.patch
---
...z981154-misleading-yum-install-warning.exp | 20 ++++++++++++++++---
1 file changed, 17 insertions(+), 3 deletions(-)
diff --git a/gdb/testsuite/gdb.base/rhbz981154-misleading-yum-install-warning.exp b/gdb/testsuite/gdb.base/rhbz981154-misleading-yum-install-warning.exp
index 991ffef474d..ab5f1667f31 100644
--- a/gdb/testsuite/gdb.base/rhbz981154-misleading-yum-install-warning.exp
+++ b/gdb/testsuite/gdb.base/rhbz981154-misleading-yum-install-warning.exp
@@ -55,6 +55,20 @@ gdb_test "set build-id-verbose 1" "" \
gdb_test "set debug-file-directory /usr/lib/" "" \
"set debug-file-directory"
-gdb_test "core-file [standard_output_file gcore.test]" \
- "Missing file\\(s\\), try: dnf --enablerepo='\\*debug\\*' install [string_to_regexp /usr/lib/$build_id_without_debug] [string_to_regexp /usr/lib/debug/$build_id_debug_file]" \
- "test first yum/dnf warning"
+# Supporting this for SUSE/openSUSE requires a gdb.missing_objfile handler,
+# but that's not enabled. Zypper doesn't support finding packages based on
+# build-id, unless the package's installed.
+# So, instead of testing for the SUSE/openSUSE-specific solution, check that
+# the fedora solution doesn't appear.
+
+set cmd "core-file [standard_output_file gcore.test]"
+set test "test first yum/dnf warning"
+set fail_re [string_to_regexp "Missing file(s), try: dnf "].*
+gdb_test_multiple $cmd $test {
+ -re -wrap $fail_re {
+ fail $gdb_test_name
+ }
+ -re -wrap "" {
+ pass $gdb_test_name
+ }
+}
--
2.43.0

View File

@@ -0,0 +1,237 @@
From FEDORA_PATCHES Mon Sep 17 00:00:00 2001
From: Fedora GDB patches <invalid@email.com>
Date: Fri, 27 Oct 2017 21:07:50 +0200
Subject: gdb-6.6-buildid-locate-tests.patch
;; Tests and test updates related to the rpm suggestion feature.
diff --git a/gdb/testsuite/gdb.base/gcore-buildid-exec-but-not-solib-lib.c b/gdb/testsuite/gdb.base/gcore-buildid-exec-but-not-solib-lib.c
new file mode 100644
--- /dev/null
+++ b/gdb/testsuite/gdb.base/gcore-buildid-exec-but-not-solib-lib.c
@@ -0,0 +1,21 @@
+/* Copyright 2010 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+void
+lib (void)
+{
+}
diff --git a/gdb/testsuite/gdb.base/gcore-buildid-exec-but-not-solib-main.c b/gdb/testsuite/gdb.base/gcore-buildid-exec-but-not-solib-main.c
new file mode 100644
--- /dev/null
+++ b/gdb/testsuite/gdb.base/gcore-buildid-exec-but-not-solib-main.c
@@ -0,0 +1,25 @@
+/* Copyright 2010 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+extern void lib (void);
+
+int
+main (void)
+{
+ lib ();
+ return 0;
+}
diff --git a/gdb/testsuite/gdb.base/gcore-buildid-exec-but-not-solib.exp b/gdb/testsuite/gdb.base/gcore-buildid-exec-but-not-solib.exp
new file mode 100644
--- /dev/null
+++ b/gdb/testsuite/gdb.base/gcore-buildid-exec-but-not-solib.exp
@@ -0,0 +1,104 @@
+# Copyright 2016 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+require allow_shlib_tests
+
+set testfile "gcore-buildid-exec-but-not-solib"
+set srcmainfile ${testfile}-main.c
+set srclibfile ${testfile}-lib.c
+set libfile [standard_output_file ${testfile}-lib.so]
+set objfile [standard_output_file ${testfile}-main.o]
+set executable ${testfile}-main
+set binfile [standard_output_file ${executable}]
+set gcorefile [standard_output_file ${executable}.gcore]
+set outdir [file dirname $binfile]
+
+if { [gdb_compile_shlib ${srcdir}/${subdir}/${srclibfile} ${libfile} "debug additional_flags=-Wl,--build-id"] != ""
+ || [gdb_compile ${srcdir}/${subdir}/${srcmainfile} ${objfile} object {debug}] != "" } {
+ unsupported "-Wl,--build-id compilation failed"
+ return -1
+}
+set opts [list debug shlib=${libfile} "additional_flags=-Wl,--build-id"]
+if { [gdb_compile ${objfile} ${binfile} executable $opts] != "" } {
+ unsupported "-Wl,--build-id compilation failed"
+ return -1
+}
+
+clean_restart $executable
+gdb_load_shlib $libfile
+
+# Does this gdb support gcore?
+set test "help gcore"
+gdb_test_multiple $test $test {
+ -re "Undefined command: .gcore.*\r\n$gdb_prompt $" {
+ # gcore command not supported -- nothing to test here.
+ unsupported "gdb does not support gcore on this target"
+ return -1;
+ }
+ -re "Save a core file .*\r\n$gdb_prompt $" {
+ pass $test
+ }
+}
+
+if { ![runto lib] } then {
+ return -1
+}
+
+set escapedfilename [string_to_regexp ${gcorefile}]
+
+set test "save a corefile"
+gdb_test_multiple "gcore ${gcorefile}" $test {
+ -re "Saved corefile ${escapedfilename}\r\n$gdb_prompt $" {
+ pass $test
+ }
+ -re "Can't create a corefile\r\n$gdb_prompt $" {
+ unsupported $test
+ return -1
+ }
+}
+
+# Now restart gdb and load the corefile.
+
+clean_restart $executable
+gdb_load_shlib $libfile
+
+set buildid [build_id_debug_filename_get $libfile]
+
+regsub {\.debug$} $buildid {} buildid
+
+set debugdir [standard_output_file ${testfile}-debugdir]
+file delete -force -- $debugdir
+
+file mkdir $debugdir/[file dirname $libfile]
+file copy $libfile $debugdir/${libfile}
+
+file mkdir $debugdir/[file dirname $buildid]
+file copy $libfile $debugdir/${buildid}
+
+remote_exec build "ln -s /lib ${debugdir}/"
+remote_exec build "ln -s /lib64 ${debugdir}/"
+# /usr is not needed, all the libs are in /lib64: libm.so.6 libc.so.6 ld-linux-x86-64.so.2
+
+gdb_test_no_output "set solib-absolute-prefix $debugdir" \
+ "set solib-absolute-prefix"
+
+gdb_test_no_output "set debug-file-directory $debugdir" "set debug-file-directory"
+
+gdb_test "core ${gcorefile}" "Core was generated by .*" "re-load generated corefile"
+
+gdb_test "frame" "#0 \[^\r\n\]* lib .*" "library got loaded"
+
+gdb_test "bt"
+gdb_test "info shared"
diff --git a/gdb/testsuite/gdb.base/rhbz981154-misleading-yum-install-warning.exp b/gdb/testsuite/gdb.base/rhbz981154-misleading-yum-install-warning.exp
new file mode 100644
--- /dev/null
+++ b/gdb/testsuite/gdb.base/rhbz981154-misleading-yum-install-warning.exp
@@ -0,0 +1,60 @@
+# Copyright (C) 2014 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# Create a core file, then hide the executable. Restart GDB and load
+# the core file. Check GDB gives a message suggesting a 'dnf' command
+# to try and install the executable based on its build-id.
+
+standard_testfile "normal.c"
+
+if { [prepare_for_testing ${testfile}.exp ${testfile} ${srcfile}] } {
+ return -1
+}
+
+# Get the build-id of the file.
+set build_id_debug_file [build_id_debug_filename_get $binfile]
+regsub -all ".debug$" $build_id_debug_file "" build_id_without_debug
+
+# Run to main.
+if { ![runto_main] } {
+ return -1
+}
+
+# We first need to generate a corefile.
+set corefilename "[standard_output_file gcore.test]"
+if { ![gdb_gcore_cmd "$corefilename" "save corefile"] } {
+ untested "could not generate a corefile"
+ return -1
+}
+
+# Move the binfile to a temporary name.
+remote_exec build "mv $binfile ${binfile}.old"
+
+# Reinitialize GDB and see if we get a dnf suggestion.
+clean_restart
+
+gdb_test "set build-id-verbose 1" "" \
+ "set build-id-verbose"
+
+# GDB only makes build-id based RPM suggestions if /usr/lib is in
+# the debug-file-directory list, the reason being that system RPMs
+# will always install under this location. If GDB is not looking
+# here then there's no point making suggestions.
+gdb_test "set debug-file-directory /usr/lib/" "" \
+ "set debug-file-directory"
+
+gdb_test "core-file [standard_output_file gcore.test]" \
+ "Missing file\\(s\\), try: dnf --enablerepo='\\*debug\\*' install [string_to_regexp /usr/lib/$build_id_without_debug] [string_to_regexp /usr/lib/debug/$build_id_debug_file]" \
+ "test first yum/dnf warning"

View File

@@ -0,0 +1,278 @@
From FEDORA_PATCHES Mon Sep 17 00:00:00 2001
From: Jan Kratochvil <jan.kratochvil@redhat.com>
Date: Fri, 27 Oct 2017 21:07:50 +0200
Subject: gdb-6.6-bz237572-ppc-atomic-sequence-test.patch
;; Support for stepping over PPC atomic instruction sequences (BZ 237572).
;;=fedoratest
2007-06-25 Jan Kratochvil <jan.kratochvil@redhat.com>
* gdb.threads/atomic-seq-threaded.c,
gdb.threads/atomic-seq-threaded.exp: New files.
diff --git a/gdb/testsuite/gdb.threads/atomic-seq-threaded.c b/gdb/testsuite/gdb.threads/atomic-seq-threaded.c
new file mode 100644
--- /dev/null
+++ b/gdb/testsuite/gdb.threads/atomic-seq-threaded.c
@@ -0,0 +1,171 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2007 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+/* Test stepping over RISC atomic sequences.
+ This variant testcases the code for stepping another thread while skipping
+ over the atomic sequence in the former thread
+ (STEPPING_PAST_SINGLESTEP_BREAKPOINT).
+ Code comes from gcc/testsuite/gcc.dg/sync-2.c */
+
+/* { dg-options "-march=i486" { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */
+/* { dg-options "-mcpu=v9" { target sparc*-*-* } } */
+
+/* Test functionality of the intrinsics for 'short' and 'char'. */
+
+#include <stdlib.h>
+#include <string.h>
+#include <pthread.h>
+#include <assert.h>
+#include <unistd.h>
+
+#define LOOPS 2
+
+static int unused;
+
+static char AI[18];
+static char init_qi[18] = { 3,5,7,9,0,0,0,0,-1,0,0,0,0,0,-1,0,0,0 };
+static char test_qi[18] = { 3,5,7,9,1,4,22,-12,7,8,9,7,1,-12,7,8,9,7 };
+
+static void
+do_qi (void)
+{
+ if (__sync_fetch_and_add(AI+4, 1) != 0)
+ abort ();
+ if (__sync_fetch_and_add(AI+5, 4) != 0)
+ abort ();
+ if (__sync_fetch_and_add(AI+6, 22) != 0)
+ abort ();
+ if (__sync_fetch_and_sub(AI+7, 12) != 0)
+ abort ();
+ if (__sync_fetch_and_and(AI+8, 7) != (char)-1)
+ abort ();
+ if (__sync_fetch_and_or(AI+9, 8) != 0)
+ abort ();
+ if (__sync_fetch_and_xor(AI+10, 9) != 0)
+ abort ();
+ if (__sync_fetch_and_nand(AI+11, 7) != 0)
+ abort ();
+
+ if (__sync_add_and_fetch(AI+12, 1) != 1)
+ abort ();
+ if (__sync_sub_and_fetch(AI+13, 12) != (char)-12)
+ abort ();
+ if (__sync_and_and_fetch(AI+14, 7) != 7)
+ abort ();
+ if (__sync_or_and_fetch(AI+15, 8) != 8)
+ abort ();
+ if (__sync_xor_and_fetch(AI+16, 9) != 9)
+ abort ();
+ if (__sync_nand_and_fetch(AI+17, 7) != 7)
+ abort ();
+}
+
+static short AL[18];
+static short init_hi[18] = { 3,5,7,9,0,0,0,0,-1,0,0,0,0,0,-1,0,0,0 };
+static short test_hi[18] = { 3,5,7,9,1,4,22,-12,7,8,9,7,1,-12,7,8,9,7 };
+
+static void
+do_hi (void)
+{
+ if (__sync_fetch_and_add(AL+4, 1) != 0)
+ abort ();
+ if (__sync_fetch_and_add(AL+5, 4) != 0)
+ abort ();
+ if (__sync_fetch_and_add(AL+6, 22) != 0)
+ abort ();
+ if (__sync_fetch_and_sub(AL+7, 12) != 0)
+ abort ();
+ if (__sync_fetch_and_and(AL+8, 7) != -1)
+ abort ();
+ if (__sync_fetch_and_or(AL+9, 8) != 0)
+ abort ();
+ if (__sync_fetch_and_xor(AL+10, 9) != 0)
+ abort ();
+ if (__sync_fetch_and_nand(AL+11, 7) != 0)
+ abort ();
+
+ if (__sync_add_and_fetch(AL+12, 1) != 1)
+ abort ();
+ if (__sync_sub_and_fetch(AL+13, 12) != -12)
+ abort ();
+ if (__sync_and_and_fetch(AL+14, 7) != 7)
+ abort ();
+ if (__sync_or_and_fetch(AL+15, 8) != 8)
+ abort ();
+ if (__sync_xor_and_fetch(AL+16, 9) != 9)
+ abort ();
+ if (__sync_nand_and_fetch(AL+17, 7) != 7)
+ abort ();
+}
+
+static void *
+start1 (void *arg)
+{
+ unsigned loop;
+ sleep(1);
+
+ for (loop = 0; loop < LOOPS; loop++)
+ {
+ memcpy(AI, init_qi, sizeof(init_qi));
+
+ do_qi ();
+
+ if (memcmp (AI, test_qi, sizeof(test_qi)))
+ abort ();
+ }
+
+ return arg; /* _delete1_ */
+}
+
+static void *
+start2 (void *arg)
+{
+ unsigned loop;
+
+ for (loop = 0; loop < LOOPS; loop++)
+ {
+ memcpy(AL, init_hi, sizeof(init_hi));
+
+ do_hi ();
+
+ if (memcmp (AL, test_hi, sizeof(test_hi)))
+ abort ();
+ }
+
+ return arg; /* _delete2_ */
+}
+
+int
+main (int argc, char **argv)
+{
+ pthread_t thread;
+ int i;
+
+ i = pthread_create (&thread, NULL, start1, NULL); /* _create_ */
+ assert (i == 0); /* _create_after_ */
+
+ sleep (1);
+
+ start2 (NULL);
+
+ i = pthread_join (thread, NULL); /* _delete_ */
+ assert (i == 0);
+
+ return 0; /* _exit_ */
+}
diff --git a/gdb/testsuite/gdb.threads/atomic-seq-threaded.exp b/gdb/testsuite/gdb.threads/atomic-seq-threaded.exp
new file mode 100644
--- /dev/null
+++ b/gdb/testsuite/gdb.threads/atomic-seq-threaded.exp
@@ -0,0 +1,84 @@
+# atomic-seq-threaded.exp -- Test case for stepping over RISC atomic code seqs.
+# This variant testcases the code for stepping another thread while skipping
+# over the atomic sequence in the former thread
+# (STEPPING_PAST_SINGLESTEP_BREAKPOINT).
+# Copyright (C) 2007 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+set testfile atomic-seq-threaded
+set srcfile ${testfile}.c
+set binfile [standard_output_file ${testfile}]
+
+foreach opts {{} {compiler=gcc4} {FAIL}} {
+ if {$opts eq "FAIL"} {
+ return -1
+ }
+ if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable [list debug $opts]] eq "" } {
+ break
+ }
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+
+gdb_load ${binfile}
+if ![runto_main] then {
+ fail "Can't run to main"
+ return 0
+}
+
+# pthread_create () will not pass even on x86_64 with software watchpoint.
+# Pass after pthread_create () without any watchpoint active.
+set line [gdb_get_line_number "_create_after_"]
+gdb_test "tbreak $line" \
+ "reakpoint (\[0-9\]+) at .*$srcfile, line $line\..*" \
+ "set breakpoint after pthread_create ()"
+gdb_test "c" \
+ ".*/\\* _create_after_ \\*/.*" \
+ "run till after pthread_create ()"
+
+# Without a watchpoint being software no single-stepping would be used.
+set test "Start (software) watchpoint"
+gdb_test_multiple "watch unused" $test {
+ -re "Watchpoint \[0-9\]+: unused.*$gdb_prompt $" {
+ pass $test
+ }
+ -re "Hardware watchpoint \[0-9\]+: unused.*$gdb_prompt $" {
+ # We do not test the goal but still the whole testcase should pass.
+ unsupported $test
+ }
+}
+
+# More thorough testing of the scheduling logic.
+gdb_test "set scheduler-locking step" ""
+
+# Critical code path is stepped through at this point.
+set line [gdb_get_line_number "_exit_"]
+gdb_test "tbreak $line" \
+ "reakpoint \[0-9\]+ at .*$srcfile, line $line\..*" \
+ "set breakpoint at _exit_"
+gdb_test "c" \
+ ".*/\\* _exit_ \\*/.*" \
+ "run till _exit_"
+
+# Just a nonproblematic program exit.
+gdb_test "c" \
+ ".*Program exited normally\\..*" \
+ "run till program exit"

View File

@@ -0,0 +1,68 @@
From FEDORA_PATCHES Mon Sep 17 00:00:00 2001
From: Andrew Burgess <aburgess@redhat.com>
Date: Tue, 19 Nov 2024 13:56:56 +0000
Subject: gdb-add-deprecated-settings-py-script.patch
;; Not a backport. Add a new script which defines a setting which is
;; deprecated, but we don't want to remove it from Fedora GDB just yet.
gdb: add script which defines a deprecated settings
The build-id-core-load setting has not been useful since 2020, but its
not clear when it will be OK to remove this from GDB.
Rather than defining this setting in C++ code, lets just create it
using this Python script, this helps keep the Fedora stuff out of core
GDB.
diff --git a/gdb/data-directory/Makefile.in b/gdb/data-directory/Makefile.in
--- a/gdb/data-directory/Makefile.in
+++ b/gdb/data-directory/Makefile.in
@@ -86,6 +86,7 @@ PYTHON_FILE_LIST = \
gdb/unwinder.py \
gdb/xmethod.py \
gdb/command/__init__.py \
+ gdb/command/deprecated-settings.py \
gdb/command/explore.py \
gdb/command/frame_filters.py \
gdb/command/missing_files.py \
diff --git a/gdb/python/lib/gdb/command/deprecated-settings.py b/gdb/python/lib/gdb/command/deprecated-settings.py
new file mode 100644
--- /dev/null
+++ b/gdb/python/lib/gdb/command/deprecated-settings.py
@@ -0,0 +1,35 @@
+import gdb
+
+# This setting was added to Fedora GDB back in 2007. It controlled
+# whether GDB would use the build-id extracted from a core file to
+# auto-load the executable if the user had not already loaded an
+# executable.
+#
+# In 2020 this setting was effectively deprecated as the only use of
+# the setting's value was removed. After this GDB would always
+# auto-load an executable based on the build-id if no executable was
+# already loaded.
+#
+# For now we maintain this setting for backward compatibility reasons.
+
+class build_id_core_load(gdb.Parameter):
+ """This setting is deprecated. Changing it will have no effect.
+ This is maintained only for backwards compatibility.
+
+ When opening a core-file, and no executable is loaded, GDB will
+ always try to auto-load a suitable executable using the build-id
+ extracted from the core file (if a suitable build-id can be
+ found)."""
+
+ def __init__(self):
+ self.set_doc = "This setting is deprecated and has no effect."
+ self.show_doc = "This setting is deprecated and has no effect."
+ self.value = True
+
+ super().__init__("build-id-core-load", gdb.COMMAND_DATA, gdb.PARAM_BOOLEAN)
+ def validate(self):
+ return True
+ def get_set_string(self):
+ raise gdb.GdbError("The 'build-id-core-load' setting is deprecated.")
+
+build_id_core_load()

View File

@@ -0,0 +1,21 @@
[gdb-add-index.sh] Fix bashism
---
gdb/contrib/gdb-add-index.sh | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/gdb/contrib/gdb-add-index.sh b/gdb/contrib/gdb-add-index.sh
index 734110caa3b..00d3ae8b0ae 100755
--- a/gdb/contrib/gdb-add-index.sh
+++ b/gdb/contrib/gdb-add-index.sh
@@ -38,7 +38,9 @@ fi
file="$1"
if test -L "$file"; then
- if ! command -v readlink >/dev/null 2>&1; then
+ target=$(readlink "$file")
+ st=$?
+ if [ $st -eq 127 ]; then
echo "$myname: 'readlink' missing. Failed to follow symlink $1." 1>&2
exit 1
fi

View File

@@ -0,0 +1,40 @@
From 423c53757e2fe22815fef8a04abf21caff951937 Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Tue, 25 Mar 2025 14:12:51 +0100
Subject: [PATCH 1/4] [distro] Update gdb-add-rpm-suggestion-script.patch for
SUSE
---
gdb/python/lib/gdb/command/rpm-suggestions.py | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/gdb/python/lib/gdb/command/rpm-suggestions.py b/gdb/python/lib/gdb/command/rpm-suggestions.py
index 156fce0672b..f1034070989 100644
--- a/gdb/python/lib/gdb/command/rpm-suggestions.py
+++ b/gdb/python/lib/gdb/command/rpm-suggestions.py
@@ -358,7 +358,7 @@ else:
# Take a non-empty list of RPM names and print a command line a
# user could run to install these RPMs.
def print_rpm_suggestions(rpm_name_list):
- print("Missing rpms, try: dnf --enablerepo='*debug*' install " + ' '.join(rpm_name_list))
+ print("Missing separate debuginfos, use: zypper install " + ' '.join(rpm_name_list))
# Take a non-empty list of build-id strings and print a series of
# lines that a user could run to instll the RPMs that provide
@@ -423,7 +423,10 @@ else:
# Register the missing debug and missing objfile handlers with GDB.
gdb.missing_debug.register_handler(None, RPM_MissingDebugHandler())
- gdb.missing_objfile.register_handler(None, RPM_MissingObjfileHandler())
+
+ # Not enabled for SUSE/openSUSE. Zypper doesn't support finding packages
+ # based on build-id, unless the package's installed.
+ #gdb.missing_objfile.register_handler(None, RPM_MissingObjfileHandler())
# Implement the core of 'info rpm-suggestions'. Reprint all rpm
# suggestions.
base-commit: 956ad1d51aa6e4117a98c4124bd7154a1aaeec55
--
2.43.0

View File

@@ -0,0 +1,806 @@
From FEDORA_PATCHES Mon Sep 17 00:00:00 2001
From: Andrew Burgess <aburgess@redhat.com>
Date: Thu, 7 Mar 2024 15:14:23 +0000
Subject: gdb-add-rpm-suggestion-script.patch
;; Not a backport. Add a new script which hooks into GDB and suggests
;; RPMs to install when GDB finds an objfile with no debug info.
gdb: add script which will suggest debuginfo RPMs to install
This script hooks into GDB's missing debug info Python API and
suggests debuginfo RPMs to install.
diff --git a/gdb/data-directory/Makefile.in b/gdb/data-directory/Makefile.in
--- a/gdb/data-directory/Makefile.in
+++ b/gdb/data-directory/Makefile.in
@@ -91,6 +91,7 @@ PYTHON_FILE_LIST = \
gdb/command/missing_files.py \
gdb/command/pretty_printers.py \
gdb/command/prompt.py \
+ gdb/command/rpm-suggestions.py \
gdb/command/type_printers.py \
gdb/command/unwinders.py \
gdb/command/xmethods.py \
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -186,6 +186,7 @@
* Trace File Format:: @value{GDBN} trace file format
* Index Section Format:: .gdb_index section format
* Debuginfod:: Download debugging resources with @code{debuginfod}
+* RPM Suggestions:: RPM Suggestions from GDB
* Man Pages:: Manual pages
* Copying:: GNU General Public License says
how you can copy and share @value{GDBN}
@@ -50341,6 +50342,111 @@
@end table
+@node RPM Suggestions
+@appendix Receiving RPM installation suggestions
+@cindex rpm suggestions
+
+When @value{GDBN} loads an executable, or shared library, and cannot
+find the corresponding debug information, @value{GDBN} will check to
+see if an RPM is available which could provide the missing debug
+information. If a suitable RPM is found then @value{GDBN} will print
+a hint before the next prompt is displayed:
+
+@smallexample
+(@value{GDBP}) file /bin/ls
+Reading symbols from /bin/ls...
+Reading symbols from .gnu_debugdata for /usr/bin/ls...
+(No debugging symbols found in .gnu_debugdata for /usr/bin/ls)
+Missing rpms, try: dnf --enablerepo='*debug*' install coreutils-debuginfo-9.3-7.fc39.x86_64
+(@value{GDBP})
+@end smallexample
+
+In this case, installing @file{coreutils-debuginfo-9.3-7.fc39.x86_64}
+will provide the missing debug information for @file{/bin/ls}. It is
+up to you to install the suggested package, if possible, and after
+that reload the executable in @value{GDBN} so that the newly installed
+debug information can be found.
+
+The RPM suggestion feature can be disabled:
+
+@table @code
+@kindex set rpm-suggestion enabled
+@kindex show rpm-suggestion enabled
+@cindex rpm suggestions, disabling
+@item set rpm-suggestion enabled @r{[}on@r{|}off@r{]}
+@itemx show rpm-suggestion enabled
+When @samp{on} @value{GDBN} will make RPM suggestions where possible.
+When @samp{off} all RPM suggestion will be disabled.
+@end table
+
+When opening a core file (@pxref{core-file command}), it may be the
+case that not only is the debug information missing, but the
+corresponding executable itself is missing. For example, if a core
+file is copied from one machine to another in order to debug.
+
+In this case @value{GDBN} is able to suggest a command which will
+install the missing executable based on the build-id of the
+executable. For example:
+
+@smallexample
+(@value{GDBP}) core-file /tmp/core.5489
+warning: Can't open file /usr/bin/sl during file-backed mapping note processing
+[New LWP 5489]
+Core was generated by `sl'.
+Program terminated with signal SIGQUIT, Quit.
+#0 0x00007f1b41ced1a7 in ?? ()
+Missing file(s), try: dnf --enablerepo='*debug*' install /usr/lib/.build-id/33/2f1a8e56693960e3beb2d70cd79ddfec451cc3 /usr/lib/debug/.build-id/33/2f1a8e56693960e3beb2d70cd79ddfec451cc3.debug
+(@value{GDBP})
+@end smallexample
+
+The core file was generated from the @file{/usr/bin/sl} binary, which
+is not present on the machine opening the core file. @value{GDBN} has
+suggested a command, based on the build-id of the binary, which was
+extracted from the core file, that would install both the missing
+binary, and the corresponding debug information.
+
+Unfortunately, @value{GDBN} doesn't know if the suggested command will
+actually find a matching RPM or not. Querying the RPM database to see
+which packages, if any, will provide a file with the given build-id,
+is rather slow. As @file{/usr/bin/sl} is available in an RPM, then
+the above command will succeed.
+
+It is possible to have @value{GDBN} check to see if there is a package
+available before making the suggestion, but this is significantly
+slower. To enable this mode use the following command:
+
+@table @code
+@kindex set rpm-suggestion build-id-mode
+@kindex show rpm-suggestion build-id-mode
+@cindex rpm suggestions, build-id-mode
+@item set rpm-suggestion build-id-mode @r{[}fast@r{|}slow@r{]}
+@itemx show rpm-suggestion build-id-mode
+When set to @samp{fast}, which is the default, @value{GDBN} will offer
+suggestions based on the build-id of any missing executables or shared
+libraries while opening a core file. This is fast, but @value{GDBN}
+has not checked if there is a package available that can supply the
+required file, so running the suggested command might not install any
+packages.
+
+When set to @samp{slow}, each time @value{GDBN} encounters an
+executable, or shared library, that is missing, @value{GDBN} will
+check to see if there is an RPM available that will supply the missing
+binary. If a suitable RPM is found then @value{GDBN} will offer a
+command which will install the missing RPM. If no suitable RPM is
+found then @value{GDBN} will make no suggestions.
+@end table
+
+It is possible to review all of the previous RPM suggestions that
+@value{GDBN} has made using the following command:
+
+@table @code
+@kindex info rpm-suggestions
+@cindex rpm suggestions, listing
+@item info rpm-suggestions
+List all of the RPM suggestions @value{GDBN} has made since the
+executable was last changed.
+@end table
+
@node Man Pages
@appendix Manual pages
@cindex Man pages
diff --git a/gdb/python/lib/gdb/command/rpm-suggestions.py b/gdb/python/lib/gdb/command/rpm-suggestions.py
new file mode 100644
--- /dev/null
+++ b/gdb/python/lib/gdb/command/rpm-suggestions.py
@@ -0,0 +1,552 @@
+# Copyright 2023 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+import gdb
+import gdb.missing_debug
+import gdb.missing_objfile
+
+# These modules are all system modules, and should be available on any
+# correctly setup Python install.
+import sys
+import os
+import subprocess
+import re
+from threading import Thread
+import time
+
+try:
+ import rpm
+except ModuleNotFoundError:
+ # The "RPM suggestions" mechanism will not work without the (python)
+ # rpm module. Inform the user of this, but wait to do so until
+ # just prior to printing the GDB prompt. If we do it right away,
+ # the message typically appears before the version and copyright
+ # info, which is easily missed by many users. Additionally, it
+ # seems that several other packages which parse GDB version info
+ # are confused by an early error message regarding a missing
+ # python3-rpm package, so waiting to print the error allows those
+ # applications to work as they used to.
+ def before_prompt():
+ print(
+ ("\nUnable to load the Python 'rpm' module. Lack of this module disables\n"
+ "the RPM suggestions mechanism which recommends shell commands for\n"
+ "installing missing debuginfo packages. To enable this functionality,\n"
+ "please install the python3-rpm package."),
+ file=sys.stderr
+ )
+ gdb.events.before_prompt.disconnect(before_prompt)
+
+ gdb.events.before_prompt.connect(before_prompt)
+
+ # Implement 'info rpm-suggestions' when the 'rpm' module is not
+ # available. Just throws an error.
+ def info_rpm_suggestions():
+ raise gdb.GdbError("rpm-suggestions are disabled as the Python 'rpm' module is not installed")
+else:
+ # Track all the RPMs suggested during a single debug session so we
+ # don't suggest the same RPM twice. This is only cleared when the
+ # main executable is changed.
+ __missing_rpms = {}
+
+ # Track any missing RPMs that have been discovered since the last time
+ # the prompt was displayed. RPMs in here are also present in the
+ # __MISSING_RPMS dictionary, but this dictionary is cleared each time
+ # the prompt is shown.
+ __suggest_rpms = {}
+
+ # Track all the build-ids suggested during a single debug session so we
+ # don't suggest installing using the same build-id twice. This is only
+ # cleared when the main executable is changed.
+ __missing_build_ids = {}
+
+ # Track any build-ids that have been discovered missing since the last
+ # time the prompt was displayed. Build-ids in here are also present in
+ # the __MISSING_BUILD_IDS dictionary, but this dictionary is cleared
+ # each time the prompt is shown.
+ __suggest_build_ids = {}
+
+ # The build-id to RPM lookup is very slow. This cache maps
+ # build-ids to the set of RPM we can suggest installing. The key
+ # is the build-id string, and the value is a list of RPM names, or
+ # None if there was an error with the build-id to RPM lookup.
+ #
+ # This cache is never cleared, even when the executable is
+ # changed. The build-ids should be unique, so a build-id lookup
+ # should be good for the lifetime of the session.
+ __build_id_lookup_cache = {}
+
+ # When searching for an RPM given a build-id, if the search takes
+ # too long, then a message is printed to the user. We only print
+ # the message once between each GDB prompt. This flag is set True
+ # when the message is printed, and reset to False when a prompt is
+ # displayed.
+ __searching_message_printed = False
+
+ # Add a suggestion to install RPM_NAME (the full name of an RPM)
+ # to the list of suggestions to make the next time a prompt is
+ # displayed.
+ def add_rpm_suggestion(rpm_name):
+ global __missing_rpms
+ global __suggest_rpms
+
+ if not rpm_name in __missing_rpms:
+ __suggest_rpms[rpm_name] = True
+ __missing_rpms[rpm_name] = True
+
+ # Return True if RPM_NAME is installed, where RPM_NAME is the full
+ # name of an RPM.
+ def is_rpm_installed(ts, rpm_name):
+ res = ts.dbMatch(rpm.RPMDBI_LABEL, rpm_name)
+ return len(res) > 0
+
+ # Add a suggestion to install RPMs based on BUILD_ID, a string
+ # containing a build-id, to the list of suggestions to make the next
+ # time a prompt is displayed.
+ def add_build_id_suggestion(build_id):
+ global __missing_build_ids
+ global __suggest_build_ids
+
+ if not build_id in __missing_build_ids:
+ __suggest_build_ids[build_id] = True
+ __missing_build_ids[build_id] = True
+
+ # Return true if '/usr/lib' is in the debug-file-directory list.
+ # System packages install their debug information into /usr/lib,
+ # so if GDB isn't looking in that directory, then there's no
+ # reason to try and figure out a suitable RPM to install.
+ def using_suitable_debug_file_directory():
+ debug_file_directories = gdb.parameter("debug-file-directory")
+ for d in debug_file_directories.split(os.pathsep):
+ if d[:8] == "/usr/lib":
+ return True
+ return False
+
+ # Return True if rpm-suggestion is disabled for any reason.
+ def rpm_suggestion_is_disabled():
+ global param_build_id_verbose
+
+ # If /usr/lib/ is not being used to find debug information
+ # then there's no point offering any RPMs as GDB would not
+ # find the newly installed content.
+ if not using_suitable_debug_file_directory():
+ return True
+
+ # For backwards compatibility, if build-id-verbose is set to
+ # zero, then disable RPM suggestion.
+ if param_build_id_verbose.value == 0:
+ return True
+
+ # Is 'rpm-suggestion enabled' set to 'off'?
+ if not param_rpm_suggestion_enabled.value:
+ return True
+
+ return False
+
+
+ # Lookup RPMs that might provide the debug information for FILENAME,
+ # which is a string containing the path to an object file GDB could
+ # not find any debug information for.
+ #
+ # If a possible RPM is found then this is added to the globals
+ # __MISSING_RPMS and __SUGGEST_RPMS, which are used elsewhere in this
+ # script.
+ def find_debug_suggestions(filename):
+ if rpm_suggestion_is_disabled():
+ return
+
+ ts = rpm.TransactionSet()
+ mi = ts.dbMatch(rpm.RPMDBI_BASENAMES, filename)
+ for h in mi:
+ # Build the debuginfo package name.
+ obj = h.format("%{name}-debuginfo-%{version}-%{release}.%{arch}")
+ rpm_name = str(obj)
+
+ # Check to see if the package is installed.
+ if is_rpm_installed(ts, rpm_name):
+ continue
+
+ add_rpm_suggestion(rpm_name)
+
+
+ # Return a string which is the filename of the filename
+ # corresponding to BUILD_ID in one of the two locations under
+ # /usr/lib.
+ #
+ # When DEBUG_P is True, return a filename within:
+ # /usr/lib/debug/.build-id/ and when DEBUG_P is False, return a
+ # filename within: /usr/lib/.build-id/.
+ #
+ # The SUFFIX string is appended to the generated filename.
+ def build_id_to_usr_lib_filename(build_id, debug_p, suffix = ""):
+ key = build_id[:2]
+ rst = build_id[2:]
+
+ filename = '/usr/lib'
+ if debug_p:
+ filename += '/debug'
+ filename += '/.build-id/' + key + '/' + rst + suffix
+
+ return filename
+
+ # A regexp object used to match against the output of `dnf`. This
+ # is initialised the first time it is needed.
+ find_objfile_suggestions_re = None
+
+ # Given BUILD_ID, a string containing a build-id, run a `dnf`
+ # command to figure out if any RPMs can provide a file with that
+ # build-id.
+ #
+ # If any suitable RPMs are found then `add_rpm_suggestion` is called
+ # to register the suggestion.
+ #
+ # This function is pretty slow, which is a shame, as the results
+ # returned are much nicer than just telling the user to try the
+ # lookup command for themselves.
+ def find_objfile_suggestions_in_thread(build_id):
+ global find_objfile_suggestions_re
+
+ if find_objfile_suggestions_re is None:
+ find_objfile_suggestions_re = re.compile("^(.*)-debuginfo-(.*) : Debug information for package (.*)$")
+
+ result = subprocess.run(['dnf', "--enablerepo=*debug*", '--nogpgcheck', '-C', 'provides',
+ build_id_to_usr_lib_filename(build_id, True)],
+ capture_output=True, timeout=30)
+
+ lines = result.stdout.decode('utf-8').splitlines()
+ ts = rpm.TransactionSet()
+
+ for l in lines:
+ m = find_objfile_suggestions_re.match(l)
+ if not m:
+ continue
+ if m.group(1) != m.group(3):
+ return
+
+ main_rpm = m.group(1) + '-' + m.group(2)
+ dbg_rpm = m.group(1) + '-debuginfo-' + m.group(2)
+
+ if not is_rpm_installed(ts, main_rpm):
+ add_rpm_suggestion(main_rpm)
+
+ if not is_rpm_installed(ts, dbg_rpm):
+ add_rpm_suggestion(dbg_rpm)
+
+ return
+
+ # Call `find_objfile_suggestions_in_thread` is a separate thread,
+ # then wait for the thread to complete. Don't touch any shared
+ # state while waiting for the thread to complete. There's no
+ # locking on any of our caches, and the worker thread will add RPM
+ # suggestions as it wants.
+ #
+ # If thre thread takes too long to complete then print a message
+ # to the user telling them what's going on.
+ def find_objfile_suggestions_slow_core(build_id):
+ global __searching_message_printed
+
+ thread = Thread(target = find_objfile_suggestions_in_thread, args = (build_id, ))
+ thread.start()
+ start = time.time_ns()
+
+ while thread.is_alive ():
+ time.sleep(0.05)
+ now = time.time_ns ()
+ if not __searching_message_printed and (now - start > 1000000000):
+ print("Searching for packages to install that could improve debugging...")
+ __searching_message_printed = True
+
+ thread.join()
+
+
+ # Given BUILD_ID, a string containing a build-id, lookup suitable
+ # RPMs that could be installed to provide a file with the required
+ # build-id.
+ #
+ # Any suitable RPMs are recorded by calling `add_rpm_suggestion`, and
+ # will be printed before the next prompt.
+ def find_objfile_suggestions_slow(build_id):
+ global __build_id_lookup_cache
+ global __suggest_rpms
+
+ # The code to lookup an RPM given only a build-id is pretty
+ # slow. Cache the results to try and reduce the UI delays.
+ if build_id in __build_id_lookup_cache:
+ rpms = __build_id_lookup_cache[build_id]
+ if rpms is not None:
+ for r in rpms:
+ add_rpm_suggestion(r)
+ return
+
+ # Make sure the cache entry exists before we do the lookup.
+ # If, for any reason, the lookup raises an exception, then
+ # having a cache entry will prevent us retrying this lookup in
+ # the future.
+ __build_id_lookup_cache[build_id] = None
+
+ # Now do the lookup. This is the slow part.
+ find_objfile_suggestions_slow_core(build_id)
+
+ # Fill in the cache, for a given build-id which RPMs were
+ # suggested.
+ rpms = []
+ for r in __suggest_rpms:
+ rpms.append(r)
+ __build_id_lookup_cache[build_id] = rpms
+
+
+ # Given BUILD_ID, a string containing a build-id, just record that we
+ # should advise the user to try installing RPMs based on this build-id.
+ def find_objfile_suggestions_fast(build_id):
+ add_build_id_suggestion(build_id)
+
+ # Given BUILD_ID, a string containing a build-id, which GDB has failed
+ # to find, possibly record some information so that we can, at the next
+ # prompt, give some RPM installation advice to the user.
+ #
+ # We have two different strategies for RPM lookup based on a build-id,
+ # one approach is that we actually lookup the RPMs and only suggest
+ # something if there is a suitable RPM. However, this is pretty slow,
+ # and users will probably find this annoying.
+ #
+ # So we also have a fast way. With this approach we just record the
+ # build-id that was missing and tell the user to try installing based on
+ # the build-id. The downside with this is that if there is no RPM for
+ # that build-id, then the user will try the command, but nothing will
+ # install.
+ def find_objfile_suggestions(build_id):
+ if rpm_suggestion_is_disabled():
+ return
+
+ if param_rpm_suggestion_build_id_mode.fast_mode():
+ find_objfile_suggestions_fast(build_id)
+ else:
+ find_objfile_suggestions_slow(build_id)
+
+ # A missing debug handler class. Just forwards the name of the
+ # objfile for which we are missing debug information to
+ # find_debug_suggestions.
+ class RPM_MissingDebugHandler(gdb.missing_debug.MissingDebugHandler):
+ def __init__(self):
+ super().__init__("rpm-suggestions")
+
+ def __call__(self, objfile):
+ find_debug_suggestions(objfile.filename)
+ return False
+
+ # A missing objfile handler class. Just forwards the build-id of
+ # the objfile that is missing to find_objfile_suggestions.
+ class RPM_MissingObjfileHandler(gdb.missing_objfile.MissingObjfileHandler):
+ def __init__(self):
+ super().__init__("rpm-suggestions")
+
+ def __call__(self, pspace, build_id, filename):
+ find_objfile_suggestions(build_id)
+ return False
+
+ # Take a non-empty list of RPM names and print a command line a
+ # user could run to install these RPMs.
+ def print_rpm_suggestions(rpm_name_list):
+ print("Missing rpms, try: dnf --enablerepo='*debug*' install " + ' '.join(rpm_name_list))
+
+ # Take a non-empty list of build-id strings and print a series of
+ # lines that a user could run to instll the RPMs that provide
+ # files with this build-id.
+ #
+ # The printed commands will also install the corresponding debug
+ # packages for the executable with the given build-id.
+ def print_build_id_suggestions(build_id_list):
+ for build_id in build_id_list:
+ print("Missing file(s), try: dnf --enablerepo='*debug*' install "
+ + build_id_to_usr_lib_filename(build_id, False)
+ + ' '
+ + build_id_to_usr_lib_filename(build_id, True, ".debug"))
+
+ # Called before GDB displays its prompt. If the global __SUGGEST_RPMS
+ # dictionary is not empty, then this hook prints the keys of this
+ # dictionary as strings which are the names of RPMs. This hook formats
+ # each RPM name into a suggested 'dnf install' command and suggests this
+ # to the user.
+ #
+ # Additionally, if the global __SUGGEST_BUILD_IDS dictionary is not
+ # empty, then this hook uses the keys of this dictionary as build-ids
+ # that were found to be missing, and formats these into some file based
+ # 'dnf install' suggestions to the user.
+ def before_prompt():
+ global __suggest_rpms
+ global __suggest_build_ids
+ global __searching_message_printed
+
+ # We allow the searching message to be printed just once
+ # between prompts.
+ __searching_message_printed = False
+
+ if len(__suggest_rpms) > 0:
+ print_rpm_suggestions(__suggest_rpms.keys())
+ __suggest_rpms = {}
+
+ if len(__suggest_build_ids) > 0:
+ print_build_id_suggestions(__suggest_build_ids.keys())
+ __suggest_build_ids = {}
+
+ # Called when the executable within a progrm space is changed. Clear
+ # the lists of RPM suggestions. We only clear the previous suggestion
+ # list when the executable really changes. If the user simply
+ # recompiles the executable, then we don't both clearing this list.
+ def executable_changed_handler(event):
+ global __missing_rpms
+ global __suggest_rpms
+ global __suggest_build_ids
+ global __missing_build_ids
+
+ if not event.reload:
+ __missing_rpms = {}
+ __suggest_rpms = {}
+ __missing_build_ids = {}
+ __suggest_build_ids = {}
+
+
+ # Attach to the required GDB events.
+ gdb.events.executable_changed.connect(executable_changed_handler)
+ gdb.events.before_prompt.connect(before_prompt)
+
+ # Register the missing debug and missing objfile handlers with GDB.
+ gdb.missing_debug.register_handler(None, RPM_MissingDebugHandler())
+ gdb.missing_objfile.register_handler(None, RPM_MissingObjfileHandler())
+
+ # Implement the core of 'info rpm-suggestions'. Reprint all rpm
+ # suggestions.
+ def info_rpm_suggestions():
+ global __missing_rpms
+ global __missing_build_ids
+
+ if len(__missing_rpms) == 0 and len(__missing_build_ids) == 0:
+ print("No RPM suggestions have been made so far.")
+ return
+
+ if len(__missing_rpms) > 0:
+ print_rpm_suggestions(__missing_rpms.keys())
+ if len(__missing_build_ids) > 0:
+ print_build_id_suggestions(__missing_build_ids.keys())
+
+####################################################################
+# The following code is outside the 'else' block of the attempt to #
+# load the 'rpm' module. Nothing after this point depends on the #
+# 'rpm' module. #
+####################################################################
+
+# The 'set rpm-suggestion' prefix command.
+class rpm_suggestion_set_prefix(gdb.Command):
+ """Prefix command for 'set' rpm-suggestion related commands."""
+
+ def __init__(self):
+ super().__init__("set rpm-suggestion", gdb.COMMAND_NONE,
+ gdb.COMPLETE_NONE, True)
+
+# The 'show rpm-suggestion' prefix command.
+class rpm_suggestion_show_prefix(gdb.Command):
+ """Prefix command for 'show' rpm-suggestion related commands."""
+
+ def __init__(self):
+ super().__init__("show rpm-suggestion", gdb.COMMAND_NONE,
+ gdb.COMPLETE_NONE, True)
+
+# The 'set/show rpm-suggestion enabled' command.
+class rpm_suggestion_enabled(gdb.Parameter):
+ """
+ When 'on' GDB will search for RPMS that might provide additional
+ debug information, or provide missing executables or shared
+ libraries (when opening a core file), and will make suggestions
+ about what should be installed.
+
+ When 'off' GDB will not make these suggestions.
+ """
+
+ set_doc = "Set whether to perform rpm-suggestion."
+ show_doc = "Show whether rpm-suggestion is enabled."
+
+ def __init__(self):
+ super().__init__("rpm-suggestion enabled", gdb.COMMAND_NONE, gdb.PARAM_BOOLEAN)
+ self.value = True
+
+# The 'set/show rpm-suggestion enabled' command.
+class rpm_suggestion_build_id_mode(gdb.Parameter):
+ """
+ When set to 'fast' (the default), GDB doesn't try to map a build-id to
+ an actual RPM, instead, GDB just suggests a command based on the
+ build-id which might install some RPMs, if there are any RPMs that
+ supply that build-id. However, it is equally possible that there are no
+ suitable RPMs, and nothing will install. This approach has almost zero
+ overhead.
+
+ When set to 'slow', GDB first does the build-id to RPM check itself, and
+ only if something is found are RPMs installation commands suggested.
+ The suggested command will include the name of the RPM to install. This
+ approach is considerably slower as querying the RPM database for the RPM
+ that supplies a specific file is slow.
+ """
+
+ set_doc = "Set how build-id based rpm suggestions should be performed."
+ show_doc = "Show how build-id based rpm suggestions shoud be performed."
+
+ def __init__(self):
+ super().__init__("rpm-suggestion build-id-mode",
+ gdb.COMMAND_NONE, gdb.PARAM_ENUM, ["fast", "slow"])
+ self.value = "fast"
+
+ def fast_mode(self):
+ return self.value == "fast"
+
+# The 'info rpm-suggestions' command.
+class rpm_suggestion_info(gdb.Command):
+ """Relist any RPM installation suggestions that have been made
+ since the executable was last changed."""
+ def __init__(self):
+ super().__init__("info rpm-suggestions", gdb.COMMAND_NONE, gdb.COMPLETE_NONE)
+
+ def invoke(self, args, from_tty):
+ if args != "":
+ raise gdb.GdbError("unexpected arguments: %s" % args)
+
+ info_rpm_suggestions ()
+
+
+# Create the 'set/show rpm-suggestion' commands.
+rpm_suggestion_set_prefix()
+rpm_suggestion_show_prefix()
+param_rpm_suggestion_enabled = rpm_suggestion_enabled()
+param_rpm_suggestion_build_id_mode = rpm_suggestion_build_id_mode()
+
+# Create the 'info rpm-suggestions' commands.
+rpm_suggestion_info()
+
+# Create the 'build-id-verbose' parameter. This is implemented as an
+# integer for backward compatibility reasons. It would be nice to
+# convert this to a boolean, but it's not clear if that will break
+# existing users uses of this flag.
+
+class build_id_verbose(gdb.Parameter):
+ """
+ Level 0 disable printing the missing debug filesname,
+ Level 1 (default) enables printing the missing debug filenames,
+ """
+
+ set_doc = "Set debugging level of the build-id locator."
+ show_doc = "Show debugging level of the build-id locator."
+
+ def __init__(self):
+ super().__init__("build-id-verbose", gdb.COMMAND_NONE, gdb.PARAM_ZINTEGER)
+ self.value = 1
+
+param_build_id_verbose = build_id_verbose()
diff --git a/gdb/testsuite/gdb.base/gdbinit-history.exp b/gdb/testsuite/gdb.base/gdbinit-history.exp
--- a/gdb/testsuite/gdb.base/gdbinit-history.exp
+++ b/gdb/testsuite/gdb.base/gdbinit-history.exp
@@ -179,7 +179,8 @@ proc test_empty_history_filename { } {
global env
global gdb_prompt
- set common_history [list "set height 0" "set width 0"]
+ set common_history [list "set height 0" "set width 0" \
+ "set build-id-verbose 0"]
set test_dir [standard_output_file history_test]
remote_exec host "mkdir -p $test_dir"
diff --git a/gdb/testsuite/gdb.python/py-missing-debug.py b/gdb/testsuite/gdb.python/py-missing-debug.py
--- a/gdb/testsuite/gdb.python/py-missing-debug.py
+++ b/gdb/testsuite/gdb.python/py-missing-debug.py
@@ -19,6 +19,13 @@ from enum import Enum
import gdb
from gdb.missing_debug import MissingDebugHandler
+# This is a RHEL/Fedora work around: There's already a
+# missing-debug-info handler registered for these versions of GDB.
+# Discard the handler now so that the tests will pass (the tests
+# assume no handler is currently registered).
+gdb.missing_debug_handlers = []
+
+
# A global log that is filled in by instances of the LOG_HANDLER class
# when they are called.
handler_call_log = []
@@ -118,4 +125,7 @@ def register(name, locus=None):
rhandler = exception_handler()
handler_obj = handler()
+# Discard the rpm-suggestion handler.
+gdb.missing_file_handlers = []
+
print("Success")
diff --git a/gdb/testsuite/gdb.python/py-missing-objfile.py b/gdb/testsuite/gdb.python/py-missing-objfile.py
--- a/gdb/testsuite/gdb.python/py-missing-objfile.py
+++ b/gdb/testsuite/gdb.python/py-missing-objfile.py
@@ -164,4 +164,7 @@ def register(name, locus=None):
rhandler = exception_handler()
handler_obj = handler()
+# Discard the rpm-suggestion handler.
+gdb.missing_file_handlers = []
+
print("Success")
diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp
--- a/gdb/testsuite/lib/gdb.exp
+++ b/gdb/testsuite/lib/gdb.exp
@@ -238,7 +238,8 @@ if ![info exists INTERNAL_GDBFLAGS] {
"-nx" \
"-q" \
{-iex "set height 0"} \
- {-iex "set width 0"}]]
+ {-iex "set width 0"} \
+ {-iex "set build-id-verbose 0"}]]
# If DEBUGINFOD_URLS is set, gdb will try to download sources and
# debug info for f.i. system libraries. Prevent this.
@@ -2493,6 +2494,18 @@ proc default_gdb_start { } {
}
}
+ # Turn off the missing debug info messages as the testsuite does
+ # not expect them.
+ send_gdb "set build-id-verbose 0\n"
+ gdb_expect 10 {
+ -re "$gdb_prompt $" {
+ verbose "Disabled the missing debug info messages." 2
+ }
+ timeout {
+ warning "Could not disable the missing debug info messages."
+ }
+ }
+
gdb_debug_init
return 0
}
diff --git a/gdb/testsuite/lib/mi-support.exp b/gdb/testsuite/lib/mi-support.exp
--- a/gdb/testsuite/lib/mi-support.exp
+++ b/gdb/testsuite/lib/mi-support.exp
@@ -321,6 +321,17 @@ proc default_mi_gdb_start { { flags {} } } {
warning "Couldn't set the width to 0."
}
}
+ # Turn off the missing debug info messages as the testsuite does
+ # not expect them.
+ send_gdb "190-gdb-set build-id-verbose 0\n"
+ gdb_expect 10 {
+ -re ".*190-gdb-set build-id-verbose 0\r\n190\\\^done\r\n$mi_gdb_prompt$" {
+ verbose "Disabled the missing debug info messages." 2
+ }
+ timeout {
+ warning "Could not disable the missing debug info messages."
+ }
+ }
if { $separate_inferior_pty } {
mi_create_inferior_pty

View File

@@ -0,0 +1,88 @@
From FEDORA_PATCHES Mon Sep 17 00:00:00 2001
From: Fedora GDB patches <invalid@email.com>
Date: Fri, 27 Oct 2017 21:07:50 +0200
Subject: gdb-archer-next-over-throw-cxx-exec.patch
;; Fix follow-exec for C++ programs (bugreported by Martin Stransky).
;;=fedoratest
Archer-upstreamed:
http://sourceware.org/ml/archer/2010-q2/msg00031.html
diff --git a/gdb/testsuite/gdb.cp/cxxexec.cc b/gdb/testsuite/gdb.cp/cxxexec.cc
new file mode 100644
--- /dev/null
+++ b/gdb/testsuite/gdb.cp/cxxexec.cc
@@ -0,0 +1,25 @@
+/* This test script is part of GDB, the GNU debugger.
+
+ Copyright 2010 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include <unistd.h>
+
+int
+main()
+{
+ execlp ("true", "true", NULL);
+ return 1;
+}
diff --git a/gdb/testsuite/gdb.cp/cxxexec.exp b/gdb/testsuite/gdb.cp/cxxexec.exp
new file mode 100644
--- /dev/null
+++ b/gdb/testsuite/gdb.cp/cxxexec.exp
@@ -0,0 +1,42 @@
+# Copyright 2010 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+require allow_cplus_tests
+
+set testfile cxxexec
+if { [prepare_for_testing ${testfile}.exp ${testfile} ${testfile}.cc {c++ debug}] } {
+ return -1
+}
+
+runto_main
+
+# We could stop after `continue' again at `main'.
+delete_breakpoints
+
+set test "p _Unwind_DebugHook"
+gdb_test_multiple $test $test {
+ -re " = .* 0x\[0-9a-f\].*\r\n$gdb_prompt $" {
+ pass $test
+ }
+ -re "\r\nNo symbol .*\r\n$gdb_prompt $" {
+ xfail $test
+ untested ${testfile}.exp
+ return -1
+ }
+}
+
+# Run to end. The buggy GDB failed instead with:
+# Cannot access memory at address ADDR.
+gdb_continue_to_end "" "continue" 1

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,46 @@
From c179fc89cf61d3d9c58db571d709969bfa566289 Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Tue, 10 Sep 2024 10:08:29 +0200
Subject: [PATCH] [gdb/build] Fix unused var in corelow.c
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
On x86_64-linux, with gcc 7.5.0 and CFLAGS/CXXFLAGS="-O0 -g -Wall" I ran into
a build breaker:
...
gdb/corelow.c: In member function void mapped_file_info::add(const char*, const char*, const char*, std::vector<mem_range>&&, const bfd_build_id*):
gdb/corelow.c:1822:27: error: unused variable it [-Werror=unused-variable]
const auto [it, inserted]
^
...
Fix this by dropping the variable it.
Tested on x86_64-linux.
Reviewed-By: Lancelot Six<lancelot.six@amd.com>
---
gdb/corelow.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/gdb/corelow.c b/gdb/corelow.c
index 1884075ec67..30b98c2865d 100644
--- a/gdb/corelow.c
+++ b/gdb/corelow.c
@@ -1872,8 +1872,8 @@ mapped_file_info::add (const char *soname,
parsed, we group the build-id information based on the file name. As
a consequence, we should see each EXPECTED_FILENAME value exactly
once. This means that each insertion should always succeed. */
- const auto [it, inserted]
- = m_filename_to_build_id_map.emplace (expected_filename, build_id);
+ const auto inserted
+ = m_filename_to_build_id_map.emplace (expected_filename, build_id).second;
gdb_assert (inserted);
/* Setup the reverse build-id to file name map. */
base-commit: a7d9abecbc24e3d68746ea5b905eba11913980e1
--
2.43.0

575
gdb-catchpoint-re-set.patch Normal file
View File

@@ -0,0 +1,575 @@
From FEDORA_PATCHES Mon Sep 17 00:00:00 2001
From: Andrew Burgess <aburgess@redhat.com>
Date: Wed, 14 Aug 2024 15:16:46 +0100
Subject: gdb-catchpoint-re-set.patch
;; Backport upstream commit a92e943014f to fix rhbz2304296.
gdb: implement ::re_set method for catchpoint class
It is possible to attach a condition to a catchpoint. This can't be
done when the catchpoint is created, but can be done with the
'condition' command, this is documented in the GDB manual:
You can also use the 'if' keyword with the 'watch' command. The
'catch' command does not recognize the 'if' keyword; 'condition' is the
only way to impose a further condition on a catchpoint.
A GDB crash was reported against Fedora GDB where a user had attached
a condition to a catchpoint and then restarted the inferior. When the
catchpoint was hit GDB would immediately segfault. I was able to
reproduce the failure on upstream GDB:
(gdb) file ./some/binary
(gdb) catch syscall write
(gdb) run
...
Catchpoint 1 (returned from syscall write), 0x00007ffff7b594a7 in write () from /lib64/libc.so.6
(gdb) condition 1 $_streq((char *) $rsi, "foobar") == 0
(gdb) run
...
Fatal signal: Segmentation fault
...
What happened here is that on the system in question we had debug
information available for both the main application and also for
libc.
When the condition was attached GDB was stopped inside libc and as the
debug information was available GDB found a reference to the 'char'
type (for the cast) inside libc's debug information.
When the inferior is restarted GDB discards all of the objfiles
associated with shared libraries, and this includes libc. As such the
'char' type, which is objfile owned, is discarded and the reference to
it from the catchpoint's condition expression becomes invalid.
Now, if it were a breakpoint instead of a catchpoint, what would
happen is that after the shared library objfiles had been discarded
we'd call the virtual breakpoint::re_set method on the breakpoint, and
this would update the breakpoint's condition expression. This is
because user breakpoints are actually instances of the code_breakpoint
class and the code_breakpoint::re_set method contains the code to
recompute the breakpoint's condition expression.
However, catchpoints are instances of the catchpoint class which
inherits from the base breakpoint class. The catchpoint class does
not override breakpoint::re_set, and breakpoint::re_set is empty!
The consequence of this is that catchpoint condition expressions are
never recomputed, and the dangling pointer to the now deleted, objfile
owned type 'char' is left around, and, when the catchpoint is hit, the
invalid pointer is used when GDB tries to evaluate the condition
expression.
In this commit I have implemented catchpoint::re_set. This is pretty
simple and just recomputes the condition expression as you'd expect.
If the condition doesn't evaluate then the catchpoint is marked as
disabled_by_cond.
I have also made breakpoint::re_set pure virtual. With the addition
of catchpoint::re_set every sub-class of breakpoint now implements the
::re_set method, and if new sub-classes are added in the future I
think that they _must_ implement ::re_set in order to avoid this
problem. As such falling back to an empty breakpoint::re_set doesn't
seem helpful.
For testing I have not relied on stopping in libc and having libc
debug information available, this doesn't seem like a good idea for
the GDB testsuite. Instead I create a (rather pointless) condition
check that uses a type defined only within a shared library. When the
inferior is restarted the catchpoint will temporarily be marked as
disabled_by_cond (due to the type not being available), but once the
shared library is loaded again the catchpoint will be re-enabled.
Without the fixes above then the same crashing behaviour can be
observed.
One point of note: the dangling pointer of course exposes undefined
behaviour, with no guarantee of a crash. Though a crash is what I
usually see I have see GDB throw random errors from the expression
evaluation code, and once, I saw no problem at all! If you recompile
GDB with the address sanitizer, or run under valgrind, then the bug
will be exposed every time.
After fixing this bug I checked bugzilla and found PR gdb/29960 which
is the same bug. I was able to reproduce the bug before this commit,
and after this commit GDB is no longer crashing.
Before:
(gdb) file /tmp/hello.x
Reading symbols from /tmp/hello.x...
(gdb) run
Starting program: /tmp/hello.x
Hello World
[Inferior 1 (process 1101855) exited normally]
(gdb) catch syscall 1
Catchpoint 1 (syscall 'write' [1])
(gdb) condition 1 write.fd == 1
(gdb) run
Starting program: /tmp/hello.x
Fatal signal: Segmentation fault
...
And after:
(gdb) file /tmp/hello.x
Reading symbols from /tmp/hello.x...
(gdb) run
Starting program: /tmp/hello.x
Hello World
Args: ( 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 )
[Inferior 1 (process 1102373) exited normally]
(gdb) catch syscall 1
Catchpoint 1 (syscall 'write' [1])
(gdb) condition 1 write.fd == 1
(gdb) r
Starting program: /tmp/hello.x
Error in testing condition for breakpoint 1:
Attempt to extract a component of a value that is not a structure.
Catchpoint 1 (call to syscall write), 0x00007ffff7eb94a7 in write ()
from /lib64/libc.so.6
(gdb) ptype write
type = <unknown return type> ()
(gdb)
Notice we get the error now when the condition fails to evaluate.
This seems reasonable given that 'write' will be a function, and
indeed the final 'ptype' shows that it's a function, not a struct.
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=29960
Reviewed-By: Tom de Vries <tdevries@suse.de>
diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
--- a/gdb/breakpoint.c
+++ b/gdb/breakpoint.c
@@ -8146,6 +8146,60 @@ catchpoint::catchpoint (struct gdbarch *gdbarch, bool temp,
pspace = current_program_space;
}
+/* See breakpoint.h. */
+
+void
+catchpoint::re_set ()
+{
+ /* All catchpoints are associated with a specific program_space. */
+ gdb_assert (pspace != nullptr);
+
+ /* Catchpoints have a single dummy location. */
+ gdb_assert (locations ().size () == 1);
+ bp_location &bl = m_locations.front ();
+
+ if (cond_string == nullptr)
+ {
+ /* It shouldn't be possible to have a parsed condition expression
+ cached on this location if the catchpoint doesn't have a condition
+ string set. */
+ gdb_assert (bl.cond == nullptr);
+
+ /* Nothing to re-compute, and the catchpoint cannot change. */
+ return;
+ }
+
+ bool previous_disabled_by_cond = bl.disabled_by_cond;
+
+ /* Start by marking the location disabled and discarding the previously
+ computed condition expression. Now if we get an exception, even if
+ it's a quit exception, we'll leave the location disabled and there
+ will be no (possibly invalid) expression cached. */
+ bl.disabled_by_cond = true;
+ bl.cond = nullptr;
+
+ const char *s = cond_string.get ();
+ try
+ {
+ switch_to_program_space_and_thread (pspace);
+
+ bl.cond = parse_exp_1 (&s, bl.address, block_for_pc (bl.address),
+ nullptr);
+ bl.disabled_by_cond = false;
+ }
+ catch (const gdb_exception_error &e)
+ {
+ /* Any exception thrown must be from either the parse_exp_1 or
+ earlier in the try block. As such the following two asserts
+ should be true. */
+ gdb_assert (bl.disabled_by_cond);
+ gdb_assert (bl.cond == nullptr);
+ }
+
+ if (previous_disabled_by_cond != bl.disabled_by_cond)
+ notify_breakpoint_modified (this);
+}
+
/* Notify interpreters and observers that breakpoint B was created. */
static void
diff --git a/gdb/breakpoint.h b/gdb/breakpoint.h
--- a/gdb/breakpoint.h
+++ b/gdb/breakpoint.h
@@ -702,11 +702,10 @@ struct breakpoint : public intrusive_list_node<breakpoint>
/* Reevaluate a breakpoint. This is necessary after symbols change
(e.g., an executable or DSO was loaded, or the inferior just
- started). */
- virtual void re_set ()
- {
- /* Nothing to re-set. */
- }
+ started). This is pure virtual as, at a minimum, each sub-class must
+ recompute any cached condition expressions based off of the
+ cond_string member variable. */
+ virtual void re_set () = 0;
/* Insert the breakpoint or watchpoint or activate the catchpoint.
Return 0 for success, 1 if the breakpoint, watchpoint or
@@ -1120,6 +1119,10 @@ struct catchpoint : public breakpoint
catchpoint (struct gdbarch *gdbarch, bool temp, const char *cond_string);
~catchpoint () override = 0;
+
+ /* If the catchpoint has a condition set then recompute the cached
+ expression within the single dummy location. */
+ void re_set () override;
};
diff --git a/gdb/testsuite/gdb.base/reset-catchpoint-cond-lib.c b/gdb/testsuite/gdb.base/reset-catchpoint-cond-lib.c
new file mode 100644
--- /dev/null
+++ b/gdb/testsuite/gdb.base/reset-catchpoint-cond-lib.c
@@ -0,0 +1,76 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2024 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include <stdio.h>
+#include <signal.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <assert.h>
+#include <stdlib.h>
+
+/* This type is used by GDB. */
+struct lib_type
+{
+ int a;
+ int b;
+ int c;
+};
+
+/* Ensure the type above is used. */
+volatile struct lib_type global_lib_object = { 1, 2, 3 };
+
+/* This pointer is checked by GDB. */
+volatile void *opaque_ptr = 0;
+
+void
+lib_func_test_syscall (void)
+{
+ puts ("Inside library\n");
+ fflush (stdout);
+}
+
+static void
+sig_handler (int signo)
+{
+ /* Nothing. */
+}
+
+void
+lib_func_test_signal (void)
+{
+ signal (SIGUSR1, sig_handler);
+
+ kill (getpid (), SIGUSR1);
+}
+
+void
+lib_func_test_fork (void)
+{
+ pid_t pid = fork ();
+ assert (pid != -1);
+
+ if (pid == 0)
+ {
+ /* Child: just exit. */
+ exit (0);
+ }
+
+ /* Parent. */
+ waitpid (pid, NULL, 0);
+}
diff --git a/gdb/testsuite/gdb.base/reset-catchpoint-cond.c b/gdb/testsuite/gdb.base/reset-catchpoint-cond.c
new file mode 100644
--- /dev/null
+++ b/gdb/testsuite/gdb.base/reset-catchpoint-cond.c
@@ -0,0 +1,50 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2024 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+extern void lib_func_test_syscall (void);
+extern void lib_func_test_signal (void);
+extern void lib_func_test_fork (void);
+
+/* We use this to perform some filler work. */
+volatile int global_var = 0;
+
+/* Just somewhere for GDB to put a breakpoint. */
+void
+breakpt_before_exit (void)
+{
+ /* Nothing. */
+}
+
+int
+main (void)
+{
+#if defined TEST_SYSCALL
+ lib_func_test_syscall ();
+#elif defined TEST_SIGNAL
+ lib_func_test_signal ();
+#elif defined TEST_FORK
+ lib_func_test_fork ();
+#else
+# error compile with suitable -DTEST_xxx macro defined
+#endif
+
+ ++global_var;
+
+ breakpt_before_exit ();
+
+ return 0;
+}
diff --git a/gdb/testsuite/gdb.base/reset-catchpoint-cond.exp b/gdb/testsuite/gdb.base/reset-catchpoint-cond.exp
new file mode 100644
--- /dev/null
+++ b/gdb/testsuite/gdb.base/reset-catchpoint-cond.exp
@@ -0,0 +1,169 @@
+# Copyright 2024 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# Test that the condition for a catchpoint is correctly reset after
+# shared libraries are unloaded, as happens when an inferior is
+# restarted.
+#
+# If this is not done then, when the catchpoint is hit on the second
+# run, we'll evaluate the parsed expression from the first run, which
+# might include references to types owned by the now deleted objfile
+# (for the shared library loaded in the first run).
+#
+# This scripts tests a number of different catchpoint types. Inside
+# GDB these are all sub-classes of the 'catchpoint' type, which is
+# where the fix for the above issue resides, so all catchpoint types
+# should work correctly.
+
+standard_testfile .c -lib.c
+
+set libfile $binfile-lib.so
+
+set pyfile [gdb_remote_download host ${srcdir}/${subdir}/${testfile}.py]
+
+if {[build_executable "build shared library" $libfile $srcfile2 \
+ {debug shlib}] == -1} {
+ return
+}
+
+# Depending on whether or not libc debug info is installed, when we
+# hit a syscall catchpoint inside libc there might be a source line
+# included in the output.
+#
+# This regexp will match an optional line and can be added to the
+# expected catchpoint output to ignore the (possibly missing) source
+# line.
+set libc_src_line_re "(?:\r\n\[^\r\n\]+)?"
+
+# Check the Python bp_modified_list and then reset the list back to
+# empty. TESTNAME is just a string. BP_NUM is a list of breakpoint
+# numbers that are expected to appear (in the given order) in the
+# bp_modified_list.
+
+proc check_modified_bp_list { testname bp_num } {
+ if { [allow_python_tests] } {
+ set expected [join $bp_num ", "]
+
+ gdb_test "python print(bp_modified_list)" "\\\[$expected\\\]" \
+ $testname
+ gdb_test_no_output -nopass "python bp_modified_list=\[\]" \
+ "reset bp_modified_list after $testname"
+ }
+}
+
+# Build an executable and run tests on 'catch MODE'.
+
+proc run_test { mode } {
+ set exec_name ${::binfile}-${mode}
+
+ set macro TEST_[string toupper $mode]
+
+ if {[build_executable "build test executable" $exec_name $::srcfile \
+ [list debug shlib=$::libfile additional_flags=-D${macro}]] == -1} {
+ return
+ }
+
+ clean_restart $exec_name
+ gdb_load_shlib $::libfile
+
+ if {![runto_main]} {
+ return
+ }
+
+ if { $mode eq "syscall" } {
+ gdb_test "catch syscall write" \
+ "Catchpoint $::decimal \\(syscall 'write' \[^)\]+\\)"
+ set catch_re "call to syscall write"
+ } elseif { $mode eq "signal" } {
+ gdb_test "catch signal SIGUSR1" \
+ "Catchpoint $::decimal \\(signal SIGUSR1\\)"
+ set catch_re "signal SIGUSR1"
+ } elseif { $mode eq "fork" } {
+ gdb_test "catch fork" \
+ "Catchpoint $::decimal \\(fork\\)"
+ set catch_re "forked process $::decimal"
+ } else {
+ error "unknown mode $mode"
+ }
+ set cp_num [get_integer_valueof "\$bpnum" "*UNKNOWN*"]
+
+ gdb_breakpoint "breakpt_before_exit"
+
+ gdb_test "continue" \
+ "Catchpoint ${cp_num} \[^\r\n\]+$::libc_src_line_re"
+
+ if { [allow_python_tests] } {
+ gdb_test_no_output "source $::pyfile" "import python scripts"
+ check_modified_bp_list \
+ "check b/p modified observer has not yet triggered" {}
+ }
+
+ with_test_prefix "with false condition" {
+ gdb_test_no_output "condition $cp_num ((struct lib_type *) opaque_ptr) != 0" \
+ "set catchpoint condition"
+
+ check_modified_bp_list \
+ "catchpoint modified once by setting condition" \
+ [list $cp_num]
+
+ gdb_run_cmd
+ gdb_test "" [multi_line \
+ "Breakpoint $::decimal, main \\(\\) \[^\r\n\]+" \
+ "$::decimal\\s+\[^\r\n\]+"]
+
+ check_modified_bp_list "catchpoint modified twice at startup" \
+ [list $cp_num $cp_num "$::decimal"]
+
+ gdb_test "continue" \
+ [multi_line \
+ "Breakpoint $::decimal, breakpt_before_exit \\(\\) at \[^\r\n\]+" \
+ "$::decimal\\s+\[^\r\n\]+"] \
+ "continue to breakpt_before_exit"
+ }
+
+ # Check the bp_modified_list against '.*'. We don't care at this
+ # point what's in the list (nothing relevant has happened since we
+ # last checked), but this has the side effect of clearing the list.
+ check_modified_bp_list "clear bp modified list" { .* }
+
+ with_test_prefix "with true condition" {
+ gdb_test_no_output "condition $cp_num ((struct lib_type *) opaque_ptr) == 0" \
+ "set catchpoint condition"
+
+ check_modified_bp_list \
+ "catchpoint modified once by setting condition" \
+ [list $cp_num]
+
+ gdb_run_cmd
+ gdb_test "" [multi_line \
+ "Breakpoint $::decimal, main \\(\\) \[^\r\n\]+" \
+ "$::decimal\\s+\[^\r\n\]+"]
+
+ check_modified_bp_list "catchpoint modified twice at startup" \
+ [list $cp_num $cp_num "$::decimal"]
+
+ gdb_test "continue" \
+ "Catchpoint $cp_num \\($catch_re\\), \[^\r\n\]+$::libc_src_line_re" \
+ "continue until catchpoint hit"
+
+ check_modified_bp_list "catchpoint modified again when hit" \
+ [list $cp_num]
+ }
+}
+
+# Run the tests.
+foreach_with_prefix mode { syscall signal fork } {
+ run_test $mode
+}
diff --git a/gdb/testsuite/gdb.base/reset-catchpoint-cond.py b/gdb/testsuite/gdb.base/reset-catchpoint-cond.py
new file mode 100644
--- /dev/null
+++ b/gdb/testsuite/gdb.base/reset-catchpoint-cond.py
@@ -0,0 +1,21 @@
+# Copyright (C) 2024 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+bp_modified_list = []
+
+def bp_modified(bp):
+ bp_modified_list.append (bp.number)
+
+gdb.events.breakpoint_modified.connect(bp_modified)

View File

@@ -0,0 +1,201 @@
From 0bb6f49bb9ad577667075550ca2ad4cb49931078 Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Thu, 18 Apr 2024 14:27:04 +0200
Subject: [PATCH 2/2] gdb-cli-add-ignore-errors-command
[gdb/cli] Add ignore-errors command
While trying to reproduce a failing test-case from the testsuite on the
command line using a gdb command script, I ran into the problem that a command
failed which stopped script execution.
I could work around this by splitting the script at each error, but I realized
it would be nice if I could tell gdb to ignore the error.
A python workaround ignore-errors exists, mentioned here (
https://sourceware.org/legacy-ml/gdb/2010-06/msg00100.html ), which is
already supplied by distros like Fedora and openSUSE.
FTR, a more elaborate try-catch solution was posted here (
https://sourceware.org/bugzilla/show_bug.cgi?id=8487 ).
This patch adds native ignore-errors support (so no python needed).
So with this script:
...
$ cat script.gdb
ignore-errors run
echo here
...
we have:
...
$ gdb -q -batch -x script.gdb
No executable file specified.
Use the "file" or "exec-file" command.
here$
...
Note that quit is not caught:
...
$ gdb -q
(gdb) ignore-errors quit
$
...
which is the same behaviour as with the python implementation.
Tested on x86_64-linux.
gdb/ChangeLog:
2021-05-18 Tom de Vries <tdevries@suse.de>
* cli/cli-cmds.c (ignore_errors_command_completer)
(ignore_errors_command): New function.
(_initialize_cli_cmds): Add "ignore-errors" cmd.
gdb/doc/ChangeLog:
2021-05-18 Tom de Vries <tdevries@suse.de>
* gdb.texinfo (Command Files): Document command ignore-errors.
gdb/testsuite/ChangeLog:
2021-05-18 Tom de Vries <tdevries@suse.de>
* gdb.base/ignore-errors.exp: New test.
* gdb.base/ignore-errors.gdb: New command file.
---
gdb/cli/cli-cmds.c | 35 ++++++++++++++++++++++++
gdb/doc/gdb.texinfo | 8 +++++-
gdb/testsuite/gdb.base/ignore-errors.exp | 24 ++++++++++++++++
gdb/testsuite/gdb.base/ignore-errors.gdb | 2 ++
4 files changed, 68 insertions(+), 1 deletion(-)
create mode 100644 gdb/testsuite/gdb.base/ignore-errors.exp
create mode 100644 gdb/testsuite/gdb.base/ignore-errors.gdb
diff --git a/gdb/cli/cli-cmds.c b/gdb/cli/cli-cmds.c
index cfe7b71b0b7..0ae5530c558 100644
--- a/gdb/cli/cli-cmds.c
+++ b/gdb/cli/cli-cmds.c
@@ -40,6 +40,7 @@
#include "location.h"
#include "block.h"
#include "valprint.h"
+#include "event-top.h"
#include "ui-out.h"
#include "interps.h"
@@ -2544,6 +2545,34 @@ shell_internal_fn (struct gdbarch *gdbarch,
return value::allocate_optimized_out (int_type);
}
+/* Completer for "ignore-errors". */
+
+static void
+ignore_errors_command_completer (cmd_list_element *ignore,
+ completion_tracker &tracker,
+ const char *text, const char * /*word*/)
+{
+ complete_nested_command_line (tracker, text);
+}
+
+/* Implementation of the ignore-errors command. */
+
+static void
+ignore_errors_command (const char *args, int from_tty)
+{
+ try
+ {
+ execute_command (args, from_tty);
+ }
+ catch (const gdb_exception_error &ex)
+ {
+ exception_print (gdb_stderr, ex);
+
+ /* See also execute_gdb_command. */
+ async_enable_stdin ();
+ }
+}
+
void _initialize_cli_cmds ();
void
_initialize_cli_cmds ()
@@ -2942,4 +2971,10 @@ when GDB is started."), GDBINIT).release ();
c = add_cmd ("source", class_support, source_command,
source_help_text, &cmdlist);
set_cmd_completer (c, filename_completer);
+
+ c = add_cmd ("ignore-errors", class_support, ignore_errors_command,
+ _("Execute a single command, ignoring all errors.\n"
+ "Only one-line commands are supported.\n"
+ "This is primarily useful in scripts."), &cmdlist);
+ set_cmd_completer (c, ignore_errors_command_completer);
}
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 1abf91c4470..c277c16297c 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -29250,7 +29250,8 @@ The lines in a command file are generally executed sequentially,
unless the order of execution is changed by one of the
@emph{flow-control commands} described below. The commands are not
printed as they are executed. An error in any command terminates
-execution of the command file and control is returned to the console.
+execution of the command file and control is returned to the console,
+unless the line is prefixed with the @code{ignore-errors} command.
@value{GDBN} first searches for @var{filename} in the current directory.
If the file is not found there, and @var{filename} does not specify a
@@ -29345,6 +29346,11 @@ the controlling expression.
@item end
Terminate the block of commands that are the body of @code{if},
@code{else}, or @code{while} flow-control commands.
+
+@kindex ignore-errors
+@item ignore-errors
+This command executes the command specified by its arguments, but
+doesn't stop execution of the script if the command fails.
@end table
diff --git a/gdb/testsuite/gdb.base/ignore-errors.exp b/gdb/testsuite/gdb.base/ignore-errors.exp
new file mode 100644
index 00000000000..30dac7a94e2
--- /dev/null
+++ b/gdb/testsuite/gdb.base/ignore-errors.exp
@@ -0,0 +1,24 @@
+# Copyright 2021 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+# Check command ignore-errors.
+
+clean_restart
+
+gdb_test "source ignore-errors.gdb" \
+ [multi_line \
+ "No executable file specified\\." \
+ "Use the \"file\" or \"exec-file\" command\\." \
+ "here"]
diff --git a/gdb/testsuite/gdb.base/ignore-errors.gdb b/gdb/testsuite/gdb.base/ignore-errors.gdb
new file mode 100644
index 00000000000..5962ff49b11
--- /dev/null
+++ b/gdb/testsuite/gdb.base/ignore-errors.gdb
@@ -0,0 +1,2 @@
+ignore-errors run
+echo here\n
--
2.35.3

View File

@@ -0,0 +1,41 @@
From 442c996a4de355459eeabd280649ddb282d7de41 Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Sat, 25 Jan 2025 10:08:53 +0100
Subject: [PATCH 2/2] [gdb/cli] Print AT_HWCAP3 and AT_HWCAP4
PR cli/32590
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32590
---
gdb/auxv.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/gdb/auxv.c b/gdb/auxv.c
index 8cda0b687b4..bb4c7ea70a0 100644
--- a/gdb/auxv.c
+++ b/gdb/auxv.c
@@ -453,6 +453,13 @@ fprint_auxv_entry (struct ui_file *file, const char *name,
}
}
+#ifndef AT_HWCAP3
+#define AT_HWCAP3 29
+#endif
+#ifndef AT_HWCAP4
+#define AT_HWCAP4 30
+#endif
+
/* The default implementation of gdbarch_print_auxv_entry. */
void
@@ -495,6 +502,8 @@ default_print_auxv_entry (struct gdbarch *gdbarch, struct ui_file *file,
AUXV_FORMAT_STR);
TAG (AT_RANDOM, _("Address of 16 random bytes"), AUXV_FORMAT_HEX);
TAG (AT_HWCAP2, _("Extension of AT_HWCAP"), AUXV_FORMAT_HEX);
+ TAG (AT_HWCAP3, _("Extension of AT_HWCAP"), AUXV_FORMAT_HEX);
+ TAG (AT_HWCAP4, _("Extension of AT_HWCAP"), AUXV_FORMAT_HEX);
TAG (AT_RSEQ_FEATURE_SIZE, _("rseq supported feature size"),
AUXV_FORMAT_DEC);
TAG (AT_RSEQ_ALIGN, _("rseq allocation alignment"),
--
2.43.0

View File

@@ -0,0 +1,61 @@
From b57066d1eaafab3100a8d7d788feba5802c409b7 Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Mon, 27 Jan 2025 10:33:28 +0100
Subject: [PATCH] [gdb/doc] Fix gdb.unwinder docs
When building gdb with an older makeinfo (4.13), I run into:
...
gdb/doc/python.texi:3015: warning: `(' follows defined name \
`gdb.unwinder.Unwinder.__init__' instead of whitespace.
gdb/doc/python.texi:3041: warning: `(' follows defined name \
`gdb.unwinder.FrameId.__init__' instead of whitespace.
...
The warnings are related to these two lines:
...
@defun gdb.unwinder.Unwinder.__init__(name)
...
@defun gdb.unwinder.FrameId.__init__(sp, pc, special = @code{None})
...
Indeed, when checking the command and variable index, we can see that it
contains an incorrect entry:
...
gdb.unwinder.FrameId.__init__(sp,: Unwinding Frames in Python
...
Fix this by adding a space before the left parenthesis.
Tested by rebuilding the documentation and checking the command and variable
index.
---
gdb/doc/python.texi | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/gdb/doc/python.texi b/gdb/doc/python.texi
index e49cc580b1b..58904298c71 100644
--- a/gdb/doc/python.texi
+++ b/gdb/doc/python.texi
@@ -3011,7 +3011,7 @@ unwinders can derive, though it is not required that unwinders derive
from this class, so long as any user created unwinder has the required
@code{name} and @code{enabled} attributes.
-@defun gdb.unwinder.Unwinder.__init__(name)
+@defun gdb.unwinder.Unwinder.__init__ (name)
The @var{name} is a string used to reference this unwinder within some
@value{GDBN} commands (@pxref{Managing Registered Unwinders}).
@end defun
@@ -3037,7 +3037,7 @@ most cases this class will be sufficient.
@code{gdb.unwinder.FrameId} has the following method:
-@defun gdb.unwinder.FrameId.__init__(sp, pc, special = @code{None})
+@defun gdb.unwinder.FrameId.__init__ (sp, pc, special = @code{None})
The @var{sp} and @var{pc} arguments are required and should be either
a @code{gdb.Value} object, or an integer.
base-commit: fe0e6edbcb65ab5eca50c1a0ad8ddc9844f8ea98
--
2.43.0

View File

@@ -0,0 +1,41 @@
From c23182d85ad9b5b6a45ba74993de55eac00a71bc Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Mon, 27 Jan 2025 11:22:12 +0100
Subject: [PATCH] [gdb/doc] Fix qIsAddressTagged anchor
When building gdb with an older makeinfo (4.13), I run into:
...
gdb/doc/gdb.texinfo:44159: @anchor expected braces.
gdb/doc/gdb.texinfo:44159: ` {qIsAddressTagged}
...
This is related to this line:
...
@anchor {qIsAddressTagged}
...
Fix this by removing the space before the left brace.
Tested by rebuilding the documentation.
---
gdb/doc/gdb.texinfo | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 6b08838862c..97508863776 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -44156,7 +44156,7 @@ tags found in the requested memory range.
@cindex check if a given address is in a memory tagged region
@cindex @samp{qIsAddressTagged} packet
@item qIsAddressTagged:@var{address}
-@anchor {qIsAddressTagged}
+@anchor{qIsAddressTagged}
Check if address @var{address} is in a memory tagged region; if it is, it's
said to be @dfn{tagged}. The target is responsible for checking it, as this
is architecture-specific.
base-commit: 3e2d8d7edd244dd5a82588c3e7145c47c7b539ab
--
2.43.0

View File

@@ -0,0 +1,44 @@
From 2004e74e0e28ed0b762d98380972b1e6984b9c46 Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Tue, 28 Jan 2025 08:01:46 +0100
Subject: [PATCH] [gdb/doc] Fix "Standard Replies" xref
When building gdb with an older makeinfo (4.13), I run into:
...
gdb/doc/gdb.texinfo:42613: warning: `.' or `,' must follow @xref, not `f'.
...
This is related to this line:
...
@xref{Standard Replies} for standard error responses, and how to
respond indicating a command is not supported.
...
Fix this by adding a comma.
Tested by rebuilding the docs.
Reviewed-By: Eli Zaretskii <eliz@gnu.org>
Co-Authored-By: Eli Zaretskii <eliz@gnu.org>
---
gdb/doc/gdb.texinfo | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index e5d562c00b4..0bfe6be6126 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -42610,7 +42610,7 @@ seven repeats (@samp{$}) can be expanded using a repeat count of only
five (@samp{"}). For example, @samp{00000000} can be encoded as
@samp{0*"00}.
-@xref{Standard Replies} for standard error responses, and how to
+@xref{Standard Replies}, for standard error responses, and how to
respond indicating a command is not supported.
In describing packets (commands and responses), each description has a
base-commit: 7992b582e5a55bf2fd64f2f94b854d335c36c6a5
--
2.43.0

View File

@@ -0,0 +1,232 @@
From 1e295ef5fa3a5a89e9ee08d6e60d971ddb9e6e46 Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Wed, 31 Jul 2024 13:11:48 +0200
Subject: [PATCH 13/46] [gdb/exp] Fix gdb.fortran/intrinsics.exp fail on arm
When running test-case gdb.fortran/intrinsics.exp on arm-linux, I get:
...
(gdb) p cmplx (4,4,16)^M
/home/linux/gdb/src/gdb/f-lang.c:1002: internal-error: eval_op_f_cmplx: \
Assertion `kind_arg->code () == TYPE_CODE_COMPLEX' failed.^M
A problem internal to GDB has been detected,^M
further debugging may prove unreliable.^M
----- Backtrace -----^M
FAIL: gdb.fortran/intrinsics.exp: p cmplx (4,4,16) (GDB internal error)
...
The problem is that 16-byte floats are unsupported:
...
$ gfortran test.f90
test.f90:2:17:
2 | REAL(kind=16) :: foo = 1
| 1
Error: Kind 16 not supported for type REAL at (1)
...
and consequently we end up with a builtin_real_s16 and builtin_complex_s16 with
code TYPE_CODE_ERROR.
Fix this by bailing out asap when encountering such a type.
Without this patch we're able to do the rather useless:
...
(gdb) ptype real*16
type = real*16
(gdb) ptype real_16
type = real*16
...
but with this patch we get:
...
(gdb) ptype real*16
unsupported kind 16 for type real*4
(gdb) ptype real_16
unsupported type real*16
...
Tested on arm-linux.
PR fortran/30537
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30537
---
gdb/f-exp.y | 39 +++++++++++++++++-------
gdb/testsuite/gdb.fortran/intrinsics.exp | 8 +++--
gdb/testsuite/gdb.fortran/type-kinds.exp | 22 ++++++++++---
gdb/testsuite/gdb.fortran/types.exp | 19 +++++++++++-
4 files changed, 70 insertions(+), 18 deletions(-)
diff --git a/gdb/f-exp.y b/gdb/f-exp.y
index bdf9c32a81b..259f274d341 100644
--- a/gdb/f-exp.y
+++ b/gdb/f-exp.y
@@ -754,7 +754,11 @@ typebase /* Implements (approximately): (type-qualifier)* type-specifier */
| REAL_S8_KEYWORD
{ $$ = parse_f_type (pstate)->builtin_real_s8; }
| REAL_S16_KEYWORD
- { $$ = parse_f_type (pstate)->builtin_real_s16; }
+ { $$ = parse_f_type (pstate)->builtin_real_s16;
+ if ($$->code () == TYPE_CODE_ERROR)
+ error (_("unsupported type %s"),
+ TYPE_SAFE_NAME ($$));
+ }
| COMPLEX_KEYWORD
{ $$ = parse_f_type (pstate)->builtin_complex; }
| COMPLEX_S4_KEYWORD
@@ -762,7 +766,11 @@ typebase /* Implements (approximately): (type-qualifier)* type-specifier */
| COMPLEX_S8_KEYWORD
{ $$ = parse_f_type (pstate)->builtin_complex_s8; }
| COMPLEX_S16_KEYWORD
- { $$ = parse_f_type (pstate)->builtin_complex_s16; }
+ { $$ = parse_f_type (pstate)->builtin_complex_s16;
+ if ($$->code () == TYPE_CODE_ERROR)
+ error (_("unsupported type %s"),
+ TYPE_SAFE_NAME ($$));
+ }
| SINGLE PRECISION
{ $$ = parse_f_type (pstate)->builtin_real;}
| DOUBLE PRECISION
@@ -1156,12 +1164,9 @@ push_kind_type (LONGEST val, struct type *type)
type_stack->push (tp_kind);
}
-/* Called when a type has a '(kind=N)' modifier after it, for example
- 'character(kind=1)'. The BASETYPE is the type described by 'character'
- in our example, and KIND is the integer '1'. This function returns a
- new type that represents the basetype of a specific kind. */
+/* Helper function for convert_to_kind_type. */
static struct type *
-convert_to_kind_type (struct type *basetype, int kind)
+convert_to_kind_type_1 (struct type *basetype, int kind)
{
if (basetype == parse_f_type (pstate)->builtin_character)
{
@@ -1211,13 +1216,25 @@ convert_to_kind_type (struct type *basetype, int kind)
return parse_f_type (pstate)->builtin_integer_s8;
}
- error (_("unsupported kind %d for type %s"),
- kind, TYPE_SAFE_NAME (basetype));
-
- /* Should never get here. */
return nullptr;
}
+/* Called when a type has a '(kind=N)' modifier after it, for example
+ 'character(kind=1)'. The BASETYPE is the type described by 'character'
+ in our example, and KIND is the integer '1'. This function returns a
+ new type that represents the basetype of a specific kind. */
+static struct type *
+convert_to_kind_type (struct type *basetype, int kind)
+{
+ struct type *res = convert_to_kind_type_1 (basetype, kind);
+
+ if (res == nullptr || res->code () == TYPE_CODE_ERROR)
+ error (_("unsupported kind %d for type %s"),
+ kind, TYPE_SAFE_NAME (basetype));
+
+ return res;
+}
+
struct f_token
{
/* The string to match against. */
diff --git a/gdb/testsuite/gdb.fortran/intrinsics.exp b/gdb/testsuite/gdb.fortran/intrinsics.exp
index 60c79f956dc..060bb53db97 100644
--- a/gdb/testsuite/gdb.fortran/intrinsics.exp
+++ b/gdb/testsuite/gdb.fortran/intrinsics.exp
@@ -112,10 +112,14 @@ gdb_test "ptype cmplx (4,4)" "= complex\\*4"
gdb_test "p cmplx (-14,-4)" "= \\(-14,-4\\)"
gdb_test "p cmplx (4,4,4)" "\\(4,4\\)"
gdb_test "p cmplx (4,4,8)" "\\(4,4\\)"
-gdb_test "p cmplx (4,4,16)" "\\(4,4\\)"
+set re_unsupported_kind_16 \
+ [string_to_regexp "unsupported kind 16 for type complex*4"]
+gdb_test "p cmplx (4,4,16)" \
+ ([string_to_regexp " = (4,4)"]|$re_unsupported_kind_16)
gdb_test "ptype cmplx (4,4,4)" "= complex\\*4"
gdb_test "ptype cmplx (4,4,8)" "= complex\\*8"
-gdb_test "ptype cmplx (4,4,16)" "= complex\\*16"
+gdb_test "ptype cmplx (4,4,16)" \
+ ([string_to_regexp " = complex*16"]|$re_unsupported_kind_16)
gdb_test "p cmplx (4,4,1)" "unsupported kind 1 for type complex\\*4"
gdb_test "p cmplx (4,4,-1)" "unsupported kind -1 for type complex\\*4"
diff --git a/gdb/testsuite/gdb.fortran/type-kinds.exp b/gdb/testsuite/gdb.fortran/type-kinds.exp
index ab5f19f97a4..a6f2aa4e870 100644
--- a/gdb/testsuite/gdb.fortran/type-kinds.exp
+++ b/gdb/testsuite/gdb.fortran/type-kinds.exp
@@ -43,12 +43,20 @@ proc test_basic_parsing_of_type_kinds {} {
test_cast_1_to_type_kind "complex" "" "\\(1,0\\)" "8"
test_cast_1_to_type_kind "complex" "4" "\\(1,0\\)" "8"
test_cast_1_to_type_kind "complex" "8" "\\(1,0\\)" "16"
- test_cast_1_to_type_kind "complex" "16" "\\(1,0\\)" "32"
+ set re_unsupported_kind \
+ [string_to_regexp "unsupported kind 16 for type complex*4"]
+ test_cast_1_to_type_kind "complex" "16" \
+ [string_to_regexp (1,0)]|$re_unsupported_kind \
+ 32|$re_unsupported_kind
test_cast_1_to_type_kind "real" "" "1" "4"
test_cast_1_to_type_kind "real" "4" "1" "4"
test_cast_1_to_type_kind "real" "8" "1" "8"
- test_cast_1_to_type_kind "real" "16" "1" "16"
+ set re_unsupported_kind \
+ [string_to_regexp "unsupported kind 16 for type real*4"]
+ test_cast_1_to_type_kind "real" "16" \
+ 1|$re_unsupported_kind \
+ 16|$re_unsupported_kind
test_cast_1_to_type_kind "logical" "" "\\.TRUE\\." "4"
test_cast_1_to_type_kind "logical" "1" "\\.TRUE\\." "1"
@@ -83,11 +91,17 @@ proc test_old_star_type_sizes {} {
gdb_test "p ((complex*4) 1)" " = \\(1,0\\)"
gdb_test "p ((complex*8) 1)" " = \\(1,0\\)"
- gdb_test "p ((complex*16) 1)" " = \\(1,0\\)"
+ set re_unsupported_kind \
+ [string_to_regexp "unsupported kind 16 for type complex*4"]
+ gdb_test "p ((complex*16) 1)" \
+ [string_to_regexp " = (1,0)"]|$re_unsupported_kind
gdb_test "p ((real*4) 1)" " = 1"
gdb_test "p ((real*8) 1)" " = 1"
- gdb_test "p ((real*16) 1)" " = 1"
+ set re_unsupported_kind \
+ [string_to_regexp "unsupported kind 16 for type real*4"]
+ gdb_test "p ((real*16) 1)" \
+ "( = 1|$re_unsupported_kind)"
gdb_test "p ((logical*1) 1)" " = \\.TRUE\\."
gdb_test "p ((logical*4) 1)" " = \\.TRUE\\."
diff --git a/gdb/testsuite/gdb.fortran/types.exp b/gdb/testsuite/gdb.fortran/types.exp
index 83b109869e6..edbf5abee97 100644
--- a/gdb/testsuite/gdb.fortran/types.exp
+++ b/gdb/testsuite/gdb.fortran/types.exp
@@ -94,7 +94,24 @@ proc test_primitive_types_known {} {
# While TYPE_KIND is allowed as input, GDB will always return the
# Fortran notation TYPE*KIND
regsub -all "_" $type "\*" type_res
- gdb_test "ptype $type" [string_to_regexp "type = $type_res"]
+ set re [string_to_regexp "type = $type_res"]
+ switch $type {
+ real*16 - complex*16 {
+ regexp {^[^*_]*} $type base
+ set re_unsupported \
+ [string_to_regexp \
+ "unsupported kind 16 for type $base*4"]
+ set re ($re|$re_unsupported)
+ }
+ real_16 - complex_16 {
+ set re_unsupported \
+ [string_to_regexp \
+ "unsupported type $type_res"]
+ set re ($re|$re_unsupported)
+ }
+ }
+
+ gdb_test "ptype $type" $re
}
}
--
2.43.0

10
gdb-gcore-bash.patch Normal file
View File

@@ -0,0 +1,10 @@
diff --git a/gdb/gcore.in b/gdb/gcore.in
index b9770ea415..3149f6e1fe 100644
--- a/gdb/gcore.in
+++ b/gdb/gcore.in
@@ -1,4 +1,4 @@
-#!/usr/bin/env bash
+#!/bin/bash
# Copyright (C) 2003-2024 Free Software Foundation, Inc.

48
gdb-gstack.man Normal file
View File

@@ -0,0 +1,48 @@
.\"
.\" gstack manual page.
.\" Copyright (c) 1999 Ross Thompson
.\" Copyright (c) 2001, 2002, 2004, 2008 Red Hat, Inc.
.\"
.\" Original author: Ross Thompson <ross@whatsis.com>
.\"
.\" This program is free software; you can redistribute it and/or modify
.\" it under the terms of the GNU General Public License as published by
.\" the Free Software Foundation; either version 2, or (at your option)
.\" any later version.
.\"
.\" This program is distributed in the hope that it will be useful,
.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
.\" GNU General Public License for more details.
.\"
.\" You should have received a copy of the GNU General Public License
.\" along with this program; see the file COPYING. If not, write to
.\" the Free Software Foundation, 59 Temple Place - Suite 330,
.\" Boston, MA 02111-1307, USA.
.\"
.TH GSTACK 1 "Feb 15 2008" "Red Hat Linux" "Linux Programmer's Manual"
.SH NAME
gstack \- print a stack trace of a running process
.SH SYNOPSIS
.B gstack
pid
.SH DESCRIPTION
\f3gstack\f1 attaches to the active process named by the \f3pid\f1 on
the command line, and prints out an execution stack trace. If ELF
symbols exist in the binary (usually the case unless you have run
strip(1)), then symbolic addresses are printed as well.
If the process is part of a thread group, then \f3gstack\f1 will print
out a stack trace for each of the threads in the group.
.SH SEE ALSO
nm(1), ptrace(2), gdb(1)
.SH AUTHORS
Ross Thompson <ross@whatsis.com>
Red Hat, Inc. <http://bugzilla.redhat.com/bugzilla>

View File

@@ -0,0 +1,68 @@
From fe0e6edbcb65ab5eca50c1a0ad8ddc9844f8ea98 Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Mon, 27 Jan 2025 09:23:18 +0100
Subject: [PATCH] [gdb/guile] Use SCM_DEBUG_TYPING_STRICTNESS 0
I build gdb with libguile v2.0.9, and ran into:
...
In file included from /usr/include/guile/2.0/libguile.h:56,
from ../../gdb/guile/guile-internal.h:30,
from ../../gdb/guile/scm-arch.c:26:
/usr/include/guile/2.0/libguile/inline.h: In function 'int scm_is_pair(SCM)':
/usr/include/guile/2.0/libguile/tags.h:97:53: error: \
operation on '*0' may be undefined [-Werror=sequence-point]
# define SCM_UNPACK(x) ((scm_t_bits) (0? (*(SCM*)0=(x)): x))
~~~~~~~~~^~~~~
...
Fix this by using SCM_DEBUG_TYPING_STRICTNESS 0.
We were already using this for c++20 due to a Werror=volatile in SCM_UNPACK
when using libguile v2.0.10.
Tested on x86_64-linux.
---
gdb/guile/guile-internal.h | 22 +++++++++++++++++++++-
1 file changed, 21 insertions(+), 1 deletion(-)
diff --git a/gdb/guile/guile-internal.h b/gdb/guile/guile-internal.h
index be16fee0dd2..6665bfc7813 100644
--- a/gdb/guile/guile-internal.h
+++ b/gdb/guile/guile-internal.h
@@ -27,10 +27,30 @@
#include "hashtab.h"
#include "extension-priv.h"
#include "symtab.h"
-#include "libguile.h"
#include "objfiles.h"
#include "top.h"
+/* For libguile v2.0.9 and SCM_DEBUG_TYPING_STRICTNESS == 1, SCM_UNPACK(x) is
+ defined as:
+
+ ((scm_t_bits) (0? (*(SCM*)0=(x)): x))
+
+ and for v2.0.10 it's defined as:
+
+ ((scm_t_bits) (0? (*(volatile SCM *)0=(x)): x))
+
+ The volatile was added to avoid a clang warning.
+
+ The latter form causes a Werror=volatile with C++20.
+ This was reported upstream (
+ https://debbugs.gnu.org/cgi/bugreport.cgi?bug=65333 ).
+
+ The former form causes a Werror=sequence-point with gcc 7-14.
+
+ Work around these problem by using SCM_DEBUG_TYPING_STRICTNESS == 0. */
+#define SCM_DEBUG_TYPING_STRICTNESS 0
+#include "libguile.h"
+
struct block;
struct frame_info;
struct objfile;
base-commit: 94df6741bbabaa9a51960446b2af4c0bed01b54b
--
2.43.0

752
gdb-orphanripper.c Normal file
View File

@@ -0,0 +1,752 @@
/*
* Copyright 2006-2007 Free Software Foundation, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* Reap any leftover children possibly holding file descriptors.
* Children are identified by the stale file descriptor or PGID / SID.
* Both can be missed but only the stale file descriptors are important for us.
* PGID / SID may be set by the children on their own.
* If we fine a candidate we kill it will all its process tree (grandchildren).
* The child process is run with `2>&1' redirection (due to forkpty(3)).
* 2007-07-10 Jan Kratochvil <jan.kratochvil@redhat.com>
*/
/* For getpgid(2). */
#define _GNU_SOURCE 1
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <dirent.h>
#include <unistd.h>
#include <errno.h>
#include <ctype.h>
#include <string.h>
#include <limits.h>
#include <fcntl.h>
#include <assert.h>
#include <pty.h>
#include <poll.h>
#include <sys/stat.h>
#define LENGTH(x) (sizeof (x) / sizeof (*(x)))
static const char *progname;
static volatile pid_t child;
static void signal_chld (int signo)
{
}
static volatile int signal_alrm_hit = 0;
static void signal_alrm (int signo)
{
signal_alrm_hit = 1;
}
static char childptyname[LINE_MAX];
static void print_child_error (const char *reason, char **argv)
{
char **sp;
fprintf (stderr, "%s: %d %s:", progname, (int) child, reason);
for (sp = argv; *sp != NULL; sp++)
{
fputc (' ', stderr);
fputs (*sp, stderr);
}
fputc ('\n', stderr);
}
static int read_out (int amaster)
{
char buf[LINE_MAX];
ssize_t buf_got;
buf_got = read (amaster, buf, sizeof buf);
if (buf_got == 0)
return 0;
/* Weird but at least after POLLHUP we get EIO instead of just EOF. */
if (buf_got == -1 && errno == EIO)
return 0;
if (buf_got == -1 && errno == EAGAIN)
return 0;
if (buf_got < 0)
{
perror ("read (amaster)");
exit (EXIT_FAILURE);
}
if (write (STDOUT_FILENO, buf, buf_got) != buf_got)
{
perror ("write(2)");
exit (EXIT_FAILURE);
}
return 1;
}
/* kill (child, 0) == 0 sometimes even when CHILD's state is already "Z". */
static int child_exited (void)
{
char buf[200];
int fd, i, retval;
ssize_t got;
char state[3];
snprintf (buf, sizeof (buf), "/proc/%ld/stat", (long) child);
fd = open (buf, O_RDONLY);
if (fd == -1)
{
perror ("open (/proc/CHILD/stat)");
exit (EXIT_FAILURE);
}
got = read (fd, buf, sizeof(buf));
if (got <= 0)
{
perror ("read (/proc/CHILD/stat)");
exit (EXIT_FAILURE);
}
if (close (fd) != 0)
{
perror ("close (/proc/CHILD/stat)");
exit (EXIT_FAILURE);
}
/* RHEL-5 does not support %ms. */
i = sscanf (buf, "%*d%*s%2s", state);
if (i != 1)
{
perror ("sscanf (/proc/CHILD/stat)");
exit (EXIT_FAILURE);
}
retval = strcmp (state, "Z") == 0;
return retval;
}
static int spawn (char **argv, int timeout)
{
pid_t child_got;
int status, amaster, i, rc;
struct sigaction act;
sigset_t set;
struct termios termios;
unsigned alarm_orig;
/* We do not use signal(2) to be sure we do not have SA_RESTART. */
memset (&act, 0, sizeof (act));
act.sa_handler = signal_chld;
i = sigemptyset (&act.sa_mask);
assert (i == 0);
act.sa_flags = 0; /* !SA_RESTART */
i = sigaction (SIGCHLD, &act, NULL);
assert (i == 0);
i = sigemptyset (&set);
assert (i == 0);
i = sigaddset (&set, SIGCHLD);
assert (i == 0);
i = sigprocmask (SIG_SETMASK, &set, NULL);
assert (i == 0);
/* With TERMP passed as NULL we get "\n" -> "\r\n". */
termios.c_iflag = IGNBRK | IGNPAR;
termios.c_oflag = 0;
termios.c_cflag = CS8 | CREAD | CLOCAL | HUPCL | B9600;
termios.c_lflag = IEXTEN | NOFLSH;
memset (termios.c_cc, _POSIX_VDISABLE, sizeof (termios.c_cc));
termios.c_cc[VTIME] = 0;
termios.c_cc[VMIN ] = 1;
cfmakeraw (&termios);
#ifdef FLUSHO
/* Workaround a readline deadlock bug in _get_tty_settings(). */
termios.c_lflag &= ~FLUSHO;
#endif
child = forkpty (&amaster, childptyname, &termios, NULL);
switch (child)
{
case -1:
perror ("forkpty(3)");
exit (EXIT_FAILURE);
case 0:
/* Do not replace STDIN as inferiors query its termios. */
#if 0
i = close (STDIN_FILENO);
assert (i == 0);
i = open ("/dev/null", O_RDONLY);
assert (i == STDIN_FILENO);
#endif
i = sigemptyset (&set);
assert (i == 0);
i = sigprocmask (SIG_SETMASK, &set, NULL);
assert (i == 0);
/* Do not setpgrp(2) in the parent process as the process-group
is shared for the whole sh(1) pipeline we could be a part
of. The process-group is set according to PID of the first
command in the pipeline.
We would rip even vi(1) in the case of:
./orphanripper sh -c 'sleep 1&' | vi -
*/
/* Do not setpgrp(2) as our pty would not be ours and we would
get `SIGSTOP' later, particularly after spawning gdb(1).
setsid(3) was already executed by forkpty(3) and it would fail if
executed again. */
if (getpid() != getpgrp ())
{
perror ("getpgrp(2)");
exit (EXIT_FAILURE);
}
execvp (argv[0], argv);
perror ("execvp(2)");
exit (EXIT_FAILURE);
default:
break;
}
i = fcntl (amaster, F_SETFL, O_RDWR | O_NONBLOCK);
if (i != 0)
{
perror ("fcntl (amaster, F_SETFL, O_NONBLOCK)");
exit (EXIT_FAILURE);
}
/* We do not use signal(2) to be sure we do not have SA_RESTART. */
act.sa_handler = signal_alrm;
i = sigaction (SIGALRM, &act, NULL);
assert (i == 0);
alarm_orig = alarm (timeout);
assert (alarm_orig == 0);
i = sigemptyset (&set);
assert (i == 0);
while (!signal_alrm_hit)
{
struct pollfd pollfd;
pollfd.fd = amaster;
pollfd.events = POLLIN;
i = ppoll (&pollfd, 1, NULL, &set);
if (i == -1 && errno == EINTR)
{
if (child_exited ())
break;
/* Non-CHILD child may have exited. */
continue;
}
assert (i == 1);
/* Data available? Process it first. */
if (pollfd.revents & POLLIN)
{
if (!read_out (amaster))
{
fprintf (stderr, "%s: Unexpected EOF\n", progname);
exit (EXIT_FAILURE);
}
}
if (pollfd.revents & POLLHUP)
break;
if ((pollfd.revents &= ~POLLIN) != 0)
{
fprintf (stderr, "%s: ppoll(2): revents 0x%x\n", progname,
(unsigned) pollfd.revents);
exit (EXIT_FAILURE);
}
/* Child exited? */
if (child_exited ())
break;
}
if (signal_alrm_hit)
{
i = kill (child, SIGKILL);
assert (i == 0);
}
else
alarm (0);
/* WNOHANG still could fail. */
child_got = waitpid (child, &status, 0);
if (child != child_got)
{
fprintf (stderr, "waitpid (%d) = %d: %m\n", (int) child, (int) child_got);
exit (EXIT_FAILURE);
}
if (signal_alrm_hit)
{
char *buf;
if (asprintf (&buf, "Timed out after %d seconds", timeout) != -1)
{
print_child_error (buf, argv);
free (buf);
}
rc = 128 + SIGALRM;
}
else if (WIFEXITED (status))
rc = WEXITSTATUS (status);
else if (WIFSIGNALED (status))
{
print_child_error (strsignal (WTERMSIG (status)), argv);
rc = 128 + WTERMSIG (status);
}
else if (WIFSTOPPED (status))
{
fprintf (stderr, "waitpid (%d): WIFSTOPPED - WSTOPSIG is %d\n",
(int) child, WSTOPSIG (status));
exit (EXIT_FAILURE);
}
else
{
fprintf (stderr, "waitpid (%d): !WIFEXITED (%d)\n", (int) child, status);
exit (EXIT_FAILURE);
}
/* Not used in fact. */
i = sigprocmask (SIG_SETMASK, &set, NULL);
assert (i == 0);
/* Do not unset O_NONBLOCK as a stale child (the whole purpose of this
program) having open its output pty would block us in read_out. */
#if 0
i = fcntl (amaster, F_SETFL, O_RDONLY /* !O_NONBLOCK */);
if (i != 0)
{
perror ("fcntl (amaster, F_SETFL, O_RDONLY /* !O_NONBLOCK */)");
exit (EXIT_FAILURE);
}
#endif
while (read_out (amaster));
/* Do not close the master FD as the child would have `/dev/pts/23 (deleted)'
entries which are not expected (and expecting ` (deleted)' would be
a race. */
#if 0
i = close (amaster);
if (i != 0)
{
perror ("close (forkpty ()'s amaster)");
exit (EXIT_FAILURE);
}
#endif
return rc;
}
/* Detected commandline may look weird due to a race:
Original command:
./orphanripper sh -c 'sleep 1&' &
Correct output:
[1] 29610
./orphanripper: Killed -9 orphan PID 29612 (PGID 29611): sleep 1
Raced output (sh(1) child still did not update its argv[]):
[1] 29613
./orphanripper: Killed -9 orphan PID 29615 (PGID 29614): sh -c sleep 1&
We could delay a bit before ripping the children. */
static const char *read_cmdline (pid_t pid)
{
char cmdline_fname[32];
static char cmdline[LINE_MAX];
int fd;
ssize_t got;
char *s;
if (snprintf (cmdline_fname, sizeof cmdline_fname, "/proc/%d/cmdline",
(int) pid) < 0)
return NULL;
fd = open (cmdline_fname, O_RDONLY);
if (fd == -1)
{
/* It may have already exited - ENOENT. */
#if 0
fprintf (stderr, "%s: open (\"%s\"): %m\n", progname, cmdline_fname);
#endif
return NULL;
}
got = read (fd, cmdline, sizeof (cmdline) - 1);
if (got == -1)
fprintf (stderr, "%s: read (\"%s\"): %m\n", progname,
cmdline_fname);
if (close (fd) != 0)
fprintf (stderr, "%s: close (\"%s\"): %m\n", progname,
cmdline_fname);
if (got < 0)
return NULL;
/* Convert '\0' argument delimiters to spaces. */
for (s = cmdline; s < cmdline + got; s++)
if (!*s)
*s = ' ';
/* Trim the trailing spaces (typically single '\0'->' '). */
while (s > cmdline && isspace (s[-1]))
s--;
*s = 0;
return cmdline;
}
static int dir_scan (const char *dirname,
int (*callback) (struct dirent *dirent, const char *pathname))
{
DIR *dir;
struct dirent *dirent;
int rc = 0;
dir = opendir (dirname);
if (dir == NULL)
{
if (errno == EACCES || errno == ENOENT)
return rc;
fprintf (stderr, "%s: opendir (\"%s\"): %m\n", progname, dirname);
exit (EXIT_FAILURE);
}
while ((errno = 0, dirent = readdir (dir)))
{
char pathname[LINE_MAX];
int pathname_len;
pathname_len = snprintf (pathname, sizeof pathname, "%s/%s",
dirname, dirent->d_name);
if (pathname_len <= 0 || pathname_len >= (int) sizeof pathname)
{
fprintf (stderr, "entry file name too long: `%s' / `%s'\n",
dirname, dirent->d_name);
continue;
}
/* RHEL-4.5 on s390x never fills in D_TYPE. */
if (dirent->d_type == DT_UNKNOWN)
{
struct stat statbuf;
int i;
/* We are not interested in the /proc/PID/fd/ links targets. */
i = lstat (pathname, &statbuf);
if (i == -1)
{
if (errno == EACCES || errno == ENOENT)
continue;
fprintf (stderr, "%s: stat (\"%s\"): %m\n", progname, pathname);
exit (EXIT_FAILURE);
}
if (S_ISDIR (statbuf.st_mode))
dirent->d_type = DT_DIR;
if (S_ISLNK (statbuf.st_mode))
dirent->d_type = DT_LNK;
/* No other D_TYPE types used in this code. */
}
rc = (*callback) (dirent, pathname);
if (rc != 0)
{
errno = 0;
break;
}
}
if (errno != 0)
{
fprintf (stderr, "%s: readdir (\"%s\"): %m\n", progname, dirname);
exit (EXIT_FAILURE);
}
if (closedir (dir) != 0)
{
fprintf (stderr, "%s: closedir (\"%s\"): %m\n", progname, dirname);
exit (EXIT_FAILURE);
}
return rc;
}
static int fd_fs_scan (pid_t pid, int (*func) (pid_t pid, const char *link))
{
char dirname[64];
if (snprintf (dirname, sizeof dirname, "/proc/%d/fd", (int) pid) < 0)
{
perror ("snprintf(3)");
exit (EXIT_FAILURE);
}
int callback (struct dirent *dirent, const char *pathname)
{
char buf[LINE_MAX];
ssize_t buf_len;
if ((dirent->d_type != DT_DIR && dirent->d_type != DT_LNK)
|| (dirent->d_type == DT_DIR && strcmp (dirent->d_name, ".") != 0
&& strcmp (dirent->d_name, "..") != 0)
|| (dirent->d_type == DT_LNK && strspn (dirent->d_name, "0123456789")
!= strlen (dirent->d_name)))
{
fprintf (stderr, "Unexpected entry \"%s\" (d_type %u)"
" on readdir (\"%s\"): %m\n",
dirent->d_name, (unsigned) dirent->d_type, dirname);
return 0;
}
if (dirent->d_type == DT_DIR)
return 0;
buf_len = readlink (pathname, buf, sizeof buf - 1);
if (buf_len <= 0 || buf_len >= (ssize_t) sizeof buf - 1)
{
if (errno != ENOENT && errno != EACCES)
fprintf (stderr, "Error reading link \"%s\": %m\n", pathname);
return 0;
}
buf[buf_len] = 0;
return (*func) (pid, buf);
}
return dir_scan (dirname, callback);
}
static void pid_fs_scan (void (*func) (pid_t pid, void *data), void *data)
{
int callback (struct dirent *dirent, const char *pathname)
{
if (dirent->d_type != DT_DIR
|| strspn (dirent->d_name, "0123456789") != strlen (dirent->d_name))
return 0;
(*func) (atoi (dirent->d_name), data);
return 0;
}
dir_scan ("/proc", callback);
}
static int rip_check_ptyname (pid_t pid, const char *link)
{
assert (pid != getpid ());
return strcmp (link, childptyname) == 0;
}
struct pid
{
struct pid *next;
pid_t pid;
};
static struct pid *pid_list;
static int pid_found (pid_t pid)
{
struct pid *entry;
for (entry = pid_list; entry != NULL; entry = entry->next)
if (entry->pid == pid)
return 1;
return 0;
}
/* Single pass is not enough, a (multithreaded) process was seen to survive.
Repeated killing of the same process is not enough, zombies can be killed.
*/
static int cleanup_acted;
static void pid_record (pid_t pid)
{
struct pid *entry;
if (pid_found (pid))
return;
cleanup_acted = 1;
entry = malloc (sizeof (*entry));
if (entry == NULL)
{
fprintf (stderr, "%s: malloc: %m\n", progname);
exit (EXIT_FAILURE);
}
entry->pid = pid;
entry->next = pid_list;
pid_list = entry;
}
static void pid_forall (void (*func) (pid_t pid))
{
struct pid *entry;
for (entry = pid_list; entry != NULL; entry = entry->next)
(*func) (entry->pid);
}
/* Returns 0 on failure. */
static pid_t pid_get_parent (pid_t pid)
{
char fname[64];
FILE *f;
char line[LINE_MAX];
pid_t retval = 0;
if (snprintf (fname, sizeof fname, "/proc/%d/status", (int) pid) < 0)
{
perror ("snprintf(3)");
exit (EXIT_FAILURE);
}
f = fopen (fname, "r");
if (f == NULL)
{
return 0;
}
while (errno = 0, fgets (line, sizeof line, f) == line)
{
if (strncmp (line, "PPid:\t", sizeof "PPid:\t" - 1) != 0)
continue;
retval = atoi (line + sizeof "PPid:\t" - 1);
errno = 0;
break;
}
if (errno != 0)
{
fprintf (stderr, "%s: fgets (\"%s\"): %m\n", progname, fname);
exit (EXIT_FAILURE);
}
if (fclose (f) != 0)
{
fprintf (stderr, "%s: fclose (\"%s\"): %m\n", progname, fname);
exit (EXIT_FAILURE);
}
return retval;
}
static void killtree (pid_t pid);
static void killtree_pid_fs_scan (pid_t pid, void *data)
{
pid_t parent_pid = *(pid_t *) data;
/* Do not optimize it as we could miss some newly spawned processes.
Always traverse all the leaves. */
#if 0
/* Optimization. */
if (pid_found (pid))
return;
#endif
if (pid_get_parent (pid) != parent_pid)
return;
killtree (pid);
}
static void killtree (pid_t pid)
{
pid_record (pid);
pid_fs_scan (killtree_pid_fs_scan, &pid);
}
static void rip_pid_fs_scan (pid_t pid, void *data)
{
pid_t pgid;
/* Shouldn't happen. */
if (pid == getpid ())
return;
/* Check both PGID and the stale file descriptors. */
pgid = getpgid (pid);
if (pgid == child
|| fd_fs_scan (pid, rip_check_ptyname) != 0)
killtree (pid);
}
static void killproc (pid_t pid)
{
const char *cmdline;
cmdline = read_cmdline (pid);
/* Avoid printing the message for already gone processes. */
if (kill (pid, 0) != 0 && errno == ESRCH)
return;
if (cmdline == NULL)
cmdline = "<error>";
fprintf (stderr, "%s: Killed -9 orphan PID %d: %s\n", progname, (int) pid, cmdline);
if (kill (pid, SIGKILL) == 0)
cleanup_acted = 1;
else if (errno != ESRCH)
fprintf (stderr, "%s: kill (%d, SIGKILL): %m\n", progname, (int) pid);
/* RHEL-3 kernels cannot SIGKILL a `T (stopped)' process. */
kill (pid, SIGCONT);
/* Do not waitpid(2) as it cannot be our direct descendant and it gets
cleaned up by init(8). */
#if 0
pid_t pid_got;
pid_got = waitpid (pid, NULL, 0);
if (pid != pid_got)
{
fprintf (stderr, "%s: waitpid (%d) != %d: %m\n", progname,
(int) pid, (int) pid_got);
return;
}
#endif
}
static void rip (void)
{
cleanup_acted = 0;
do
{
if (cleanup_acted)
usleep (1000000 / 10);
cleanup_acted = 0;
pid_fs_scan (rip_pid_fs_scan, NULL);
pid_forall (killproc);
}
while (cleanup_acted);
}
int main (int argc, char **argv)
{
int timeout = 0;
int rc;
progname = *argv++;
argc--;
if (argc < 1 || strcmp (*argv, "-h") == 0
|| strcmp (*argv, "--help") == 0)
{
puts ("Syntax: orphanripper [-t <seconds>] <execvp(3) commandline>");
exit (EXIT_FAILURE);
}
if ((*argv)[0] == '-' && (*argv)[1] == 't')
{
char *timeout_s = NULL;
if ((*argv)[2] == 0)
timeout_s = *++argv;
else if (isdigit ((*argv)[2]))
timeout_s = (*argv) + 2;
if (timeout_s != NULL)
{
long l;
char *endptr;
argv++;
l = strtol (timeout_s, &endptr, 0);
timeout = l;
if ((endptr != NULL && *endptr != 0) || timeout < 0 || timeout != l)
{
fprintf (stderr, "%s: Invalid timeout value: %s\n", progname,
timeout_s);
exit (EXIT_FAILURE);
}
}
}
rc = spawn (argv, timeout);
rip ();
return rc;
}

View File

@@ -0,0 +1,130 @@
From 22d05b4879b8608e3768483735140a729952b565 Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Sun, 18 Aug 2024 20:51:29 +0200
Subject: [PATCH 39/46] [gdb] Prune inferior after switching inferior
Usually with test-case gdb.python/py-progspace-events.exp I get:
...
(gdb) inferior 1^M
[Switching to inferior 1 [process 4116] (py-progspace-events)]^M
[Switching to thread 1.1 (Thread 0xf77d0ce0 (LWP 4116))]^M
28 { /* Nothing. */ }^M
(gdb) PASS: gdb.python/py-progspace-events.exp: inferior 1
step^M
FreeProgspaceEvent: <gdb.Progspace object at 0xabf4f850>^M
do_parent_stuff () at py-progspace-events.c:41^M
41 ++global_var;^M
(gdb) PASS: gdb.python/py-progspace-events.exp: step
...
But occasionally I run into the following FAIL:
...
(gdb) inferior 1^M
[Switching to inferior 1 [process 5199] (py-progspace-events)]^M
[Switching to thread 1.1 (Thread 0xf77d0ce0 (LWP 5199))]^M
28 { /* Nothing. */ }^M
(gdb) FreeProgspaceEvent: <gdb.Progspace object at 0xabaf03a0>^M
FAIL: gdb.python/py-progspace-events.exp: inferior 1 (timeout)
...
This is caused by a race between the handling of an event, and the
"inferior 1" command.
In the passing case, the event is handled first. During which prune_inferiors
is called, but it can't remove inferior 2, because it's still the current one.
In the failing case, the "inferior 1" command is handled first. Then during
handling of the event, prune_inferiors is called, and it can remove inferior 2
because it's no longer the current one.
This looks like a test-case issue to me, but ISTM that we can do better: by
calling prune_inferiors asap, at the end of the "inferior 1" command, we
stabilize the moment when the inferior is removed:
...
(gdb) inferior 1^M
[Switching to inferior 1 [process 5199] (py-progspace-events)]^M
[Switching to thread 1.1 (Thread 0xf77d0ce0 (LWP 5199))]^M
28 { /* Nothing. */ }^M
FreeProgspaceEvent: <gdb.Progspace object at 0xabaf03a0>^M
(gdb) PASS: gdb.python/py-progspace-events.exp: inferior 1
...
This also allows us to simplify the test-case by removing the step command,
which is no longer required to trigger the pruning of the inferior.
Tested on x86_64-linux.
Approved-by: Kevin Buettner <kevinb@redhat.com>
PR gdb/31440
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31440
---
gdb/inferior.c | 4 +++
.../gdb.python/py-progspace-events.exp | 31 +++----------------
2 files changed, 9 insertions(+), 26 deletions(-)
diff --git a/gdb/inferior.c b/gdb/inferior.c
index 0522cb5c14d..2a19c5b19a1 100644
--- a/gdb/inferior.c
+++ b/gdb/inferior.c
@@ -790,6 +790,10 @@ inferior_command (const char *args, int from_tty)
notify_user_selected_context_changed
(USER_SELECTED_INFERIOR);
}
+
+ /* Switching current inferior may have made one of the inferiors
+ prunable, so prune it. */
+ prune_inferiors ();
}
}
diff --git a/gdb/testsuite/gdb.python/py-progspace-events.exp b/gdb/testsuite/gdb.python/py-progspace-events.exp
index 95e4ca8da0b..9dfc7573d40 100644
--- a/gdb/testsuite/gdb.python/py-progspace-events.exp
+++ b/gdb/testsuite/gdb.python/py-progspace-events.exp
@@ -79,37 +79,16 @@ gdb_test "continue" \
"\\\[Inferior $decimal \[^\r\n\]+ exited normally\\\]"] \
"continue until inferior 2 exits"
-gdb_test "inferior 1" "\\\[Switching to inferior 1 .*"
-
-# Step the inferior. During this process GDB will prune the now
+# Switch to inferior 1. During this process GDB will prune the now
# defunct inferior, which deletes its program space, which should
# trigger the FreeProgspaceEvent.
#
-# However, there is a slight problem. When the target is remote, and
-# GDB is accessing files using remote fileio, then GDB will attempt to
-# prune the inferior at a point in time when the remote target is
-# waiting for a stop reply. Pruning an inferior causes GDB to close
-# files associated with that inferior.
-#
-# In non-async mode we can't send fileio packets while waiting for a
-# stop reply, so the attempts to close files fails, and this shows up
-# as an error.
-#
-# As this error has nothing to do with the feature being tested here,
-# we just accept the error message, the important part is the
-# 'FreeProgspaceEvent' string, so long as that appears (just once)
-# then the test is a success.
-set warning_msg \
- [multi_line \
- "warning: cannot close \"\[^\r\n\]+\": Cannot execute this command while the target is running\\." \
- "Use the \"interrupt\" command to stop the target" \
- "and then try again\\."]
-gdb_test "step" \
+gdb_test "inferior 1" \
[multi_line \
- "^FreeProgspaceEvent.*: <gdb.Progspace object at $hex>(?:\r\n$warning_msg)*" \
- "do_parent_stuff \\(\\) at \[^\r\n\]+" \
- "$decimal\\s+\[^\r\n\]+"]
+ "\\\[Switching to inferior 1 .*" \
+ ".*" \
+ "FreeProgspaceEvent.*: <gdb.Progspace object at $hex>"]
# Let this inferior run to completion.
gdb_continue_to_end
--
2.43.0

View File

@@ -0,0 +1,445 @@
From 086a725aa02b1195f63b2df4c2a2b4516788b2c6 Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Thu, 18 Apr 2024 14:27:04 +0200
Subject: [PATCH 42/46] gdb-python-finishbreakpoint-update
[gdb/python] FinishBreakPoint update
I.
Consider the python gdb.FinishBreakpoint class, an extension of the
gdb.Breakpoint class.
It sets a temporary breakpoint on the return address of a frame.
This type of breakpoints is thread-specific.
II.
If the FinishBreakpoint is hit, it is deleted, and the method return_value
can be used to get the value returned by the function.
Let's demonstrate this:
...
$ cat -n test.c
1 int foo (int a) { return a + 2; }
2 int main () { return foo (1); }
$ gcc -g test.c
$ gdb -q -batch a.out -ex "set trace-commands on" -ex "tbreak foo" -ex run \
-ex "python bp = gdb.FinishBreakpoint()" -ex "info breakpoints" \
-ex continue -ex "info breakpoints" -ex "python print (bp.return_value)"
+tbreak foo
Temporary breakpoint 1 at 0x40049e: file test.c, line 1.
+run
Temporary breakpoint 1, foo (a=1) at test.c:1
1 int foo (int a) { return a + 2; }
+python bp = gdb.FinishBreakpoint()
Temporary breakpoint 2 at 0x4004b4: file test.c, line 2.
+info breakpoints
Num Type Disp Enb Address What
2 breakpoint del y 0x004004b4 in main at test.c:2 thread 1
stop only in thread 1
+continue
Temporary breakpoint 2, 0x004004b4 in main () at test.c:2
2 int main () { return foo (1); }
+info breakpoints
No breakpoints or watchpoints.
+python print (bp.return_value)
3
...
III.
Another possibility is that the FinishBreakpoint is not hit, because the
function did not terminate, f.i. because of longjmp, C++ exceptions, or GDB
return command.
Let's demonstrate this, using C++ exceptions:
...
$ cat -n test.c
1 int foo (int a) { throw 1; return a + 2; }
2 int main () {
3 try { return foo (1); } catch (...) {};
4 return 1;
5 }
$ g++ -g test.c
$ gdb -q -batch a.out -ex "set trace-commands on" -ex "tbreak foo" -ex run \
-ex "python bp = gdb.FinishBreakpoint()" -ex "info breakpoints" \
-ex continue -ex "info breakpoints" -ex "python print (bp.return_value)"
+tbreak foo
Temporary breakpoint 1 at 0x400712: file test.c, line 1.
+run
Temporary breakpoint 1, foo (a=1) at test.c:1
1 int foo (int a) { throw 1; return a + 2; }
+python bp = gdb.FinishBreakpoint()
Temporary breakpoint 2 at 0x400742: file test.c, line 3.
+info breakpoints
Num Type Disp Enb Address What
2 breakpoint del y 0x00400742 in main() at test.c:3 thread 1
stop only in thread 1
+continue
[Inferior 1 (process 25269) exited with code 01]
Thread-specific breakpoint 2 deleted - thread 1 no longer in the thread list.
+info breakpoints
No breakpoints or watchpoints.
+python print (bp.return_value)
None
...
Indeed, we do not hit the FinishBreakpoint. Instead, it's deleted when the
thread disappears, like any other thread-specific breakpoint.
I think this is a bug: the deletion is meant to be handled by FinishBreakpoint
itself.
IV.
Fix aforementioned bug by:
- adding an observer of the thread_exit event in FinishBreakpoint
- making sure that this observer is called before the
remove_threaded_breakpoints observer of that same event.
This changes the behaviour to:
...
+continue
[Inferior 1 (process 30256) exited with code 01]
+info breakpoints
No breakpoints or watchpoints.
+python print (bp.return_value)
None
...
V.
An out_of_scope callback can be defined to make this more verbose:
...
$ cat fbp.py
class FBP(gdb.FinishBreakpoint):
def __init__(self):
gdb.FinishBreakpoint.__init__(self)
def out_of_scope(self):
try:
frame = gdb.selected_frame ()
sal = frame.find_sal ()
print ("out_of_scope triggered at %s:%s"
% (sal.symtab.fullname(), sal.line))
except gdb.error as e:
print ("out_of_scope triggered at thread/inferior exit")
...
and using that gets us:
...
+continue
[Inferior 1 (process 30742) exited with code 01]
out_of_scope triggered at thread/inferior exit
+info breakpoints
No breakpoints or watchpoints.
+python print (bp.return_value)
None
...
VI.
This out_of_scope event can be triggered earlier than inferior/thread exit.
Let's demonstrate this:
...
$ cat -n test.c
1 int bar (int a) { throw 1; return a + 2; }
2 int foo (int a) {
3 int res = a;
4 try
5 {
6 res += bar (1);
7 }
8 catch (...)
9 {
10 }
11 return res;
12 }
13 int main () {
14 int res = 0;
15 res += foo (1);
16 res += 2;
17 return res * 2;
18 }
$ g++ -g test.c
$ gdb -q -batch -ex "source fbp.py" a.out -ex "set trace-commands on" \
-ex "tbreak bar" -ex run -ex "python bp = FBP()" -ex "info breakpoints" \
-ex "tbreak 16" -ex continue -ex "info breakpoints" \
-ex "python print (bp.return_value)"
+tbreak bar
Temporary breakpoint 1 at 0x400712: file test.c, line 1.
+run
Temporary breakpoint 1, bar (a=1) at test.c:1
1 int bar (int a) { throw 1; return a + 2; }
+python bp = FBP()
Temporary breakpoint 2 at 0x40074f: file test.c, line 6.
+info breakpoints
Num Type Disp Enb Address What
2 breakpoint del y 0x0040074f in foo(int) at test.c:6 thread 1
stop only in thread 1
+tbreak 16
Temporary breakpoint 3 at 0x400784: file test.c, line 16.
+continue
Temporary breakpoint 3, main () at test.c:16
16 res += 2;
out_of_scope triggered at /home/vries/gdb_versions/devel/test.c:16
+info breakpoints
No breakpoints or watchpoints.
+python print (bp.return_value)
None
...
Note that the out_of_scope event triggers at the breakpoint we set at
test.c:16. If we'd set that breakpoint at line 17, the out_of_scope event
would trigger at line 17 instead.
Also note that it can't be triggered earlier, say by setting the breakpoint in
foo at line 11. We would get instead "out_of_scope triggered at
thread/inferior exit".
VII.
Now consider a reduced version of
src/gdb/testsuite/gdb.python/py-finish-breakpoint2.cc:
...
$ cat -n test.c
1 #include <iostream>
2
3 void
4 throw_exception_1 (int e)
5 {
6 throw new int (e);
7 }
8
9 int
10 main (void)
11 {
12 int i;
13 try
14 {
15 throw_exception_1 (10);
16 }
17 catch (const int *e)
18 {
19 std::cerr << "Exception #" << *e << std::endl;
20 }
21 i += 1;
22
23 return i;
24 }
$ g++ -g test.c
...
Now let's try to see if the FinishBreakPoint triggers:
...
$ gdb -q -batch -ex "source fbp.py" a.out -ex "set trace-commands on" \
-ex "tbreak throw_exception_1" -ex run -ex "python bp = FBP()" \
-ex "info breakpoints" -ex continue -ex "info breakpoints" \
-ex "python print (bp.return_value)"
+tbreak throw_exception_1
Temporary breakpoint 1 at 0x400bd5: file test.c, line 6.
+run
Temporary breakpoint 1, throw_exception_1 (e=10) at test.c:6
6 throw new int (e);
+python bp = FBP()
Temporary breakpoint 2 at 0x400c2f: file test.c, line 21.
+info breakpoints
Num Type Disp Enb Address What
2 breakpoint del y 0x00400c2f in main() at test.c:21 thread 1
stop only in thread 1
+continue
Exception #10
Temporary breakpoint 2, main () at test.c:21
21 i += 1;
+info breakpoints
No breakpoints or watchpoints.
+python print (bp.return_value)
None
...
Surprisingly, it did. The explanation is that FinishBreakPoint is really a
frame-return-address breakpoint, and that address happens to be at line 21,
which is still executed after the throw in throw_exception_1.
Interestingly, with -m32 the FinishBreakPoint doesn't trigger, because the
frame-return-address happens to be an instruction which is part of line 15.
VIII.
In conclusion, the FinishBreakpoint is a frame-return-address breakpoint.
After being set, either:
- it triggers, or
- an out-of-scope event will be generated.
If an out-of-scope event is generated, it will be due to incomplete function
termination.
OTOH, incomplete function termination does not guarantee an out-of-scope event
instead of hitting the breakpoint.
IX.
The documentation states that 'A finish breakpoint is a temporary breakpoint
set at the return address of a frame, based on the finish command'.
It's indeed somewhat similar to the finish command, at least in the sense that
both may stop at the frame-return-address.
But the finish command can accurately detect function termination.
And the finish command will stop at any other address that is the first
address not in the original function.
The documentation needs updating to accurately describe what it does.
X.
A better implementation of a finish breakpoint would be one that borrows from
the finish command implementation. That one:
- installs a thread_fsm, and
- continues
A finish breakpoint would do the same minus the continue, but it requires gdb
to handle multiple thread_fsms at a time (because other commands may wish to
install their own thread_fsm), which AFAICT is not supported yet.
XI.
This patch repairs a minor part of the functionality, and updates
documentation and test-cases to match actual behaviour.
The question remains how useful the functionality is, as it is now
( see f.i. discussion at
https://sourceware.org/pipermail/gdb-patches/2021-January/175290.html ).
Perhaps it would be better to deprecate this in a follow-up patch in some form
or another, say by disabling it by default and introducing a maintenance
command that switches it on, with the warning that it is deprecated.
Tested on x86_64-linux with native and target board unix/-m32, by rebuilding
and running the test-cases:
- gdb.python/py-finish-breakpoint.exp
- gdb.python/py-finish-breakpoint2.exp
---
gdb/breakpoint.c | 10 ++++++++++
gdb/doc/python.texi | 6 ++++--
gdb/python/py-finishbreakpoint.c | 20 +++++++++++++++++++
.../gdb.python/py-finish-breakpoint2.exp | 1 +
4 files changed, 35 insertions(+), 2 deletions(-)
diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
index 5653842ce76..6e10914a316 100644
--- a/gdb/breakpoint.c
+++ b/gdb/breakpoint.c
@@ -14693,6 +14693,10 @@ breakpoint_free_objfile (struct objfile *objfile)
static struct cmd_list_element *enablebreaklist = NULL;
+#if HAVE_PYTHON
+extern gdb::observers::token bpfinishpy_handle_thread_exit_observer_token;
+#endif
+
/* See breakpoint.h. */
cmd_list_element *commands_cmd_element = nullptr;
@@ -15255,8 +15259,14 @@ This is useful for formatted output in user-defined commands."));
gdb::observers::about_to_proceed.attach (breakpoint_about_to_proceed,
"breakpoint");
+#if HAVE_PYTHON
+ gdb::observers::thread_exit.attach
+ (remove_threaded_breakpoints, "breakpoint",
+ { &bpfinishpy_handle_thread_exit_observer_token });
+#else
gdb::observers::thread_exit.attach (remove_threaded_breakpoints,
"breakpoint");
+#endif
gdb::observers::inferior_removed.attach (remove_inferior_breakpoints,
"breakpoint");
}
diff --git a/gdb/doc/python.texi b/gdb/doc/python.texi
index 86ccc140c6d..e49cc580b1b 100644
--- a/gdb/doc/python.texi
+++ b/gdb/doc/python.texi
@@ -6882,7 +6882,7 @@ is not writable.
@tindex gdb.FinishBreakpoint
A finish breakpoint is a temporary breakpoint set at the return address of
-a frame, based on the @code{finish} command. @code{gdb.FinishBreakpoint}
+a frame. @code{gdb.FinishBreakpoint}
extends @code{gdb.Breakpoint}. The underlying breakpoint will be disabled
and deleted when the execution will run out of the breakpoint scope (i.e.@:
@code{Breakpoint.stop} or @code{FinishBreakpoint.out_of_scope} triggered).
@@ -6901,7 +6901,9 @@ details about this argument.
In some circumstances (e.g.@: @code{longjmp}, C@t{++} exceptions, @value{GDBN}
@code{return} command, @dots{}), a function may not properly terminate, and
thus never hit the finish breakpoint. When @value{GDBN} notices such a
-situation, the @code{out_of_scope} callback will be triggered.
+situation, the @code{out_of_scope} callback will be triggered. Note
+though that improper function termination does not guarantee that the
+finish breakpoint is not hit.
You may want to sub-class @code{gdb.FinishBreakpoint} and override this
method:
diff --git a/gdb/python/py-finishbreakpoint.c b/gdb/python/py-finishbreakpoint.c
index c74a2473a81..957d4ebc142 100644
--- a/gdb/python/py-finishbreakpoint.c
+++ b/gdb/python/py-finishbreakpoint.c
@@ -433,6 +433,24 @@ bpfinishpy_handle_exit (struct inferior *inf)
bpfinishpy_detect_out_scope_cb (&bp, nullptr, true);
}
+/* Attached to `thread_exit' notifications, triggers all the necessary out of
+ scope notifications. */
+
+static void
+bpfinishpy_handle_thread_exit (struct thread_info *tp, std::optional<ULONGEST>, bool)
+{
+ gdbpy_enter enter_py (target_thread_architecture (tp->ptid), current_language);
+
+ for (breakpoint &bp : all_breakpoints_safe ())
+ {
+ if (tp->global_num == bp.thread)
+ bpfinishpy_detect_out_scope_cb (&bp, nullptr, true);
+ }
+}
+
+extern gdb::observers::token bpfinishpy_handle_thread_exit_observer_token;
+gdb::observers::token bpfinishpy_handle_thread_exit_observer_token;
+
/* Initialize the Python finish breakpoint code. */
static int CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION
@@ -452,6 +470,8 @@ gdbpy_initialize_finishbreakpoints (void)
"py-finishbreakpoint");
gdb::observers::inferior_exit.attach (bpfinishpy_handle_exit,
"py-finishbreakpoint");
+ gdb::observers::thread_exit.attach
+ (bpfinishpy_handle_thread_exit, "py-finishbreakpoint");
return 0;
}
diff --git a/gdb/testsuite/gdb.python/py-finish-breakpoint2.exp b/gdb/testsuite/gdb.python/py-finish-breakpoint2.exp
index b837bb3a108..7d99aad2fd2 100644
--- a/gdb/testsuite/gdb.python/py-finish-breakpoint2.exp
+++ b/gdb/testsuite/gdb.python/py-finish-breakpoint2.exp
@@ -87,6 +87,7 @@ if { $need_continue } {
gdb_test "continue" ".*Breakpoint.* throw_exception_1.*" \
"continue to second exception"
}
+
gdb_test "python ExceptionFinishBreakpoint(gdb.newest_frame())" \
"init ExceptionFinishBreakpoint" "set FinishBP after the exception again"
--
2.43.0

View File

@@ -0,0 +1,89 @@
From 9b1fc55c1887675923d4ddeda4b38ab05e6bb44c Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Thu, 13 Mar 2025 11:15:05 +0100
Subject: [PATCH 1/2] [gdb/record] Fix out-of-bounds write in
aarch64_record_asimd_load_store
After compiling gdb with -fstack-protector-all, and running test-case
gdb.reverse/getrandom.exp on aarch64-linux, we run into
"Stack smashing detected" in function aarch64_record_asimd_load_store.
This is reported in PR record/32784.
This happens due to an out-of-bounds write to local array record_buf_mem:
...
uint64_t record_buf_mem[24];
...
when recording insn:
...
B+>0xfffff7ff4d10 st1 {v0.16b-v3.16b}, [x0]
...
We can fix this by increasing the array size to 128, but rather than again
hardcoding a size, reimplement record_buf_mem as std::vector.
Tested on aarch64-linux.
Approved-By: Guinevere Larsen <guinevere@redhat.com>
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32784
(cherry picked from commit 51729ea0905d1f688b7fd2ea769e69b29daa1b7c)
---
gdb/aarch64-tdep.c | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/gdb/aarch64-tdep.c b/gdb/aarch64-tdep.c
index e4bca6c6632..92daaa75b1c 100644
--- a/gdb/aarch64-tdep.c
+++ b/gdb/aarch64-tdep.c
@@ -5030,9 +5030,9 @@ aarch64_record_asimd_load_store (aarch64_insn_decode_record *aarch64_insn_r)
CORE_ADDR address;
uint64_t addr_offset = 0;
uint32_t record_buf[24];
- uint64_t record_buf_mem[24];
+ std::vector<uint64_t> record_buf_mem;
uint32_t reg_rn, reg_rt;
- uint32_t reg_index = 0, mem_index = 0;
+ uint32_t reg_index = 0;
uint8_t opcode_bits, size_bits;
reg_rt = bits (aarch64_insn_r->aarch64_insn, 0, 4);
@@ -5095,8 +5095,8 @@ aarch64_record_asimd_load_store (aarch64_insn_decode_record *aarch64_insn_r)
record_buf[reg_index++] = reg_rt + AARCH64_V0_REGNUM;
else
{
- record_buf_mem[mem_index++] = esize / 8;
- record_buf_mem[mem_index++] = address + addr_offset;
+ record_buf_mem.push_back (esize / 8);
+ record_buf_mem.push_back (address + addr_offset);
}
addr_offset = addr_offset + (esize / 8);
reg_rt = (reg_rt + 1) % 32;
@@ -5167,8 +5167,8 @@ aarch64_record_asimd_load_store (aarch64_insn_decode_record *aarch64_insn_r)
record_buf[reg_index++] = reg_tt + AARCH64_V0_REGNUM;
else
{
- record_buf_mem[mem_index++] = esize / 8;
- record_buf_mem[mem_index++] = address + addr_offset;
+ record_buf_mem.push_back (esize / 8);
+ record_buf_mem.push_back (address + addr_offset);
}
addr_offset = addr_offset + (esize / 8);
reg_tt = (reg_tt + 1) % 32;
@@ -5180,9 +5180,9 @@ aarch64_record_asimd_load_store (aarch64_insn_decode_record *aarch64_insn_r)
record_buf[reg_index++] = reg_rn;
aarch64_insn_r->reg_rec_count = reg_index;
- aarch64_insn_r->mem_rec_count = mem_index / 2;
+ aarch64_insn_r->mem_rec_count = record_buf_mem.size () / 2;
MEM_ALLOC (aarch64_insn_r->aarch64_mems, aarch64_insn_r->mem_rec_count,
- record_buf_mem);
+ record_buf_mem.data ());
REG_ALLOC (aarch64_insn_r->aarch64_regs, aarch64_insn_r->reg_rec_count,
record_buf);
return AARCH64_RECORD_SUCCESS;
base-commit: 96a340e789f714156bbac7f78f340e06659b5e70
--
2.43.0

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,83 @@
From FEDORA_PATCHES Mon Sep 17 00:00:00 2001
From: Fedora GDB patches <invalid@email.com>
Date: Fri, 27 Oct 2017 21:07:50 +0200
Subject: gdb-rhbz-818343-set-solib-absolute-prefix-testcase.patch
;; Testcase for `Setting solib-absolute-prefix breaks vDSO' (BZ 818343).
;;=fedoratest
diff --git a/gdb/testsuite/gdb.base/set-solib-absolute-prefix.c b/gdb/testsuite/gdb.base/set-solib-absolute-prefix.c
new file mode 100644
--- /dev/null
+++ b/gdb/testsuite/gdb.base/set-solib-absolute-prefix.c
@@ -0,0 +1,26 @@
+/* Copyright (C) 2012 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+int
+main (int argc, char *argv[])
+{
+ printf ("Hello, World.\n");
+ abort ();
+}
diff --git a/gdb/testsuite/gdb.base/set-solib-absolute-prefix.exp b/gdb/testsuite/gdb.base/set-solib-absolute-prefix.exp
new file mode 100644
--- /dev/null
+++ b/gdb/testsuite/gdb.base/set-solib-absolute-prefix.exp
@@ -0,0 +1,39 @@
+# Copyright 2012 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+set testfile "set-solib-absolute-prefix"
+set srcfile ${testfile}.c
+
+# It is necessary to verify if the binary is 32-bit, so that the system
+# call `__kernel_vsyscall' originates from vDSO.
+
+if { ![is_ilp32_target] } {
+ return -1
+}
+
+if { [prepare_for_testing $testfile.exp $testfile $srcfile] } {
+ return -1
+}
+
+if { ![runto_main] } {
+ return -1
+}
+
+gdb_test "continue" "Program received signal SIGABRT, Aborted.*" \
+ "continue until abort"
+gdb_test "set solib-absolute-prefix /BOGUS_DIRECT" \
+ ".*warning: Unable to find dynamic linker breakpoint function.*" \
+ "set solib-absolute-prefix"
+gdb_test "bt" "__kernel_vsyscall.*" "backtrace with __kernel_vsyscall"

View File

@@ -0,0 +1,235 @@
From FEDORA_PATCHES Mon Sep 17 00:00:00 2001
From: Fedora GDB patches <invalid@email.com>
Date: Fri, 27 Oct 2017 21:07:50 +0200
Subject: gdb-rhbz1084404-ppc64-s390x-wrong-prologue-skip-O2-g-3of3.patch
;; Fix '[ppc64] and [s390x] wrong prologue skip on -O2 -g code' (Jan
;; Kratochvil, RH BZ 1084404).
;;=fedoratest
These testcases have been created by compiling glibc-2.17-78 on
RHEL-7.1 s390x/ppc64 boxes, and then taking the "select.o" file
present at $builddir/misc/select.o.
diff --git a/gdb/testsuite/gdb.arch/ppc64-prologue-skip.exp b/gdb/testsuite/gdb.arch/ppc64-prologue-skip.exp
new file mode 100644
--- /dev/null
+++ b/gdb/testsuite/gdb.arch/ppc64-prologue-skip.exp
@@ -0,0 +1,34 @@
+# Copyright 2015 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+if { ![istarget powerpc64-*linux-*] || ![is_lp64_target] } {
+ verbose "Skipping ppc64-prologue-skip.exp"
+ return
+}
+
+set testfile "ppc64-prologue-skip"
+set uufile "${srcdir}/${subdir}/${testfile}.o.uu"
+set ofile "${srcdir}/${subdir}/${testfile}.o"
+
+if { [catch "system \"uudecode -o ${ofile} ${uufile}\"" ] != 0 } {
+ untested "failed uudecode"
+ return -1
+}
+
+gdb_exit
+gdb_start
+gdb_load $ofile
+
+gdb_test "break ___newselect_nocancel" "Breakpoint $decimal at 0xc: file ../sysdeps/unix/syscall-template.S, line 81." "breakpoint on ___newselect_nocancel"
diff --git a/gdb/testsuite/gdb.arch/ppc64-prologue-skip.o.uu b/gdb/testsuite/gdb.arch/ppc64-prologue-skip.o.uu
new file mode 100644
--- /dev/null
+++ b/gdb/testsuite/gdb.arch/ppc64-prologue-skip.o.uu
@@ -0,0 +1,70 @@
+begin 644 ppc64-skip-prologue.o.uu
+M?T5,1@("`0`````````````!`!4````!````````````````````````````
+M``-(``````!```````!``!0`$8%-B-`L"@``0,(`-#@``(Y$```"3.,`('P(
+M`J;X`0`0^"'_D4@```%@````Z`$`@#@A`'!\"`.F3H``(/@A_X%]*`*F^2$`
+MD/CA`-#XP0#(^*$`P/B!`+CX80"P2````6````#X80!PZ.$`T.C!`,CHH0#`
+MZ($`N.AA`+`X``".1````GP``";X80!X^`$`B.AA`'!(```!8````.DA`)#H
+M`0"(Z&$`>'TH`Z9\#_$@."$`@$SC`"!+__]@```````,($``````````O``(
+M7U]S96QE8W0```````````````````````````!6``(````Y!`'[#@T``0$!
+M`0````$```$N+B]S>7-D97!S+W5N:7@``'-Y<V-A;&PM=&5M<&QA=&4N4P`!
+M``````D"```````````#T``!`BT3`@D``0$```"/``(`````"`$`````````
+M`````````````````"XN+W-Y<V1E<',O=6YI>"]S>7-C86QL+71E;7!L871E
+M+E,`+W)O;W0O9VQI8F,O9VQI8F,M,BXQ-RTW."YE;#<N<W)C+V=L:6)C+3(N
+M,3<M8S<U.&$V.#8O;6ES8P!'3E4@05,@,BXR,RXU,BXP+C$`@`$!$0`0!A$!
+M$@$#"!L()0@3!0`````````````````L``(`````"```````````````````
+M````````V``````````````````````````0``````%Z4@`$>$$!&PP!````
+M`#`````8`````````+P`20YP$4%^1`X`009!0@Z``4(107Y2$49_20X`!D$&
+M1@``````+G-Y;71A8@`N<W1R=&%B`"YS:'-T<G1A8@`N<F5L82YT97AT`"YD
+M871A`"YB<W,`+G)E;&$N;W!D`"YN;W1E+D=.52US=&%C:P`N<F5L82YD96)U
+M9U]L:6YE`"YR96QA+F1E8G5G7VEN9F\`+F1E8G5G7V%B8G)E=@`N<F5L82YD
+M96)U9U]A<F%N9V5S`"YR96QA+F5H7V9R86UE````````````````````````
+M````````````````````````````````````````````````````````````
+M`````````"`````!``````````8```````````````````!``````````-@`
+M```````````````````$```````````````;````!```````````````````
+M```````````*>`````````!(````$@````$`````````"``````````8````
+M)@````$``````````P```````````````````1@`````````````````````
+M``````````$``````````````"P````(``````````,`````````````````
+M``$8```````````````````````````````!```````````````V`````0``
+M```````#```````````````````!&``````````0````````````````````
+M"```````````````,0````0`````````````````````````````"L``````
+M````,````!(````%``````````@`````````&````#L````!````````````
+M``````````````````$H```````````````````````````````!````````
+M``````!0`````0`````````````````````````````!*`````````!:````
+M`````````````````0``````````````2P````0`````````````````````
+M````````"O``````````&````!(````(``````````@`````````&````&$`
+M```!``````````````````````````````&"`````````),`````````````
+M```````!``````````````!<````!``````````````````````````````+
+M"`````````!@````$@````H`````````"``````````8````;0````$`````
+M`````````````````````````A4`````````%`````````````````````$`
+M`````````````(`````!``````````````````````````````(P````````
+M`#`````````````````````0``````````````![````!```````````````
+M```````````````+:``````````P````$@````T`````````"``````````8
+M````E`````$``````````@```````````````````F``````````2```````
+M``````````````@``````````````(\````$````````````````````````
+M``````N8`````````!@````2````#P`````````(`````````!@````1````
+M`P`````````````````````````````"J`````````">````````````````
+M`````0```````````````0````(`````````````````````````````"$@`
+M```````!L````!,````+``````````@`````````&`````D````#````````
+M``````````````````````GX`````````'H````````````````````!````
+M`````````````````````````````````````````````P```0``````````
+M`````````````````P```P```````````````````````````P``!```````
+M`````````````````````P``!0```````````````````````````P``"@``
+M`````````````````````````P``#````````````````````````````P``
+M"````````````````````````````P``#0``````````````````````````
+M`P``#P```````````````````````````P``!P``````````````````````
+M```!$@``!0```````````````````-@````*$@```0`````````,````````
+M`#`````@$``````````````````````````````P$```````````````````
+M``````````!*$`````````````````````````````!E(@``!0``````````
+M`````````-@```!S(@``!0```````````````````-@`7U]S96QE8W0`7U]?
+M;F5W<V5L96-T7VYO8V%N8V5L`%]?<WES8V%L;%]E<G)O<@!?7VQI8F-?96YA
+M8FQE7V%S>6YC8V%N8V5L`%]?;&EB8U]D:7-A8FQE7V%S>6YC8V%N8V5L`%]?
+M;&EB8U]S96QE8W0`<V5L96-T```````````````````D````#0````H`````
+M``````````````!<````#@````H```````````````````"4````#P````H`
+M`````````````````````````0```"8````````````````````(````````
+M`#,```````````````````!&`````0```"8````````````````````&````
+M!@````$````````````````````,````!P````$````````````````````0
+M`````0```"8````````````````````8`````0```"8`````````V```````
+M```&````!0````$````````````````````0`````0```"8`````````````
+6```````<`````0```!H`````````````
+`
+end
diff --git a/gdb/testsuite/gdb.arch/s390x-prologue-skip.exp b/gdb/testsuite/gdb.arch/s390x-prologue-skip.exp
new file mode 100644
--- /dev/null
+++ b/gdb/testsuite/gdb.arch/s390x-prologue-skip.exp
@@ -0,0 +1,34 @@
+# Copyright 2015 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+if { ![istarget s390x-*linux-*] || ![is_lp64_target] } {
+ verbose "Skipping s390x-prologue-skip.exp"
+ return
+}
+
+set testfile "s390x-prologue-skip"
+set uufile "${srcdir}/${subdir}/${testfile}.o.uu"
+set ofile "${srcdir}/${subdir}/${testfile}.o"
+
+if { [catch "system \"uudecode -o ${ofile} ${uufile}\"" ] != 0 } {
+ untested "failed uudecode"
+ return -1
+}
+
+gdb_exit
+gdb_start
+gdb_load $ofile
+
+gdb_test "break select" "Breakpoint $decimal at 0x48: file ../sysdeps/unix/syscall-template.S, line 81." "breakpoint on select"
diff --git a/gdb/testsuite/gdb.arch/s390x-prologue-skip.o.uu b/gdb/testsuite/gdb.arch/s390x-prologue-skip.o.uu
new file mode 100644
--- /dev/null
+++ b/gdb/testsuite/gdb.arch/s390x-prologue-skip.o.uu
@@ -0,0 +1,64 @@
+begin 644 s390x-prologue-skip.o.uu
+M?T5,1@("`0`````````````!`!8````!````````````````````````````
+M``+```````!```````!``!(`#^LE\!``).O?\&@`)+D$`.^G^_]@X^#P```D
+MP.4`````N00``NLE\+``!`J.N00`TKD$`"#`Y0````"Y!``MZ]_Q"``$I_0`
+M"L`0`````+\/$`"G=/_7"HZG2?`!N2$`),"T``````?^````5@`"````.0$!
+M^PX-``$!`0$````!```!+BXO<WES9&5P<R]U;FEX``!S>7-C86QL+71E;7!L
+M871E+E,``0`````)`@```````````]```0)F$P("``$!````CP`"``````@!
+M```````````````````````````N+B]S>7-D97!S+W5N:7@O<WES8V%L;"UT
+M96UP;&%T92Y3`"]R;V]T+V=L:6)C+V=L:6)C+3(N,3<M-S@N96PW+G-R8R]G
+M;&EB8RTR+C$W+6,W-3AA-C@V+VUI<V,`1TY5($%3(#(N,C,N-3(N,"XQ`(`!
+M`1$`$`81`1(!`P@;""4($P4`````````````````+``"``````@`````````
+M`````````````````&@`````````````````````````%``````!>E(``7@.
+M`1L,#Z`!````````&````!P`````````1`!,CP6.!HT'2`[``@```!`````X
+M`````````"```````"YS>6UT86(`+G-T<G1A8@`N<VAS=')T86(`+G)E;&$N
+M=&5X=``N9&%T80`N8G-S`"YN;W1E+D=.52US=&%C:P`N<F5L82YD96)U9U]L
+M:6YE`"YR96QA+F1E8G5G7VEN9F\`+F1E8G5G7V%B8G)E=@`N<F5L82YD96)U
+M9U]A<F%N9V5S`"YR96QA+F5H7V9R86UE````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````(`````$`````````!@```````````````````$``````````:```
+M``````````````````0``````````````!L````$````````````````````
+M``````````F``````````&`````0`````0`````````(`````````!@````F
+M`````0`````````#````````````````````J```````````````````````
+M````````!```````````````+`````@``````````P``````````````````
+M`*@```````````````````````````````0``````````````#$````!````
+M``````````````````````````"H```````````````````````````````!
+M``````````````!&`````0``````````````````````````````J```````
+M``!:`````````````````````0``````````````00````0`````````````
+M````````````````">``````````&````!`````&``````````@`````````
+M&````%<````!``````````````````````````````$"`````````),`````
+M```````````````!``````````````!2````!```````````````````````
+M```````)^`````````!@````$`````@`````````"``````````8````8P``
+M``$``````````````````````````````94`````````%```````````````
+M``````$``````````````'8````!``````````````````````````````&P
+M`````````#`````````````````````0``````````````!Q````!```````
+M```````````````````````*6``````````P````$`````L`````````"```
+M```````8````B@````$``````````@```````````````````>``````````
+M2`````````````````````@``````````````(4````$````````````````
+M``````````````J(`````````#`````0````#0`````````(`````````!@`
+M```1`````P`````````````````````````````"*`````````"4````````
+M`````````````0```````````````0````(`````````````````````````
+M````!T`````````!L````!$````*``````````@`````````&`````D````#
+M``````````````````````````````CP`````````(X`````````````````
+M```!`````````````````````````````````````````````````P```0``
+M`````````````````````````P```P```````````````````````````P``
+M!````````````````````````````P``"```````````````````````````
+M`P``"@```````````````````````````P``!@``````````````````````
+M`````P``"P```````````````````````````P``#0``````````````````
+M`````````P``!0`````````````````````````!$```````````````````
+M```````````;$``````````````````````````````V$@```0````````!(
+M`````````"`````_$`````````````````````````````!7$@```0``````
+M``!6`````````!````!I$`````````````````````````````!Y(@```0``
+M``````!(`````````"````"'(@```0````````!(`````````"``7U]L:6)C
+M7V5N86)L95]A<WEN8V-A;F-E;`!?7VQI8F-?9&ES86)L95]A<WEN8V-A;F-E
+M;`!?7W-E;&5C=`!?7VQI8F-?;75L=&EP;&5?=&AR96%D<P!?7W-E;&5C=%]N
+M;V-A;F-E;`!?7W-Y<V-A;&Q?97)R;W(`7U]L:6)C7W-E;&5C=`!S96QE8W0`
+M````````````'`````H````3``````````(`````````-@````L````3````
+M``````(`````````2@````T````3``````````(`````````8@````\````3
+M``````````(`````````1@````$````6````````````````````!@````4`
+M```$````````````````````#`````8````$````````````````````$```
+M``$````6````````````````````&`````$````6`````````&@`````````
+M!@````0````$````````````````````$`````$````6````````````````
+L````(`````$````%````````````````````/`````$````%`````````$@`
+`
+end

View File

@@ -0,0 +1,123 @@
From FEDORA_PATCHES Mon Sep 17 00:00:00 2001
From: Fedora GDB patches <invalid@email.com>
Date: Fri, 27 Oct 2017 21:07:50 +0200
Subject: gdb-rhbz1149205-catch-syscall-after-fork-test.patch
;; Fix '`catch syscall' doesn't work for parent after `fork' is called'
;; (Philippe Waroquiers, RH BZ 1149205).
;;=fedoratest
URL: <https://sourceware.org/ml/gdb-patches/2013-05/msg00364.html>
Message-ID: <1368136582.30058.7.camel@soleil>
From: Philippe Waroquiers <philippe dot waroquiers at skynet dot be>
To: gdb-patches at sourceware dot org
Subject: RFA: fix gdb_assert caused by 'catch signal ...' and fork
Date: Thu, 09 May 2013 23:56:22 +0200
The attached patch fixes a gdb_assert caused by the combination of catch
signal and fork:
break-catch-sig.c:152: internal-error: signal_catchpoint_remove_location: Assertion `signal_catch_counts[iter] > 0' failed.
The problem is that the signal_catch_counts is decremented by detach_breakpoints.
The fix consists in not detaching breakpoint locations of type bp_loc_other.
The patch introduces a new test.
Comments by Sergio Durigan Junior:
I addded a specific testcase for this patch, which tests exactly the
issue that the customer is facing. This patch does not solve the
whole problem of catching a syscall and forking (for more details,
see <https://sourceware.org/bugzilla/show_bug.cgi?id=13457>,
specifically comment #3), but it solves the issue reported by the
customer.
I also removed the original testcase of this patch, because it
relied on "catch signal", which is a command that is not implemented
in this version of GDB.
commit bd9673a4ded96ea5c108601501c8e59003ea1be6
Author: Philippe Waroquiers <philippe@sourceware.org>
Date: Tue May 21 18:47:05 2013 +0000
Fix internal error caused by interaction between catch signal and fork
diff --git a/gdb/testsuite/gdb.base/gdb-rhbz1149205-catch-syscall-fork.c b/gdb/testsuite/gdb.base/gdb-rhbz1149205-catch-syscall-fork.c
new file mode 100644
--- /dev/null
+++ b/gdb/testsuite/gdb.base/gdb-rhbz1149205-catch-syscall-fork.c
@@ -0,0 +1,11 @@
+#include <stdio.h>
+#include <unistd.h>
+
+int
+main (int argc, char **argv)
+{
+ if (fork () == 0)
+ sleep (1);
+ chdir (".");
+ return 0;
+}
diff --git a/gdb/testsuite/gdb.base/gdb-rhbz1149205-catch-syscall-fork.exp b/gdb/testsuite/gdb.base/gdb-rhbz1149205-catch-syscall-fork.exp
new file mode 100644
--- /dev/null
+++ b/gdb/testsuite/gdb.base/gdb-rhbz1149205-catch-syscall-fork.exp
@@ -0,0 +1,58 @@
+# Copyright 2015 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+if { [is_remote target] || ![isnative] } then {
+ continue
+}
+
+set testfile "gdb-rhbz1149205-catch-syscall-fork"
+set srcfile ${testfile}.c
+set binfile [standard_output_file ${testfile}]
+
+# Until "catch syscall" is implemented on other targets...
+if {![istarget "hppa*-hp-hpux*"] && ![istarget "*-linux*"]} then {
+ continue
+}
+
+# This shall be updated whenever 'catch syscall' is implemented
+# on some architecture.
+#if { ![istarget "i\[34567\]86-*-linux*"]
+if { ![istarget "x86_64-*-linux*"] && ![istarget "i\[34567\]86-*-linux*"]
+ && ![istarget "powerpc-*-linux*"] && ![istarget "powerpc64-*-linux*"]
+ && ![istarget "sparc-*-linux*"] && ![istarget "sparc64-*-linux*"] } {
+ continue
+}
+
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
+ untested ${testfile}.exp
+ return -1
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load $binfile
+
+if { ![runto_main] } {
+ return -1
+}
+
+gdb_test "catch syscall chdir" \
+ "Catchpoint $decimal \\\(syscall (.)?chdir(.)? \\\[$decimal\\\]\\\)" \
+ "catch syscall chdir"
+
+gdb_test "continue" \
+ "Continuing\.\r\n.*\r\nCatchpoint $decimal \\\(call to syscall .?chdir.?.*" \
+ "continue from catch syscall after fork"

16
gdb-rpmlintrc Normal file
View File

@@ -0,0 +1,16 @@
# This line is mandatory to access the configuration functions
from Config import *
# The testresult logs contain part of the build log and thus
# necessarily mention the buildroot
addFilter ("gdb-testresults.*file-contains-buildroot")
# Historically libinproctrace was always in gdbserver. It's
# LD_PRELOADed into processes, so there are no direct ELF
# dependencies to it. It's required on the remote side (where
# gdbserver is) so it makes sense to put it in the same package.
# This never was a problem for rpmlint before because libinproctrace
# had no SONAME, so the check wasn't active. Now it has, so it's checked
# and because the gdbserver binary has no direct ELF visible dependency
# it's thought to be necessary to follow shlib policy. That's not the case.
addFilter ("gdbserver.*shlib-policy-name-error.*libinproctrace")

View File

@@ -0,0 +1,337 @@
From e485fec626c14303a31bf7eab35c4288f9710c9d Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Wed, 19 Jun 2024 17:32:55 +0200
Subject: [PATCH 07/46] [gdb/symtab] Fix target type of complex long double on
arm
When running test-case gdb.base/complex-parts.exp on arm-linux, I get:
...
(gdb) p $_cimag (z3)^M
$6 = 6.5^M
(gdb) PASS: gdb.base/complex-parts.exp: long double imaginary: p $_cimag (z3)
ptype $^M
type = double^M
(gdb) FAIL: gdb.base/complex-parts.exp: long double imaginary: ptype $
...
Given that z3 is a complex long double, the test-case expects the type of the
imaginary part of z3 to be long double, but it's double instead.
This is due to the fact that the dwarf info doesn't specify an explicit target
type:
...
<5b> DW_AT_name : z3
<60> DW_AT_type : <0xa4>
...
<1><a4>: Abbrev Number: 2 (DW_TAG_base_type)
<a5> DW_AT_byte_size : 16
<a6> DW_AT_encoding : 3 (complex float)
<a7> DW_AT_name : complex long double
...
and consequently we're guessing in dwarf2_init_complex_target_type based on
the size:
...
case 64:
tt = builtin_type (gdbarch)->builtin_double;
break;
case 96: /* The x86-32 ABI specifies 96-bit long double. */
case 128:
tt = builtin_type (gdbarch)->builtin_long_double;
break;
...
For arm-linux, complex long double is 16 bytes, so the target type is assumed
to be 8 bytes, which is handled by the "case 64", which gets us double
instead of long double.
Fix this by searching for "long" in the name_hint parameter, and using long
double instead.
Note that base types in dwarf are not allowed to contain references to other
types, and the complex types are base types, so the missing explicit target
type is standard-conformant.
A gcc PR was filed to add this as a dwarf extension (
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115272 ).
Tested on arm-linux.
---
gdb/dwarf2/read.c | 10 +-
.../gdb.dwarf2/dw2-complex-parts.exp | 244 ++++++++++++++++++
2 files changed, 253 insertions(+), 1 deletion(-)
create mode 100644 gdb/testsuite/gdb.dwarf2/dw2-complex-parts.exp
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 7cd1d2b4c4e..18054d0070d 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -15123,7 +15123,15 @@ dwarf2_init_complex_target_type (struct dwarf2_cu *cu,
tt = builtin_type (gdbarch)->builtin_float;
break;
case 64:
- tt = builtin_type (gdbarch)->builtin_double;
+ if (builtin_type (gdbarch)->builtin_long_double->length () == 8
+ && name_hint != nullptr
+ && strstr (name_hint, "long") != nullptr)
+ {
+ /* Use "long double" for "complex long double". */
+ tt = builtin_type (gdbarch)->builtin_long_double;
+ }
+ else
+ tt = builtin_type (gdbarch)->builtin_double;
break;
case 96: /* The x86-32 ABI specifies 96-bit long double. */
case 128:
diff --git a/gdb/testsuite/gdb.dwarf2/dw2-complex-parts.exp b/gdb/testsuite/gdb.dwarf2/dw2-complex-parts.exp
new file mode 100644
index 00000000000..281e87d2fc8
--- /dev/null
+++ b/gdb/testsuite/gdb.dwarf2/dw2-complex-parts.exp
@@ -0,0 +1,244 @@
+# Copyright 2024 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# Test complex types, and their parts. Dwarf assembly counterpart of
+# gdb.base/complex-parts.exp.
+#
+# In dwarf, base types are not allowed to have references to other types. And
+# because complex types are modeled as base types, gdb has to figure out what
+# the part type is.
+#
+# It would be easier for gdb if compilers would add a dwarf extension and
+# supply this information, but that may or may not happen
+# ( https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115272 ).
+
+load_lib dwarf.exp
+
+# This test can only be run on targets which support DWARF-2 and use gas.
+require dwarf2_support
+
+standard_testfile main.c -debug.S
+
+if [prepare_for_testing "failed to prepare" $testfile \
+ "${srcfile}" {}] {
+ return -1
+}
+
+set float_size [get_sizeof float 0]
+set double_size [get_sizeof double 0]
+set long_double_size [get_sizeof "long double" 0]
+
+set int_size [get_sizeof int 0]
+
+# Create the DWARF.
+set asm_file [standard_output_file $srcfile2]
+Dwarf::assemble $asm_file {
+ cu { version 2 } {
+ compile_unit {} {
+ # Main.
+
+ declare_labels int_type
+
+ int_type: DW_TAG_base_type {
+ {DW_AT_byte_size $::int_size DW_FORM_sdata}
+ {DW_AT_encoding @DW_ATE_signed}
+ {DW_AT_name int}
+ }
+
+ DW_TAG_subprogram {
+ {MACRO_AT_func {main}}
+ {type :$int_type}
+ }
+
+ # GCC complex float.
+
+ declare_labels cf_type cd_type cld_type
+
+ cf_type: DW_TAG_base_type {
+ {DW_AT_byte_size [expr 2 * $::float_size] DW_FORM_sdata}
+ {DW_AT_encoding @DW_ATE_complex_float}
+ {DW_AT_name "complex float"}
+ }
+
+ cd_type: DW_TAG_base_type {
+ {DW_AT_byte_size [expr 2 * $::double_size] DW_FORM_sdata}
+ {DW_AT_encoding @DW_ATE_complex_float}
+ {DW_AT_name "complex double"}
+ }
+
+ cld_type: DW_TAG_base_type {
+ {DW_AT_byte_size [expr 2 * $::long_double_size] DW_FORM_sdata}
+ {DW_AT_encoding @DW_ATE_complex_float}
+ {DW_AT_name "complex long double"}
+ }
+
+ DW_TAG_variable {
+ {name var_complex_float}
+ {DW_AT_type :$cf_type}
+ }
+
+ DW_TAG_variable {
+ {name var_complex_double}
+ {DW_AT_type :$cd_type}
+ }
+
+ DW_TAG_variable {
+ {name var_complex_long_double}
+ {DW_AT_type :$cld_type}
+ }
+
+ # GCC complex int.
+ # This is what gcc currently generates, see gcc PR debug/93988.
+
+ declare_labels ci_type
+
+ ci_type: DW_TAG_base_type {
+ {DW_AT_byte_size [expr 2 * $::int_size] DW_FORM_sdata}
+ {DW_AT_encoding @DW_ATE_lo_user}
+ {DW_AT_name "complex int"}
+ }
+
+ DW_TAG_variable {
+ {name var_complex_int}
+ {DW_AT_type :$ci_type}
+ }
+
+ # Clang complex float.
+ # This is what clang currently generates, see this issue (
+ # https://github.com/llvm/llvm-project/issues/52996 ).
+
+ declare_labels clang_cf_type clang_cd_type clang_cld_type
+
+ clang_cf_type: DW_TAG_base_type {
+ {DW_AT_byte_size [expr 2 * $::float_size] DW_FORM_sdata}
+ {DW_AT_encoding @DW_ATE_complex_float}
+ {DW_AT_name "complex"}
+ }
+
+ DW_TAG_variable {
+ {name var_complex_clang_float}
+ {DW_AT_type :$clang_cf_type}
+ }
+
+ clang_cd_type: DW_TAG_base_type {
+ {DW_AT_byte_size [expr 2 * $::double_size] DW_FORM_sdata}
+ {DW_AT_encoding @DW_ATE_complex_float}
+ {DW_AT_name "complex"}
+ }
+
+ DW_TAG_variable {
+ {name var_complex_clang_double}
+ {DW_AT_type :$clang_cd_type}
+ }
+
+ clang_cld_type: DW_TAG_base_type {
+ {DW_AT_byte_size [expr 2 * $::long_double_size] DW_FORM_sdata}
+ {DW_AT_encoding @DW_ATE_complex_float}
+ {DW_AT_name "complex"}
+ }
+
+ DW_TAG_variable {
+ {name var_complex_clang_long_double}
+ {DW_AT_type :$clang_cld_type}
+ }
+ }
+ }
+}
+
+if [prepare_for_testing "failed to prepare" $testfile \
+ "${asm_file} ${srcfile}" {}] {
+ return -1
+}
+
+if ![runto_main] {
+ return -1
+}
+
+proc do_test { type {clang 0}} {
+ with_test_prefix $type {
+ with_test_prefix clang=$clang {
+
+ if { $clang } {
+ set type_id [regsub -all " " $type _]
+ set var "var_complex_clang_$type_id"
+
+ # Gdb could try to synthesize better names, see enhancement
+ # PR symtab/31858.
+ set ctype "complex"
+ set ctype_id "complex"
+ } else {
+ set ctype "complex $type"
+ set type_id [regsub -all " " $type _]
+ set ctype_id [regsub -all " " $ctype _]
+ set var "var_$ctype_id"
+ }
+
+ gdb_test "ptype '$type'" \
+ "type = $type"
+
+ gdb_test "ptype '$ctype'" \
+ "type = $ctype"
+
+ eval set type_size \$::${type_id}_size
+
+ gdb_test "p sizeof ('$type')" \
+ " = $type_size"
+
+ if { ! $clang } {
+ # With clang, the ctype name does not uniquely map to a type,
+ # so the size is unpredictable.
+ gdb_test "p sizeof ('$ctype')" \
+ " = [expr 2 * $type_size]"
+ }
+
+ set re_kfail \
+ [string_to_regexp \
+ "'var_complex_int' has unknown type; cast it to its declared type"]
+
+ foreach f { {$_cimag} {$_creal} } {
+ gdb_test_multiple "p $f ($var)" "" {
+ -re -wrap " = <optimized out>" {
+ pass $gdb_test_name
+ }
+ -re -wrap $re_kfail {
+ kfail gdb/31857 $gdb_test_name
+ }
+ }
+
+ if { $clang } {
+ # Without a specific complex type name, it's
+ # unpredictable which type name the part will have.
+ gdb_test {ptype $} \
+ "type = (float|double|long double)" \
+ "ptype $f"
+ } else {
+ gdb_test {ptype $} \
+ "type = $type" \
+ "ptype $f"
+ }
+ }
+ }
+ }
+}
+
+do_test "float"
+do_test "double"
+do_test "long double"
+
+do_test "int"
+
+do_test "float" 1
+do_test "double" 1
+do_test "long double" 1
--
2.43.0

View File

@@ -0,0 +1,31 @@
From 0f53dc7e5cc07e30d11f3f5a0645239535824890 Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Thu, 7 Dec 2023 10:36:07 +0100
Subject: [PATCH 11/13] [gdb/symtab] Recurse into c++ DW_TAG_subprogram DIEs
for cooked index
Recurse into c++ DW_TAG_subprogram DIEs for cooked index, to add
DW_TAG_inlined_subroutine entries.
Tested on x86_64-linux.
---
gdb/dwarf2/read.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index e7904532434..de7b655d26c 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -16781,7 +16781,8 @@ cooked_indexer::index_dies (cutu_reader *reader,
case DW_TAG_subprogram:
if ((m_language == language_fortran
- || m_language == language_ada)
+ || m_language == language_ada
+ || m_language == language_cplus)
&& this_entry != nullptr)
{
info_ptr = recurse (reader, info_ptr, this_entry, true);
--
2.35.3

View File

@@ -0,0 +1,224 @@
From 84b9218d98eb2ac242fe3afc81598206279f7b13 Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Thu, 22 Aug 2024 10:00:27 +0200
Subject: [PATCH] [gdb/symtab] Return correct reader for top-level CU in
cooked_indexer::ensure_cu_exists
With the test-case included in this patch, we run into:
...
$ gdb -q -batch $exec
Dwarf Error: Could not find abbrev number 3 in CU at offset 0xdb \
[in module $exec]
...
The debug info consists of two CUs:
...
Compilation Unit @ offset 0xb2:
Length: 0x25 (32-bit)
Version: 4
Abbrev Offset: 0x6c
Pointer Size: 8
<0><bd>: Abbrev Number: 1 (DW_TAG_compile_unit)
<be> DW_AT_language : 2 (non-ANSI C)
<1><bf>: Abbrev Number: 2 (DW_TAG_subprogram)
<c0> DW_AT_low_pc : 0x4004a7
<c8> DW_AT_high_pc : 0x4004b2
<d0> DW_AT_specification: <0xe8>
<1><d4>: Abbrev Number: 3 (DW_TAG_subprogram)
<d5> DW_AT_name : main
<1><da>: Abbrev Number: 0
Compilation Unit @ offset 0xdb:
Length: 0xf (32-bit)
Version: 4
Abbrev Offset: 0x86
Pointer Size: 8
<0><e6>: Abbrev Number: 1 (DW_TAG_compile_unit)
<e7> DW_AT_language : 2 (non-ANSI C)
<1><e8>: Abbrev Number: 2 (DW_TAG_subprogram)
<e9> DW_AT_specification: <0xd4>
<1><ed>: Abbrev Number: 0
...
where:
- DIE 0xbf in CU@0xb2 contains an inter-CU reference to
- DIE 0xe8 in CU@0xdb, which contains an inter-CU reference to
- DIE 0xd4 back in CU@0xb2.
The dwarf error is caused by this bit of code in
cooked_indexer::ensure_cu_exists:
...
if (per_cu == m_per_cu)
return reader;
...
The dwarf error happens as follows:
- a cutu_reader A is created for CU@0xb2
- using cutu_reader A, the cooked index reader starts indexing dies, with
m_per_cu set to CU@0xb2
- while indexing it scans the attributes of DIE 0xbf and encounters the
inter-CU reference to DIE 0xe8
- it calls cooked_indexer::ensure_cu_exists, which creates a cutu_reader B for
CU@0xdb and returns it
- using cutu_reader B, it continues scanning attributes of DIE 0xe8 and
encounters the inter-CU reference to DIE 0xd4
- it calls cooked_indexer::ensure_cu_exists, the problematic bit is triggered
and cutu_reader B is returned
- using cutu_reader B, it continues scanning attributes of DIE 0xd4
- this goes wrong because:
- the attributes of the DIE are encoded using the abbreviation table at
offset 0x6c, while
- the decoding is done using cutu_reader B which uses the abbreviation table
at offset 0x86.
Fix this by removing the problematic if clause.
Since cutu_reader A is not preserved in m_index_storage,
cooked_indexer::ensure_cu_exists cannot find it there and creates a duplicate
cutu_reader C for CU@0xb2. Fix this in process_psymtab_comp_unit by preserving
the cutu_reader A as well in m_index_storage.
Tested on x86_64-linux and aarch64-linux.
PR symtab/32081
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32081
Approved-By: Tom Tromey <tom@tromey.com>
Reported-By: Andreas Schwab <schwab@linux-m68k.org>
---
gdb/dwarf2/read.c | 35 ++++++-----
.../dw2-inter-cu-forth-and-back.exp | 60 +++++++++++++++++++
2 files changed, 80 insertions(+), 15 deletions(-)
create mode 100644 gdb/testsuite/gdb.dwarf2/dw2-inter-cu-forth-and-back.exp
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 8f2d7a34aef..b72b5fe8c83 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -4880,28 +4880,35 @@ process_psymtab_comp_unit (dwarf2_per_cu_data *this_cu,
dwarf2_per_objfile *per_objfile,
cooked_index_storage *storage)
{
- cutu_reader reader (this_cu, per_objfile, nullptr, nullptr, false,
- storage->get_abbrev_cache ());
+ cutu_reader *reader = storage->get_reader (this_cu);
+ if (reader == nullptr)
+ {
+ cutu_reader new_reader (this_cu, per_objfile, nullptr, nullptr, false,
+ storage->get_abbrev_cache ());
- if (reader.comp_unit_die == nullptr)
- return;
+ if (new_reader.comp_unit_die == nullptr || new_reader.dummy_p)
+ return;
- if (reader.dummy_p)
- {
- /* Nothing. */
+ std::unique_ptr<cutu_reader> copy
+ (new cutu_reader (std::move (new_reader)));
+ reader = storage->preserve (std::move (copy));
}
- else if (this_cu->is_debug_types)
- build_type_psymtabs_reader (&reader, storage);
- else if (reader.comp_unit_die->tag != DW_TAG_partial_unit)
+
+ if (reader->comp_unit_die == nullptr || reader->dummy_p)
+ return;
+
+ if (this_cu->is_debug_types)
+ build_type_psymtabs_reader (reader, storage);
+ else if (reader->comp_unit_die->tag != DW_TAG_partial_unit)
{
bool nope = false;
if (this_cu->scanned.compare_exchange_strong (nope, true))
{
- prepare_one_comp_unit (reader.cu, reader.comp_unit_die,
+ prepare_one_comp_unit (reader->cu, reader->comp_unit_die,
language_minimal);
gdb_assert (storage != nullptr);
- cooked_indexer indexer (storage, this_cu, reader.cu->lang ());
- indexer.make_index (&reader);
+ cooked_indexer indexer (storage, this_cu, reader->cu->lang ());
+ indexer.make_index (reader);
}
}
}
@@ -16280,8 +16287,6 @@ cooked_indexer::ensure_cu_exists (cutu_reader *reader,
if (!per_cu->scanned.compare_exchange_strong (nope, true))
return nullptr;
}
- if (per_cu == m_per_cu)
- return reader;
cutu_reader *result = m_index_storage->get_reader (per_cu);
if (result == nullptr)
diff --git a/gdb/testsuite/gdb.dwarf2/dw2-inter-cu-forth-and-back.exp b/gdb/testsuite/gdb.dwarf2/dw2-inter-cu-forth-and-back.exp
new file mode 100644
index 00000000000..62674bdb700
--- /dev/null
+++ b/gdb/testsuite/gdb.dwarf2/dw2-inter-cu-forth-and-back.exp
@@ -0,0 +1,60 @@
+# Copyright 2024 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# Check that the cooked index reader can handle inter-CU references:
+# - DIE1@CU1 -> DIE2@CU2
+# - DIE2@CU2 -> DIE3@CU1.
+
+load_lib dwarf.exp
+
+# This test can only be run on targets which support DWARF-2 and use gas.
+require dwarf2_support
+
+standard_testfile main.c .S
+
+# Create the DWARF.
+set asm_file [standard_output_file $srcfile2]
+Dwarf::assemble $asm_file {
+ declare_labels label1 label2
+
+ cu {} {
+ compile_unit {{language @DW_LANG_C}} {
+ subprogram {
+ {MACRO_AT_range { main }}
+ {DW_AT_specification %$label1}
+ }
+
+ label2: subprogram {
+ {DW_AT_name main}
+ }
+ }
+ }
+
+ cu {} {
+ compile_unit {{language @DW_LANG_C}} {
+ label1: subprogram {
+ {DW_AT_specification %$label2}
+ }
+ }
+ }
+}
+
+if [prepare_for_testing "failed to prepare" $testfile \
+ [list $asm_file $srcfile] {nodebug}] {
+ return -1
+}
+
+# Regression test for PR32081.
+gdb_assert { ![regexp -nocase "error:" $gdb_file_cmd_msg] } "No Error message"
base-commit: 102b31b0b7f62e6e4f685e725f325f2ab6283c2a
--
2.35.3

View File

@@ -0,0 +1,13 @@
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index f8797537108..cb8f86fa352 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -1250,7 +1250,7 @@ struct field_info
compilation units. Set this to zero to disable caching. Cache
sizes of up to at least twenty will improve startup time for
typical inter-CU-reference binaries, at an obvious memory cost. */
-static int dwarf_max_cache_age = 5;
+static int dwarf_max_cache_age = 1000;
static void
show_dwarf_max_cache_age (struct ui_file *file, int from_tty,
struct cmd_list_element *c, const char *value)

View File

@@ -0,0 +1,192 @@
From 32c2e500525b91b2771022252f79e1c5c29ddf48 Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Thu, 13 Mar 2025 09:39:51 +0100
Subject: [PATCH 2/2] [gdb/tdep] Backport i386_canonicalize_syscall rewrite to
gdb-16-branch
Commit fbfb29b304e ("[gdb/tdep] Rewrite i386_canonicalize_syscall") fixes
PR32770, which reproduces on the gdb-16-branch, but the commit is not ideal
for backporting because it completely rewrites i386_canonicalize_syscall.
Instead, this is a version of the patch that adds a single line entry for each
syscall value for which i386_canonicalize_syscall gives a different result
with and without the patch.
Consequently, the two versions give identical results. I've checked this for
syscalls 0 to 466.
Tested on x86_64-linux with target board unix/-m32, on top of gdb-16-branch.
PR tdep/32770
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32770
---
gdb/i386-linux-tdep.c | 153 +++++++++++++++++++++++++++++++++++++++++-
1 file changed, 152 insertions(+), 1 deletion(-)
diff --git a/gdb/i386-linux-tdep.c b/gdb/i386-linux-tdep.c
index a78f03fac8d..b0ca8694ba5 100644
--- a/gdb/i386-linux-tdep.c
+++ b/gdb/i386-linux-tdep.c
@@ -376,7 +376,158 @@ i386_all_but_ip_registers_record (struct regcache *regcache)
static enum gdb_syscall
i386_canonicalize_syscall (int syscall)
{
- enum { i386_syscall_max = 499 };
+ enum { i386_syscall_max = 466 };
+
+ switch (syscall)
+ {
+ case 359 /* socket */: return gdb_sys_socket;
+ case 360 /* socketpair */: return gdb_sys_socketpair;
+ case 361 /* bind */: return gdb_sys_bind;
+ case 362 /* connect */: return gdb_sys_connect;
+ case 363 /* listen */: return gdb_sys_listen;
+ case 365 /* getsockopt */: return gdb_sys_getsockopt;
+ case 366 /* setsockopt */: return gdb_sys_setsockopt;
+ case 367 /* getsockname */: return gdb_sys_getsockname;
+ case 368 /* getpeername */: return gdb_sys_getpeername;
+ case 369 /* sendto */: return gdb_sys_sendto;
+ case 370 /* sendmsg */: return gdb_sys_sendmsg;
+ case 371 /* recvfrom */: return gdb_sys_recvfrom;
+ case 372 /* recvmsg */: return gdb_sys_recvmsg;
+ case 373 /* shutdown */: return gdb_sys_shutdown;
+ case 393 /* semget */: return gdb_sys_semget;
+ case 394 /* semctl */: return gdb_sys_semctl;
+ case 395 /* shmget */: return gdb_sys_shmget;
+ case 396 /* shmctl */: return gdb_sys_shmctl;
+ case 397 /* shmat */: return gdb_sys_shmat;
+ case 398 /* shmdt */: return gdb_sys_shmdt;
+ case 399 /* msgget */: return gdb_sys_msgget;
+ case 400 /* msgsnd */: return gdb_sys_msgsnd;
+ case 401 /* msgrcv */: return gdb_sys_msgrcv;
+ case 402 /* msgctl */: return gdb_sys_msgctl;
+ case 420 /* semtimedop_time64 */: return gdb_sys_semtimedop;
+
+ case 320 /* utimensat */: return gdb_sys_no_syscall;
+ case 321 /* signalfd */: return gdb_sys_no_syscall;
+ case 322 /* timerfd_create */: return gdb_sys_no_syscall;
+ case 323 /* eventfd */: return gdb_sys_no_syscall;
+ case 325 /* timerfd_settime */: return gdb_sys_no_syscall;
+ case 326 /* timerfd_gettime */: return gdb_sys_no_syscall;
+ case 327 /* signalfd4 */: return gdb_sys_no_syscall;
+ case 333 /* preadv */: return gdb_sys_no_syscall;
+ case 334 /* pwritev */: return gdb_sys_no_syscall;
+ case 335 /* rt_tgsigqueueinfo */: return gdb_sys_no_syscall;
+ case 336 /* perf_event_open */: return gdb_sys_no_syscall;
+ case 337 /* recvmmsg */: return gdb_sys_no_syscall;
+ case 338 /* fanotify_init */: return gdb_sys_no_syscall;
+ case 339 /* fanotify_mark */: return gdb_sys_no_syscall;
+ case 340 /* prlimit64 */: return gdb_sys_no_syscall;
+ case 341 /* name_to_handle_at */: return gdb_sys_no_syscall;
+ case 342 /* open_by_handle_at */: return gdb_sys_no_syscall;
+ case 343 /* clock_adjtime */: return gdb_sys_no_syscall;
+ case 344 /* syncfs */: return gdb_sys_no_syscall;
+ case 345 /* sendmmsg */: return gdb_sys_no_syscall;
+ case 346 /* setns */: return gdb_sys_no_syscall;
+ case 347 /* process_vm_readv */: return gdb_sys_no_syscall;
+ case 348 /* process_vm_writev */: return gdb_sys_no_syscall;
+ case 349 /* kcmp */: return gdb_sys_no_syscall;
+ case 350 /* finit_module */: return gdb_sys_no_syscall;
+ case 351 /* sched_setattr */: return gdb_sys_no_syscall;
+ case 352 /* sched_getattr */: return gdb_sys_no_syscall;
+ case 353 /* renameat2 */: return gdb_sys_no_syscall;
+ case 354 /* seccomp */: return gdb_sys_no_syscall;
+ case 356 /* memfd_create */: return gdb_sys_no_syscall;
+ case 357 /* bpf */: return gdb_sys_no_syscall;
+ case 358 /* execveat */: return gdb_sys_no_syscall;
+ case 364 /* accept4 */: return gdb_sys_no_syscall;
+ case 374 /* userfaultfd */: return gdb_sys_no_syscall;
+ case 375 /* membarrier */: return gdb_sys_no_syscall;
+ case 376 /* mlock2 */: return gdb_sys_no_syscall;
+ case 377 /* copy_file_range */: return gdb_sys_no_syscall;
+ case 378 /* preadv2 */: return gdb_sys_no_syscall;
+ case 379 /* pwritev2 */: return gdb_sys_no_syscall;
+ case 380 /* pkey_mprotect */: return gdb_sys_no_syscall;
+ case 381 /* pkey_alloc */: return gdb_sys_no_syscall;
+ case 382 /* pkey_free */: return gdb_sys_no_syscall;
+ case 384 /* arch_prctl */: return gdb_sys_no_syscall;
+ case 385 /* io_pgetevents */: return gdb_sys_no_syscall;
+ case 386 /* rseq */: return gdb_sys_no_syscall;
+ case 404 /* clock_settime64 */: return gdb_sys_no_syscall;
+ case 405 /* clock_adjtime64 */: return gdb_sys_no_syscall;
+ case 406 /* clock_getres_time64 */: return gdb_sys_no_syscall;
+ case 407 /* clock_nanosleep_time64 */: return gdb_sys_no_syscall;
+ case 408 /* timer_gettime64 */: return gdb_sys_no_syscall;
+ case 409 /* timer_settime64 */: return gdb_sys_no_syscall;
+ case 410 /* timerfd_gettime64 */: return gdb_sys_no_syscall;
+ case 411 /* timerfd_settime64 */: return gdb_sys_no_syscall;
+ case 412 /* utimensat_time64 */: return gdb_sys_no_syscall;
+ case 413 /* pselect6_time64 */: return gdb_sys_no_syscall;
+ case 414 /* ppoll_time64 */: return gdb_sys_no_syscall;
+ case 416 /* io_pgetevents_time64 */: return gdb_sys_no_syscall;
+ case 417 /* recvmmsg_time64 */: return gdb_sys_no_syscall;
+ case 418 /* mq_timedsend_time64 */: return gdb_sys_no_syscall;
+ case 419 /* mq_timedreceive_time64 */: return gdb_sys_no_syscall;
+ case 421 /* rt_sigtimedwait_time64 */: return gdb_sys_no_syscall;
+ case 422 /* futex_time64 */: return gdb_sys_no_syscall;
+ case 423 /* sched_rr_get_interval_time64 */: return gdb_sys_no_syscall;
+ case 424 /* pidfd_send_signal */: return gdb_sys_no_syscall;
+ case 425 /* io_uring_setup */: return gdb_sys_no_syscall;
+ case 426 /* io_uring_enter */: return gdb_sys_no_syscall;
+ case 427 /* io_uring_register */: return gdb_sys_no_syscall;
+ case 428 /* open_tree */: return gdb_sys_no_syscall;
+ case 429 /* move_mount */: return gdb_sys_no_syscall;
+ case 430 /* fsopen */: return gdb_sys_no_syscall;
+ case 431 /* fsconfig */: return gdb_sys_no_syscall;
+ case 432 /* fsmount */: return gdb_sys_no_syscall;
+ case 433 /* fspick */: return gdb_sys_no_syscall;
+ case 434 /* pidfd_open */: return gdb_sys_no_syscall;
+ case 435 /* clone3 */: return gdb_sys_no_syscall;
+ case 436 /* close_range */: return gdb_sys_no_syscall;
+ case 437 /* openat2 */: return gdb_sys_no_syscall;
+ case 438 /* pidfd_getfd */: return gdb_sys_no_syscall;
+ case 439 /* faccessat2 */: return gdb_sys_no_syscall;
+ case 440 /* process_madvise */: return gdb_sys_no_syscall;
+ case 441 /* epoll_pwait2 */: return gdb_sys_no_syscall;
+ case 442 /* mount_setattr */: return gdb_sys_no_syscall;
+ case 443 /* quotactl_fd */: return gdb_sys_no_syscall;
+ case 444 /* landlock_create_ruleset */: return gdb_sys_no_syscall;
+ case 445 /* landlock_add_rule */: return gdb_sys_no_syscall;
+ case 446 /* landlock_restrict_self */: return gdb_sys_no_syscall;
+ case 447 /* memfd_secret */: return gdb_sys_no_syscall;
+ case 448 /* process_mrelease */: return gdb_sys_no_syscall;
+ case 449 /* futex_waitv */: return gdb_sys_no_syscall;
+ case 450 /* set_mempolicy_home_node */: return gdb_sys_no_syscall;
+ case 451 /* cachestat */: return gdb_sys_no_syscall;
+ case 452 /* fchmodat2 */: return gdb_sys_no_syscall;
+ case 453 /* map_shadow_stack */: return gdb_sys_no_syscall;
+ case 454 /* futex_wake */: return gdb_sys_no_syscall;
+ case 455 /* futex_wait */: return gdb_sys_no_syscall;
+ case 456 /* futex_requeue */: return gdb_sys_no_syscall;
+ case 457 /* statmount */: return gdb_sys_no_syscall;
+ case 458 /* listmount */: return gdb_sys_no_syscall;
+ case 459 /* lsm_get_self_attr */: return gdb_sys_no_syscall;
+ case 460 /* lsm_set_self_attr */: return gdb_sys_no_syscall;
+ case 461 /* lsm_list_modules */: return gdb_sys_no_syscall;
+ case 462 /* mseal */: return gdb_sys_no_syscall;
+ case 463 /* setxattrat */: return gdb_sys_no_syscall;
+ case 464 /* getxattrat */: return gdb_sys_no_syscall;
+ case 465 /* listxattrat */: return gdb_sys_no_syscall;
+ case 466 /* removexattrat */: return gdb_sys_no_syscall;
+
+ case 222 /* unused */: return gdb_sys_no_syscall;
+ case 223 /* unused */: return gdb_sys_no_syscall;
+ case 251 /* unused */: return gdb_sys_no_syscall;
+ case 285 /* unused */: return gdb_sys_no_syscall;
+ case 387 /* unused */: return gdb_sys_no_syscall;
+ case 388 /* unused */: return gdb_sys_no_syscall;
+ case 389 /* unused */: return gdb_sys_no_syscall;
+ case 390 /* unused */: return gdb_sys_no_syscall;
+ case 391 /* unused */: return gdb_sys_no_syscall;
+ case 392 /* unused */: return gdb_sys_no_syscall;
+ case 415 /* unused */: return gdb_sys_no_syscall;
+
+ default:
+ break;
+ }
if (syscall <= i386_syscall_max)
return (enum gdb_syscall) syscall;
--
2.43.0

View File

@@ -0,0 +1,264 @@
From 64dc13a4571b4092726291f3ee30bf5c2166fa13 Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Sat, 27 Jul 2024 10:05:20 +0200
Subject: [PATCH 09/46] [gdb/tdep] Fix arm thumb2 hw breakpoint
On an aarch64-linux system with 32-bit userland running in a chroot, and using
target board unix/mthumb I get:
...
(gdb) hbreak hbreak.c:27^M
Hardware assisted breakpoint 2 at 0x4004e2: file hbreak.c, line 27.^M
(gdb) PASS: gdb.base/hbreak.exp: hbreak
continue^M
Continuing.^M
Unexpected error setting breakpoint: Invalid argument.^M
(gdb) XFAIL: gdb.base/hbreak.exp: continue to break-at-exit after hbreak
...
due to this call in arm_linux_nat_target::low_prepare_to_resume:
...
if (ptrace (PTRACE_SETHBPREGS, pid,
(PTRACE_TYPE_ARG3) ((i << 1) + 1), &bpts[i].address) < 0)
perror_with_name (_("Unexpected error setting breakpoint"));
...
This problem does not happen if instead we use a 4-byte aligned address.
This may or may not be a kernel bug.
Work around this by first using an inoffensive address bpts[i].address & ~0x7.
Likewise in arm_target::low_prepare_to_resume, which fixes the same fail on
target board native-gdbserver/mthumb.
While we're at it:
- use arm_hwbp_control_is_initialized in
arm_linux_nat_target::low_prepare_to_resume,
- handle the !arm_hwbp_control_is_initialized case explicitly,
- add missing '_()' in arm_target::low_prepare_to_resume,
- make error messages identical between arm_target::low_prepare_to_resume and
arm_linux_nat_target::low_prepare_to_resume,
- factor out sethbpregs_hwbp_address and sethbpregs_hwbp_control to
make the implementation more readable.
Remove the tentative xfail added in d0af16d5a10 ("[gdb/testsuite] Add xfail in
gdb.base/hbreak.exp") by simply reverting the commit.
Tested on arm-linux.
Approved-By: Luis Machado <luis.machado@arm.com>
Tested-By: Luis Machado <luis.machado@arm.com>
---
gdb/arm-linux-nat.c | 98 ++++++++++++++++++++++++++++++++++----
gdbserver/linux-arm-low.cc | 65 ++++++++++++++++++++-----
2 files changed, 141 insertions(+), 22 deletions(-)
diff --git a/gdb/arm-linux-nat.c b/gdb/arm-linux-nat.c
index ac53bed72d7..7b4faacd601 100644
--- a/gdb/arm-linux-nat.c
+++ b/gdb/arm-linux-nat.c
@@ -876,6 +876,14 @@ arm_hwbp_control_is_enabled (arm_hwbp_control_t control)
return control & 0x1;
}
+/* Is the breakpoint control value CONTROL initialized? */
+
+static int
+arm_hwbp_control_is_initialized (arm_hwbp_control_t control)
+{
+ return control != 0;
+}
+
/* Change a breakpoint control word so that it is in the disabled state. */
static arm_hwbp_control_t
arm_hwbp_control_disable (arm_hwbp_control_t control)
@@ -1234,6 +1242,34 @@ arm_linux_nat_target::low_delete_thread (struct arch_lwp_info *arch_lwp)
xfree (arch_lwp);
}
+/* For PID, set the address register of hardware breakpoint pair I to
+ ADDRESS. */
+
+static void
+sethbpregs_hwbp_address (int pid, int i, unsigned int address)
+{
+ PTRACE_TYPE_ARG3 address_reg = (PTRACE_TYPE_ARG3) ((i << 1) + 1);
+
+ errno = 0;
+
+ if (ptrace (PTRACE_SETHBPREGS, pid, address_reg, &address) < 0)
+ perror_with_name (_("Unexpected error updating breakpoint address"));
+}
+
+/* For PID, set the control register of hardware breakpoint pair I to
+ CONTROL. */
+
+static void
+sethbpregs_hwbp_control (int pid, int i, arm_hwbp_control_t control)
+{
+ PTRACE_TYPE_ARG3 control_reg = (PTRACE_TYPE_ARG3) ((i << 1) + 2);
+
+ errno = 0;
+
+ if (ptrace (PTRACE_SETHBPREGS, pid, control_reg, &control) < 0)
+ perror_with_name (_("Unexpected error setting breakpoint control"));
+}
+
/* Called when resuming a thread.
The hardware debug registers are updated when there is any change. */
@@ -1257,16 +1293,58 @@ arm_linux_nat_target::low_prepare_to_resume (struct lwp_info *lwp)
for (i = 0; i < arm_linux_get_hw_breakpoint_count (); i++)
if (arm_lwp_info->bpts_changed[i])
{
- errno = 0;
- if (arm_hwbp_control_is_enabled (bpts[i].control))
- if (ptrace (PTRACE_SETHBPREGS, pid,
- (PTRACE_TYPE_ARG3) ((i << 1) + 1), &bpts[i].address) < 0)
- perror_with_name (_("Unexpected error setting breakpoint"));
-
- if (bpts[i].control != 0)
- if (ptrace (PTRACE_SETHBPREGS, pid,
- (PTRACE_TYPE_ARG3) ((i << 1) + 2), &bpts[i].control) < 0)
- perror_with_name (_("Unexpected error setting breakpoint"));
+ unsigned int address = bpts[i].address;
+ arm_hwbp_control_t control = bpts[i].control;
+
+ if (!arm_hwbp_control_is_initialized (control))
+ {
+ /* Nothing to do. */
+ }
+ else if (!arm_hwbp_control_is_enabled (control))
+ {
+ /* Disable hardware breakpoint, just write the control
+ register. */
+ sethbpregs_hwbp_control (pid, i, control);
+ }
+ else
+ {
+ /* We used to do here simply:
+ 1. address_reg = address
+ 2. control_reg = control
+ but the write to address_reg can fail for thumb2 instructions if
+ the address is not 4-byte aligned.
+
+ It's not clear whether this is a kernel bug or not, partly
+ because PTRACE_SETHBPREGS is undocumented.
+
+ The context is that we're using two ptrace calls to set the two
+ halves of a register pair. For each ptrace call, the kernel must
+ check the arguments, and return -1 and set errno appropriately if
+ something is wrong. One of the aspects that needs validation is
+ whether, in terms of hw_breakpoint_arch_parse, the breakpoint
+ address matches the breakpoint length. This aspect can only be
+ checked by looking in both registers, which only makes sense
+ once a pair is written in full.
+
+ The problem is that the kernel checks this aspect after each
+ ptrace call, and consequently for the first call it may be
+ checking this aspect using a default or previous value for the
+ part of the pair not written by the call. A possible fix for
+ this would be to only check this aspect when writing the
+ control reg.
+
+ Work around this by first using an inoffensive address, which is
+ guaranteed to hit the offset == 0 case in
+ hw_breakpoint_arch_parse. */
+ unsigned int aligned_address = address & ~0x7U;
+ if (aligned_address != address)
+ {
+ sethbpregs_hwbp_address (pid, i, aligned_address);
+ sethbpregs_hwbp_control (pid, i, control);
+ }
+ sethbpregs_hwbp_address (pid, i, address);
+ sethbpregs_hwbp_control (pid, i, control);
+ }
arm_lwp_info->bpts_changed[i] = 0;
}
diff --git a/gdbserver/linux-arm-low.cc b/gdbserver/linux-arm-low.cc
index eec4649b235..ee89949a2a2 100644
--- a/gdbserver/linux-arm-low.cc
+++ b/gdbserver/linux-arm-low.cc
@@ -819,6 +819,34 @@ arm_target::low_new_fork (process_info *parent, process_info *child)
child_lwp_info->wpts_changed[i] = 1;
}
+/* For PID, set the address register of hardware breakpoint pair I to
+ ADDRESS. */
+
+static void
+sethbpregs_hwbp_address (int pid, int i, unsigned int address)
+{
+ PTRACE_TYPE_ARG3 address_reg = (PTRACE_TYPE_ARG3) ((i << 1) + 1);
+
+ errno = 0;
+
+ if (ptrace (PTRACE_SETHBPREGS, pid, address_reg, &address) < 0)
+ perror_with_name (_("Unexpected error updating breakpoint address"));
+}
+
+/* For PID, set the control register of hardware breakpoint pair I to
+ CONTROL. */
+
+static void
+sethbpregs_hwbp_control (int pid, int i, arm_hwbp_control_t control)
+{
+ PTRACE_TYPE_ARG3 control_reg = (PTRACE_TYPE_ARG3) ((i << 1) + 2);
+
+ errno = 0;
+
+ if (ptrace (PTRACE_SETHBPREGS, pid, control_reg, &control) < 0)
+ perror_with_name (_("Unexpected error setting breakpoint control"));
+}
+
/* Called when resuming a thread.
If the debug regs have changed, update the thread's copies. */
void
@@ -834,19 +862,32 @@ arm_target::low_prepare_to_resume (lwp_info *lwp)
for (i = 0; i < arm_linux_get_hw_breakpoint_count (); i++)
if (lwp_info->bpts_changed[i])
{
- errno = 0;
+ unsigned int address = proc_info->bpts[i].address;
+ arm_hwbp_control_t control = proc_info->bpts[i].control;
- if (arm_hwbp_control_is_enabled (proc_info->bpts[i].control))
- if (ptrace (PTRACE_SETHBPREGS, pid,
- (PTRACE_TYPE_ARG3) ((i << 1) + 1),
- &proc_info->bpts[i].address) < 0)
- perror_with_name ("Unexpected error setting breakpoint address");
-
- if (arm_hwbp_control_is_initialized (proc_info->bpts[i].control))
- if (ptrace (PTRACE_SETHBPREGS, pid,
- (PTRACE_TYPE_ARG3) ((i << 1) + 2),
- &proc_info->bpts[i].control) < 0)
- perror_with_name ("Unexpected error setting breakpoint");
+ if (!arm_hwbp_control_is_initialized (control))
+ {
+ /* Nothing to do. */
+ }
+ else if (!arm_hwbp_control_is_enabled (control))
+ {
+ /* Disable hardware breakpoint, just write the control
+ register. */
+ sethbpregs_hwbp_control (pid, i, control);
+ }
+ else
+ {
+ /* See arm_linux_nat_target::low_prepare_to_resume for detailed
+ comment. */
+ unsigned int aligned_address = address & ~0x7U;
+ if (aligned_address != address)
+ {
+ sethbpregs_hwbp_address (pid, i, aligned_address);
+ sethbpregs_hwbp_control (pid, i, control);
+ }
+ sethbpregs_hwbp_address (pid, i, address);
+ sethbpregs_hwbp_control (pid, i, control);
+ }
lwp_info->bpts_changed[i] = 0;
}
--
2.43.0

View File

@@ -0,0 +1,191 @@
From 680379be6e3bcd4f8e1fcc85055e9dd0d6bbbaff Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Fri, 10 Jan 2025 10:32:00 +0100
Subject: [PATCH 28/46] [gdb/tdep] Fix gdb.cp/non-trivial-retval.exp on
riscv64-linux
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
With test-case gdb.cp/non-trivial-retval.exp on riscv64-linux, I ran into:
...
(gdb) finish^M
Run till exit from #0 f1 (i1=i1@entry=23, i2=i2@entry=100) \
at non-trivial-retval.cc:34^M
main () at non-trivial-retval.cc:163^M
163 B b = f2 (i1, i2);^M
Value returned is $6 = {a = -5856}^M
(gdb) FAIL: $exp: finish from f1
...
where "Value returned is $6 = {a = 123}" is expected.
The problem is that gdb thinks that the return value is in $a0:
...
$ gdb -q -batch non-trivial-retval \
-ex "b f1" \
-ex run \
-ex "set debug riscv infcall on" \
-ex finish
Breakpoint 1 at 0x80a: file non-trivial-retval.cc, line 34.
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/riscv64-linux-gnu/libthread_db.so.1".
Breakpoint 1, f1 (i1=i1@entry=23, i2=i2@entry=100) at non-trivial-retval.cc:34
34 {
[riscv-infcall] riscv_return_value: \
[R] type: 'A', length: 0x4, alignment: 0x4, register a0
[riscv-infcall] riscv_return_value: \
[R] type: 'A', length: 0x4, alignment: 0x4, register a0
[riscv-infcall] riscv_return_value: \
[R] type: 'A', length: 0x4, alignment: 0x4, register a0
main () at non-trivial-retval.cc:163
163 B b = f2 (i1, i2);
Value returned is $1 = {a = -3568}
...
while $a0 actually contains a pointer to the returned value 123:
...
(gdb) p /x $a0
$3 = 0x3ffffff210
(gdb) p *((unsigned int *)$a0)
$5 = 123
...
The returned type is:
...
class A
{
public:
A () {}
A (A &obj);
int a;
};
...
which is a C++ aggregate with a nontrivial (because it's user-defined) copy
constructor:
According to the ABI [1], indeed this is returned by reference:
...
Values are returned in the same manner as a first named argument of the same
type would be passed. If such an argument would have been passed by
reference, the caller allocates memory for the return value, and passes the
address as an implicit first parameter.
...
Aggregates larger than 2×XLEN bits are passed by reference and are replaced in
the argument list with the address, as are C++ aggregates with nontrivial copy
constructors, destructors, or vtables.
...
Fix this in riscv_call_arg_scalar_int by checking for
language_pass_by_reference ().trivially_copy_constructible.
The vtable case is explictly mentioned in the ABI, but AFAIU already covered
by the nontrivial copy constructor case.
The nontrivial destructor case is also not supported, but the testsuite
doesn't seem to trigger this.
Fix this by:
- extending the test-case to cover this scenario, and
- fixing it in riscv_call_arg_scalar_int by checking for
language_pass_by_reference ().trivially_destructible.
Tested on riscv64-linux.
PR tdep/32152
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32152
Approved-By: Andrew Burgess <aburgess@redhat.com>
[1] https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/master/riscv-cc.adoc
---
gdb/riscv-tdep.c | 6 +++++-
gdb/testsuite/gdb.cp/non-trivial-retval.cc | 19 +++++++++++++++++++
gdb/testsuite/gdb.cp/non-trivial-retval.exp | 6 ++++++
3 files changed, 30 insertions(+), 1 deletion(-)
diff --git a/gdb/riscv-tdep.c b/gdb/riscv-tdep.c
index d592d2dc0c4..edb40d6babf 100644
--- a/gdb/riscv-tdep.c
+++ b/gdb/riscv-tdep.c
@@ -2857,8 +2857,12 @@ static void
riscv_call_arg_scalar_int (struct riscv_arg_info *ainfo,
struct riscv_call_info *cinfo)
{
+ auto lang_req = language_pass_by_reference (ainfo->type);
+
if (TYPE_HAS_DYNAMIC_LENGTH (ainfo->type)
- || ainfo->length > (2 * cinfo->xlen))
+ || ainfo->length > (2 * cinfo->xlen)
+ || !lang_req.trivially_copy_constructible
+ || !lang_req.trivially_destructible)
{
/* Argument is going to be passed by reference. */
ainfo->argloc[0].loc_type
diff --git a/gdb/testsuite/gdb.cp/non-trivial-retval.cc b/gdb/testsuite/gdb.cp/non-trivial-retval.cc
index 4bba0f1c3af..4e812516d63 100644
--- a/gdb/testsuite/gdb.cp/non-trivial-retval.cc
+++ b/gdb/testsuite/gdb.cp/non-trivial-retval.cc
@@ -142,6 +142,24 @@ f4 (int i1, int i2)
return e;
}
+class F
+{
+public:
+ ~F () {}
+
+ int f;
+};
+
+F
+f5 (int i1, int i2)
+{
+ F f;
+
+ f.f = i1 + i2;
+
+ return f;
+}
+
/* We place a breakpoint on the call to this function. */
void
@@ -164,6 +182,7 @@ main (void)
B1 b1 = f22 (i1, i2);
C c = f3 (i1, i2);
E e = f4 (i1, i2);
+ F f = f5 (i1, i2);
return 0;
}
diff --git a/gdb/testsuite/gdb.cp/non-trivial-retval.exp b/gdb/testsuite/gdb.cp/non-trivial-retval.exp
index 89035e178ed..6c9f7e13d2a 100644
--- a/gdb/testsuite/gdb.cp/non-trivial-retval.exp
+++ b/gdb/testsuite/gdb.cp/non-trivial-retval.exp
@@ -42,12 +42,14 @@ gdb_test "p f2 (i1, i2)" ".* = {b = 123}"
gdb_test "p f22 (i1, i2)" ".* = {b1 = 123}"
gdb_test "p f3 (i1, i2)" ".* = {.* c = 123}"
gdb_test "p f4 (i1, i2)" ".* = {.* e = 123}"
+gdb_test "p f5 (i1, i2)" ".* = {f = 123}"
gdb_breakpoint "f1"
gdb_breakpoint "f2"
gdb_breakpoint "f22"
gdb_breakpoint "f3"
gdb_breakpoint "f4"
+gdb_breakpoint "f5"
gdb_continue_to_breakpoint "Break in f1"
gdb_test "finish" " = {a = 123}" \
@@ -68,3 +70,7 @@ gdb_test "finish" " = {.* c = 123}" \
gdb_continue_to_breakpoint "Break in f4"
gdb_test "finish" " = {.* e = 123}" \
"finish from f4"
+
+gdb_continue_to_breakpoint "Break in f5"
+gdb_test "finish" " = {f = 123}" \
+ "finish from f5"
--
2.43.0

View File

@@ -0,0 +1,69 @@
From 0494211cb5f418654ca3a4ac1b9f10518426732f Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Wed, 13 Nov 2024 19:44:21 +0100
Subject: [PATCH 15/46] [gdb/tdep] Fix recording of T1 push
When running test-case gdb.reverse/recursion.exp on arm-linux with target
board unix/-mthumb, I run into:
...
(gdb) PASS: gdb.reverse/recursion.exp: Skipping recursion from inside
reverse-next^M
bar (x=4195569) at /home/linux/gdb/src/gdb/testsuite/gdb.reverse/recursion.c:34^M
34 int r = foo (x);^M
(gdb) FAIL: gdb.reverse/recursion.exp: print frame when stepping out
...
The problem is the recording of the T1 push instruction [1,2], specifically:
...
000004d8 <foo>:
4d8: b580 push {r7, lr}
...
The current code fails to add a memory record for the memory written with the
value of the lr register.
Fix this by adding the missing memory record.
Tested on arm-linux.
Reviewed-By: Guinevere Larsen <guinevere@redhat.com>
Approved-By: Luis Machado <luis.machado@arm.com>
[1] https://developer.arm.com/documentation/ddi0406/c/Application-Level-Architecture/Instruction-Details/Encoding-of-lists-of-ARM-core-registers
[2] https://developer.arm.com/documentation/ddi0597/2024-09/T32-Instructions-by-Encoding/16-bit?lang=en#pushpop16
---
gdb/arm-tdep.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c
index f36ce631a08..d898a426609 100644
--- a/gdb/arm-tdep.c
+++ b/gdb/arm-tdep.c
@@ -13561,9 +13561,12 @@ thumb_record_misc (arm_insn_decode_record *thumb_insn_r)
record_buf[0] = bits (thumb_insn_r->arm_insn, 0, 2);
thumb_insn_r->reg_rec_count = 1;
break;
- case 4: /* fall through */
case 5:
- /* PUSH. */
+ /* PUSH with lr. */
+ register_count++;
+ [[fallthrough]];
+ case 4:
+ /* PUSH without lr. */
register_bits = bits (thumb_insn_r->arm_insn, 0, 7);
regcache_raw_read_unsigned (reg_cache, ARM_SP_REGNUM, &u_regval);
while (register_bits)
@@ -13572,8 +13575,7 @@ thumb_record_misc (arm_insn_decode_record *thumb_insn_r)
register_count++;
register_bits = register_bits >> 1;
}
- start_address = u_regval - \
- (4 * (bit (thumb_insn_r->arm_insn, 8) + register_count));
+ start_address = u_regval - (4 * register_count);
thumb_insn_r->mem_rec_count = register_count;
while (register_count)
{
--
2.43.0

View File

@@ -0,0 +1,46 @@
From 559ec501f594101dd786ce7dad1c89069934c965 Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Wed, 13 Nov 2024 19:37:04 +0100
Subject: [PATCH 14/46] [gdb/tdep] Handle sycall statx for arm-linux
When running test-case gdb.reverse/fstatat-reverse.exp on arm-linux, I run
into:
...
(gdb) continue^M
Continuing.^M
Process record and replay target doesn't support syscall number 397^M
Process record does not support instruction 0xdf00 at address 0xf7ebf774.^M
Process record: failed to record execution log.^M
^M
Program stopped.^M
0xf7ebf774 in ?? () from /lib/arm-linux-gnueabihf/libc.so.6^M
(gdb) FAIL: gdb.reverse/fstatat-reverse.exp: continue to breakpoint: marker2
...
Syscall number 397 stands for statx on arm-linux.
Fix this by handling 397 in arm_canonicalize_syscall.
Tested on arm-linux.
Reviewed-By: Guinevere Larsen <guinevere@redhat.com>
Approved-By: Luis Machado <luis.machado@arm.com>
---
gdb/arm-linux-tdep.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/gdb/arm-linux-tdep.c b/gdb/arm-linux-tdep.c
index 43869e4fcfe..bb3d808bd5a 100644
--- a/gdb/arm-linux-tdep.c
+++ b/gdb/arm-linux-tdep.c
@@ -1644,6 +1644,7 @@ arm_canonicalize_syscall (int syscall)
case 379: return gdb_sys_finit_module;
*/
case 384: return gdb_sys_getrandom;
+ case 397: return gdb_sys_statx;
case 983041: /* ARM_breakpoint */ return gdb_sys_no_syscall;
case 983042: /* ARM_cacheflush */ return gdb_sys_no_syscall;
case 983043: /* ARM_usr26 */ return gdb_sys_no_syscall;
--
2.43.0

View File

@@ -0,0 +1,80 @@
From 522e3a4837eaef79fc255b29c5ed75fc6f817ce1 Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Wed, 13 Nov 2024 22:41:35 +0100
Subject: [PATCH 16/46] [gdb/tdep] Handle syscall clock_gettime64 for arm-linux
When running test-case gdb.reverse/time-reverse.exp on arm-linux, I run into:
...
(gdb) continue^M
Continuing.^M
Process record and replay target doesn't support syscall number 403^M
Process record does not support instruction 0xdf00 at address 0xf7ebf774.^M
Process record: failed to record execution log.^M
^M
Program stopped.^M
0xf7ebf774 in ?? () from /lib/arm-linux-gnueabihf/libc.so.6^M
(gdb) FAIL: $exp: mode=c: continue to breakpoint: marker2
...
Syscall number 403 stands for clock_gettime64 on arm-linux.
Fix this by handling 403 in arm_canonicalize_syscall, and handling
gdb_sys_clock_gettime64 elsewhere.
Since i386_canonicalize_syscall is the identity function, enum value
gdb_sys_clock_gettime64 gets a value to match i386, which also happens to be
403.
Tested on arm-linux.
Approved-By: Guinevere Larsen <guinevere@redhat.com> (record-full)
---
gdb/arm-linux-tdep.c | 1 +
gdb/linux-record.c | 6 ++++++
gdb/linux-record.h | 1 +
3 files changed, 8 insertions(+)
diff --git a/gdb/arm-linux-tdep.c b/gdb/arm-linux-tdep.c
index bb3d808bd5a..4dc8f00d8c2 100644
--- a/gdb/arm-linux-tdep.c
+++ b/gdb/arm-linux-tdep.c
@@ -1645,6 +1645,7 @@ arm_canonicalize_syscall (int syscall)
*/
case 384: return gdb_sys_getrandom;
case 397: return gdb_sys_statx;
+ case 403: return gdb_sys_clock_gettime64;
case 983041: /* ARM_breakpoint */ return gdb_sys_no_syscall;
case 983042: /* ARM_cacheflush */ return gdb_sys_no_syscall;
case 983043: /* ARM_usr26 */ return gdb_sys_no_syscall;
diff --git a/gdb/linux-record.c b/gdb/linux-record.c
index 549ea1bd713..33efa026a53 100644
--- a/gdb/linux-record.c
+++ b/gdb/linux-record.c
@@ -1820,6 +1820,12 @@ Do you want to stop the program?"),
return -1;
break;
+ case gdb_sys_clock_gettime64:
+ /* Size of struct __timespec64 is 16. */
+ if (record_mem_at_reg (regcache, tdep->arg2, 16))
+ return -1;
+ break;
+
case gdb_sys_clock_getres:
if (record_mem_at_reg (regcache, tdep->arg2, tdep->size_timespec))
return -1;
diff --git a/gdb/linux-record.h b/gdb/linux-record.h
index 962cedc3d34..54696124bf2 100644
--- a/gdb/linux-record.h
+++ b/gdb/linux-record.h
@@ -512,6 +512,7 @@ enum gdb_syscall {
gdb_sys_inotify_init1 = 332,
gdb_sys_getrandom = 355,
gdb_sys_statx = 383,
+ gdb_sys_clock_gettime64 = 403,
gdb_sys_socket = 500,
gdb_sys_connect = 501,
gdb_sys_accept = 502,
--
2.43.0

View File

@@ -0,0 +1,168 @@
From 9afcf99e16a4adecc7d1a18c30bed65a29c96e52 Mon Sep 17 00:00:00 2001
From: Andreas Arnez <arnez@linux.ibm.com>
Date: Tue, 19 Nov 2024 18:24:06 +0100
Subject: [PATCH] [gdb/tdep] s390: Add arch15 record/replay support
Enable recording of the new "arch15" instructions on z/Architecture
targets.
---
gdb/s390-tdep.c | 78 +++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 75 insertions(+), 3 deletions(-)
diff --git a/gdb/s390-tdep.c b/gdb/s390-tdep.c
index dcac407caef..e25bcfaf974 100644
--- a/gdb/s390-tdep.c
+++ b/gdb/s390-tdep.c
@@ -4245,6 +4245,10 @@ s390_process_record (struct gdbarch *gdbarch, struct regcache *regcache,
case 0xb917: /* LLGTR - load logical thirty one bits */
case 0xb91c: /* MSGFR - multiply single 64<32 */
case 0xb946: /* BCTGR - branch on count */
+ case 0xb968: /* CLZG - count leading zeros */
+ case 0xb969: /* CTZG - count trailing zeros */
+ case 0xb96c: /* BEXTG - bit extract */
+ case 0xb96d: /* BDEPG - bit deposit */
case 0xb984: /* LLGCR - load logical character */
case 0xb985: /* LLGHR - load logical halfword */
case 0xb9e2: /* LOCGR - load on condition */
@@ -5125,7 +5129,14 @@ s390_process_record (struct gdbarch *gdbarch, struct regcache *regcache,
return -1;
break;
- /* 0xc86-0xc8f undefined */
+ case 0xc86: /* CAL - compare and load 32 */
+ case 0xc87: /* CALG - compare and load 64 */
+ case 0xc8f: /* CALGF - compare and load 64<32 */
+ if (s390_record_gpr_g (gdbarch, regcache, inib[2]))
+ return -1;
+ if (record_full_arch_list_add_reg (regcache, S390_PSWM_REGNUM))
+ return -1;
+ break;
default:
goto UNKNOWN_OP;
@@ -5336,6 +5347,16 @@ s390_process_record (struct gdbarch *gdbarch, struct regcache *regcache,
case 0xe33b: /* LZRF - load and zero rightmost byte */
case 0xe351: /* MSY - multiply single */
case 0xe358: /* LY - load */
+ case 0xe360: /* LXAB - load indexed address (shift 0) */
+ case 0xe361: /* LLXAB - load logical indexed address (shift 0) */
+ case 0xe362: /* LXAH - load indexed address (shift 1) */
+ case 0xe363: /* LLXAH - load logical indexed address (shift 1) */
+ case 0xe364: /* LXAF - load indexed address (shift 2) */
+ case 0xe365: /* LLXAF - load logical indexed address (shift 2) */
+ case 0xe366: /* LXAG - load indexed address (shift 3) */
+ case 0xe367: /* LLXAG - load logical indexed address (shift 3) */
+ case 0xe368: /* LXAQ - load indexed address (shift 4) */
+ case 0xe369: /* LLXAQ - load logical indexed address (shift 4) */
case 0xe371: /* LAY - load address */
case 0xe373: /* ICY - insert character */
case 0xe376: /* LB - load byte */
@@ -5448,7 +5469,7 @@ s390_process_record (struct gdbarch *gdbarch, struct regcache *regcache,
break;
/* 0xe35d undefined */
- /* 0xe360-0xe36f undefined */
+ /* 0xe36a-0xe36f undefined */
case 0xe372: /* STCY - store character */
case 0xe3c3: /* STCH - store character high */
@@ -5569,6 +5590,7 @@ s390_process_record (struct gdbarch *gdbarch, struct regcache *regcache,
case 0xe750: /* VPOPCT - vector population count */
case 0xe752: /* VCTZ - vector count trailing zeros */
case 0xe753: /* VCLZ - vector count leading zeros */
+ case 0xe754: /* VGEM - vector generate element masks */
case 0xe756: /* VLR - vector load */
case 0xe75f: /* VSEG -vector sign extend to doubleword */
case 0xe760: /* VMRL - vector merge low */
@@ -5602,6 +5624,8 @@ s390_process_record (struct gdbarch *gdbarch, struct regcache *regcache,
case 0xe785: /* VBPERM - vector bit permute */
case 0xe786: /* VSLD - vector shift left double by bit */
case 0xe787: /* VSRD - vector shift right double by bit */
+ case 0xe788: /* VEVAL - vector evaluate */
+ case 0xe789: /* VBLEND - vector blend */
case 0xe78b: /* VSTRS - vector string search */
case 0xe78c: /* VPERM - vector permute */
case 0xe78d: /* VSEL - vector select */
@@ -5624,6 +5648,10 @@ s390_process_record (struct gdbarch *gdbarch, struct regcache *regcache,
case 0xe7ad: /* VMALO - vector multiply and add logical odd */
case 0xe7ae: /* VMAE - vector multiply and add even */
case 0xe7af: /* VMAO - vector multiply and add odd */
+ case 0xe7b0: /* VDL - vector divide logical */
+ case 0xe7b1: /* VRL - vector remainder logical */
+ case 0xe7b2: /* VD - vector divide */
+ case 0xe7b3: /* VR - vector remainder */
case 0xe7b4: /* VGFM - vector Galois field multiply sum */
case 0xe7b8: /* VMSL - vector multiply sum logical */
case 0xe7b9: /* VACCC - vector add with carry compute carry */
@@ -5799,6 +5827,8 @@ s390_process_record (struct gdbarch *gdbarch, struct regcache *regcache,
/* 0xe747-0xe749 undefined */
+ case 0xe64a: /* VCVDQ - vector convert to decimal 128 bits */
+ case 0xe64e: /* VCVBQ - vector convert to binary 128 bits */
case 0xe651: /* VCLZDP - vector count leading zero digits */
case 0xe654: /* VUPKZH - vector unpack zoned high */
case 0xe658: /* VCVD - vector convert to decimal 32 bit */
@@ -5839,6 +5869,7 @@ s390_process_record (struct gdbarch *gdbarch, struct regcache *regcache,
break;
case 0xe65f: /* VTP - vector test decimal */
+ case 0xe67f: /* VTZ - vector test zoned */
/* flags + FPC */
if (record_full_arch_list_add_reg (regcache, S390_PSWM_REGNUM))
return -1;
@@ -5932,7 +5963,48 @@ s390_process_record (struct gdbarch *gdbarch, struct regcache *regcache,
return -1;
break;
- /* 0xeb15-0xeb1b undefined */
+ case 0xeb16: /* PFCR - perform functions with concurrent results */
+ if (record_full_arch_list_add_reg (regcache, S390_PSWM_REGNUM))
+ return -1;
+ regcache_raw_read_unsigned (regcache, S390_R0_REGNUM, &tmp);
+ oaddr = s390_record_calc_disp (gdbarch, regcache, 0, insn[1],
+ ibyte[4]);
+ {
+ uint8_t fc = tmp & 0xff;
+ if (fc == 0) /* PFCR-QAF */
+ {
+ if (record_full_arch_list_add_mem (oaddr, 16))
+ return -1;
+ }
+ else if (fc >= 1 && fc <= 4)
+ {
+ /* Compare and swap and double/triple store. */
+ int bytesize = fc & 1 ? 4 : 8;
+ int startbit = fc >= 3 ? 16 : 32;
+ if (record_full_arch_list_add_reg (regcache,
+ S390_R0_REGNUM + inib[2]))
+ return -1;
+ regcache_raw_read_unsigned (regcache,
+ S390_R0_REGNUM + inib[3], &tmp);
+ for (i = startbit; i < 64; i += 16)
+ {
+ oaddr = s390_record_calc_disp (gdbarch, regcache, 0,
+ (tmp >> i) & 0xffff, 0);
+ if (record_full_arch_list_add_mem (oaddr, bytesize))
+ return -1;
+ }
+ }
+ else
+ {
+ gdb_printf (gdb_stdlog,
+ "Warning: Unknown PFCR FC %02x at %s.\n",
+ fc, paddress (gdbarch, addr));
+ return -1;
+ }
+ }
+ break;
+
+ /* 0xeb17-0xeb1b undefined */
/* 0xeb1e-0xeb1f undefined */
/* 0xeb22 undefined */
base-commit: 029bb9a91184eae765dda5220ccfb29d7d02f395
--
2.43.0

121
gdb-testsuite-ada-pie.patch Normal file
View File

@@ -0,0 +1,121 @@
From 6de9111c512de99fd8cb3ea89f9890b1d72f6ef0 Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Fri, 21 Apr 2023 09:12:35 +0200
Subject: [PATCH] Compile ada hello world for skip_ada_tests
For openSUSE Leap 15.0 with gcc-PIE installed (which makes gcc create PIE
executables by default) we get:
...
FAIL: gdb.ada/O2_float_param.exp: compilation foo.adb
...
The problem is that while gcc-PIE affects gcc, it does not affect gnatlink,
so it links in the libgnat.a, rather than libgnat_pic.a. [ This is
bsc#1115034. ]
[ Without gcc-PIE, we have a related problem: if we run ada tests with
--target_board=unix/-fPIE/-pie, which makes sure PIE executables are generated
for c/c++ test-cases, still we get non-PIE ada executables, because gnatmake
does not pass -pie to gnatlink. And if gnatmake would pass -pie to gnatlink,
we'd run into the same FAIL as above because gnatlink does not use use
libgnat_pic.a when -pie is specified (this is PR gcc/87936). So, in order to
have ada tests generate PIE executables, we need
--target_board=unix/-fPIE/-largs/-pie/-lgnat_pic/-margs, which will not work
with c/c++ test-cases. ]
For now, we check whether we can compile an ada hello world, and if not,
generate an UNSUPPORTED in either skip_ada_tests or gdb_compile_ada, to
not have this problem result in ~200 FAILs.
gdb/testsuite/ChangeLog:
2020-11-06 Tom de Vries <tdevries@suse.de>
* lib/ada.exp (gdb_compile_ada): Call gdb_can_compile_ada.
(gdb_can_compile_ada): New gdb_caching_proc.
* lib/gdb.exp: Add load_lib ada.exp.
(skip_ada_tests): Return 1 if !gdb_can_compile_ada.
---
gdb/testsuite/lib/ada.exp | 31 +++++++++++++++++++++++++++++++
gdb/testsuite/lib/gdb.exp | 8 ++++++++
2 files changed, 39 insertions(+)
diff --git a/gdb/testsuite/lib/ada.exp b/gdb/testsuite/lib/ada.exp
index 4bf1368f29f..7d8fbf01fbd 100644
--- a/gdb/testsuite/lib/ada.exp
+++ b/gdb/testsuite/lib/ada.exp
@@ -90,12 +90,43 @@ proc gdb_compile_ada_1 {source dest type options} {
# compile was successful.
proc gdb_compile_ada {source dest type options} {
+ if { [gdb_can_compile_ada] == 0 } {
+ global gdb_test_file_name
+ unsupported "$gdb_test_file_name"
+ return "Cannot compile ada"
+ }
set result [gdb_compile_ada_1 $source $dest $type $options]
gdb_compile_test $source $result
return $result
}
+gdb_caching_proc gdb_can_compile_ada {} {
+ set name "hello"
+ set dir "[pwd]/tmp-ada-hello-[pid]"
+ set src "$dir/$name.adb"
+ set dest "$dir/$name"
+
+ set code {
+ with Ada.Text_IO;
+
+ procedure Hello is
+ begin
+ Ada.Text_IO.Put_Line("Hello, world!");
+ end Hello;
+ }
+
+ file mkdir $dir
+ gdb_produce_source $src $code
+ set res [gdb_compile_ada_1 $src $dest executable {debug}]
+ file delete -force $dir
+
+ if { $res != "" } {
+ return 0
+ }
+ return 1
+}
+
# Like standard_testfile, but for Ada. Historically the Ada tests
# used a different naming convention from many of the other gdb tests,
# and this difference was preserved during the conversion to
diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp
index 990d0c8a70f..6c1f59ef4a6 100644
--- a/gdb/testsuite/lib/gdb.exp
+++ b/gdb/testsuite/lib/gdb.exp
@@ -145,6 +145,7 @@ load_lib cache.exp
load_lib gdb-utils.exp
load_lib memory.exp
load_lib check-test-names.exp
+load_lib ada.exp
# The path to the GDB binary to test.
global GDB
@@ -2538,6 +2539,13 @@ proc allow_ada_tests {} {
# Currently gdb_ada_compile doesn't support remote host.
return 0
}
+
+ if { [gdb_can_compile_ada] == 0 } {
+ global gdb_test_file_name
+ unsupported "$gdb_test_file_name"
+ return 0
+ }
+
return 1
}
base-commit: af4a87e2b3c2ac5acae1e6f4405fc59e1218de74
--
2.35.3

View File

@@ -0,0 +1,93 @@
From 29bcee2db6233ff0ea4fc9231910bb2da530308e Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Thu, 6 Mar 2025 21:19:39 +0100
Subject: [PATCH 10/10] [gdb/testsuite] Add gdb.arch/s390-disassemble.exp
In commit a98a6fa2d8e ("s390: Add arch15 instructions"), support for
new instructions was added to libopcodes, but the added tests only exercise
this for gas.
Add a test-case gdb.arch/s390-disassemble.exp that checks gdb's ability to
disassemble one of these instructions.
Tested on s390x-linux.
---
gdb/testsuite/gdb.arch/s390-disassemble.c | 23 ++++++++++++++
gdb/testsuite/gdb.arch/s390-disassemble.exp | 35 +++++++++++++++++++++
2 files changed, 58 insertions(+)
create mode 100644 gdb/testsuite/gdb.arch/s390-disassemble.c
create mode 100644 gdb/testsuite/gdb.arch/s390-disassemble.exp
diff --git a/gdb/testsuite/gdb.arch/s390-disassemble.c b/gdb/testsuite/gdb.arch/s390-disassemble.c
new file mode 100644
index 00000000000..ee6469ddf98
--- /dev/null
+++ b/gdb/testsuite/gdb.arch/s390-disassemble.c
@@ -0,0 +1,23 @@
+/* This file is part of GDB, the GNU debugger.
+
+ Copyright 2025 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+void
+clzg (void)
+{
+ /* clzg %r0,%r3. */
+ asm volatile (" .long 0xb9680003");
+}
diff --git a/gdb/testsuite/gdb.arch/s390-disassemble.exp b/gdb/testsuite/gdb.arch/s390-disassemble.exp
new file mode 100644
index 00000000000..0c187df3c11
--- /dev/null
+++ b/gdb/testsuite/gdb.arch/s390-disassemble.exp
@@ -0,0 +1,35 @@
+# Copyright 2025 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# Check that GDB is able to disassemble certain s390x instructions.
+
+require {istarget "s390x*-*-*"}
+
+standard_testfile
+set objfile [standard_output_file ${testfile}.o]
+
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" $objfile object {}] != "" } {
+ return -1
+}
+
+clean_restart $objfile
+
+gdb_test "disassemble clzg" \
+ [join \
+ [list \
+ ".*\t" \
+ "clzg\t%r0,%r3" \
+ "\r\n.*"] \
+ ""]
--
2.43.0

View File

@@ -0,0 +1,68 @@
From b08bf94f170dd39db21cf8f62941f1866b6978c0 Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Thu, 16 Feb 2023 11:36:47 +0100
Subject: [PATCH 080/155] Add gdb.suse/debranding.exp
---
gdb/testsuite/gdb.suse/debranding.exp | 49 +++++++++++++++++++++++++++
1 file changed, 49 insertions(+)
create mode 100644 gdb/testsuite/gdb.suse/debranding.exp
diff --git a/gdb/testsuite/gdb.suse/debranding.exp b/gdb/testsuite/gdb.suse/debranding.exp
new file mode 100644
index 00000000000..cdee10b75a7
--- /dev/null
+++ b/gdb/testsuite/gdb.suse/debranding.exp
@@ -0,0 +1,49 @@
+# Copyright 2023 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# There's a problem with dumping the entire output into gdb.log
+# on SLE-11, so redirect to file instead. Also means the gdb.log
+# is smaller.
+set f [standard_output_file "gdb-strings.txt"]
+
+# Not using remote_exec due to using file redirection.
+set cmd "exec strings $GDB > $f"
+set status [catch $cmd msg]
+verbose -log "status: $status"
+verbose -log "msg: $msg"
+gdb_assert { $status == 0 }
+
+set fp [open $f r]
+set output [read $fp]
+close $fp
+
+set re {^.*(?:fedora|red[^a-z]?hat).*$}
+set matches [regexp -line -nocase -all -inline $re $output]
+
+set disallowed_matches 0
+set allowed_re "warning: deprecated Red Hat reloc"
+foreach match $matches {
+ if { [regexp -nocase $allowed_re $match] } {
+ verbose -log "allowed_match: '$match'"
+ continue
+ }
+
+ verbose -log "disallowed_match: '$match'"
+ incr disallowed_matches
+}
+
+gdb_assert { $disallowed_matches == 0 }
+
+remote_file build delete $f
--
2.35.3

View File

@@ -0,0 +1,101 @@
gdb-testsuite-add-gdb.suse-zypper-hint.exp
[gdb/testsuite] Add gdb.suse/zypper-hint.exp
---
gdb/testsuite/gdb.suse/zypper-hint.c | 25 ++++++++++++++++
gdb/testsuite/gdb.suse/zypper-hint.exp | 55 ++++++++++++++++++++++++++++++++++
2 files changed, 80 insertions(+)
diff --git a/gdb/testsuite/gdb.suse/zypper-hint.c b/gdb/testsuite/gdb.suse/zypper-hint.c
new file mode 100644
index 00000000000..e179788f04f
--- /dev/null
+++ b/gdb/testsuite/gdb.suse/zypper-hint.c
@@ -0,0 +1,25 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2021 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include <stdio.h>
+
+int
+main (void)
+{
+ printf ("hello\n");
+ return 0;
+}
diff --git a/gdb/testsuite/gdb.suse/zypper-hint.exp b/gdb/testsuite/gdb.suse/zypper-hint.exp
new file mode 100644
index 00000000000..c2b9a1134bd
--- /dev/null
+++ b/gdb/testsuite/gdb.suse/zypper-hint.exp
@@ -0,0 +1,55 @@
+# Copyright 2021 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+standard_testfile .c
+
+if { [prepare_for_testing "failed to prepare" $testfile $srcfile] } {
+ return -1
+}
+
+clean_restart ${binfile}
+
+gdb_test_no_output "set build-id-verbose 1"
+
+set test "zypper hint printed"
+if { ![gdb_breakpoint main qualified] } {
+ unresolved $test
+ return -1
+}
+
+gdb_run_cmd
+
+set re_64 \
+ "Missing separate debuginfos, use: zypper install glibc-debuginfo-"
+set re_32 \
+ "Missing separate debuginfos, use: zypper install glibc-32bit-debuginfo-"
+
+set hexno0x "\[0-9A-Fa-f\]+"
+set re_nolibrpm \
+ [multi_line \
+ "Missing separate debuginfo for .*libc.so.*" \
+ "Try: zypper install -C \"debuginfo\\(build-id\\)=$hexno0x\""]
+
+gdb_test_multiple "" $test {
+ -re -wrap ($re_64|$re_32).* {
+ pass "$gdb_test_name (librpm)"
+ }
+ -re -wrap $re_nolibrpm.* {
+ pass "$gdb_test_name (no librpm)"
+ }
+}
+
+# To give some background information in case the previous test failed.
+gdb_test "info shared"

View File

@@ -0,0 +1,59 @@
From 729d6b050f41d1d058c0f22f2c767995f5441b7a Mon Sep 17 00:00:00 2001
From: Andrew Burgess <aburgess@redhat.com>
Date: Sun, 27 Oct 2024 08:55:16 +0000
Subject: [PATCH] gdb/testsuite: avoid intermittent failures on a debuginfod
test
I saw a failure in gdb.debuginfod/build-id-no-debug-warning.exp which
I could only produce one time.
Normally the test output looks like this:
file /tmp/build/gdb/testsuite/outputs/gdb.debuginfod/build-id-no-debug-warning/.build-id/0c/30f589cc4f2c0fb22c8914d042ddf39c9a3885.debug
Reading symbols from /tmp/build/gdb/testsuite/outputs/gdb.debuginfod/build-id-no-debug-warning/.build-id/0c/30f589cc4f2c0fb22c8914d042ddf39c9a3885.debug...
Downloading separate debug info for /tmp/build/gdb/testsuite/outputs/gdb.debuginfod/build-id-no-debug-warning/.build-id/0c/30f589cc4f2c0fb22c8914d042ddf39c9a3885.debug...
Reading symbols from /tmp/build/gdb/testsuite/outputs/gdb.debuginfod/build-id-no-debug-warning/.client_cache/0c30f589cc4f2c0fb22c8914d042ddf39c9a3885/debuginfo...
(gdb) PASS: gdb.debuginfod/build-id-no-debug-warning.exp: local_debuginfod: debuginfod running, info downloaded, no war
But one time I saw this:
file /tmp/build/gdb/testsuite/outputs/gdb.debuginfod/build-id-no-debug-warning/.build-id/0c/30f589cc4f2c0fb22c8914d042ddf39c9a3885.debug
Reading symbols from /tmp/build/gdb/testsuite/outputs/gdb.debuginfod/build-id-no-debug-warning/.build-id/0c/30f589cc4f2c0fb22c8914d042ddf39c9a3885.debug...
Downloading 6.77 K separate debug info for /tmp/build/gdb/testsuite/outputs/gdb.debuginfod/build-id-no-debug-warning/.build-id/0c/30f589cc4f2c0fb22c8914d042ddf39c9a3885.debug...
Reading symbols from /tmp/build/gdb/testsuite/outputs/gdb.debuginfod/build-id-no-debug-warning/.client_cache/0c30f589cc4f2c0fb22c8914d042ddf39c9a3885/debuginfo...
(gdb) FAIL: gdb.debuginfod/build-id-no-debug-warning.exp: local_debuginfod: debuginfod running, info downloaded, no warnings
The difference is the "Downloading separate debug info for ..." line
has gained an extra '6.77 K' component. When I got the FAIL the
machine was under heavy load, so I suspect everything was running
pretty slow. I think the size is only added when the debuginfod
download is taking its time.
Anyway, the test in question is not expecting to see a size, which is
why it failed.
Every other debuginfod test does allow for an optional size being
printed, so lets update this test to also accept an optional size,
this should prevent failures like this in the future.
---
gdb/testsuite/gdb.debuginfod/build-id-no-debug-warning.exp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/gdb/testsuite/gdb.debuginfod/build-id-no-debug-warning.exp b/gdb/testsuite/gdb.debuginfod/build-id-no-debug-warning.exp
index 8ee3bb0e78c..fcadfddd293 100644
--- a/gdb/testsuite/gdb.debuginfod/build-id-no-debug-warning.exp
+++ b/gdb/testsuite/gdb.debuginfod/build-id-no-debug-warning.exp
@@ -148,7 +148,7 @@ proc_with_prefix local_debuginfod { } {
gdb_test "file ${build_id_debug_file}" \
[multi_line \
"Reading symbols from ${build_id_debug_file}\\.\\.\\." \
- "Downloading separate debug info for ${build_id_debug_file}\\.\\.\\." \
+ "Downloading\[^\r\n\]*separate debug info for ${build_id_debug_file}\\.\\.\\." \
"Reading symbols from ${cache}/\[^\r\n\]+\\.\\.\\.(?:\r\nExpanding full symbols from \[^\r\n\]+)*"] \
"debuginfod running, info downloaded, no warnings"
}
base-commit: 6cfb7bf81be3ab6f131dbc6a27eefca516cf7517
--
2.43.0

View File

@@ -0,0 +1,48 @@
From 889debbb7270408fa96401d5482dc2b9caec494d Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Wed, 8 Jan 2025 16:24:11 +0100
Subject: [PATCH 05/46] [gdb/testsuite] Check gnatmake version in
gdb.ada/scalar_storage.exp
On a system with gcc 14.2.0 and gnatmake 13.3.0 I run into:
...
(gdb) PASS: gdb.ada/scalar_storage.exp: print V_LE
get_compiler_info: gcc-14-2-0
print V_BE^M
$2 = (value => 126, another_value => 12, color => red)^M
(gdb) FAIL: gdb.ada/scalar_storage.exp: print V_BE
...
The test-case contains a corresponding kfail:
...
# This requires a compiler fix that is in GCC 14.
if {[gcc_major_version] < 14} {
setup_kfail "DW_AT_endianity on enum types" *-*-*
}
...
which doesn't trigger because it checks the gcc version rather than the
gnatmake version.
Fix this by checking the gnatmake version instead.
Tested on aarch64-linux and x86_64-linux.
---
gdb/testsuite/gdb.ada/scalar_storage.exp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/gdb/testsuite/gdb.ada/scalar_storage.exp b/gdb/testsuite/gdb.ada/scalar_storage.exp
index e01e75fe5d2..5dccaef8f14 100644
--- a/gdb/testsuite/gdb.ada/scalar_storage.exp
+++ b/gdb/testsuite/gdb.ada/scalar_storage.exp
@@ -36,7 +36,7 @@ if {![runto "storage.adb:$bp_location"]} {
gdb_test "print V_LE" "= \\(value => 126, another_value => 12, color => green\\)"
# This requires a compiler fix that is in GCC 14.
-if {[gcc_major_version] < 14} {
+if { ![gnatmake_version_at_least 14] } {
setup_kfail "DW_AT_endianity on enum types" *-*-*
}
gdb_test "print V_BE" "= \\(value => 126, another_value => 12, color => green\\)"
--
2.43.0

View File

@@ -0,0 +1,274 @@
From 42f3a32877ab455607662c7a12c7a793f3744e4e Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Mon, 10 Jun 2024 10:43:10 +0200
Subject: [PATCH 08/46] [gdb/testsuite] Don't use set auto-solib-add off
In test-case gdb.mi/mi-var-child-f.exp, we have:
...
mi_gdb_test "-gdb-set auto-solib-add off" "\\^done"
mi_runto prog_array
mi_gdb_test "nosharedlibrary" ".*\\^done"
...
This was added to avoid a name clash between the array variable as defined in
gdb.mi/array.f90 and debug info in shared libraries, and used in other places
in the testsuite.
The same workaround is also used to ignore symbols from shared libraries when
excercising for instance a command that prints all symbols.
However, this approach can cause problems for targets like arm that require
symbol info for some libraries like ld.so and libc to fully function.
While absense of debug info for shared libraries should be handled gracefully
(which does need fixing, see PR31817), failure to do so should not result
in failures in unrelated test-cases.
Fix this by removing "set auto-solib-add off".
This ensures that we don't run into PR31817, while the presence of
nosharedlibrary still ensures that in the rest of the test-case we're not
bothered by shared library symbols.
Likewise in other test-cases.
Approved-by: Kevin Buettner <kevinb@redhat.com>
Tested on arm-linux.
---
gdb/testsuite/gdb.base/gold-gdb-index.exp | 4 ++--
gdb/testsuite/gdb.base/info-types.exp.tcl | 3 ++-
gdb/testsuite/gdb.base/print-symbol-loading.exp | 4 +++-
gdb/testsuite/gdb.dwarf2/dw2-zero-range.exp | 6 ++----
gdb/testsuite/gdb.fortran/allocated.exp | 3 ---
gdb/testsuite/gdb.fortran/array-slices-bad.exp | 3 ---
gdb/testsuite/gdb.fortran/array-slices-sub-slices.exp | 3 ---
gdb/testsuite/gdb.fortran/array-slices.exp | 3 ---
gdb/testsuite/gdb.fortran/info-modules.exp | 3 ---
gdb/testsuite/gdb.fortran/lbound-ubound.exp | 3 ---
gdb/testsuite/gdb.fortran/module.exp | 3 ---
gdb/testsuite/gdb.fortran/subarray.exp | 3 ---
gdb/testsuite/gdb.mi/mi-fortran-modules.exp | 3 ---
gdb/testsuite/gdb.mi/mi-var-child-f.exp | 3 ---
14 files changed, 9 insertions(+), 38 deletions(-)
diff --git a/gdb/testsuite/gdb.base/gold-gdb-index.exp b/gdb/testsuite/gdb.base/gold-gdb-index.exp
index c9c6598c3fa..0309dd353ad 100644
--- a/gdb/testsuite/gdb.base/gold-gdb-index.exp
+++ b/gdb/testsuite/gdb.base/gold-gdb-index.exp
@@ -32,12 +32,12 @@ if { [have_index $binfile] != "gdb_index" } {
return -1
}
-gdb_test_no_output "set auto-solib-add off"
-
if {![runto_main]} {
return 0
}
+gdb_test_no_output "nosharedlibrary"
+
gdb_test_no_output "set breakpoint pending off"
gdb_test "break N1::misspelled" "Function \"N1::misspelled\" not defined\."
diff --git a/gdb/testsuite/gdb.base/info-types.exp.tcl b/gdb/testsuite/gdb.base/info-types.exp.tcl
index 69d53b9f8de..0a33afedf86 100644
--- a/gdb/testsuite/gdb.base/info-types.exp.tcl
+++ b/gdb/testsuite/gdb.base/info-types.exp.tcl
@@ -32,12 +32,13 @@ proc run_test { lang } {
"${testfile}" $srcfile "debug $lang"]} {
return -1
}
- gdb_test_no_output "set auto-solib-add off"
if ![runto_main] then {
return 0
}
+ gdb_test_no_output "nosharedlibrary"
+
set file_re "File .*[string_to_regexp $srcfile]:"
if { $lang == "c++" } {
diff --git a/gdb/testsuite/gdb.base/print-symbol-loading.exp b/gdb/testsuite/gdb.base/print-symbol-loading.exp
index b61dba33377..b3520f1e032 100644
--- a/gdb/testsuite/gdb.base/print-symbol-loading.exp
+++ b/gdb/testsuite/gdb.base/print-symbol-loading.exp
@@ -95,10 +95,12 @@ proc test_load_shlib { print_symbol_loading } {
global gdb_prompt
with_test_prefix "shlib ${print_symbol_loading}" {
clean_restart ${binfile}
- gdb_test_no_output "set auto-solib-add off"
if ![runto_main] {
return -1
}
+
+ gdb_test_no_output "nosharedlibrary"
+
gdb_test_no_output "set print symbol-loading $print_symbol_loading"
set test_name "load shared-lib"
set libc_re \
diff --git a/gdb/testsuite/gdb.dwarf2/dw2-zero-range.exp b/gdb/testsuite/gdb.dwarf2/dw2-zero-range.exp
index 59840b8d0e2..e2e4f240c88 100644
--- a/gdb/testsuite/gdb.dwarf2/dw2-zero-range.exp
+++ b/gdb/testsuite/gdb.dwarf2/dw2-zero-range.exp
@@ -29,14 +29,12 @@ proc_with_prefix test_relocated { exec_path lib_path complaint_re readnow_p } {
clean_restart $exec_path
gdb_load_shlib $lib_path
- # Don't load the symbols for $lib_path during runto_main.
- # Instead, we do this afterwards using "sharedlibrary $lib_path".
- gdb_test_no_output "set auto-solib-add off"
-
if { ![runto_main] } {
return
}
+ gdb_test_no_output "nosharedlibrary"
+
# Test for presence of complaint.
with_complaints 1 {
set have_complaint 0
diff --git a/gdb/testsuite/gdb.fortran/allocated.exp b/gdb/testsuite/gdb.fortran/allocated.exp
index d8aee441d7f..1d87bf76244 100644
--- a/gdb/testsuite/gdb.fortran/allocated.exp
+++ b/gdb/testsuite/gdb.fortran/allocated.exp
@@ -25,9 +25,6 @@ if {[prepare_for_testing ${testfile}.exp ${testfile} ${srcfile} \
return -1
}
-# Avoid shared lib symbols.
-gdb_test_no_output "set auto-solib-add off"
-
if ![fortran_runto_main] {
return -1
}
diff --git a/gdb/testsuite/gdb.fortran/array-slices-bad.exp b/gdb/testsuite/gdb.fortran/array-slices-bad.exp
index 8f23b38599f..ac4a77d2e39 100644
--- a/gdb/testsuite/gdb.fortran/array-slices-bad.exp
+++ b/gdb/testsuite/gdb.fortran/array-slices-bad.exp
@@ -30,9 +30,6 @@ if {![runto [gdb_get_line_number "First Breakpoint"]]} {
return -1
}
-# Avoid shared lib symbols.
-gdb_test_no_output "set auto-solib-add off"
-
# Avoid libc symbols, in particular the 'array' type.
gdb_test_no_output "nosharedlibrary"
diff --git a/gdb/testsuite/gdb.fortran/array-slices-sub-slices.exp b/gdb/testsuite/gdb.fortran/array-slices-sub-slices.exp
index 5bdc7d59f16..5a0f0406afe 100644
--- a/gdb/testsuite/gdb.fortran/array-slices-sub-slices.exp
+++ b/gdb/testsuite/gdb.fortran/array-slices-sub-slices.exp
@@ -25,9 +25,6 @@ if {[prepare_for_testing ${testfile}.exp ${testfile} ${srcfile} \
return -1
}
-# Avoid shared lib symbols.
-gdb_test_no_output "set auto-solib-add off"
-
if ![fortran_runto_main] {
return -1
}
diff --git a/gdb/testsuite/gdb.fortran/array-slices.exp b/gdb/testsuite/gdb.fortran/array-slices.exp
index f2928676bf3..919a2c6e7eb 100644
--- a/gdb/testsuite/gdb.fortran/array-slices.exp
+++ b/gdb/testsuite/gdb.fortran/array-slices.exp
@@ -58,9 +58,6 @@ proc run_test { repack } {
clean_restart ${binfile}
- # Avoid shared lib symbols.
- gdb_test_no_output "set auto-solib-add off"
-
if ![fortran_runto_main] {
return -1
}
diff --git a/gdb/testsuite/gdb.fortran/info-modules.exp b/gdb/testsuite/gdb.fortran/info-modules.exp
index e6c515ff70f..c8ae7362223 100644
--- a/gdb/testsuite/gdb.fortran/info-modules.exp
+++ b/gdb/testsuite/gdb.fortran/info-modules.exp
@@ -28,9 +28,6 @@ if { [prepare_for_testing "failed to prepare" $testfile \
return -1
}
-# Avoid shared lib symbols.
-gdb_test_no_output "set auto-solib-add off"
-
if { ![fortran_runto_main] } {
perror "Could not run to main."
return
diff --git a/gdb/testsuite/gdb.fortran/lbound-ubound.exp b/gdb/testsuite/gdb.fortran/lbound-ubound.exp
index 01597ca23ff..781d3614f4c 100644
--- a/gdb/testsuite/gdb.fortran/lbound-ubound.exp
+++ b/gdb/testsuite/gdb.fortran/lbound-ubound.exp
@@ -25,9 +25,6 @@ if {[prepare_for_testing ${testfile}.exp ${testfile} ${srcfile} \
return -1
}
-# Avoid shared lib symbols.
-gdb_test_no_output "set auto-solib-add off"
-
if ![fortran_runto_main] {
return -1
}
diff --git a/gdb/testsuite/gdb.fortran/module.exp b/gdb/testsuite/gdb.fortran/module.exp
index eea83ad71f1..df7ee3b9605 100644
--- a/gdb/testsuite/gdb.fortran/module.exp
+++ b/gdb/testsuite/gdb.fortran/module.exp
@@ -31,9 +31,6 @@ gdb_test "p modmany::var_i" " = 14" "stopped language detection"
gdb_test "print mod1::var_const" " = 20" "fully qualified name of DW_TAG_constant"
-# Avoid shared lib symbols.
-gdb_test_no_output "set auto-solib-add off"
-
if {![fortran_runto_main]} {
return
}
diff --git a/gdb/testsuite/gdb.fortran/subarray.exp b/gdb/testsuite/gdb.fortran/subarray.exp
index 1ec80e78fe4..70a7a2345ba 100644
--- a/gdb/testsuite/gdb.fortran/subarray.exp
+++ b/gdb/testsuite/gdb.fortran/subarray.exp
@@ -27,9 +27,6 @@ if {[prepare_for_testing "failed to prepare" $testfile $srcfile {debug f90}]} {
return -1
}
-# Avoid shared lib symbols.
-gdb_test_no_output "set auto-solib-add off"
-
if {![fortran_runto_main]} {
return
}
diff --git a/gdb/testsuite/gdb.mi/mi-fortran-modules.exp b/gdb/testsuite/gdb.mi/mi-fortran-modules.exp
index 13996b9547f..5441d8f15e5 100644
--- a/gdb/testsuite/gdb.mi/mi-fortran-modules.exp
+++ b/gdb/testsuite/gdb.mi/mi-fortran-modules.exp
@@ -30,9 +30,6 @@ if {[build_executable "failed to prepare" ${testfile} \
mi_clean_restart $binfile
-# Avoid shared lib symbols.
-mi_gdb_test "-gdb-set auto-solib-add off" "\\^done"
-
mi_runto_main
# Avoid libc symbols.
diff --git a/gdb/testsuite/gdb.mi/mi-var-child-f.exp b/gdb/testsuite/gdb.mi/mi-var-child-f.exp
index 258cbe7cb40..441c3a09366 100644
--- a/gdb/testsuite/gdb.mi/mi-var-child-f.exp
+++ b/gdb/testsuite/gdb.mi/mi-var-child-f.exp
@@ -32,9 +32,6 @@ if {[mi_clean_restart $binfile]} {
return
}
-# Avoid shared lib symbols.
-mi_gdb_test "-gdb-set auto-solib-add off" "\\^done"
-
mi_runto prog_array
# Avoid libc symbols, in particular the 'array' type.
--
2.43.0

View File

@@ -0,0 +1,40 @@
From 002b882370fb3d69b7c89fc99e85fc1b767567b9 Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Thu, 29 Aug 2024 11:39:02 +0200
Subject: [PATCH 2/2] [gdb/testsuite] Fix another regexp in
gdb.threads/stepi-over-clone.exp
On openSUSE Tumbleweed, I run into:
...
(gdb) PASS: gdb.threads/stepi-over-clone.exp: catch process syscalls
continue^M
Continuing.^M
^M
Catchpoint 2 (call to syscall clone3), __clone3 () at clone3.S:62^M
(gdb) FAIL: gdb.threads/stepi-over-clone.exp: continue
...
Fix this by updating another (see commit 8fbf220321d) regexp to also recognize
__clone3.
Tested on x86_64-linux.
---
gdb/testsuite/gdb.threads/stepi-over-clone.exp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/gdb/testsuite/gdb.threads/stepi-over-clone.exp b/gdb/testsuite/gdb.threads/stepi-over-clone.exp
index da8bbf6a215..b93cfe69c7f 100644
--- a/gdb/testsuite/gdb.threads/stepi-over-clone.exp
+++ b/gdb/testsuite/gdb.threads/stepi-over-clone.exp
@@ -50,7 +50,7 @@ gdb_test_multiple "catch syscall group:process" "catch process syscalls" {
set re_loc1 "$hex in (__)?clone\[23\]? \\(\\)"
set re_loc2 "$decimal\[ \t\]+in \[^\r\n\]+"
-set re_loc3 "clone\[23\]? \\(\\) at \[^:\]+:$decimal"
+set re_loc3 "(__)?clone\[23\]? \\(\\) at \[^:\]+:$decimal"
gdb_test "continue" \
"Catchpoint $decimal \\(call to syscall clone\[23\]?\\), ($re_loc1|$re_loc3).*"
--
2.43.0

View File

@@ -0,0 +1,54 @@
From b33811a85ff53af77cdad995ad8cb50431c8c362 Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Thu, 30 May 2024 12:56:35 +0200
Subject: [PATCH] [gdb/testsuite] Fix error in
gdb.server/server-kill-python.exp
With test-case gdb.server/server-kill-python.exp, I sometimes run into:
...
builtin_spawn gdb -nw -nx -q -iex set height 0 -iex set width 0 \
-data-directory data-directory^M
kill^M
(gdb) kill^M
file /home/abuild/rpmbuild/BUILD/gdb-14.2/build-x86_64-suse-linux/gdb/testsuite.unix.-m64.-fno-PIE.-no-pie/outputs/gdb.server/server-kill-python/server-kill-python^M
The program is not being run.^M
(gdb) ERROR: Couldn't load server-kill-python into GDB.
...
The problem is that the spawn produces a prompt, but it's not explicitly
consumed.
This is a regression since commit 0f077fcae0f ("[gdb/testsuite] Simplify
gdb.server/server-kill-python.exp").
Fix this by consuming the initial prompt.
PR testsuite/31819
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31819
Fixes: 0f077fcae0f ("[gdb/testsuite] Simplify gdb.server/server-kill-python.exp"
---
gdb/testsuite/gdb.server/server-kill-python.exp | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/gdb/testsuite/gdb.server/server-kill-python.exp b/gdb/testsuite/gdb.server/server-kill-python.exp
index 778880984ec..c0768558eeb 100644
--- a/gdb/testsuite/gdb.server/server-kill-python.exp
+++ b/gdb/testsuite/gdb.server/server-kill-python.exp
@@ -63,6 +63,12 @@ if {[gdb_spawn_with_cmdline_opts \
return
}
+gdb_test_multiple "" "initial prompt" {
+ -re "^$gdb_prompt $" {
+ pass $gdb_test_name
+ }
+}
+
gdb_load $binfile
gdb_target_cmd $gdbserver_protocol $gdbserver_gdbport
base-commit: 3faa0f850b27f64f08ad4ec5987f711be8862851
--
2.35.3

View File

@@ -0,0 +1,62 @@
From f74652042d7330cd5db2fe1c2f6f4e9cd23f2d55 Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Tue, 4 Feb 2025 14:06:20 +0100
Subject: [PATCH 44/46] [gdb/testsuite] Fix gdb.ada/big_packed_array.exp on
s390x-linux
When running test-case gdb.ada/big_packed_array.exp on s390x-linux, I run
into:
...
(gdb) print bad^M
$2 = (0 => 0 <repeats 24 times>, 1)^M
(gdb) FAIL: gdb.ada/big_packed_array.exp: scenario=minimal: print bad
...
This is with gcc 7.5.0, and this xfail should trigger:
...
if { $have_xfail && [string is integer $last] \
&& [expr ($last & 0xf) == 0] } {
# gcc/101643
setup_xfail *-*-*
}
...
but it doesn't because $last is '1'.
Fix this by using 0xf0 as mask for big endian.
Tested on s390x-linux.
---
gdb/testsuite/gdb.ada/big_packed_array.exp | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/gdb/testsuite/gdb.ada/big_packed_array.exp b/gdb/testsuite/gdb.ada/big_packed_array.exp
index 1ba2c4853c8..1a10ea1d2a5 100644
--- a/gdb/testsuite/gdb.ada/big_packed_array.exp
+++ b/gdb/testsuite/gdb.ada/big_packed_array.exp
@@ -21,6 +21,8 @@ standard_ada_testfile foo_ra24_010
set old_gcc [expr [test_compiler_info {gcc-[0-8]-*}]]
+set endian [target_endianness]
+
foreach_with_prefix scenario {all minimal} {
set flags [list debug additional_flags=-fgnat-encodings=$scenario]
@@ -54,8 +56,13 @@ foreach_with_prefix scenario {all minimal} {
}
-re -wrap $re_xfail2 {
set last $expect_out(1,string)
+ if { $endian == "little" } {
+ set mask 0x0f
+ } else {
+ set mask 0xf0
+ }
if { $have_xfail && [string is integer $last] \
- && [expr ($last & 0xf) == 0] } {
+ && [expr ($last & $mask) == 0] } {
# gcc/101643
setup_xfail *-*-*
}
--
2.43.0

View File

@@ -0,0 +1,113 @@
From ac9c99f7f6b86d536c60fcb4b5ecdd4a2e767603 Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Tue, 4 Feb 2025 14:06:20 +0100
Subject: [PATCH 45/46] [gdb/testsuite] Fix gdb.ada/convvar_comp.exp on
s390x-linux
When running test-case gdb.ada/convvar_comp.exp on s390x-linux, I get:
...
(gdb) run ^M
Starting program: pb16_063 ^M
^M
Breakpoint 1, pck.break_me (item=...) at pck.adb:17^M
17 function Break_Me (Item : T) return Boolean is^M
(gdb) print item.started^M
Cannot access memory at address 0x0^M
(gdb) FAIL: gdb.ada/convvar_comp.exp: print item.started
...
This happens as follows.
The parameter item is available in (DW_OP_fbreg: -168):
...
<2><912>: Abbrev Number: 18 (DW_TAG_formal_parameter)
<913> DW_AT_name : (indirect string, offset: 0x14ca): item
<919> DW_AT_type : <0x929>
<91d> DW_AT_location : 3 byte block: 91 d8 7e (DW_OP_fbreg: -168)
...
and according to the rules of -O0, it's considered to be available after the
prologue, which looks like this:
...
0000000001002998 <pck__break_me>:
1002998: b3 c1 00 2b ldgr %f2,%r11
100299c: b3 c1 00 0f ldgr %f0,%r15
10029a0: e3 f0 ff 58 ff 71 lay %r15,-168(%r15)
10029a6: b9 04 00 bf lgr %r11,%r15
10029aa: e3 20 b0 a0 00 24 stg %r2,160(%r11)
...
To detect the prologue, gdb checks the line info, which looks like this:
...
pck.adb:
File name Line number Starting address View Stmt
pck.adb 17 0x1002998 x
pck.adb 17 0x1002998 1 x
pck.adb 19 0x10029b0 x
pck.adb 20 0x10029b8 x
pck.adb - 0x10029c6
...
and gdb concludes that it's an empty prologue, so we stop at 0x1002998 and
try to print parameter item, which is not available yet.
For more details, see this comment in skip_prologue_using_sal:
...
/* For languages other than assembly, treat two consecutive line
entries at the same address as a zero-instruction prologue.
...
The same thing happens on x86_64-linux, but it causes no problem there,
because amd64_skip_prologue decides not to trust the result:
...
struct compunit_symtab *cust = find_pc_compunit_symtab (func_addr);
/* LLVM backend (Clang/Flang) always emits a line note before the
prologue and another one after. We trust clang and newer Intel
compilers to emit usable line notes. */
if (post_prologue_pc
&& (cust != NULL
&& cust->producer () != nullptr
&& (producer_is_llvm (cust->producer ())
|| producer_is_icc_ge_19 (cust->producer ()))))
return std::max (start_pc, post_prologue_pc);
...
because the producer is GCC.
Work around this by setting a breakpoint on the first statement of
pck.break_me instead.
Tested on s390x-linux.
---
gdb/testsuite/gdb.ada/convvar_comp.exp | 4 +++-
gdb/testsuite/gdb.ada/convvar_comp/pck.adb | 2 +-
2 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/gdb/testsuite/gdb.ada/convvar_comp.exp b/gdb/testsuite/gdb.ada/convvar_comp.exp
index d59a19a40c3..e7ff3baa624 100644
--- a/gdb/testsuite/gdb.ada/convvar_comp.exp
+++ b/gdb/testsuite/gdb.ada/convvar_comp.exp
@@ -25,7 +25,9 @@ if {[gdb_compile_ada "${srcfile}" "${binfile}" executable [list debug ]] != "" }
clean_restart ${testfile}
-if {![runto "break_me"]} {
+set bp_location [gdb_get_line_number "BREAK" "$testdir/pck.adb"]
+
+if {![runto pck.adb:$bp_location]} {
return
}
diff --git a/gdb/testsuite/gdb.ada/convvar_comp/pck.adb b/gdb/testsuite/gdb.ada/convvar_comp/pck.adb
index be5d8d719d8..b7bf3efe8f9 100644
--- a/gdb/testsuite/gdb.ada/convvar_comp/pck.adb
+++ b/gdb/testsuite/gdb.ada/convvar_comp/pck.adb
@@ -16,6 +16,6 @@
package body Pck is
function Break_Me (Item : T) return Boolean is
begin
- return False;
+ return False; -- BREAK
end Break_Me;
end Pck;
--
2.43.0

View File

@@ -0,0 +1,70 @@
From 58e1c193329c4e919272f01e5626b912d36ff65d Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Tue, 23 Jul 2024 14:27:36 +0200
Subject: [PATCH 03/46] [gdb/testsuite] Fix gdb.ada/mi_task_arg.exp on
arm-linux
On arm-linux, I run into:
...
PASS: gdb.ada/mi_task_arg.exp: mi runto task_switch.break_me
Expecting: ^(-stack-list-arguments 1[^M
]+)?(\^done,stack-args=\[frame={level="0",args=\[\]},frame={level="1",args=\[{name="<_task>",value="0x[0-9A-Fa-f]+"}(,{name="<_taskL>",value="[0-9]+"})?\]},frame={level="2",args=\[({name="self_id",value="(0x[0-9A-Fa-f]+|<optimized out>)"})?\]},.*[^M
]+[(]gdb[)] ^M
[ ]*)
-stack-list-arguments 1^M
^done,stack-args=[frame={level="0",args=[]},frame={level="1",args=[{name="<_task>",value="0x40bc48"}]},frame={level="2",args=[]}]^M
(gdb) ^M
FAIL: gdb.ada/mi_task_arg.exp: -stack-list-arguments 1 (unexpected output)
...
The problem is that the test-case expects a level 3 frame, but there is none.
This can be reproduced using cli bt:
...
$ gdb -q -batch outputs/gdb.ada/mi_task_arg/task_switch \
-ex "b task_switch.break_me" \
-ex run \
-ex bt
Breakpoint 1 at 0x34b4: file task_switch.adb, line 57.
Thread 3 "my_caller" hit Breakpoint 1, task_switch.break_me () \
at task_switch.adb:57
57 null;
#0 task_switch.break_me () at task_switch.adb:57
#1 0x00403424 in task_switch.caller (<_task>=0x40bc48) at task_switch.adb:51
#2 0xf7f95a08 in ?? () from /lib/arm-linux-gnueabihf/libgnarl-12.so
Backtrace stopped: previous frame identical to this frame (corrupt stack?)
...
The purpose of the test-case is printing the frame at level 1, so I don't
think we should bother about the presence of the frame at level 3.
Fix this by allowing the backtrace to stop at level 2.
Tested on arm-linux.
Approved-By: Luis Machado <luis.machado@arm.com>
Approved-By: Andrew Burgess <aburgess@redhat.com>
---
gdb/testsuite/gdb.ada/mi_task_arg.exp | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/gdb/testsuite/gdb.ada/mi_task_arg.exp b/gdb/testsuite/gdb.ada/mi_task_arg.exp
index 098396d5c09..b4b7b4997f3 100644
--- a/gdb/testsuite/gdb.ada/mi_task_arg.exp
+++ b/gdb/testsuite/gdb.ada/mi_task_arg.exp
@@ -49,7 +49,8 @@ set frame1 "frame=\{level=\"1\",args=\\\[${frame1_args}(,$frame1_opt_args)?\\\]\
# Frame for system.tasking.stages.task_wrapper
set frame2_args "(\{name=\"self_id\",value=\"($hex|<optimized out>)\"\})?"
set frame2 "frame=\{level=\"2\",args=\\\[$frame2_args\\\]\}"
-mi_gdb_test "-stack-list-arguments 1" \
- "\\^done,stack-args=\\\[$frame0,$frame1,$frame2,.*" \
- "-stack-list-arguments 1"
+set frames "$frame0,$frame1,${frame2}(,.*)?"
+mi_gdb_test "-stack-list-arguments 1" \
+ "\\^done,stack-args=\\\[$frames\\\]" \
+ "-stack-list-arguments 1"
--
2.43.0

View File

@@ -0,0 +1,88 @@
From 23c9940a62f31071c03e54142e57aea3b8ab1eff Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Wed, 17 Jul 2024 17:04:02 +0200
Subject: [PATCH 06/46] [gdb/testsuite] Fix gdb.arch/arm-pseudo-unwind.exp with
unix/mthumb
When running test-case gdb.arch/arm-pseudo-unwind.exp with target board
unix/mthumb, we run into:
...
(gdb) continue^M
Continuing.^M
^M
Program received signal SIGILL, Illegal instruction.^M
0x00400f38 in ?? ()^M
(gdb) FAIL: $exp: continue to breakpoint: continue to callee
...
The test-case attempts to force arm-pseudo-unwind.c to be compiled in arm mode
using additional_flags=-marm, but that's overridden by using target board
unix/mthumb.
This causes function main to be in thumb mode, and consequently function
caller (which is called from main) is is executed as if it's in thumb mode,
while it's actually in arm mode.
Fix this by adding an intermediate function caller_trampoline in
arm-pseudo-unwind.c, and hardcoding it to arm mode using
__attribute__((target("arm"))).
Likewise for test-case gdb.arch/arm-pseudo-unwind-legacy.exp.
Tested on arm-linux.
Approved-By: Luis Machado <luis.machado@arm.com>
---
gdb/testsuite/gdb.arch/arm-pseudo-unwind-legacy.c | 9 ++++++++-
gdb/testsuite/gdb.arch/arm-pseudo-unwind.c | 9 ++++++++-
2 files changed, 16 insertions(+), 2 deletions(-)
diff --git a/gdb/testsuite/gdb.arch/arm-pseudo-unwind-legacy.c b/gdb/testsuite/gdb.arch/arm-pseudo-unwind-legacy.c
index 49b0553ade4..adda4b8b298 100644
--- a/gdb/testsuite/gdb.arch/arm-pseudo-unwind-legacy.c
+++ b/gdb/testsuite/gdb.arch/arm-pseudo-unwind-legacy.c
@@ -24,10 +24,17 @@ break_here_c (uint64_t value)
{
}
+__attribute__((target("arm")))
+uint64_t
+caller_trampoline (void)
+{
+ return caller ();
+}
+
int
main (void)
{
- uint64_t value = caller ();
+ uint64_t value = caller_trampoline ();
break_here_c (value);
return 0;
}
diff --git a/gdb/testsuite/gdb.arch/arm-pseudo-unwind.c b/gdb/testsuite/gdb.arch/arm-pseudo-unwind.c
index 49b0553ade4..adda4b8b298 100644
--- a/gdb/testsuite/gdb.arch/arm-pseudo-unwind.c
+++ b/gdb/testsuite/gdb.arch/arm-pseudo-unwind.c
@@ -24,10 +24,17 @@ break_here_c (uint64_t value)
{
}
+__attribute__((target("arm")))
+uint64_t
+caller_trampoline (void)
+{
+ return caller ();
+}
+
int
main (void)
{
- uint64_t value = caller ();
+ uint64_t value = caller_trampoline ();
break_here_c (value);
return 0;
}
--
2.43.0

View File

@@ -0,0 +1,79 @@
From eb20b0f725b114eb117093971cf0146113517e6b Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Fri, 16 Aug 2024 14:22:46 +0200
Subject: [PATCH 33/46] [gdb/testsuite] Fix
gdb.arch/arm-single-step-kernel-helper.exp
On arm-linux I run into:
...
(gdb) p *kernel_user_helper_version^M
Cannot access memory at address 0xffff0ffc^M
(gdb) FAIL: gdb.arch/arm-single-step-kernel-helper.exp: check kernel helper version
...
What the test-case is trying to do, is to access a special address in the arm
linux kernel [1] using ptrace, which doesn't seem to work.
This is with kernel version 6.1.55. Perhaps this used to work, but the kernel
was modified to be more strict with respect to access to this special address.
Fix this by making the inferior access that special address instead.
Tested on arm-linux.
Approved-By: Luis Machado <luis.machado@arm.com>
PR testsuite/32070
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32070
[1] https://www.kernel.org/doc/Documentation/arm/kernel_user_helpers.txt
---
gdb/testsuite/gdb.arch/arm-single-step-kernel-helper.c | 5 ++++-
gdb/testsuite/gdb.arch/arm-single-step-kernel-helper.exp | 5 ++++-
2 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/gdb/testsuite/gdb.arch/arm-single-step-kernel-helper.c b/gdb/testsuite/gdb.arch/arm-single-step-kernel-helper.c
index 393004e623a..9b5e137992d 100644
--- a/gdb/testsuite/gdb.arch/arm-single-step-kernel-helper.c
+++ b/gdb/testsuite/gdb.arch/arm-single-step-kernel-helper.c
@@ -15,7 +15,8 @@
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
-static int *kernel_user_helper_version = (int *) 0xffff0ffc;
+static int *kernel_user_helper_version_ptr = (int *) 0xffff0ffc;
+static int kernel_user_helper_version;
typedef void * (kernel_user_func_t)(void);
#define kernel_user_get_tls (*(kernel_user_func_t *) 0xffff0fe0)
@@ -25,6 +26,8 @@ main (void)
{
int i;
+ kernel_user_helper_version = *kernel_user_helper_version_ptr;
+
for (i = 0; i < 8; i++)
kernel_user_get_tls ();
}
diff --git a/gdb/testsuite/gdb.arch/arm-single-step-kernel-helper.exp b/gdb/testsuite/gdb.arch/arm-single-step-kernel-helper.exp
index 27be5d56883..788bc863799 100644
--- a/gdb/testsuite/gdb.arch/arm-single-step-kernel-helper.exp
+++ b/gdb/testsuite/gdb.arch/arm-single-step-kernel-helper.exp
@@ -26,10 +26,13 @@ if { ![runto_main] } {
return -1
}
+# Initialize kernel_user_helper_version.
+gdb_test "next" "for .*"
+
# Check kernel helpers are supported or not.
set kernel_helper_supported 0
-gdb_test_multiple "p *kernel_user_helper_version" \
+gdb_test_multiple "p kernel_user_helper_version" \
"check kernel helper version" {
-re " = ($decimal)\r\n$gdb_prompt $" {
if { $expect_out(1,string) >= 1 } {
--
2.43.0

View File

@@ -0,0 +1,84 @@
From cb85331b671b668aaea1e10b2a37d49e9260bac3 Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Wed, 4 Sep 2024 15:37:28 +0200
Subject: [PATCH 35/46] [gdb/testsuite] Fix gdb.arch/riscv-tdesc-regs.exp
On riscv64-linux, with test-case gdb.arch/riscv-tdesc-regs.exp I get:
...
(gdb) info registers fflags^M
fflags 0x0 NV:0 DZ:0 OF:0 UF:0 NX:0^M
(gdb) FAIL: gdb.arch/riscv-tdesc-regs.exp: info registers fflags
info registers frm^M
frm 0x0 FRM:0 [RNE (round to nearest; ties to even)]^M
(gdb) FAIL: gdb.arch/riscv-tdesc-regs.exp: info registers frm
...
The FAILs are produced by:
...
foreach reg {fflags frm} {
gdb_test_multiple "info registers $reg" "" {
-re "^info registers $reg\r\n" {
exp_continue
}
-wrap -re "^Invalid register `$reg`" {
fail $gdb_test_name
}
-wrap -re "^$reg\\s+\[^\r\n\]+" {
pass $gdb_test_name
}
}
}
...
The first clause is meant to consume the command.
The '^' char was updated to mean "consume command", so that clause no longer
works since it now attempts to consume the command twice.
Also, it's unnecessary because the following clauses start with ^.
Then, the second clause is unnecessary because there's a default clause
producing the FAIL.
Fix this by simplifying to:
...
foreach reg {fflags frm} {
gdb_test "info registers $reg" "^$reg\\s+\[^\r\n\]+"
}
...
Tested on riscv64-linux.
Approved-By: Andrew Burgess <aburgess@redhat.com>
---
gdb/testsuite/gdb.arch/riscv-tdesc-regs.exp | 14 +-------------
1 file changed, 1 insertion(+), 13 deletions(-)
diff --git a/gdb/testsuite/gdb.arch/riscv-tdesc-regs.exp b/gdb/testsuite/gdb.arch/riscv-tdesc-regs.exp
index bd4ba38390a..58859d161b6 100644
--- a/gdb/testsuite/gdb.arch/riscv-tdesc-regs.exp
+++ b/gdb/testsuite/gdb.arch/riscv-tdesc-regs.exp
@@ -156,17 +156,5 @@ gdb_test_no_output "set tdesc filename $remote_file" \
"load the target description that lacks fflags and frm"
foreach reg {fflags frm} {
- gdb_test_multiple "info registers $reg" "" {
- -re "^info registers $reg\r\n" {
- exp_continue
- }
-
- -wrap -re "^Invalid register `$reg`" {
- fail $gdb_test_name
- }
-
- -wrap -re "^$reg\\s+\[^\r\n\]+" {
- pass $gdb_test_name
- }
- }
+ gdb_test "info registers $reg" "^$reg\\s+\[^\r\n\]+"
}
--
2.43.0

View File

@@ -0,0 +1,96 @@
From 9625fc9c035b75f7e55350ad72c37ce1b7e8fe55 Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Wed, 22 Jan 2025 10:46:08 +0100
Subject: [PATCH 27/46] [gdb/testsuite] Fix gdb.base/branch-to-self.exp on
arm-linux
On arm-linux (ubuntu 24.04 with gcc 13.3.0) with target board unix/-marm and
test-case gdb.base/branch-to-self.exp I run into:
...
(gdb) continue^M
Continuing.^M
^M
Breakpoint 2, main () at branch-to-self.c:38^M
38 for (;;); /* loop-line */^M
(gdb) PASS: $exp: single-step: continue to breakpoint: hit breakpoint
si^M
0x0040058c 38 for (;;); /* loop-line */^M
(gdb) FAIL: $exp: single-step: si
...
In contrast, on the same machine but with debian testing and gcc 14.2.0 we have:
...
(gdb) continue^M
Continuing.^M
^M
Breakpoint 2, main () at branch-to-self.c:38^M
38 for (;;); /* loop-line */^M
(gdb) PASS: $exp: single-step: continue to breakpoint: hit breakpoint
si^M
^M
Breakpoint 2, main () at branch-to-self.c:38^M
38 for (;;); /* loop-line */^M
(gdb) PASS: $exp: single-step: stepi
...
The difference is in the instruction(s) generated for the loop.
In the passing case, we have:
...
588: eafffffe b 588 <main+0x24>
...
and in the failing case:
...
588: e320f000 nop {0}
58c: eafffffd b 588 <main+0x24>
...
The purpose of this part of the test-case is to:
- generate a branch instruction that jumps to itself, and
- set a breakpoint on it, and check that stepi-ing from that breakpoint
triggers the breakpoint again.
As we can see, in the failing case we failed to generate a branch instruction
that jumps to itself, and consequently we cannot expect to hit the breakpoint
again after issuing a single si.
Fix this by issuing stepi until we hit the breakpoint.
Tested on arm-linux.
Reviewed-by: Thiago Jung Bauermann <thiago.bauermann@linaro.org>
---
gdb/testsuite/gdb.base/branch-to-self.exp | 17 ++++++++++++++++-
1 file changed, 16 insertions(+), 1 deletion(-)
diff --git a/gdb/testsuite/gdb.base/branch-to-self.exp b/gdb/testsuite/gdb.base/branch-to-self.exp
index 9b4f7467498..71859d71e0d 100644
--- a/gdb/testsuite/gdb.base/branch-to-self.exp
+++ b/gdb/testsuite/gdb.base/branch-to-self.exp
@@ -35,7 +35,22 @@ with_test_prefix "single-step" {
gdb_test "break ${testfile}.c:${line_num}" "Breakpoint .*" \
"set breakpoint"
gdb_continue_to_breakpoint "hit breakpoint"
- gdb_test "si" ".*${testfile}.c:${line_num}.*"
+
+ set stepi_count 1
+ gdb_test_multiple "stepi" "" {
+ -re -wrap ".*${testfile}.c:${line_num}.*" {
+ pass $gdb_test_name
+ }
+ -re -wrap "" {
+ if { $stepi_count == 10 } {
+ fail $gdb_test_name
+ } else {
+ incr stepi_count
+ send_gdb "stepi\n"
+ exp_continue
+ }
+ }
+ }
}
with_test_prefix "break-cond" {
--
2.43.0

View File

@@ -0,0 +1,132 @@
From bb7497a27dc37f9775c2c00ecb464b7b44a9e8bb Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Mon, 23 Sep 2024 07:57:49 +0200
Subject: [PATCH 38/46] [gdb/testsuite] Fix gdb.base/empty-host-env-vars.exp
On aarch64-linux (debian testing) with test-case
gdb.base/empty-host-env-vars.exp I ran into:
...
(gdb) show index-cache directory^M
The directory of the index cache is "/home/linux/.cache/gdb".^M
(gdb) FAIL: $exp: env_var_name=HOME: show index-cache directory
...
Without changing any environment variables, the value of the index-cache dir
is:
...
$ gdb -q -batch -ex "show index-cache directory"
The directory of the index cache is "/home/linux/.cache/gdb".
...
and the expectation of the test-case is that setting HOME to empty will
produce an empty dir, but what it actually produces is:
...
$ HOME= gdb -q -batch -ex "show index-cache directory"
The directory of the index cache is "/home/linux/.cache/gdb".
...
There's nothing wrong with that behaviour, the dir is simply constructed using
XDG_CACHE_HOME which happens to be explictly set to its default value
$HOME/.cache [1]:
...
$ echo $XDG_CACHE_HOME
/home/linux/.cache
...
and indeed also setting that variable to empty gets us the expected empty dir:
...
$ XDG_CACHE_HOME= HOME= gdb -q -batch -ex "show index-cache directory"
gdb: warning: Couldn't determine a path for the index cache directory.
The directory of the index cache is "".
...
Furthermore, the test-case assumption that setting variables to empty either
produces the original dir or an empty dir is incorrect.
Say that XDG_CACHE_HOME has a non-default value:
...
$ echo $XDG_CACHE_HOME
/home/linux/my-xdg-cache-home
$ gdb -q -batch -ex "show index-cache directory"
The directory of the index cache is "/home/linux/my-xdg-cache-home/gdb".
...
then setting that variable to empty:
...
$ XDG_CACHE_HOME= gdb -q -batch -ex "show index-cache directory"
The directory of the index cache is "/home/linux/.cache/gdb".
...
does change the value of the dir.
Fix this by making the test-case less specific.
While we're at it, factor out regexps re_pre and re_post to make regexps more
readable, and use string_to_regexp to reduce quoting.
Tested on aarch64-linux.
PR testsuite/32132
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32132
[1] https://specifications.freedesktop.org/basedir-spec/latest/index.html#variables
---
.../gdb.base/empty-host-env-vars.exp | 32 ++++++-------------
1 file changed, 9 insertions(+), 23 deletions(-)
diff --git a/gdb/testsuite/gdb.base/empty-host-env-vars.exp b/gdb/testsuite/gdb.base/empty-host-env-vars.exp
index e6e9d6e3156..5fab65a3607 100644
--- a/gdb/testsuite/gdb.base/empty-host-env-vars.exp
+++ b/gdb/testsuite/gdb.base/empty-host-env-vars.exp
@@ -21,16 +21,14 @@ require {!is_remote host}
set all_env_vars { HOME XDG_CACHE_HOME LOCALAPPDATA XDG_CONFIG_HOME }
-# Record the initial value of the index-cache directory.
+set re_pre \
+ [string_to_regexp {The directory of the index cache is "}]
+set re_post \
+ [string_to_regexp {".}]
+
+# Show the initial value of the index-cache directory.
clean_restart
-set index_cache_directory ""
-gdb_test_multiple "show index-cache directory" "" {
- -re -wrap "The directory of the index cache is \"(.*)\"\\." {
- set index_cache_directory $expect_out(1,string)
- set index_cache_directory [string_to_regexp $index_cache_directory]
- pass $gdb_test_name
- }
-}
+gdb_test "show index-cache directory" $re_pre\[^\r\n\]*$re_post
foreach_with_prefix env_var_name $all_env_vars {
# Restore the original state of the environment variable.
@@ -38,18 +36,7 @@ foreach_with_prefix env_var_name $all_env_vars {
set env($env_var_name) {}
clean_restart
- # Verify that the empty environment variable didn't affect the
- # index-cache directory setting, that we still see the initial value.
- # "HOME" is different, because if that one is unset, GDB isn't even
- # able to compute the default location. In that case, we expect it to
- # be empty.
- if { $env_var_name == "HOME" } {
- gdb_test "show index-cache directory" \
- "The directory of the index cache is \"\"\\."
- } else {
- gdb_test "show index-cache directory" \
- "The directory of the index cache is \"$index_cache_directory\"\\."
- }
+ gdb_test "show index-cache directory" $re_pre\[^\r\n\]*$re_post
}
}
@@ -69,7 +56,6 @@ with_test_prefix "all env vars" {
clean_restart
- gdb_test "show index-cache directory" \
- "The directory of the index cache is \"\"\\."
+ gdb_test "show index-cache directory" $re_pre$re_post
}
}
--
2.43.0

View File

@@ -0,0 +1,83 @@
From 755699757fc57172c5c9a173fae9bfaf75bc1b6a Mon Sep 17 00:00:00 2001
From: Guinevere Larsen <blarsen@redhat.com>
Date: Fri, 31 May 2024 10:48:54 -0300
Subject: [PATCH 36/46] gdb,testsuite: fix gdb.base/list-dot-nodebug and make
it more robust
Thiago Jung Bauermann noticed that gdb.base/list-dot-nodebug was not
actually compiling the test with some debuginfo in the relevant part,
and while fixing I noticed that the base assumption of the "some" case
was wrong, GDB would select some symtab as a default location and the
test would always fail. This fix makes printing the default location
only be tested when there is no debuginfo.
When testing with no debuginfo, if a system had static libc debuginfo,
the test would also fail. To add an extra layer of robustness to the
test, this rewrite also strips any stray debuginfo from the executable.
The test would only fail now if it runs in a system that can't handle
stripped debuginfo and has static debuginfo pre-installed.
Reported-By: Tom de Vries <tdevries@suse.de>
Reported-By: Thiago Jung Bauermann <thiago.bauermann@linaro.org>
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31721
Reviewed-by: Thiago Jung Bauermann <thiago.bauermann@linaro.org>
Approved-By: Andrew Burgess <aburgess@redhat.com>
---
gdb/testsuite/gdb.base/list-dot-nodebug.exp | 37 +++++++++++++++------
1 file changed, 26 insertions(+), 11 deletions(-)
diff --git a/gdb/testsuite/gdb.base/list-dot-nodebug.exp b/gdb/testsuite/gdb.base/list-dot-nodebug.exp
index c9d732e801b..b7359be1a45 100644
--- a/gdb/testsuite/gdb.base/list-dot-nodebug.exp
+++ b/gdb/testsuite/gdb.base/list-dot-nodebug.exp
@@ -34,21 +34,36 @@ standard_testfile .c -extra.c
foreach_with_prefix debug {"none" "some"} {
- set flags "nodebug"
if {$debug == "some"} {
- set flags "debug"
- }
+ if {[prepare_for_testing_full "failed to prepare" \
+ [list ${testfile}-${debug} $linkflags \
+ $srcfile [list nodebug] \
+ $srcfile2 [list debug]]]} {
+ return -1
+ }
- if {[prepare_for_testing_full "failed to prepare" \
- [list ${testfile}-${debug} $linkflags \
- $srcfile [list nodebug] \
- $srcfile2 [list $debug]]]} {
- return -1
+ # We don't test "list ." before starting with some debug info
+ # because GDB will choose the symtab that has debuginfo, and
+ # print the copyright blurb. This test isn't interested (yet?)
+ # in checking if this default location choice is consistent.
+ } else {
+ set executable ${testfile}-none
+ if {[build_executable "failed to prepare" ${executable} \
+ [list $srcfile $srcfile2] $linkflags]} {
+ return -1
+ }
+
+ # Stripping is a backup in case the system has static libc debuginfo.
+ # We can continue the test even if it fails.
+ gdb_gnu_strip_debug $executable no-debuglink
+
+ clean_restart ${executable}
+
+ gdb_test "list ." \
+ "^Insufficient debug info for showing source lines at default location" \
+ "print before start"
}
- gdb_test "list ." \
- "^Insufficient debug info for showing source lines at default location" \
- "print before start"
if { ![runto bar] } {
return -1
--
2.43.0

View File

@@ -0,0 +1,60 @@
From 3048a9807737063118adfd0addbcf7218a5d8681 Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Tue, 4 Feb 2025 10:34:39 +0100
Subject: [PATCH 37/46] [gdb/testsuite] Fix gdb.base/list-dot-nodebug.exp on
openSUSE
On openSUSE Leap 15.6 with test-case gdb.base/list-dot-nodebug.exp I run into:
...
(gdb) list .^M
warning: 1 ../sysdeps/x86_64/crtn.S: No such file or directory^M
(gdb) FAIL: $exp: debug=none: print before start
...
The intent of the debug=none case is to generate an executable with no debug
info. However, we have quite a few CUs with debug info:
...
$ readelf -wi outputs/gdb.base/list-dot-nodebug/list-dot-nodebug-none \
| egrep -c " @ "
431
...
This is because this code:
...
gdb_gnu_strip_debug $executable no-debuglink
...
uses $executable, and the variable is set here:
...
set executable ${testfile}-none
...
which sets it to "list-dot-nodebug-none" and consequently
gdb_gnu_strip_debug cannot find it.
Fix this by using "[standard_output_file $executable]" instead.
Tested on x86_64-linux.
Approved-By: Tom Tromey <tom@tromey.com>
PR testsuite/31721
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31721
---
gdb/testsuite/gdb.base/list-dot-nodebug.exp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/gdb/testsuite/gdb.base/list-dot-nodebug.exp b/gdb/testsuite/gdb.base/list-dot-nodebug.exp
index b7359be1a45..107669de04d 100644
--- a/gdb/testsuite/gdb.base/list-dot-nodebug.exp
+++ b/gdb/testsuite/gdb.base/list-dot-nodebug.exp
@@ -55,7 +55,7 @@ foreach_with_prefix debug {"none" "some"} {
# Stripping is a backup in case the system has static libc debuginfo.
# We can continue the test even if it fails.
- gdb_gnu_strip_debug $executable no-debuglink
+ gdb_gnu_strip_debug [standard_output_file $executable] no-debuglink
clean_restart ${executable}
--
2.43.0

View File

@@ -0,0 +1,119 @@
From c663bffcf74ccf94f7ff3c78b98d20fa60a09d31 Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Tue, 11 Mar 2025 09:38:50 +0100
Subject: [PATCH 2/2] [gdb/testsuite] Fix gdb.base/step-over-syscall.exp with
glibc 2.41
On openSUSE Tumbleweed, with glibc 2.41, when running test-case
gdb.base/step-over-syscall.exp I run into:
...
(gdb) stepi^M
0x00007ffff7cfd09b in __abort_lock_rdlock () from /lib64/libc.so.6^M
1: x/i $pc^M
=> 0x7ffff7cfd09b <__abort_lock_rdlock+29>: syscall^M
(gdb) p $eax^M
$1 = 14^M
(gdb) FAIL: $exp: fork: displaced=off: syscall number matches
FAIL: $exp: fork: displaced=off: find syscall insn in fork (timeout)
...
We're stepi-ing through fork trying to find the fork syscall, but encounter
another syscall.
The test-case attempts to handle this:
...
gdb_test_multiple "stepi" "find syscall insn in $syscall" {
-re ".*$syscall_insn.*$gdb_prompt $" {
# Is the syscall number the correct one?
if {[syscall_number_matches $syscall]} {
pass $gdb_test_name
} else {
exp_continue
}
}
-re "x/i .*=>.*\r\n$gdb_prompt $" {
incr steps
if {$steps == $max_steps} {
fail $gdb_test_name
} else {
send_gdb "stepi\n"
exp_continue
}
}
}
...
but fails to do so because it issues an exp_continue without issuing a new
stepi command, and consequently the "find syscall insn in fork" test times
out.
Also, the call to syscall_number_matches produces a PASS or FAIL, so skipping
one syscall would produce:
...
FAIL: $exp: fork: displaced=off: syscall number matches
PASS: $exp: fork: displaced=off: syscall number matches
DUPLICATE: $exp: fork: displaced=off: syscall number matches
...
Fix this by:
- not producing PASS or FAIL in syscall_number_matches, and
- issuing stepi when encountering another syscall.
While we're at it, fix indentation in syscall_number_matches.
Tested on x86_64-linux, specifically:
- openSUSE Tumbleweed (glibc 2.41), and
- openSUSE Leap 15.6 (glibc 2.38).
PR testsuite/32780
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32780
---
gdb/testsuite/gdb.base/step-over-syscall.exp | 24 ++++++++++++++------
1 file changed, 17 insertions(+), 7 deletions(-)
diff --git a/gdb/testsuite/gdb.base/step-over-syscall.exp b/gdb/testsuite/gdb.base/step-over-syscall.exp
index b3b02acc553..cd1683d3dde 100644
--- a/gdb/testsuite/gdb.base/step-over-syscall.exp
+++ b/gdb/testsuite/gdb.base/step-over-syscall.exp
@@ -62,14 +62,18 @@ proc_with_prefix check_pc_after_cross_syscall { displaced syscall syscall_insn_n
# Verify the syscall number is the correct one.
proc syscall_number_matches { syscall } {
- global syscall_register syscall_number
+ global syscall_register syscall_number
- if {[gdb_test "p \$$syscall_register" ".*= $syscall_number($syscall)" \
- "syscall number matches"] != 0} {
- return 0
- }
+ set res 0
+ gdb_test_multiple "p \$$syscall_register" "syscall number matches" {
+ -re -wrap ".*= $syscall_number($syscall)" {
+ set res 1
+ }
+ -re -wrap "" {
+ }
+ }
- return 1
+ return $res
}
# Restart GDB and set up the test. Return a list in which the first one
@@ -139,7 +143,13 @@ proc setup { syscall } {
if {[syscall_number_matches $syscall]} {
pass $gdb_test_name
} else {
- exp_continue
+ incr steps
+ if {$steps == $max_steps} {
+ fail $gdb_test_name
+ } else {
+ send_gdb "stepi\n"
+ exp_continue
+ }
}
}
-re "x/i .*=>.*\r\n$gdb_prompt $" {
--
2.43.0

View File

@@ -0,0 +1,61 @@
From 7be3afccde80f7c580226f08715c181fd3f48e43 Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Sat, 8 Mar 2025 09:52:08 +0100
Subject: [PATCH 1/2] [gdb/testsuite] Fix gdb.base/step-over-syscall.exp with
-m32 for AMD
When running test-case gdb.base/step-over-syscall.exp with target board
unix/-m32 on an AMD processor, I run into:
...
(gdb) x/2i $pc^M
=> 0xf7fc9575 <__kernel_vsyscall+5>: syscall^M
0xf7fc9577 <__kernel_vsyscall+7>: int $0x80^M
(gdb) PASS: $exp: fork: displaced=off: pc before/after syscall instruction
stepi^M
[Detaching after fork from child process 65650]^M
0xf7fc9579 in __kernel_vsyscall ()^M
1: x/i $pc^M
=> 0xf7fc9579 <__kernel_vsyscall+9>: pop %ebp^M
(gdb) $exp: fork: displaced=off: stepi fork insn
print /x $pc^M
$2 = 0xf7fc9579^M
(gdb) PASS: gdb.base/step-over-syscall.exp: fork: displaced=off: pc after stepi
FAIL: $exp: fork: displaced=off: pc after stepi matches insn addr after syscall
...
The problem is that the syscall returns at the "pop %ebp" insn, while the
test-case expects it to return at the "int $0x80" insn.
This is similar to the problem I fixed in commit 14852123287 ("[gdb/testsuite]
Fix gdb.base/step-over-syscall.exp with -m32"), just that the syscall sequence
used there used the "sysenter" insn instead of the "syscall" insn.
Fix this by extending the fix for commit 14852123287 to also handle the
"syscall" insn.
Tested on x86_64-linux, both using an AMD and Intel processor.
PR testsuite/32439
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32439
---
gdb/testsuite/gdb.base/step-over-syscall.exp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/gdb/testsuite/gdb.base/step-over-syscall.exp b/gdb/testsuite/gdb.base/step-over-syscall.exp
index 8cacc0962c3..b3b02acc553 100644
--- a/gdb/testsuite/gdb.base/step-over-syscall.exp
+++ b/gdb/testsuite/gdb.base/step-over-syscall.exp
@@ -176,7 +176,7 @@ proc setup { syscall } {
# 0xf7fd5159 <__kernel_vsyscall+9>: pop %ebp
# then a stepi at sysenter will step over the int insn, so make sure
# next_insn_addr points after the int insn.
- if { $actual_syscall_insn == "sysenter" } {
+ if { $actual_syscall_insn == "sysenter" || $actual_syscall_insn == "syscall" } {
set test "pc after sysenter instruction"
set re_int_insn "\[ \t\]*int\[ \t\]\[^\r\n\]*"
set re [multi_line \
base-commit: 5754dc6554eb0ffef484ce898537846a6247f4a9
--
2.43.0

View File

@@ -0,0 +1,88 @@
From c77016a72a59a2f32be370d2c8d6729baa97191c Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Wed, 24 Jul 2024 14:44:33 +0200
Subject: [PATCH 10/46] [gdb/testsuite] Fix gdb.cp/m-static.exp on arm
With test-case gdb.cp/m-static.exp on arm-linux, I get:
...
(gdb) ptype test5.single_constructor^M
type = class single_constructor {^M
^M
public:^M
single_constructor(void);^M
~single_constructor(void);^M
} *(single_constructor * const)^M
(gdb) FAIL: gdb.cp/m-static.exp: simple object instance, ptype constructor
...
The test-case expects:
- no empty line before "public:", and
- no "~single_constructor(void)", but "~single_constructor()"
The latter is due to commit 137c886e9a6 ("[gdb/c++] Print destructor the same
for gcc and clang").
The failing test is in a part only enabled for is_aarch32_target == 1, so it
looks like it was left behind.
I'm assuming the same happened for the other difference.
Fix this by updating the regexps to match the observed output.
Tested on arm-linux.
Approved-By: Andrew Burgess <aburgess@redhat.com>
---
gdb/testsuite/gdb.cp/m-static.exp | 15 +++++++++++----
gdb/testsuite/lib/gdb-utils.exp | 8 ++++++++
2 files changed, 19 insertions(+), 4 deletions(-)
diff --git a/gdb/testsuite/gdb.cp/m-static.exp b/gdb/testsuite/gdb.cp/m-static.exp
index 45bc090d01f..5b41898ec9d 100644
--- a/gdb/testsuite/gdb.cp/m-static.exp
+++ b/gdb/testsuite/gdb.cp/m-static.exp
@@ -71,11 +71,18 @@ if { [is_aarch32_target] } {
gdb_test "print test5.single_constructor" \
{ = {single_constructor \*\(single_constructor \* const\)} 0x[0-9a-f]+ <single_constructor::single_constructor\(\)>} \
"simple object instance, print constructor"
- gdb_test "ptype test5.single_constructor" \
- {type = class single_constructor {\r\n public:\r\n single_constructor\(void\);\r\n ~single_constructor\(\);\r\n} \*\(single_constructor \* const\)} \
+
+ set re \
+ [multi_line_string_to_regexp \
+ "type = class single_constructor {" \
+ "" \
+ " public:" \
+ " single_constructor(void);" \
+ " ~single_constructor(void);" \
+ "} *(single_constructor * const)"]
+ gdb_test "ptype test5.single_constructor" $re \
"simple object instance, ptype constructor"
- gdb_test "ptype single_constructor::single_constructor" \
- {type = class single_constructor {\r\n public:\r\n single_constructor\(void\);\r\n ~single_constructor\(\);\r\n} \*\(single_constructor \* const\)} \
+ gdb_test "ptype single_constructor::single_constructor" $re \
"simple object class, ptype constructor"
gdb_test "print test1.~gnu_obj_1" \
diff --git a/gdb/testsuite/lib/gdb-utils.exp b/gdb/testsuite/lib/gdb-utils.exp
index 95c53d030d8..41989da3ed2 100644
--- a/gdb/testsuite/lib/gdb-utils.exp
+++ b/gdb/testsuite/lib/gdb-utils.exp
@@ -38,6 +38,14 @@ proc string_to_regexp {str} {
return $result
}
+# Convenience function that calls string_to_regexp for each arg, and
+# joins the results using "\r\n".
+
+proc multi_line_string_to_regexp { args } {
+ set res [lmap arg $args {string_to_regexp $arg}]
+ return [multi_line {*}$res]
+}
+
# Given a list of strings, adds backslashes as needed to each string to
# create a regexp that will match the string, and join the result.
--
2.43.0

View File

@@ -0,0 +1,99 @@
From 23574ea1b3502dd13efa9b3ebf32fee3118e6ff0 Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Mon, 20 Jan 2025 05:41:01 +0100
Subject: [PATCH 29/46] [gdb/testsuite] Fix gdb.cp/non-trivial-retval.exp on
arm-linux with gcc 13
On arm-linux, with target board unix/-mthumb, we get:
...
(gdb) PASS: gdb.cp/non-trivial-retval.exp: continue to breakpoint: Break here
p f1 (i1, i2)^M
$1 = {a = -136274256}^M
(gdb) FAIL: gdb.cp/non-trivial-retval.exp: gdb-command<p f1 (i1, i2)>
...
This is not a problem with the inferior call, which works fine:
...
(gdb) p f1 (23, 100)
$3 = {a = 123}
...
but instead it's a problem with the location information:
...
(gdb) p i1
$1 = -136274356
(gdb) p i2
$2 = 100
...
which tells us to find the value of i1 in (DW_OP_fbreg: -12).
The test-case passes if we drop -fvar-tracking, in which case the debug info
tells us to find the value of i1 in (DW_OP_fbreg: -20).
This is with gcc 13.3.0 on Ubuntu 24.04. With gcc 14.2.0 on Debian testing,
the code is the same, but -fvar-tracking does use the correct
'(DW_OP_fbreg: -20)'.
There seems to be some bugfix in -fvar-tracking for gcc 14.
Workaround the bug by using constants 23 and 100 instead of i1 and i2 when
using -fvar-tracking and gcc < 14.
Tested on arm-linux.
PR testsuite/32549
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32549
---
gdb/testsuite/gdb.cp/non-trivial-retval.exp | 28 ++++++++++++++++-----
1 file changed, 22 insertions(+), 6 deletions(-)
diff --git a/gdb/testsuite/gdb.cp/non-trivial-retval.exp b/gdb/testsuite/gdb.cp/non-trivial-retval.exp
index 6c9f7e13d2a..64c0867368d 100644
--- a/gdb/testsuite/gdb.cp/non-trivial-retval.exp
+++ b/gdb/testsuite/gdb.cp/non-trivial-retval.exp
@@ -21,8 +21,18 @@ require allow_cplus_tests
standard_testfile .cc
+set i1 i1
+set i2 i2
+
if {[have_fvar_tracking]} {
set additional_flags "additional_flags= -fvar-tracking"
+
+ if { [gcc_major_version] < 14 } {
+ # For armv7, target board unix/-mthumb, -fvar-tracking and gcc 13 we
+ # get incorrect location info. Work around this by using constants instead.
+ set i1 23
+ set i2 100
+ }
}
if {[prepare_for_testing "failed to prepare" $testfile $srcfile [list debug c++ $additional_flags]]} {
@@ -37,12 +47,18 @@ if {![runto_main]} {
gdb_breakpoint [gdb_get_line_number "Break here"]
gdb_continue_to_breakpoint "Break here"
-gdb_test "p f1 (i1, i2)" ".* = {a = 123}"
-gdb_test "p f2 (i1, i2)" ".* = {b = 123}"
-gdb_test "p f22 (i1, i2)" ".* = {b1 = 123}"
-gdb_test "p f3 (i1, i2)" ".* = {.* c = 123}"
-gdb_test "p f4 (i1, i2)" ".* = {.* e = 123}"
-gdb_test "p f5 (i1, i2)" ".* = {f = 123}"
+gdb_test "p f1 ($i1, $i2)" ".* = {a = 123}" \
+ "p f1 (i1, i2)"
+gdb_test "p f2 ($i1, $i2)" ".* = {b = 123}" \
+ "p f2 (i1, i2)"
+gdb_test "p f22 ($i1, $i2)" ".* = {b1 = 123}" \
+ "p f22 (i1, i2)"
+gdb_test "p f3 ($i1, $i2)" ".* = {.* c = 123}" \
+ "p f3 (i1, i2)"
+gdb_test "p f4 ($i1, $i2)" ".* = {.* e = 123}" \
+ "p f4 (i1, i2)"
+gdb_test "p f5 ($i1, $i2)" ".* = {f = 123}" \
+ "p f5 (i1, i2)"
gdb_breakpoint "f1"
gdb_breakpoint "f2"
--
2.43.0

View File

@@ -0,0 +1,54 @@
From 80150dc7ac41e767d857905702bf4b57eb1c0029 Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Fri, 16 Aug 2024 14:22:46 +0200
Subject: [PATCH 11/46] [gdb/testsuite] Fix gdb.dwarf2/dw2-fixed-point.exp on
arm-linux
With test-case gdb.dwarf2/dw2-fixed-point.exp on arm-linux I run into:
...
(gdb) PASS: gdb.dwarf2/dw2-fixed-point.exp: set lang ada
print pck.fp1_var^M
$1 = 0.3125^M
(gdb) FAIL: gdb.dwarf2/dw2-fixed-point.exp: print pck.fp1_var
...
The problem is that the thumb prologue analyzer overshoot, setting the
breakpoint for main after line 49:
...
46 int
47 main (void)
48 {
49 pck__fp1_var++;
...
and consequently we see the value of pck.fp1_var after line 49 instead of
before line 49. This is PR tdep/31981.
Work around this by removing line 49 and all similar subsequent lines, which
turn out to be dead code.
Approved-By: Luis Machado <luis.machado@arm.com>
Tested on arm-linux.
---
gdb/testsuite/gdb.dwarf2/dw2-fixed-point.c | 6 ------
1 file changed, 6 deletions(-)
diff --git a/gdb/testsuite/gdb.dwarf2/dw2-fixed-point.c b/gdb/testsuite/gdb.dwarf2/dw2-fixed-point.c
index 58b97caf055..2789e6ac0fb 100644
--- a/gdb/testsuite/gdb.dwarf2/dw2-fixed-point.c
+++ b/gdb/testsuite/gdb.dwarf2/dw2-fixed-point.c
@@ -46,11 +46,5 @@ int8_t pck__fp1_range_var = 16;
int
main (void)
{
- pck__fp1_var++;
- pck__fp1_var2++;
- pck__fp2_var++;
- pck__fp3_var++;
- pck__fp1_range_var++;
-
return 0;
}
--
2.43.0

View File

@@ -0,0 +1,279 @@
From e13b5af2c0bc0cdf1b2d66f184fff4ba019b28ec Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Wed, 4 Sep 2024 10:07:19 +0200
Subject: [PATCH 12/46] [gdb/testsuite] Fix gdb.dwarf2/dw2-lines.exp on
arm-linux
With test-case gdb.dwarf2/dw2-lines.exp on arm-linux, I run into:
...
(gdb) break bar_label^M
Breakpoint 2 at 0x4004f6: file dw2-lines.c, line 29.^M
(gdb) continue^M
Continuing.^M
^M
Breakpoint 2, bar () at dw2-lines.c:29^M
29 foo (2);^M
(gdb) PASS: $exp: cv=2: cdw=32: lv=2: ldw=32: continue to breakpoint: foo \(1\)
...
The pass is incorrect because the continue lands at line 29 with "foo (2)"
instead of line line 27 with "foo (1)".
A minimal version is:
...
$ gdb -q -batch dw2-lines.cv-2-cdw-32-lv-2-ldw-32 -ex "b bar_label"
Breakpoint 1 at 0x4f6: file dw2-lines.c, line 29.
...
where:
...
000004ec <bar>:
4ec: b580 push {r7, lr}
4ee: af00 add r7, sp, #0
000004f0 <bar_label>:
4f0: 2001 movs r0, #1
4f2: f7ff fff1 bl 4d8 <foo>
000004f6 <bar_label_2>:
4f6: 2002 movs r0, #2
4f8: f7ff ffee bl 4d8 <foo>
...
So, how does this happen? In short:
- skip_prologue_sal calls arm_skip_prologue with pc == 0x4ec,
- thumb_analyze_prologue returns 0x4f2
(overshooting by 1 insn, PR tdep/31981), and
- skip_prologue_sal decides that we're mid-line, and updates to 0x4f6.
However, this is a test-case about .debug_line info, so why didn't arm_skip_prologue
use the line info to skip the prologue?
The answer is that the line info starts at bar_label, not at bar.
Fixing that allows us to work around PR tdep/31981.
Likewise in gdb.dwarf2/dw2-line-number-zero.exp.
Instead, add a new test-case gdb.arch/skip-prologue.exp that is dedicated to
checking quality of architecture-specific prologue analysis, without being
written in an architecture-specific way.
If fails on arm-linux for both marm and mthumb:
...
FAIL: gdb.arch/skip-prologue.exp: f2: $bp_addr == $prologue_end_addr (skipped too much)
FAIL: gdb.arch/skip-prologue.exp: f4: $bp_addr == $prologue_end_addr (skipped too much)
...
and passes for:
- x86_64-linux for {m64,m32}x{-fno-PIE/-no-pie,-fPIE/-pie}
- aarch64-linux.
Tested on arm-linux.
---
gdb/testsuite/gdb.arch/skip-prologue.c | 54 +++++++++++++
gdb/testsuite/gdb.arch/skip-prologue.exp | 76 +++++++++++++++++++
.../gdb.dwarf2/dw2-line-number-zero.exp | 8 ++
gdb/testsuite/gdb.dwarf2/dw2-lines.c | 2 +-
gdb/testsuite/gdb.dwarf2/dw2-lines.exp | 4 +
5 files changed, 143 insertions(+), 1 deletion(-)
create mode 100644 gdb/testsuite/gdb.arch/skip-prologue.c
create mode 100644 gdb/testsuite/gdb.arch/skip-prologue.exp
diff --git a/gdb/testsuite/gdb.arch/skip-prologue.c b/gdb/testsuite/gdb.arch/skip-prologue.c
new file mode 100644
index 00000000000..08ceacb6aa8
--- /dev/null
+++ b/gdb/testsuite/gdb.arch/skip-prologue.c
@@ -0,0 +1,54 @@
+/* Copyright 2024 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+void
+f1 (void)
+{
+ asm ("f1_prologue_end: .globl f1_prologue_end");
+}
+
+int
+f2 (int a)
+{
+ asm ("f2_prologue_end: .globl f2_prologue_end");
+ return a;
+}
+
+void
+f3 (void)
+{
+ asm ("f3_prologue_end: .globl f3_prologue_end");
+ f1 ();
+}
+
+int
+f4 (int a)
+{
+ asm ("f4_prologue_end: .globl f4_prologue_end");
+ return f2 (a);
+}
+
+int
+main (void)
+{
+ f1 ();
+ f2 (0);
+ f3 ();
+ f4 (0);
+
+ return 0;
+}
diff --git a/gdb/testsuite/gdb.arch/skip-prologue.exp b/gdb/testsuite/gdb.arch/skip-prologue.exp
new file mode 100644
index 00000000000..89d2225151a
--- /dev/null
+++ b/gdb/testsuite/gdb.arch/skip-prologue.exp
@@ -0,0 +1,76 @@
+# Copyright 2024 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# Test-case that checks architecture-specific prologue analyzers.
+
+standard_testfile
+
+if { [prepare_for_testing "failed to prepare" $testfile $srcfile \
+ {nodebug}] } {
+ return -1
+}
+
+proc do_test { f } {
+ set bp_addr ""
+ gdb_test_multiple "break $f" "" {
+ -re -wrap "Breakpoint $::decimal at ($::hex)" {
+ set bp_addr $expect_out(1,string)
+ pass $gdb_test_name
+ }
+ }
+
+ if { $bp_addr == "" } {
+ return
+ }
+
+ set prologue_end_addr ""
+ gdb_test_multiple "p /x &${f}_prologue_end" "" {
+ -re -wrap " = ($::hex)" {
+ set prologue_end_addr $expect_out(1,string)
+ pass $gdb_test_name
+ }
+ }
+
+ if { $prologue_end_addr == "" } {
+ return
+ }
+
+ set test {$bp_addr == $prologue_end_addr}
+ if { [expr $test] } {
+ pass $test
+ } elseif { $bp_addr < $prologue_end_addr } {
+ # We'll allow this. For instance, amd64 has a prologue
+ # analyzer that doesn't skip the 3rd instruction here, which saves an
+ # argument register to stack:
+ #
+ # 00000000004004ae <f2>:
+ # 4004ae: 55 push %rbp
+ # 4004af: 48 89 e5 mov %rsp,%rbp
+ # 4004b2: 89 7d fc mov %edi,-0x4(%rbp)
+ # 00000000004004b5 <f2_prologue_end>:
+ #
+ pass "$test (skipped less than possible)"
+ } elseif { $bp_addr > $prologue_end_addr } {
+ fail "$test (skipped too much)"
+ } else {
+ fail "$test"
+ }
+}
+
+foreach f { f1 f2 f3 f4 } {
+ with_test_prefix $f {
+ do_test $f
+ }
+}
diff --git a/gdb/testsuite/gdb.dwarf2/dw2-line-number-zero.exp b/gdb/testsuite/gdb.dwarf2/dw2-line-number-zero.exp
index c510de42037..9124aff1dad 100644
--- a/gdb/testsuite/gdb.dwarf2/dw2-line-number-zero.exp
+++ b/gdb/testsuite/gdb.dwarf2/dw2-line-number-zero.exp
@@ -56,6 +56,10 @@ Dwarf::assemble $asm_file {
file_name "$srcfile" 1
program {
+ DW_LNE_set_address $bar1_start
+ line 25
+ DW_LNS_copy
+
DW_LNE_set_address bar1_label
line 27
DW_LNS_copy
@@ -76,6 +80,10 @@ Dwarf::assemble $asm_file {
DW_LNE_end_sequence
+ DW_LNE_set_address $bar2_start
+ line 39
+ DW_LNS_copy
+
DW_LNE_set_address bar2_label
line 41
DW_LNS_copy
diff --git a/gdb/testsuite/gdb.dwarf2/dw2-lines.c b/gdb/testsuite/gdb.dwarf2/dw2-lines.c
index 67c98fecf02..221d7b95bc3 100644
--- a/gdb/testsuite/gdb.dwarf2/dw2-lines.c
+++ b/gdb/testsuite/gdb.dwarf2/dw2-lines.c
@@ -22,7 +22,7 @@ foo (int x)
void
bar (void)
-{
+{ /* bar: */
asm ("bar_label: .globl bar_label");
foo (1);
asm ("bar_label_2: .globl bar_label_2");
diff --git a/gdb/testsuite/gdb.dwarf2/dw2-lines.exp b/gdb/testsuite/gdb.dwarf2/dw2-lines.exp
index af5b6b71768..fd5b83edc5b 100644
--- a/gdb/testsuite/gdb.dwarf2/dw2-lines.exp
+++ b/gdb/testsuite/gdb.dwarf2/dw2-lines.exp
@@ -88,6 +88,10 @@ proc test_1 { _cv _cdw64 _lv _ldw64 {_string_form ""}} {
# to set the current file explicitly.
DW_LNS_set_file $diridx
+ DW_LNE_set_address $bar_start
+ line [line_for bar]
+ DW_LNS_copy
+
DW_LNE_set_address bar_label
line [line_for bar_label]
DW_LNS_copy
--
2.43.0

View File

@@ -0,0 +1,95 @@
From a6f598be3d0477c5c59bd490573a5d457949658e Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Fri, 7 Jun 2024 08:12:34 +0200
Subject: [PATCH] [gdb/testsuite] Fix gdb.fortran/array-bounds.exp on arm
When running test-case gdb.fortran/array-bounds.exp on arm-linux, we run into:
...
(gdb) print &foo^M
$1 = (PTR TO -> ( real(kind=4) (0:1) )) 0xfffef008^M
(gdb) FAIL: gdb.fortran/array-bounds.exp: print &foo
print &bar^M
$2 = (PTR TO -> ( real(kind=4) (-1:0) )) 0xfffef010^M
(gdb) FAIL: gdb.fortran/array-bounds.exp: print &bar
...
This is due to gcc PR debug/54934.
The test-case contains a kfail for this, which is only activated for
x86_64/i386.
Fix this by enabling the kfail for all ilp32 targets.
Also:
- change the kfail into an xfail, because gdb is not at fault here, and
- limit the xfail to the gfortran compiler.
Tested on arm-linux.
(cherry picked from commit f9478936896ada7786e8d68622f6e6ff78b97b0d)
---
gdb/testsuite/gdb.fortran/array-bounds.exp | 45 +++++++++++++++-------
1 file changed, 31 insertions(+), 14 deletions(-)
diff --git a/gdb/testsuite/gdb.fortran/array-bounds.exp b/gdb/testsuite/gdb.fortran/array-bounds.exp
index e3f2603a118..a9d6011aed4 100644
--- a/gdb/testsuite/gdb.fortran/array-bounds.exp
+++ b/gdb/testsuite/gdb.fortran/array-bounds.exp
@@ -31,21 +31,38 @@ if {![fortran_runto_main]} {
return
}
-# Convenience proc to setup for KFAIL
-proc kfail_if {exp bugid triplet} {
- if {$exp} {
- setup_kfail $bugid $triplet
+# GCC outputs incorrect range debug info for -m32, gcc PR debug/54934.
+set expect_xfail \
+ [expr \
+ [test_compiler_info {gfortran-*} f90] \
+ && [is_ilp32_target]]
+
+set re_ok [string_to_regexp (4294967296:4294967297)]
+set re_xfail [string_to_regexp (0:1)]
+gdb_test_multiple "print &foo" "" {
+ -re -wrap $re_ok.* {
+ pass $gdb_test_name
+ }
+ -re -wrap $re_xfail.* {
+ if { $expect_xfail } {
+ xfail $gdb_test_name
+ } else {
+ fail $gdb_test_name
+ }
}
}
-# GCC outputs incorrect range debug info for -m32.
-set expect_fail false
-if {[is_ilp32_target] && ([istarget "i\[34567\]86-*-linux*"]
- || [istarget "x86_64-*-linux*"])} {
- set expect_fail true
+set re_ok [string_to_regexp (-4294967297:-4294967296)]
+set re_xfail [string_to_regexp (-1:0)]
+gdb_test_multiple "print &bar" "" {
+ -re -wrap $re_ok.* {
+ pass $gdb_test_name
+ }
+ -re -wrap $re_xfail.* {
+ if { $expect_xfail } {
+ xfail $gdb_test_name
+ } else {
+ fail $gdb_test_name
+ }
+ }
}
-
-kfail_if $expect_fail "gcc/54934" "*-*-*"
-gdb_test "print &foo" {.*\(4294967296:4294967297\).*}
-kfail_if $expect_fail "gcc/54934" "*-*-*"
-gdb_test "print &bar" {.*\(-4294967297:-4294967296\).*}
base-commit: 4c7dab250c3581e691c2da87395e80244074d8bf
--
2.35.3

View File

@@ -0,0 +1,88 @@
From 37ce118a44994fb178065eaed671c7036f3d93a5 Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Thu, 20 Jun 2024 16:54:47 +0200
Subject: [PATCH 34/46] [gdb/testsuite] Fix gdb.python/py-format-address.exp on
arm
When running test-case gdb.python/py-format-address.exp on arm-linux, I get:
...
(gdb) python print("Got: " + gdb.format_address(0x103dd))^M
Got: 0x103dd <main at py-format-address.c:30>^M
(gdb) FAIL: $exp: symbol_filename=on: gdb.format_address, \
result should have an offset
...
What is expected here is:
...
Got: 0x103dd <main+1 at py-format-address.c:30>^M
...
Main starts at main_addr:
...
(gdb) print /x &main^M
$1 = 0x103dc^M
...
and we obtained next_addr 0x103dd by adding 1 to it:
...
set next_addr [format 0x%x [expr $main_addr + 1]]
...
Adding 1 to $main_addr results in an address for a thumb function starting at
address 0x103dc, which is incorrect because main is an arm function (because
I'm running with target board unix/-marm).
At some point during the call to format_addr, arm_addr_bits_remove removes
the thumb bit, which causes the +1 offset to be dropped, causing the FAIL.
Fix this by using the address of the breakpoint on main, provided it's not at
the very start of main.
Tested on arm-linux.
PR testsuite/31452
Bug: https://www.sourceware.org/bugzilla/show_bug.cgi?id=31452
---
.../gdb.python/py-format-address.exp | 20 +++++++++++++++++--
1 file changed, 18 insertions(+), 2 deletions(-)
diff --git a/gdb/testsuite/gdb.python/py-format-address.exp b/gdb/testsuite/gdb.python/py-format-address.exp
index 8e7cf47e03a..ab8022c753b 100644
--- a/gdb/testsuite/gdb.python/py-format-address.exp
+++ b/gdb/testsuite/gdb.python/py-format-address.exp
@@ -40,7 +40,23 @@ if ![runto_main] {
# for the program space and architecture (these will be selected based
# on the current inferior).
set main_addr [get_hexadecimal_valueof "&main" "UNKNOWN"]
-set next_addr [format 0x%x [expr $main_addr + 1]]
+require {!string equal $main_addr {UNKNOWN}}
+
+set next_addr "UNKNOWN"
+gdb_test_multiple "info break 1" "" {
+ -re -wrap " y +($hex) +in .*" {
+ set next_addr $expect_out(1,string)
+ set next_addr [regsub {^0x0+} $next_addr "0x"]
+ pass $gdb_test_name
+ }
+}
+if { $next_addr == "UNKNOWN" || $next_addr == $main_addr } {
+ set next_addr [format 0x%x [expr $main_addr + 1]]
+}
+
+verbose -log "main_addr: $main_addr"
+verbose -log "next_addr: $next_addr"
+
foreach_with_prefix symbol_filename { on off } {
gdb_test_no_output "set print symbol-filename ${symbol_filename}"
@@ -56,7 +72,7 @@ foreach_with_prefix symbol_filename { on off } {
"gdb.format_address, result should have no offset"
gdb_test "python print(\"Got: \" + gdb.format_address($next_addr))" \
- "Got: $next_addr <main\\+1${filename_pattern}>" \
+ "Got: $next_addr <main\\+$decimal${filename_pattern}>" \
"gdb.format_address, result should have an offset"
}
--
2.43.0

View File

@@ -0,0 +1,65 @@
From ae564bb3259a6ae34efa3dd48561709d116dc3bc Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Thu, 1 Aug 2024 09:23:24 +0200
Subject: [PATCH 01/46] [gdb/testsuite] Fix gdb.python/py-format-string.exp
with python 3.13
On fedora rawhide, with python 3.13, I run into:
...
(gdb) python print (gdb.parse_and_eval ('a_point_t').format_string (invalid=True))^M
Python Exception <class 'TypeError'>: \
this function got an unexpected keyword argument 'invalid'^M
Error occurred in Python: \
this function got an unexpected keyword argument 'invalid'^M
(gdb) FAIL: $exp: format_string: lang_c: test_all_common: test_invalid_args: \
a_point_t with option invalid=True
...
A passing version with an older python version looks like:
...
(gdb) python print (gdb.parse_and_eval ('a_point_t').format_string (invalid=True))^M
Python Exception <class 'TypeError'>: \
'invalid' is an invalid keyword argument for this function^M
Error occurred in Python: \
'invalid' is an invalid keyword argument for this function^M
(gdb) PASS: $exp: format_string: lang_c: test_all_common: test_invalid_args: \
a_point_t with option invalid=True
...
Fix this by accepting the updated error message.
Tested on aarch64-linux.
PR testsuite/31912
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31912
---
gdb/testsuite/gdb.python/py-format-string.exp | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/gdb/testsuite/gdb.python/py-format-string.exp b/gdb/testsuite/gdb.python/py-format-string.exp
index 0c70ad562c7..92092139639 100644
--- a/gdb/testsuite/gdb.python/py-format-string.exp
+++ b/gdb/testsuite/gdb.python/py-format-string.exp
@@ -1104,10 +1104,16 @@ proc_with_prefix test_invalid_args {} {
"12" \
"TypeError.*: format_string\\(\\) takes 0 positional arguments but 1 were given.*"
+ # For python <= 3.12.
+ set re1 \
+ "TypeError.*: 'invalid' is an invalid keyword argument for this function"
+ # For python >= 3.13.
+ set re2 \
+ "TypeError.*: this function got an unexpected keyword argument 'invalid'"
check_format_string \
"a_point_t" \
"invalid=True" \
- "TypeError.*: 'invalid' is an invalid keyword argument for this function.*"
+ "($re1|$re2).*"
check_format_string \
"a_point_t" \
base-commit: 735d4dc480bcdcb0eddde33b687bd5f11d4f86ee
--
2.43.0

View File

@@ -0,0 +1,154 @@
From 6874385b527cf5d5a43a01484ea58f3912a06b67 Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Tue, 20 Aug 2024 15:57:36 +0200
Subject: [PATCH 02/46] [gdb/testsuite] Fix gdb.python/py-mi-cmd.exp with
python 3.13
When running test-case gdb.python/py-mi-cmd.exp with python 3.13, I run into:
...
Expecting: ^(-pycmd exp[^M
]+)?(.*&"Traceback \(most recent call last\):.."^M
&"[^^M
]+py-mi-cmd.py[^^M
]+"^M
&"[^^M
]+raise gdb.GdbError\(\).."^M
&"gdb.GdbError.."^M
\^error,msg="Error occurred in Python\."[^M
]+[(]gdb[)] ^M
[ ]*)
-pycmd exp^M
&"Traceback (most recent call last):\n"^M
&" File \"py-mi-cmd.py\", line 76, in invoke\n raise gdb.GdbError()\n"^M
&"gdb.GdbError\n"^M
^error,msg="Error occurred in Python."^M
(gdb) ^M
FAIL: gdb.python/py-mi-cmd.exp: -pycmd exp (unexpected output)
...
In contrast, with python 3.12 I have:
...
Expecting: ^(-pycmd exp[^M
]+)?(.*&"Traceback \(most recent call last\):.."^M
&"[^^M
]+py-mi-cmd.py[^^M
]+"^M
&"[^^M
]+raise gdb.GdbError\(\).."^M
&"gdb.GdbError.."^M
\^error,msg="Error occurred in Python\."[^M
]+[(]gdb[)] ^M
[ ]*)
-pycmd exp^M
&"Traceback (most recent call last):\n"^M
&" File \"py-mi-cmd.py\", line 76, in invoke\n"^M
&" raise gdb.GdbError()\n"^M
&"gdb.GdbError\n"^M
^error,msg="Error occurred in Python."^M
(gdb) ^M
PASS: gdb.python/py-mi-cmd.exp: -pycmd exp
...
To make it easier to understand what we're looking at, let's take this out of
the mi interpreter context and use the cli interpreter:
...
$ gdb -q -batch -ex "set trace-commands on" -x gdb.in
+set python print-stack full
+source py-mi-cmd.py
+python pycmd1('-pycmd')
+python pycmd1.invoke (pycmd1, ["exp"])
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "py-mi-cmd.py", line 76, in invoke
raise gdb.GdbError()
gdb.GdbError
gdb.in:4: Error in sourced command file:
Error occurred in Python.
...
Interestingly, this is what we're seeing with both python 3.12 and 3.13.
The difference between the python versions is that:
- with python 3.12 each line is printed by itself, and
- with python 3.13 two particular lines are printed toghether.
With the cli interpreter, that makes no difference, because the '\n' is
interpreted.
But with the mi interpreter, that causes a difference in output because the
'\n' is not interpreted, but rather printed literally.
Fix this by accepting the new output in addition to the old one.
Tested on aarch64-linux.
Reviewed-by: Thiago Jung Bauermann <thiago.bauermann@linaro.org>
PR testsuite/31913
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31913
---
gdb/testsuite/gdb.python/py-mi-cmd.exp | 48 ++++++++++++++++++++++----
1 file changed, 41 insertions(+), 7 deletions(-)
diff --git a/gdb/testsuite/gdb.python/py-mi-cmd.exp b/gdb/testsuite/gdb.python/py-mi-cmd.exp
index 28c71cd75f3..52914099e6d 100644
--- a/gdb/testsuite/gdb.python/py-mi-cmd.exp
+++ b/gdb/testsuite/gdb.python/py-mi-cmd.exp
@@ -119,13 +119,47 @@ mi_gdb_test "-pycmd dash-key" \
# With this argument the command raises a gdb.GdbError with no message
# string. GDB considers this a bug in the user program, so prints a
# backtrace, and a generic error message.
-mi_gdb_test "-pycmd exp" \
- [multi_line ".*&\"Traceback \\(most recent call last\\):..\"" \
- "&\"\[^\r\n\]+${testfile}.py\[^\r\n\]+\"" \
- "&\"\[^\r\n\]+raise gdb.GdbError\\(\\)..\"" \
- "&\"gdb.GdbError..\"" \
- "\\^error,msg=\"Error occurred in Python\\.\""] \
- "-pycmd exp"
+
+set line1 \
+ [string_to_regexp {Traceback (most recent call last):\n}]
+set line2 \
+ [string cat \
+ [string_to_regexp { File \"}] \
+ "\[^\r\n\]+" \
+ [string_to_regexp ${testfile}.py] \
+ [string_to_regexp {\", line }] \
+ $decimal \
+ [string_to_regexp {, in invoke\n}]]
+set line3 \
+ [string_to_regexp { raise gdb.GdbError()\n}]
+set line4 \
+ [string_to_regexp {gdb.GdbError\n}]
+set errline \
+ [string_to_regexp {^error,msg="Error occurred in Python."}]
+
+set start_line \
+ [string_to_regexp {&"}]
+set end_line \
+ [string_to_regexp {"}]
+
+# With python <= 3.12.
+set re1 \
+ [multi_line \
+ $start_line$line1$end_line \
+ $start_line$line2$end_line \
+ $start_line$line3$end_line \
+ $start_line$line4$end_line \
+ $errline]
+
+# With python >= 3.13.
+set re2 \
+ [multi_line \
+ $start_line$line1$end_line \
+ $start_line$line2$line3$end_line \
+ $start_line$line4$end_line \
+ $errline]
+
+mi_gdb_test "-pycmd exp" ($re1|$re2)
mi_gdb_test "python pycmd2('-pycmd')" \
".*\\^done" \
--
2.43.0

View File

@@ -0,0 +1,70 @@
From 90e16cc4b30a742387b6d8324a862a5e4a91b24e Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Fri, 10 Jan 2025 08:53:29 +0100
Subject: [PATCH 30/46] [gdb/testsuite] Fix gdb.rust/completion.exp timeout on
riscv64-linux
On riscv64-linux, with test-case gdb.rust/completion.exp I run into the
following timeout:
...
(gdb) complete break pars^M
FAIL: gdb.rust/completion.exp: complete break pars (timeout)
...
Replaying the scenario outside the testsuite show us that the command takes
~13 seconds:
...
$ gdb -q -batch -x gdb.in
...
2025-01-08 12:23:46.853 - command started
+complete break pars
break parse.rs
break parse_printf_format
break parse_running_mmaps_unix.rs
break parser.rs
2025-01-08 12:23:59.600 - command finished
Command execution time: 12.677752 (cpu), 12.748565 (wall)
...
while the timeout is 10 seconds.
The riscv64 processor on the server (cfarm91) is not fast (a fair amount of
the skip_huge_test test-cases times out), but something else is going on as
well.
For x86_64-linux, roughly measuring the size of debug info in the exec get us:
...
$ readelf -wi outputs/gdb.rust/completion/completion | wc -l
2007
...
while on the riscv64 server I get:
...
$ readelf -wi outputs/gdb.rust/completion/completion | wc -l
1606950
...
So it seems reasonable that the test is somewhat slower on riscv64.
Fix this by using timeout factor 2.
Tested on riscv64-linux and x86_64-linux.
Approved-By: Tom Tromey <tom@tromey.com>
---
gdb/testsuite/gdb.rust/completion.exp | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/gdb/testsuite/gdb.rust/completion.exp b/gdb/testsuite/gdb.rust/completion.exp
index 02fbdcdf92c..1b0638ad21a 100644
--- a/gdb/testsuite/gdb.rust/completion.exp
+++ b/gdb/testsuite/gdb.rust/completion.exp
@@ -31,4 +31,6 @@ if {![runto ${srcfile}:$line]} {
return -1
}
-gdb_test "complete break pars" ".*"
+with_timeout_factor 2 {
+ gdb_test "complete break pars" ".*"
+}
--
2.43.0

View File

@@ -0,0 +1,119 @@
From 87a754a5b94b2360f39525f63f2292f23e9e0fe6 Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Thu, 27 Mar 2025 13:18:57 +0100
Subject: [PATCH] [gdb/testsuite] Fix
gdb.threads/access-mem-running-thread-exit.exp
In OBS (Open Build Service), with a 15.2 based gdb package, occasionally I run
into:
...
(gdb) inferior 2
[Switching to inferior 2 [process 31372] (access-mem-running-thread-exit)]
[Switching to thread 2.1 (Thread 0xf7db9700 (LWP 31372))](running)
(gdb) print global_var = 555
$1 = 555
(gdb) print global_var
$2 = 556
(gdb) FAIL: $exp: all-stop: access mem \
(print global_var after writing, inf=2, iter=1)
...
I managed to reproduce this on current trunk using a reproducer patch (posted
in the PR).
The problem is due to commit 31c21e2c13d ("[gdb/testsuite] Fix
gdb.threads/access-mem-running-thread-exit.exp with clang"), which introduced
an increment of global_var at the start of main.
This created a race between:
- gdb modifying global_var, and
- the inferior modifying global_var.
Fix this by:
- adding a new empty function setup_done,
- adding a call to setup_done after the increment of global_var, and
- rather than running to main, running to setup_done.
Tested on x86_64-linux.
PR testsuite/32822
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32822
---
.../gdb.threads/access-mem-running-thread-exit.c | 7 +++++++
.../gdb.threads/access-mem-running-thread-exit.exp | 10 +++++-----
2 files changed, 12 insertions(+), 5 deletions(-)
diff --git a/gdb/testsuite/gdb.threads/access-mem-running-thread-exit.c b/gdb/testsuite/gdb.threads/access-mem-running-thread-exit.c
index af05b13c763..e22bf12df75 100644
--- a/gdb/testsuite/gdb.threads/access-mem-running-thread-exit.c
+++ b/gdb/testsuite/gdb.threads/access-mem-running-thread-exit.c
@@ -97,6 +97,11 @@ thread_fn (void *arg)
return NULL;
}
+static void
+setup_done (void)
+{
+}
+
int
main (void)
{
@@ -104,6 +109,8 @@ main (void)
global_var++;
+ setup_done ();
+
for (i = 0; i < 4; i++)
{
struct thread_arg *p;
diff --git a/gdb/testsuite/gdb.threads/access-mem-running-thread-exit.exp b/gdb/testsuite/gdb.threads/access-mem-running-thread-exit.exp
index 784f17ff3b2..42222c0fb35 100644
--- a/gdb/testsuite/gdb.threads/access-mem-running-thread-exit.exp
+++ b/gdb/testsuite/gdb.threads/access-mem-running-thread-exit.exp
@@ -54,7 +54,7 @@ proc test { non_stop } {
clean_restart ${binfile}
}
- if ![runto_main] {
+ if ![runto setup_done] {
return -1
}
@@ -76,7 +76,7 @@ proc test { non_stop } {
# Start the second inferior.
with_test_prefix "second inferior" {
# With stub targets that do reload on run, if we let the new
- # inferior share inferior 1's connection, runto_main would
+ # inferior share inferior 1's connection, runto would
# fail because GDB is already connected to something, like
# e.g. with --target_board=native-gdbserver:
#
@@ -86,10 +86,10 @@ proc test { non_stop } {
# Already connected to a remote target. Disconnect? (y or n)
#
# Instead, start the inferior with no connection, and let
- # gdb_load/runto_main spawn a new remote connection/gdbserver.
+ # gdb_load/runto spawn a new remote connection/gdbserver.
#
# OTOH, with extended-remote, we must let the new inferior
- # reuse the current connection, so that runto_main below can
+ # reuse the current connection, so that runto below can
# issue the "run" command, and have the inferior run on the
# remote target. If we forced no connection, then "run" would
# either fail if "set auto-connect-native-target" is on, like
@@ -108,7 +108,7 @@ proc test { non_stop } {
gdb_load $binfile
- if ![runto_main] {
+ if ![runto setup_done] {
return -1
}
}
base-commit: af5d18ee9fd221ca8a54de4957ec5c351599f13c
--
2.43.0

View File

@@ -0,0 +1,80 @@
From e0c1db6156fa8ee35661a9964062eeb69a963576 Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Mon, 29 Jul 2024 14:05:52 +0200
Subject: [PATCH] [gdb/testsuite] Fix gdb.threads/leader-exit-attach.exp with
check-read1
With test-case gdb.threads/leader-exit-attach.exp and check-read1, I run into:
...
(gdb) attach 18591^M
Attaching to program: leader-exit-attach, process 18591^M
warning: process 18591 is a zombie - the process has already terminatedKFAIL: $exp: attach (PRMS: gdb/31555)
^M
ptrace: Operation not permitted.^M
(gdb) FAIL: $exp: get valueof "$_inferior_thread_count"
...
The problem is that the gdb_test_multiple in the test-case doesn't consume the
prompt in all clauses:
...
gdb_test_multiple "attach $testpid" "attach" {
-re "Attaching to process $testpid failed.*" {
# GNU/Linux gdbserver. Linux ptrace does not let you attach
# to zombie threads.
setup_kfail "gdb/31555" *-*-linux*
fail $gdb_test_name
}
-re "warning: process $testpid is a zombie - the process has already terminated.*" {
# Native GNU/Linux. Linux ptrace does not let you attach to
# zombie threads.
setup_kfail "gdb/31555" *-*-linux*
fail $gdb_test_name
}
-re "Attaching to program: $escapedbinfile, process $testpid.*$gdb_prompt $" {
pass $gdb_test_name
set attached 1
}
}
...
Fix this by using -wrap in the first two clauses.
While we're at it, also use -wrap in the third clause.
Tested on x86_64-linux.
---
gdb/testsuite/gdb.threads/leader-exit-attach.exp | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/gdb/testsuite/gdb.threads/leader-exit-attach.exp b/gdb/testsuite/gdb.threads/leader-exit-attach.exp
index c1ed1baaa67..a1bc2d470d5 100644
--- a/gdb/testsuite/gdb.threads/leader-exit-attach.exp
+++ b/gdb/testsuite/gdb.threads/leader-exit-attach.exp
@@ -41,19 +41,19 @@ set is_gdbserver [target_is_gdbserver]
set attached 0
gdb_test_multiple "attach $testpid" "attach" {
- -re "Attaching to process $testpid failed.*" {
+ -re -wrap "Attaching to process $testpid failed.*" {
# GNU/Linux gdbserver. Linux ptrace does not let you attach
# to zombie threads.
setup_kfail "gdb/31555" *-*-linux*
fail $gdb_test_name
}
- -re "warning: process $testpid is a zombie - the process has already terminated.*" {
+ -re -wrap "warning: process $testpid is a zombie - the process has already terminated.*" {
# Native GNU/Linux. Linux ptrace does not let you attach to
# zombie threads.
setup_kfail "gdb/31555" *-*-linux*
fail $gdb_test_name
}
- -re "Attaching to program: $escapedbinfile, process $testpid.*$gdb_prompt $" {
+ -re -wrap "Attaching to program: $escapedbinfile, process $testpid.*" {
pass $gdb_test_name
set attached 1
}
base-commit: 6d7adb1f1e6ecad5a6b94319e4d272a82be16277
--
2.43.0

View File

@@ -0,0 +1,39 @@
From 7992b582e5a55bf2fd64f2f94b854d335c36c6a5 Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Tue, 28 Jan 2025 17:44:42 +0100
Subject: [PATCH] [gdb/testsuite] Fix gdb_py_module_available for python 3.4
On SLE-12, I run into:
...
(gdb) python import pygments
Python Exception <class 'ImportError'>: No module named 'pygments'
Error occurred in Python: No module named 'pygments'
(gdb) FAIL: gdb.base/style.exp: python import pygments
...
Fix this by handling the output string in gdb_py_module_available.
Tested on x86_64-linux.
---
gdb/testsuite/lib/gdb-python.exp | 3 +++
1 file changed, 3 insertions(+)
diff --git a/gdb/testsuite/lib/gdb-python.exp b/gdb/testsuite/lib/gdb-python.exp
index e27d5c17769..f8141193596 100644
--- a/gdb/testsuite/lib/gdb-python.exp
+++ b/gdb/testsuite/lib/gdb-python.exp
@@ -64,6 +64,9 @@ proc gdb_py_module_available { name } {
-re -wrap "ImportError: No module named '?${name}'?.*" {
set available false
}
+ -re -wrap "Python Exception <class 'ImportError'>: No module named '?${name}'?.*" {
+ set available false
+ }
-re -wrap "python import ${name}" {
set available true
}
base-commit: 94df6741bbabaa9a51960446b2af4c0bed01b54b
--
2.43.0

View File

@@ -0,0 +1,50 @@
From d9da3935f1be9c0d008764d6fff4b5dc277a5cd7 Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Tue, 30 Jul 2024 21:50:17 +0200
Subject: [PATCH 04/46] [gdb/testsuite] Fix regexp in gdb.ada/mi_var_access.exp
some more
When running test-case gdb.ada/mi_var_access.exp on arm-linux (debian trixie),
I run into:
...
Expecting: ^(-var-create A_String_Access \* A_String_Access[
]+)?((\^done,name="A_String_Access",numchild="[0-9]+",.*|\^error,msg="Value out of range.".*)[
]+[(]gdb[)]
[ ]*)
-var-create A_String_Access * A_String_Access
^error,msg="Cannot access memory at address 0x4"
(gdb)
FAIL: gdb.ada/mi_var_access.exp: Create varobj (unexpected output)
...
This is similar to the problem fixed by commit c5a72a8d1c3 ("[gdb/testsuite]
Fix regexp in gdb.ada/mi_var_access.exp").
The problem in both cases is that we're printing an uninitialized variable,
and consequently we can run into various error messages during printing.
Fix this as in the other commit, by accepting the error message.
Tested on arm-linux.
---
gdb/testsuite/gdb.ada/mi_var_access.exp | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/gdb/testsuite/gdb.ada/mi_var_access.exp b/gdb/testsuite/gdb.ada/mi_var_access.exp
index b71c8f32151..e797a1576cb 100644
--- a/gdb/testsuite/gdb.ada/mi_var_access.exp
+++ b/gdb/testsuite/gdb.ada/mi_var_access.exp
@@ -42,8 +42,9 @@ mi_continue_to_line \
# to match possible values.
set re_ok "\\^done,name=\"A_String_Access\",numchild=\"$decimal\",.*"
set re_error "\\^error,msg=\"Value out of range\.\".*"
+set re_error2 "\\^error,msg=\"Cannot access memory at address $hex\""
mi_gdb_test "-var-create A_String_Access * A_String_Access" \
- "($re_ok|$re_error)" \
+ "($re_ok|$re_error|$re_error2)" \
"Create varobj"
set bp_location [gdb_get_line_number "STOP2" ${testdir}/mi_access.adb]
--
2.43.0

View File

@@ -0,0 +1,71 @@
From da8d1a26f1015678245f23abc0b96ee6fba9f16d Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Thu, 29 Aug 2024 07:31:12 +0200
Subject: [PATCH 32/46] [gdb/testsuite] Fix regexp in
gdb.arch/i386-disp-step-self-call.exp
Usually, with test-case gdb.arch/i386-disp-step-self-call.exp I get:
...
(gdb) x/1wx 0xffffc4f8^M
0xffffc4f8: 0x08048472^M
(gdb) PASS: $exp: check return address was updated correctly
...
but sometimes I run into:
...
(gdb) x/1wx 0xffffc5c8^M
0xffffc5c8: 0x0804917e^M
(gdb) FAIL: $exp: check return address was updated correctly
...
The problem is that here:
...
set next_insn_addr 0x[format %08X $next_insn_addr]
gdb_test "x/1wx 0x[format %x $sp]" "$hex:\\s+$next_insn_addr" \
"check return address was updated correctly"
...
we're trying to match string 0x0804917e against regexp 0x0804917E due to using
"%08X" as format string.
We only run into this problem if the address contains letters, which apparently
usually isn't the case.
Fix this by using "%08x" instead as format string.
Likewise in test-case gdb.arch/amd64-disp-step-self-call.exp.
Tested on x86_64-linux.
PR testsuite/32121
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32121
---
gdb/testsuite/gdb.arch/amd64-disp-step-self-call.exp | 2 +-
gdb/testsuite/gdb.arch/i386-disp-step-self-call.exp | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/gdb/testsuite/gdb.arch/amd64-disp-step-self-call.exp b/gdb/testsuite/gdb.arch/amd64-disp-step-self-call.exp
index 762d19a2960..2db3ff228c9 100644
--- a/gdb/testsuite/gdb.arch/amd64-disp-step-self-call.exp
+++ b/gdb/testsuite/gdb.arch/amd64-disp-step-self-call.exp
@@ -77,6 +77,6 @@ gdb_assert {[expr $sp == $new_sp]} \
"check stack pointer was updated as expected"
# Check the contents of the stack were updated to the expected value.
-set next_insn_addr 0x[format %016X $next_insn_addr]
+set next_insn_addr 0x[format %016x $next_insn_addr]
gdb_test "x/1gx 0x[format %x $sp]" "$hex:\\s+$next_insn_addr" \
"check return address was updated correctly"
diff --git a/gdb/testsuite/gdb.arch/i386-disp-step-self-call.exp b/gdb/testsuite/gdb.arch/i386-disp-step-self-call.exp
index b2cb902f8ed..5de7ebcd69f 100644
--- a/gdb/testsuite/gdb.arch/i386-disp-step-self-call.exp
+++ b/gdb/testsuite/gdb.arch/i386-disp-step-self-call.exp
@@ -77,6 +77,6 @@ gdb_assert {[expr $sp == $new_sp]} \
"check stack pointer was updated as expected"
# Check the contents of the stack were updated to the expected value.
-set next_insn_addr 0x[format %08X $next_insn_addr]
+set next_insn_addr 0x[format %08x $next_insn_addr]
gdb_test "x/1wx 0x[format %x $sp]" "$hex:\\s+$next_insn_addr" \
"check return address was updated correctly"
--
2.43.0

View File

@@ -0,0 +1,42 @@
From 2140bfdb0f523bcfd4475bc9ef779d693f0852fc Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Fri, 21 Jun 2024 16:53:19 +0200
Subject: [PATCH 1/2] [gdb/testsuite] Fix regexp in
gdb.threads/stepi-over-clone.exp
On fedora rawhide, I ran into:
...
(gdb) continue^M
Continuing.^M
^M
Catchpoint 2 (call to syscall clone3), 0x000000000042097d in __clone3 ()^M
(gdb) FAIL: gdb.threads/stepi-over-clone.exp: continue
...
Fix this by updating a regexp to also recognize __clone3.
Tested on x86_64-linux.
Tested-By: Guinevere Larsen <blarsen@redhat.com>
---
gdb/testsuite/gdb.threads/stepi-over-clone.exp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/gdb/testsuite/gdb.threads/stepi-over-clone.exp b/gdb/testsuite/gdb.threads/stepi-over-clone.exp
index f671fd7b8bd..da8bbf6a215 100644
--- a/gdb/testsuite/gdb.threads/stepi-over-clone.exp
+++ b/gdb/testsuite/gdb.threads/stepi-over-clone.exp
@@ -48,7 +48,7 @@ gdb_test_multiple "catch syscall group:process" "catch process syscalls" {
}
}
-set re_loc1 "$hex in clone\[23\]? \\(\\)"
+set re_loc1 "$hex in (__)?clone\[23\]? \\(\\)"
set re_loc2 "$decimal\[ \t\]+in \[^\r\n\]+"
set re_loc3 "clone\[23\]? \\(\\) at \[^:\]+:$decimal"
base-commit: 1b57388d5731941f69010502bb59c24bd1db9f68
--
2.43.0

View File

@@ -0,0 +1,69 @@
From 25157766c1f81deecb53f2b784177a0d14c3d945 Mon Sep 17 00:00:00 2001
From: Tom de Vries <tdevries@suse.de>
Date: Mon, 23 Sep 2024 07:45:54 +0200
Subject: [PATCH 41/46] [gdb/testsuite] Fix timeout in
gdb.mi/mi-multi-commands.exp
On aarch64-linux, with test-case gdb.mi/mi-multi-commands.exp once in a while
I run into (edited for readability):
...
(gdb) ^M
<LOTS-OF-SPACES>-data-evaluate-expression $a^M
-data-evaluate-^done,value="\"FIRST COMMAND\""^M
expression $b(gdb) ^M
^M
^done,value="\"TEST COMPLETE\""^M
(gdb) ^M
PASS: $exp: args=: look for first command output, command length 236
FAIL: $exp: args=: look for second command output, command length 236 (timeout)
...
This is more likely to trigger when running the test-case using
taskset -c <cpu> (where in a big.little setup we pick a little cpu).
The setup here is that the test-case issues these two commands at once:
...
-data-evaluate-expression $a
-data-evaluate-expression $b
...
where the length of the first command is artificially increased by prefixing
it with spaces, show as <LOTS-OF-SPACES> above.
What happens is that gdb, after parsing the first command, executes it.
Then the output of the first command intermixes with the echoing of the second
command, which produces this line containing the first prompt:
...
expression $b(gdb) ^M
...
which doesn't match the \r\n prefix of the regexp supposed to consume the
first prompt:
...
-re "\r\n$mi_gdb_prompt" {
...
Fix this by dropping the \r\n prefix.
Tested on aarch64-linux.
PR testsuite/29781
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=29781
---
gdb/testsuite/gdb.mi/mi-multi-commands.exp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/gdb/testsuite/gdb.mi/mi-multi-commands.exp b/gdb/testsuite/gdb.mi/mi-multi-commands.exp
index 3a2e774bddc..028e187366a 100644
--- a/gdb/testsuite/gdb.mi/mi-multi-commands.exp
+++ b/gdb/testsuite/gdb.mi/mi-multi-commands.exp
@@ -103,7 +103,7 @@ proc run_test { args } {
set seen_first_message true
exp_continue
}
- -re "\r\n$mi_gdb_prompt" {
+ -re "$mi_gdb_prompt" {
gdb_assert $seen_first_message $gdb_test_name
}
}
--
2.43.0

Some files were not shown because too many files have changed in this diff Show More