- 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:
23
.gitattributes
vendored
Normal file
23
.gitattributes
vendored
Normal 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
1
.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
.osc
|
117
README.qa
Normal file
117
README.qa
Normal 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
24
_constraints
Normal 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
3
_multibuild
Normal file
@@ -0,0 +1,3 @@
|
||||
<multibuild>
|
||||
<package>testsuite</package>
|
||||
</multibuild>
|
100
add-dwarf_expr_piece.op.patch
Normal file
100
add-dwarf_expr_piece.op.patch
Normal 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
|
||||
|
220
add-gdbarch_dwarf2_reg_piece_offset-hook.patch
Normal file
220
add-gdbarch_dwarf2_reg_piece_offset-hook.patch
Normal 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
11
baselibs.conf
Normal 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
46
clean.sh
Normal 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
|
144
fix-gdb.ada-o2_float_param.exp-on-s390x-linux.patch
Normal file
144
fix-gdb.ada-o2_float_param.exp-on-s390x-linux.patch
Normal 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
|
||||
|
188
fix-gdb.base-finish-pretty.exp-on-s390x.patch
Normal file
188
fix-gdb.base-finish-pretty.exp-on-s390x.patch
Normal 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
|
||||
|
187
fix-gdb.base-readnever.exp-on-s390x.patch
Normal file
187
fix-gdb.base-readnever.exp-on-s390x.patch
Normal 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
|
||||
|
143
fix-gdb.base-store.exp-on-s390x.patch
Normal file
143
fix-gdb.base-store.exp-on-s390x.patch
Normal 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
|
||||
|
97
fix-gdb.dap-step-out.exp-on-s390x.patch
Normal file
97
fix-gdb.dap-step-out.exp-on-s390x.patch
Normal 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
|
||||
|
56
fix-gdb.dwarf2-shortpiece.exp-on-s390x.patch
Normal file
56
fix-gdb.dwarf2-shortpiece.exp-on-s390x.patch
Normal 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
|
||||
|
23
fix-gdb.mi-new-ui-mi-sync.exp.patch
Normal file
23
fix-gdb.mi-new-ui-mi-sync.exp.patch
Normal 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.
|
25
fixup-gdb-6.5-gcore-buffer-limit-test.patch
Normal file
25
fixup-gdb-6.5-gcore-buffer-limit-test.patch
Normal 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
|
||||
|
26
fixup-gdb-add-rpm-suggestion-script.patch
Normal file
26
fixup-gdb-add-rpm-suggestion-script.patch
Normal 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
BIN
gdb-15.2.tar.bz2
(Stored with Git LFS)
Normal file
Binary file not shown.
268
gdb-6.3-gstack-20050411.patch
Normal file
268
gdb-6.3-gstack-20050411.patch
Normal 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
|
247
gdb-6.3-mapping-zero-inode-test.patch
Normal file
247
gdb-6.3-mapping-zero-inode-test.patch
Normal 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
|
||||
+ }
|
||||
+}
|
107
gdb-6.5-bz218379-ppc-solib-trampoline-test.patch
Normal file
107
gdb-6.5-bz218379-ppc-solib-trampoline-test.patch
Normal 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"
|
||||
+ }
|
||||
+}
|
154
gdb-6.5-gcore-buffer-limit-test.patch
Normal file
154
gdb-6.5-gcore-buffer-limit-test.patch
Normal 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
|
40
gdb-6.6-buildid-locate-tests-suse.patch
Normal file
40
gdb-6.6-buildid-locate-tests-suse.patch
Normal 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
|
||||
|
237
gdb-6.6-buildid-locate-tests.patch
Normal file
237
gdb-6.6-buildid-locate-tests.patch
Normal 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"
|
278
gdb-6.6-bz237572-ppc-atomic-sequence-test.patch
Normal file
278
gdb-6.6-bz237572-ppc-atomic-sequence-test.patch
Normal 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"
|
68
gdb-add-deprecated-settings-py-script.patch
Normal file
68
gdb-add-deprecated-settings-py-script.patch
Normal 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()
|
21
gdb-add-index.sh-fix-bashism.patch
Normal file
21
gdb-add-index.sh-fix-bashism.patch
Normal 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
|
40
gdb-add-rpm-suggestion-script-suse.patch
Normal file
40
gdb-add-rpm-suggestion-script-suse.patch
Normal 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
|
||||
|
806
gdb-add-rpm-suggestion-script.patch
Normal file
806
gdb-add-rpm-suggestion-script.patch
Normal 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
|
88
gdb-archer-next-over-throw-cxx-exec.patch
Normal file
88
gdb-archer-next-over-throw-cxx-exec.patch
Normal 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
|
6753
gdb-backport-buildid-related-changes.patch
Normal file
6753
gdb-backport-buildid-related-changes.patch
Normal file
File diff suppressed because it is too large
Load Diff
46
gdb-build-fix-unused-var-in-corelow.c.patch
Normal file
46
gdb-build-fix-unused-var-in-corelow.c.patch
Normal 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
575
gdb-catchpoint-re-set.patch
Normal 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)
|
201
gdb-cli-add-ignore-errors-command.patch
Normal file
201
gdb-cli-add-ignore-errors-command.patch
Normal 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
|
||||
|
41
gdb-cli-print-at_hwcap3-and-at_hwcap4.patch
Normal file
41
gdb-cli-print-at_hwcap3-and-at_hwcap4.patch
Normal 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
|
||||
|
61
gdb-doc-fix-gdb.unwinder-docs.patch
Normal file
61
gdb-doc-fix-gdb.unwinder-docs.patch
Normal 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
|
||||
|
41
gdb-doc-fix-qisaddresstagged-anchor.patch
Normal file
41
gdb-doc-fix-qisaddresstagged-anchor.patch
Normal 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
|
||||
|
44
gdb-doc-fix-standard-replies-xref.patch
Normal file
44
gdb-doc-fix-standard-replies-xref.patch
Normal 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
|
||||
|
232
gdb-exp-fix-gdb.fortran-intrinsics.exp-fail-on-arm.patch
Normal file
232
gdb-exp-fix-gdb.fortran-intrinsics.exp-fail-on-arm.patch
Normal 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
10
gdb-gcore-bash.patch
Normal 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
48
gdb-gstack.man
Normal 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>
|
68
gdb-guile-use-scm_debug_typing_strictness-0.patch
Normal file
68
gdb-guile-use-scm_debug_typing_strictness-0.patch
Normal 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
752
gdb-orphanripper.c
Normal 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;
|
||||
}
|
130
gdb-prune-inferior-after-switching-inferior.patch
Normal file
130
gdb-prune-inferior-after-switching-inferior.patch
Normal 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
|
||||
|
445
gdb-python-finishbreakpoint-update.patch
Normal file
445
gdb-python-finishbreakpoint-update.patch
Normal 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
|
||||
|
89
gdb-record-fix-out-of-bounds-write-in-aarch64_record.patch
Normal file
89
gdb-record-fix-out-of-bounds-write-in-aarch64_record.patch
Normal 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
|
||||
|
2923
gdb-remove-qnx-neutrino-support.patch
Normal file
2923
gdb-remove-qnx-neutrino-support.patch
Normal file
File diff suppressed because it is too large
Load Diff
83
gdb-rhbz-818343-set-solib-absolute-prefix-testcase.patch
Normal file
83
gdb-rhbz-818343-set-solib-absolute-prefix-testcase.patch
Normal 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"
|
235
gdb-rhbz1084404-ppc64-s390x-wrong-prologue-skip-O2-g-3of3.patch
Normal file
235
gdb-rhbz1084404-ppc64-s390x-wrong-prologue-skip-O2-g-3of3.patch
Normal 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
|
123
gdb-rhbz1149205-catch-syscall-after-fork-test.patch
Normal file
123
gdb-rhbz1149205-catch-syscall-after-fork-test.patch
Normal 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
16
gdb-rpmlintrc
Normal 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")
|
337
gdb-symtab-fix-target-type-of-complex-long-double-on.patch
Normal file
337
gdb-symtab-fix-target-type-of-complex-long-double-on.patch
Normal 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
|
||||
|
31
gdb-symtab-recurse-into-c-dw_tag_subprogram-dies-for.patch
Normal file
31
gdb-symtab-recurse-into-c-dw_tag_subprogram-dies-for.patch
Normal 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
|
||||
|
224
gdb-symtab-return-correct-reader-for-top-level-cu-in.patch
Normal file
224
gdb-symtab-return-correct-reader-for-top-level-cu-in.patch
Normal 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
|
||||
|
13
gdb-symtab-set-default-dwarf-max-cache-age-1000.patch
Normal file
13
gdb-symtab-set-default-dwarf-max-cache-age-1000.patch
Normal 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)
|
192
gdb-tdep-backport-i386_canonicalize_syscall-rewrite-.patch
Normal file
192
gdb-tdep-backport-i386_canonicalize_syscall-rewrite-.patch
Normal 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
|
||||
|
264
gdb-tdep-fix-arm-thumb2-hw-breakpoint.patch
Normal file
264
gdb-tdep-fix-arm-thumb2-hw-breakpoint.patch
Normal 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
|
||||
|
191
gdb-tdep-fix-gdb.cp-non-trivial-retval.exp-on-riscv6.patch
Normal file
191
gdb-tdep-fix-gdb.cp-non-trivial-retval.exp-on-riscv6.patch
Normal 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
|
||||
|
69
gdb-tdep-fix-recording-of-t1-push.patch
Normal file
69
gdb-tdep-fix-recording-of-t1-push.patch
Normal 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
|
||||
|
46
gdb-tdep-handle-sycall-statx-for-arm-linux.patch
Normal file
46
gdb-tdep-handle-sycall-statx-for-arm-linux.patch
Normal 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
|
||||
|
80
gdb-tdep-handle-syscall-clock_gettime64-for-arm-linu.patch
Normal file
80
gdb-tdep-handle-syscall-clock_gettime64-for-arm-linu.patch
Normal 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
|
||||
|
168
gdb-tdep-s390-add-arch15-record-replay-support.patch
Normal file
168
gdb-tdep-s390-add-arch15-record-replay-support.patch
Normal 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
121
gdb-testsuite-ada-pie.patch
Normal 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
|
||||
|
93
gdb-testsuite-add-gdb.arch-s390-disassemble.exp.patch
Normal file
93
gdb-testsuite-add-gdb.arch-s390-disassemble.exp.patch
Normal 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
|
||||
|
68
gdb-testsuite-add-gdb.suse-debranding.exp.patch
Normal file
68
gdb-testsuite-add-gdb.suse-debranding.exp.patch
Normal 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
|
||||
|
101
gdb-testsuite-add-gdb.suse-zypper-hint.exp.patch
Normal file
101
gdb-testsuite-add-gdb.suse-zypper-hint.exp.patch
Normal 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"
|
59
gdb-testsuite-avoid-intermittent-failures-on-a-debug.patch
Normal file
59
gdb-testsuite-avoid-intermittent-failures-on-a-debug.patch
Normal 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
|
||||
|
48
gdb-testsuite-check-gnatmake-version-in-gdb.ada-scal.patch
Normal file
48
gdb-testsuite-check-gnatmake-version-in-gdb.ada-scal.patch
Normal 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
|
||||
|
274
gdb-testsuite-don-t-use-set-auto-solib-add-off.patch
Normal file
274
gdb-testsuite-don-t-use-set-auto-solib-add-off.patch
Normal 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
|
||||
|
40
gdb-testsuite-fix-another-regexp-in-gdb.threads-step.patch
Normal file
40
gdb-testsuite-fix-another-regexp-in-gdb.threads-step.patch
Normal 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
|
||||
|
54
gdb-testsuite-fix-error-in-gdb.server-server-kill-py.patch
Normal file
54
gdb-testsuite-fix-error-in-gdb.server-server-kill-py.patch
Normal 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
|
||||
|
62
gdb-testsuite-fix-gdb.ada-big_packed_array.exp-on-s3.patch
Normal file
62
gdb-testsuite-fix-gdb.ada-big_packed_array.exp-on-s3.patch
Normal 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
|
||||
|
113
gdb-testsuite-fix-gdb.ada-convvar_comp.exp-on-s390x-.patch
Normal file
113
gdb-testsuite-fix-gdb.ada-convvar_comp.exp-on-s390x-.patch
Normal 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
|
||||
|
70
gdb-testsuite-fix-gdb.ada-mi_task_arg.exp-on-arm-lin.patch
Normal file
70
gdb-testsuite-fix-gdb.ada-mi_task_arg.exp-on-arm-lin.patch
Normal 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
|
||||
|
88
gdb-testsuite-fix-gdb.arch-arm-pseudo-unwind.exp-wit.patch
Normal file
88
gdb-testsuite-fix-gdb.arch-arm-pseudo-unwind.exp-wit.patch
Normal 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
|
||||
|
79
gdb-testsuite-fix-gdb.arch-arm-single-step-kernel-he.patch
Normal file
79
gdb-testsuite-fix-gdb.arch-arm-single-step-kernel-he.patch
Normal 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
|
||||
|
84
gdb-testsuite-fix-gdb.arch-riscv-tdesc-regs.exp.patch
Normal file
84
gdb-testsuite-fix-gdb.arch-riscv-tdesc-regs.exp.patch
Normal 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
|
||||
|
96
gdb-testsuite-fix-gdb.base-branch-to-self.exp-on-arm.patch
Normal file
96
gdb-testsuite-fix-gdb.base-branch-to-self.exp-on-arm.patch
Normal 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
|
||||
|
132
gdb-testsuite-fix-gdb.base-empty-host-env-vars.exp.patch
Normal file
132
gdb-testsuite-fix-gdb.base-empty-host-env-vars.exp.patch
Normal 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
|
||||
|
83
gdb-testsuite-fix-gdb.base-list-dot-nodebug-and-make.patch
Normal file
83
gdb-testsuite-fix-gdb.base-list-dot-nodebug-and-make.patch
Normal 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
|
||||
|
60
gdb-testsuite-fix-gdb.base-list-dot-nodebug.exp-on-o.patch
Normal file
60
gdb-testsuite-fix-gdb.base-list-dot-nodebug.exp-on-o.patch
Normal 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
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
88
gdb-testsuite-fix-gdb.cp-m-static.exp-on-arm.patch
Normal file
88
gdb-testsuite-fix-gdb.cp-m-static.exp-on-arm.patch
Normal 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
|
||||
|
99
gdb-testsuite-fix-gdb.cp-non-trivial-retval.exp-on-a.patch
Normal file
99
gdb-testsuite-fix-gdb.cp-non-trivial-retval.exp-on-a.patch
Normal 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
|
||||
|
54
gdb-testsuite-fix-gdb.dwarf2-dw2-fixed-point.exp-on-.patch
Normal file
54
gdb-testsuite-fix-gdb.dwarf2-dw2-fixed-point.exp-on-.patch
Normal 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
|
||||
|
279
gdb-testsuite-fix-gdb.dwarf2-dw2-lines.exp-on-arm-li.patch
Normal file
279
gdb-testsuite-fix-gdb.dwarf2-dw2-lines.exp-on-arm-li.patch
Normal 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
|
||||
|
95
gdb-testsuite-fix-gdb.fortran-array-bounds.exp-on-ar.patch
Normal file
95
gdb-testsuite-fix-gdb.fortran-array-bounds.exp-on-ar.patch
Normal 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
|
||||
|
88
gdb-testsuite-fix-gdb.python-py-format-address.exp-o.patch
Normal file
88
gdb-testsuite-fix-gdb.python-py-format-address.exp-o.patch
Normal 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
|
||||
|
65
gdb-testsuite-fix-gdb.python-py-format-string.exp-wi.patch
Normal file
65
gdb-testsuite-fix-gdb.python-py-format-string.exp-wi.patch
Normal 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
|
||||
|
154
gdb-testsuite-fix-gdb.python-py-mi-cmd.exp-with-pyth.patch
Normal file
154
gdb-testsuite-fix-gdb.python-py-mi-cmd.exp-with-pyth.patch
Normal 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
|
||||
|
70
gdb-testsuite-fix-gdb.rust-completion.exp-timeout-on.patch
Normal file
70
gdb-testsuite-fix-gdb.rust-completion.exp-timeout-on.patch
Normal 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
|
||||
|
119
gdb-testsuite-fix-gdb.threads-access-mem-running-thr.patch
Normal file
119
gdb-testsuite-fix-gdb.threads-access-mem-running-thr.patch
Normal 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
|
||||
|
80
gdb-testsuite-fix-gdb.threads-leader-exit-attach.exp.patch
Normal file
80
gdb-testsuite-fix-gdb.threads-leader-exit-attach.exp.patch
Normal 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
|
||||
|
39
gdb-testsuite-fix-gdb_py_module_available-for-python.patch
Normal file
39
gdb-testsuite-fix-gdb_py_module_available-for-python.patch
Normal 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
|
||||
|
50
gdb-testsuite-fix-regexp-in-gdb.ada-mi_var_access.ex.patch
Normal file
50
gdb-testsuite-fix-regexp-in-gdb.ada-mi_var_access.ex.patch
Normal 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
|
||||
|
71
gdb-testsuite-fix-regexp-in-gdb.arch-i386-disp-step-.patch
Normal file
71
gdb-testsuite-fix-regexp-in-gdb.arch-i386-disp-step-.patch
Normal 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
|
||||
|
42
gdb-testsuite-fix-regexp-in-gdb.threads-stepi-over-c.patch
Normal file
42
gdb-testsuite-fix-regexp-in-gdb.threads-stepi-over-c.patch
Normal 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
|
||||
|
69
gdb-testsuite-fix-timeout-in-gdb.mi-mi-multi-command.patch
Normal file
69
gdb-testsuite-fix-timeout-in-gdb.mi-mi-multi-command.patch
Normal 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
Reference in New Issue
Block a user