- Maintenance script qa.sh:
* Update PR28561 kfail. * Remove PR31015 kfail. * Remove PR30547 kfail. - Patches added (backport from master): * gdb-symtab-add-producer_is_gas.patch * gdb-symtab-work-around-gas-pr28629.patch * gdb-tdep-fix-nr-array-elements-in-ppc64_aggregate_ca.patch * gdb-testsuite-fix-gdb.python-py-breakpoint.exp-with-.patch * gdb-tui-fix-segfault-in-tui_find_disassembly_address.patch * gdb-tui-fix-wmaybe-uninitialized-in-tui_find_disasse.patch * gdb-testsuite-add-wait_for_msg-arg-to-term-resize-fi.patch - Patches added (backport from gdb-patches): * gdb-fix-segfault-in-for_each_block-part-2.patch * gdb-tui-allow-command-window-of-1-or-2-lines.patch * gdb-tui-fix-resizing-of-terminal-to-1-or-2-lines.patch OBS-URL: https://build.opensuse.org/package/show/devel:gcc/gdb?expand=0&rev=370
This commit is contained in:
parent
e87e79cf5f
commit
169ee8027b
168
gdb-fix-segfault-in-for_each_block-part-2.patch
Normal file
168
gdb-fix-segfault-in-for_each_block-part-2.patch
Normal file
@ -0,0 +1,168 @@
|
||||
From 1cd845ab3d405412aabf9b959aa527dd60143826 Mon Sep 17 00:00:00 2001
|
||||
From: Tom de Vries <tdevries@suse.de>
|
||||
Date: Thu, 2 Nov 2023 14:51:02 +0100
|
||||
Subject: [PATCH] [gdb] Fix segfault in for_each_block, part 2
|
||||
|
||||
The previous commit describes PR gdb/30547, a segfault when running test-case
|
||||
gdb.base/vfork-follow-parent.exp on powerpc64 (likewise on s390x).
|
||||
|
||||
The root cause for the segmentation fault is that linux_is_uclinux gives an
|
||||
incorrect result: it returns true instead of false.
|
||||
|
||||
So, why does linux_is_uclinux:
|
||||
...
|
||||
int
|
||||
linux_is_uclinux (void)
|
||||
{
|
||||
CORE_ADDR dummy;
|
||||
|
||||
return (target_auxv_search (AT_NULL, &dummy) > 0
|
||||
&& target_auxv_search (AT_PAGESZ, &dummy) == 0);
|
||||
...
|
||||
return true?
|
||||
|
||||
This is because ppc_linux_target_wordsize returns 4 instead of 8, causing
|
||||
ppc_linux_nat_target::auxv_parse to misinterpret the auxv vector.
|
||||
|
||||
So, why does ppc_linux_target_wordsize:
|
||||
...
|
||||
int
|
||||
ppc_linux_target_wordsize (int tid)
|
||||
{
|
||||
int wordsize = 4;
|
||||
|
||||
/* Check for 64-bit inferior process. This is the case when the host is
|
||||
64-bit, and in addition the top bit of the MSR register is set. */
|
||||
long msr;
|
||||
|
||||
errno = 0;
|
||||
msr = (long) ptrace (PTRACE_PEEKUSER, tid, PT_MSR * 8, 0);
|
||||
if (errno == 0 && ppc64_64bit_inferior_p (msr))
|
||||
wordsize = 8;
|
||||
|
||||
return wordsize;
|
||||
}
|
||||
...
|
||||
return 4?
|
||||
|
||||
Specifically, we get this result because because tid == 0, so we get
|
||||
errno == ESRCH.
|
||||
|
||||
The tid == 0 is caused by the switch_to_no_thread in
|
||||
handle_vfork_child_exec_or_exit:
|
||||
...
|
||||
/* Switch to no-thread while running clone_program_space, so
|
||||
that clone_program_space doesn't want to read the
|
||||
selected frame of a dead process. */
|
||||
scoped_restore_current_thread restore_thread;
|
||||
switch_to_no_thread ();
|
||||
|
||||
inf->pspace = new program_space (maybe_new_address_space ());
|
||||
...
|
||||
but moving the maybe_new_address_space call to before that gives us the
|
||||
same result. The tid is no longer 0, but we still get ESRCH because the
|
||||
thread has exited.
|
||||
|
||||
Fix this in handle_vfork_child_exec_or_exit by doing the
|
||||
maybe_new_address_space call in the context of the vfork parent.
|
||||
|
||||
Tested on top of trunk on x86_64-linux and ppc64le-linux.
|
||||
Tested on top of gdb-14-branch on ppc64-linux.
|
||||
|
||||
Co-Authored-By: Simon Marchi <simon.marchi@polymtl.ca>
|
||||
|
||||
PR gdb/30547
|
||||
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30547
|
||||
---
|
||||
gdb/infrun.c | 16 +++++++++++-----
|
||||
gdb/nat/ppc-linux.c | 2 ++
|
||||
gdb/ppc-linux-nat.c | 2 ++
|
||||
gdb/s390-linux-nat.c | 5 ++++-
|
||||
4 files changed, 19 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/gdb/infrun.c b/gdb/infrun.c
|
||||
index 9c1b1f04e4d..c078098a6f8 100644
|
||||
--- a/gdb/infrun.c
|
||||
+++ b/gdb/infrun.c
|
||||
@@ -1014,13 +1014,19 @@ handle_vfork_child_exec_or_exit (int exec)
|
||||
go ahead and create a new one for this exiting
|
||||
inferior. */
|
||||
|
||||
- /* Switch to no-thread while running clone_program_space, so
|
||||
- that clone_program_space doesn't want to read the
|
||||
- selected frame of a dead process. */
|
||||
scoped_restore_current_thread restore_thread;
|
||||
- switch_to_no_thread ();
|
||||
|
||||
- inf->pspace = new program_space (maybe_new_address_space ());
|
||||
+ /* Temporarily switch to the vfork parent, to facilitate ptrace
|
||||
+ calls done during maybe_new_address_space. */
|
||||
+ switch_to_thread (any_live_thread_of_inferior (vfork_parent));
|
||||
+ address_space *aspace = maybe_new_address_space ();
|
||||
+
|
||||
+ /* Switch back to the vfork child inferior. Switch to no-thread
|
||||
+ while running clone_program_space, so that clone_program_space
|
||||
+ doesn't want to read the selected frame of a dead process. */
|
||||
+ switch_to_inferior_no_thread (inf);
|
||||
+
|
||||
+ inf->pspace = new program_space (aspace);
|
||||
inf->aspace = inf->pspace->aspace;
|
||||
set_current_program_space (inf->pspace);
|
||||
inf->removable = true;
|
||||
diff --git a/gdb/nat/ppc-linux.c b/gdb/nat/ppc-linux.c
|
||||
index 0957d1b58a7..74549754806 100644
|
||||
--- a/gdb/nat/ppc-linux.c
|
||||
+++ b/gdb/nat/ppc-linux.c
|
||||
@@ -78,6 +78,8 @@ ppc64_64bit_inferior_p (long msr)
|
||||
int
|
||||
ppc_linux_target_wordsize (int tid)
|
||||
{
|
||||
+ gdb_assert (tid != 0);
|
||||
+
|
||||
int wordsize = 4;
|
||||
|
||||
/* Check for 64-bit inferior process. This is the case when the host is
|
||||
diff --git a/gdb/ppc-linux-nat.c b/gdb/ppc-linux-nat.c
|
||||
index d8a8fbdf706..500fb566bc1 100644
|
||||
--- a/gdb/ppc-linux-nat.c
|
||||
+++ b/gdb/ppc-linux-nat.c
|
||||
@@ -1918,6 +1918,8 @@ ppc_linux_nat_target::auxv_parse (const gdb_byte **readptr,
|
||||
const gdb_byte *endptr, CORE_ADDR *typep,
|
||||
CORE_ADDR *valp)
|
||||
{
|
||||
+ gdb_assert (inferior_ptid != null_ptid);
|
||||
+
|
||||
int tid = inferior_ptid.lwp ();
|
||||
if (tid == 0)
|
||||
tid = inferior_ptid.pid ();
|
||||
diff --git a/gdb/s390-linux-nat.c b/gdb/s390-linux-nat.c
|
||||
index fc3917d30be..403f37d690d 100644
|
||||
--- a/gdb/s390-linux-nat.c
|
||||
+++ b/gdb/s390-linux-nat.c
|
||||
@@ -949,10 +949,12 @@ s390_target_wordsize (void)
|
||||
/* Check for 64-bit inferior process. This is the case when the host is
|
||||
64-bit, and in addition bit 32 of the PSW mask is set. */
|
||||
#ifdef __s390x__
|
||||
+ int tid = s390_inferior_tid ();
|
||||
+ gdb_assert (tid != 0);
|
||||
long pswm;
|
||||
|
||||
errno = 0;
|
||||
- pswm = (long) ptrace (PTRACE_PEEKUSER, s390_inferior_tid (), PT_PSWMASK, 0);
|
||||
+ pswm = (long) ptrace (PTRACE_PEEKUSER, tid, PT_PSWMASK, 0);
|
||||
if (errno == 0 && (pswm & 0x100000000ul) != 0)
|
||||
wordsize = 8;
|
||||
#endif
|
||||
@@ -965,6 +967,7 @@ s390_linux_nat_target::auxv_parse (const gdb_byte **readptr,
|
||||
const gdb_byte *endptr, CORE_ADDR *typep,
|
||||
CORE_ADDR *valp)
|
||||
{
|
||||
+ gdb_assert (inferior_ptid != null_ptid);
|
||||
int sizeof_auxv_field = s390_target_wordsize ();
|
||||
enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
|
||||
const gdb_byte *ptr = *readptr;
|
||||
|
||||
base-commit: 59053f06bd94be51efacfa80f9a1f738e3e1ee9c
|
||||
--
|
||||
2.35.3
|
||||
|
125
gdb-symtab-add-producer_is_gas.patch
Normal file
125
gdb-symtab-add-producer_is_gas.patch
Normal file
@ -0,0 +1,125 @@
|
||||
From aa8ba17b9a3fdfeeb65df4c3e0731a0e9e96cbf7 Mon Sep 17 00:00:00 2001
|
||||
From: Tom de Vries <tdevries@suse.de>
|
||||
Date: Wed, 1 Nov 2023 00:33:12 +0100
|
||||
Subject: [PATCH 1/2] [gdb/symtab] Add producer_is_gas
|
||||
|
||||
Add producer_is_gas, a generic way to get the gas version from the
|
||||
producer string.
|
||||
|
||||
Tested on x86_64-linux.
|
||||
---
|
||||
gdb/dwarf2/read.c | 4 ++--
|
||||
gdb/producer.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++
|
||||
gdb/producer.h | 5 +++++
|
||||
3 files changed, 63 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
|
||||
index 970dd54c7a5..472684a5817 100644
|
||||
--- a/gdb/dwarf2/read.c
|
||||
+++ b/gdb/dwarf2/read.c
|
||||
@@ -13376,8 +13376,8 @@ check_producer (struct dwarf2_cu *cu)
|
||||
cu->producer_is_codewarrior = true;
|
||||
else if (producer_is_clang (cu->producer, &major, &minor))
|
||||
cu->producer_is_clang = true;
|
||||
- else if (startswith (cu->producer, "GNU AS 2.39.0"))
|
||||
- cu->producer_is_gas_2_39 = true;
|
||||
+ else if (producer_is_gas (cu->producer, &major, &minor))
|
||||
+ cu->producer_is_gas_2_39 = major == 2 && minor == 39;
|
||||
else
|
||||
{
|
||||
/* For other non-GCC compilers, expect their behavior is DWARF version
|
||||
diff --git a/gdb/producer.c b/gdb/producer.c
|
||||
index 9fcf749e3d4..cd83dfce128 100644
|
||||
--- a/gdb/producer.c
|
||||
+++ b/gdb/producer.c
|
||||
@@ -81,6 +81,45 @@ producer_is_gcc (const char *producer, int *major, int *minor)
|
||||
|
||||
/* See producer.h. */
|
||||
|
||||
+bool
|
||||
+producer_is_gas (const char *producer, int *major, int *minor)
|
||||
+{
|
||||
+ if (producer == nullptr)
|
||||
+ {
|
||||
+ /* No producer, don't know. */
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ /* Detect prefix. */
|
||||
+ const char prefix[] = "GNU AS ";
|
||||
+ if (!startswith (producer, prefix))
|
||||
+ {
|
||||
+ /* Producer is not gas. */
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ /* Skip prefix. */
|
||||
+ const char *cs = &producer[strlen (prefix)];
|
||||
+
|
||||
+ /* Ensure that major/minor are not nullptrs. */
|
||||
+ int maj, min;
|
||||
+ if (major == nullptr)
|
||||
+ major = &maj;
|
||||
+ if (minor == nullptr)
|
||||
+ minor = &min;
|
||||
+
|
||||
+ int scanned = sscanf (cs, "%d.%d", major, minor);
|
||||
+ if (scanned != 2)
|
||||
+ {
|
||||
+ /* Unable to scan major/minor version. */
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ return true;
|
||||
+}
|
||||
+
|
||||
+ /* See producer.h. */
|
||||
+
|
||||
bool
|
||||
producer_is_icc_ge_19 (const char *producer)
|
||||
{
|
||||
@@ -251,6 +290,23 @@ Version 18.0 Beta";
|
||||
SELF_CHECK (!producer_is_gcc (flang_llvm_exp, &major, &minor));
|
||||
SELF_CHECK (producer_is_llvm (flang_llvm_exp));
|
||||
}
|
||||
+
|
||||
+ {
|
||||
+ static const char gas_exp[] = "GNU AS 2.39.0";
|
||||
+ int major = 0, minor = 0;
|
||||
+ SELF_CHECK (!producer_is_gcc (gas_exp, &major, &minor));
|
||||
+ SELF_CHECK (producer_is_gas (gas_exp, &major, &minor));
|
||||
+ SELF_CHECK (major == 2 && minor == 39);
|
||||
+
|
||||
+ static const char gas_incomplete_exp[] = "GNU AS ";
|
||||
+ SELF_CHECK (!producer_is_gas (gas_incomplete_exp, &major, &minor));
|
||||
+ SELF_CHECK (!producer_is_gcc (gas_incomplete_exp, &major, &minor));
|
||||
+
|
||||
+ static const char gas_incomplete_exp_2[] = "GNU AS 2";
|
||||
+ SELF_CHECK (!producer_is_gas (gas_incomplete_exp_2, &major, &minor));
|
||||
+ SELF_CHECK (!producer_is_gcc (gas_incomplete_exp_2, &major, &minor));
|
||||
+ }
|
||||
+
|
||||
}
|
||||
}
|
||||
}
|
||||
diff --git a/gdb/producer.h b/gdb/producer.h
|
||||
index c915979b122..00718511775 100644
|
||||
--- a/gdb/producer.h
|
||||
+++ b/gdb/producer.h
|
||||
@@ -30,6 +30,11 @@ extern int producer_is_gcc_ge_4 (const char *producer);
|
||||
is NULL or it isn't GCC. */
|
||||
extern int producer_is_gcc (const char *producer, int *major, int *minor);
|
||||
|
||||
+/* Returns nonzero if the given PRODUCER string is GAS and sets the MAJOR
|
||||
+ and MINOR versions when not NULL. Returns zero if the given PRODUCER
|
||||
+ is NULL or it isn't GAS. */
|
||||
+bool producer_is_gas (const char *producer, int *major, int *minor);
|
||||
+
|
||||
/* Check for Intel compilers >= 19.0. */
|
||||
extern bool producer_is_icc_ge_19 (const char *producer);
|
||||
|
||||
|
||||
base-commit: 39553c1e285c426946188ec2a890c1c1cb933060
|
||||
--
|
||||
2.35.3
|
||||
|
278
gdb-symtab-work-around-gas-pr28629.patch
Normal file
278
gdb-symtab-work-around-gas-pr28629.patch
Normal file
@ -0,0 +1,278 @@
|
||||
From b1136560e772dd4c74f1fbb41f6ba840b92fb9d6 Mon Sep 17 00:00:00 2001
|
||||
From: Tom de Vries <tdevries@suse.de>
|
||||
Date: Wed, 1 Nov 2023 00:33:12 +0100
|
||||
Subject: [PATCH 2/2] [gdb/symtab] Work around gas PR28629
|
||||
|
||||
When running test-case gdb.tui/tui-layout-asm-short-prog.exp on AlmaLinux 9.2
|
||||
ppc64le, I run into:
|
||||
...
|
||||
FAIL: gdb.tui/tui-layout-asm-short-prog.exp: check asm box contents
|
||||
...
|
||||
|
||||
The problem is that we get:
|
||||
...
|
||||
7 [ No Assembly Available ]
|
||||
...
|
||||
because tui_get_begin_asm_address doesn't succeed.
|
||||
|
||||
In more detail, tui_get_begin_asm_address calls:
|
||||
...
|
||||
find_line_pc (sal.symtab, sal.line, &addr);
|
||||
...
|
||||
with:
|
||||
...
|
||||
(gdb) p *sal.symtab
|
||||
$5 = {next = 0x130393c0, m_compunit = 0x130392f0, m_linetable = 0x0,
|
||||
filename = "tui-layout-asm-short-prog.S",
|
||||
filename_for_id = "$gdb/build/gdb/testsuite/tui-layout-asm-short-prog.S",
|
||||
m_language = language_asm, fullname = 0x0}
|
||||
(gdb) p sal.line
|
||||
$6 = 1
|
||||
...
|
||||
|
||||
The problem is the filename_for_id which is the source file prefixed with the
|
||||
compilation dir rather than the source dir.
|
||||
|
||||
This is due to faulty debug info generated by gas, PR28629:
|
||||
...
|
||||
<1a> DW_AT_name : tui-layout-asm-short-prog.S
|
||||
<1e> DW_AT_comp_dir : $gdb/build/gdb/testsuite
|
||||
<22> DW_AT_producer : GNU AS 2.35.2
|
||||
...
|
||||
|
||||
The DW_AT_name is relative, and it's relative to the DW_AT_comp_dir entry,
|
||||
making the effective name $gdb/build/gdb/testsuite/tui-layout-asm-short-prog.S.
|
||||
|
||||
The bug is fixed starting version 2.38, where we get instead:
|
||||
...
|
||||
<1a> DW_AT_name :
|
||||
$gdb/src/gdb/testsuite/gdb.tui/tui-layout-asm-short-prog.S
|
||||
<1e> DW_AT_comp_dir : $gdb/build/gdb/testsuite
|
||||
<22> DW_AT_producer : GNU AS 2.38
|
||||
...
|
||||
|
||||
Work around the faulty debug info by constructing the filename_for_id using
|
||||
the second directory from the directory table in the .debug_line header:
|
||||
...
|
||||
The Directory Table (offset 0x22, lines 2, columns 1):
|
||||
Entry Name
|
||||
0 $gdb/build/gdb/testsuite
|
||||
1 $gdb/src/gdb/testsuite/gdb.tui
|
||||
...
|
||||
|
||||
Note that the used gas contains a backport of commit 3417bfca676 ("GAS:
|
||||
DWARF-5: Ensure that the 0'th entry in the directory table contains the
|
||||
current working directory."), because directory 0 is correct. With the
|
||||
unpatched 2.35.2 release the directory 0 entry is incorrect: it's a copy of
|
||||
entry 1.
|
||||
|
||||
Add a dwarf assembly test-case that reflects the debug info as generated by
|
||||
unpatched gas 2.35.2.
|
||||
|
||||
Tested on x86_64-linux.
|
||||
|
||||
Approved-By: Tom Tromey <tom@tromey.com>
|
||||
---
|
||||
gdb/dwarf2/cu.c | 1 +
|
||||
gdb/dwarf2/cu.h | 1 +
|
||||
gdb/dwarf2/read.c | 37 +++++++-
|
||||
.../gdb.dwarf2/dw2-gas-workaround.exp | 94 +++++++++++++++++++
|
||||
4 files changed, 132 insertions(+), 1 deletion(-)
|
||||
create mode 100644 gdb/testsuite/gdb.dwarf2/dw2-gas-workaround.exp
|
||||
|
||||
diff --git a/gdb/dwarf2/cu.c b/gdb/dwarf2/cu.c
|
||||
index 42fd4f4441b..6b5d956649f 100644
|
||||
--- a/gdb/dwarf2/cu.c
|
||||
+++ b/gdb/dwarf2/cu.c
|
||||
@@ -40,6 +40,7 @@ dwarf2_cu::dwarf2_cu (dwarf2_per_cu_data *per_cu,
|
||||
producer_is_icc_lt_14 (false),
|
||||
producer_is_codewarrior (false),
|
||||
producer_is_clang (false),
|
||||
+ producer_is_gas_lt_2_38 (false),
|
||||
producer_is_gas_2_39 (false),
|
||||
processing_has_namespace_info (false),
|
||||
load_all_dies (false)
|
||||
diff --git a/gdb/dwarf2/cu.h b/gdb/dwarf2/cu.h
|
||||
index 710aeb5b237..9b1e8775ff4 100644
|
||||
--- a/gdb/dwarf2/cu.h
|
||||
+++ b/gdb/dwarf2/cu.h
|
||||
@@ -265,6 +265,7 @@ struct dwarf2_cu
|
||||
bool producer_is_icc_lt_14 : 1;
|
||||
bool producer_is_codewarrior : 1;
|
||||
bool producer_is_clang : 1;
|
||||
+ bool producer_is_gas_lt_2_38 : 1;
|
||||
bool producer_is_gas_2_39 : 1;
|
||||
|
||||
/* When true, the file that we're processing is known to have
|
||||
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
|
||||
index 472684a5817..2339cceb829 100644
|
||||
--- a/gdb/dwarf2/read.c
|
||||
+++ b/gdb/dwarf2/read.c
|
||||
@@ -146,6 +146,8 @@ static int dwarf2_loclist_index;
|
||||
static int dwarf2_locexpr_block_index;
|
||||
static int dwarf2_loclist_block_index;
|
||||
|
||||
+static bool producer_is_gas_lt_2_38 (struct dwarf2_cu *cu);
|
||||
+
|
||||
/* Size of .debug_loclists section header for 32-bit DWARF format. */
|
||||
#define LOCLIST_HEADER_SIZE32 12
|
||||
|
||||
@@ -9663,6 +9665,27 @@ read_file_scope (struct die_info *die, struct dwarf2_cu *cu)
|
||||
|
||||
file_and_directory &fnd = find_file_and_directory (die, cu);
|
||||
|
||||
+ /* GAS supports generating dwarf-5 info starting version 2.35. Versions
|
||||
+ 2.35-2.37 generate an incorrect CU name attribute: it's relative,
|
||||
+ implicitly prefixing it with the compilation dir. Work around this by
|
||||
+ prefixing it with the source dir instead. */
|
||||
+ if (cu->header.version == 5 && !IS_ABSOLUTE_PATH (fnd.get_name ())
|
||||
+ && producer_is_gas_lt_2_38 (cu))
|
||||
+ {
|
||||
+ attr = dwarf2_attr (die, DW_AT_stmt_list, cu);
|
||||
+ if (attr != nullptr && attr->form_is_unsigned ())
|
||||
+ {
|
||||
+ sect_offset line_offset = (sect_offset) attr->as_unsigned ();
|
||||
+ line_header_up lh = dwarf_decode_line_header (line_offset, cu,
|
||||
+ fnd.get_comp_dir ());
|
||||
+ if (lh->version == 5 && lh->is_valid_file_index (1))
|
||||
+ {
|
||||
+ std::string dir = lh->include_dir_at (1);
|
||||
+ fnd.set_comp_dir (std::move (dir));
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
cu->start_compunit_symtab (fnd.get_name (), fnd.intern_comp_dir (objfile),
|
||||
lowpc);
|
||||
|
||||
@@ -13377,7 +13400,10 @@ check_producer (struct dwarf2_cu *cu)
|
||||
else if (producer_is_clang (cu->producer, &major, &minor))
|
||||
cu->producer_is_clang = true;
|
||||
else if (producer_is_gas (cu->producer, &major, &minor))
|
||||
- cu->producer_is_gas_2_39 = major == 2 && minor == 39;
|
||||
+ {
|
||||
+ cu->producer_is_gas_lt_2_38 = major < 2 || (major == 2 && minor < 38);
|
||||
+ cu->producer_is_gas_2_39 = major == 2 && minor == 39;
|
||||
+ }
|
||||
else
|
||||
{
|
||||
/* For other non-GCC compilers, expect their behavior is DWARF version
|
||||
@@ -13413,6 +13439,15 @@ producer_is_codewarrior (struct dwarf2_cu *cu)
|
||||
return cu->producer_is_codewarrior;
|
||||
}
|
||||
|
||||
+static bool
|
||||
+producer_is_gas_lt_2_38 (struct dwarf2_cu *cu)
|
||||
+{
|
||||
+ if (!cu->checked_producer)
|
||||
+ check_producer (cu);
|
||||
+
|
||||
+ return cu->producer_is_gas_lt_2_38;
|
||||
+}
|
||||
+
|
||||
static bool
|
||||
producer_is_gas_2_39 (struct dwarf2_cu *cu)
|
||||
{
|
||||
diff --git a/gdb/testsuite/gdb.dwarf2/dw2-gas-workaround.exp b/gdb/testsuite/gdb.dwarf2/dw2-gas-workaround.exp
|
||||
new file mode 100644
|
||||
index 00000000000..416778f51b7
|
||||
--- /dev/null
|
||||
+++ b/gdb/testsuite/gdb.dwarf2/dw2-gas-workaround.exp
|
||||
@@ -0,0 +1,94 @@
|
||||
+# 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/>.
|
||||
+
|
||||
+# Test line number information in various configurations.
|
||||
+
|
||||
+load_lib dwarf.exp
|
||||
+
|
||||
+# This test can only be run on targets which support DWARF-2 and use gas.
|
||||
+if { ![dwarf2_support] } {
|
||||
+ return -1
|
||||
+}
|
||||
+
|
||||
+standard_testfile dw2-lines.c -dw2.S
|
||||
+
|
||||
+with_shared_gdb {
|
||||
+ set func_info_vars [get_func_info bar]
|
||||
+}
|
||||
+
|
||||
+# Helper function.
|
||||
+proc line_for { l } {
|
||||
+ global srcfile
|
||||
+ set line [gdb_get_line_number "$l:" $srcfile]
|
||||
+ return [expr $line + 1]
|
||||
+}
|
||||
+
|
||||
+set asm_file [standard_output_file $srcfile2]
|
||||
+Dwarf::assemble $asm_file {
|
||||
+ declare_labels Llines
|
||||
+ global srcdir subdir srcfile objdir
|
||||
+ global func_info_vars
|
||||
+ foreach var $func_info_vars {
|
||||
+ global $var
|
||||
+ }
|
||||
+
|
||||
+ cu { version 5 } {
|
||||
+ compile_unit {
|
||||
+ {language @DW_LANG_Mips_Assembler}
|
||||
+ {name $srcfile}
|
||||
+ {comp_dir $objdir}
|
||||
+ {stmt_list $Llines DW_FORM_sec_offset}
|
||||
+ {producer "GNU AS 2.35.2"}
|
||||
+ } {
|
||||
+ subprogram {
|
||||
+ {external 1 flag}
|
||||
+ {name bar}
|
||||
+ {low_pc $bar_start addr}
|
||||
+ {high_pc "$bar_start + $bar_len" addr}
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ lines [list version 5] Llines {
|
||||
+ set diridx1 [include_dir "${srcdir}/${subdir}"]
|
||||
+ set diridx2 [include_dir "${srcdir}/${subdir}"]
|
||||
+ file_name "$srcfile" $diridx1
|
||||
+ file_name "$srcfile" $diridx2
|
||||
+
|
||||
+ program {
|
||||
+ DW_LNE_set_address bar_label
|
||||
+ line [line_for bar_label]
|
||||
+ DW_LNS_copy
|
||||
+
|
||||
+ DW_LNE_set_address bar_label_2
|
||||
+ DW_LNE_end_sequence
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+if { [prepare_for_testing "failed to prepare" ${testfile} \
|
||||
+ [list $srcfile $asm_file] {nodebug}] } {
|
||||
+ return -1
|
||||
+}
|
||||
+
|
||||
+gdb_test_no_output "set debug symtab-create 1"
|
||||
+gdb_test_multiple "ptype bar" "" {
|
||||
+ -re -wrap "$objdir.*" {
|
||||
+ fail $gdb_test_name
|
||||
+ }
|
||||
+ -re -wrap "" {
|
||||
+ pass $gdb_test_name
|
||||
+ }
|
||||
+}
|
||||
--
|
||||
2.35.3
|
||||
|
86
gdb-tdep-fix-nr-array-elements-in-ppc64_aggregate_ca.patch
Normal file
86
gdb-tdep-fix-nr-array-elements-in-ppc64_aggregate_ca.patch
Normal file
@ -0,0 +1,86 @@
|
||||
From 3f0c512dc37dbede372a018732d315726a56d10e Mon Sep 17 00:00:00 2001
|
||||
From: Tom de Vries <tdevries@suse.de>
|
||||
Date: Wed, 1 Nov 2023 08:07:15 +0100
|
||||
Subject: [PATCH] [gdb/tdep] Fix nr array elements in ppc64_aggregate_candidate
|
||||
|
||||
On AlmaLinux 9.2 powerpc64le I run into:
|
||||
...
|
||||
(gdb) PASS: gdb.ada/array_return.exp: continuing to Create_Small_Float_Vector
|
||||
finish^M
|
||||
Run till exit from #0 pck.create_small_float_vector () at pck.adb:30^M
|
||||
0x00000000100022d4 in p () at p.adb:25^M
|
||||
25 Vector := Create_Small_Float_Vector;^M
|
||||
Value returned is $3 = (2.80259693e-45, 2.80259693e-45)^M
|
||||
(gdb) FAIL: gdb.ada/array_return.exp: value printed by finish of Create_Small_Float_Vector
|
||||
...
|
||||
while this is expected:
|
||||
...
|
||||
Value returned is $3 = (4.25, 4.25)^M
|
||||
...
|
||||
|
||||
The problem is here in ppc64_aggregate_candidate:
|
||||
...
|
||||
if (!get_array_bounds (type, &low_bound, &high_bound))
|
||||
return -1;
|
||||
count *= high_bound - low_bound
|
||||
...
|
||||
|
||||
The array type (containing 2 elements) is:
|
||||
...
|
||||
type Small_Float_Vector is array (1 .. 2) of Float;
|
||||
...
|
||||
so we have:
|
||||
...
|
||||
(gdb) p low_bound
|
||||
$1 = 1
|
||||
(gdb) p high_bound
|
||||
$2 = 2
|
||||
...
|
||||
but we calculate the number of elements in the array using
|
||||
"high_bound - low_bound", which is 1.
|
||||
|
||||
Consequently, gdb fails to correctly classify the type as a ELFv2 homogeneous
|
||||
aggregate.
|
||||
|
||||
Fix this by calculating the number of elements in the array by using
|
||||
"high_bound - low_bound + 1" instead.
|
||||
|
||||
Furthermore, high_bound can (in general, though perhaps not here) be also be
|
||||
smaller than low_bound, so to be safe take that into account as well:
|
||||
...
|
||||
LONGEST nr_array_elements = (low_bound > high_bound
|
||||
? 0
|
||||
: (high_bound - low_bound + 1));
|
||||
count *= nr_array_elements;
|
||||
...
|
||||
|
||||
Tested on powerpc64le-linux.
|
||||
|
||||
PR tdep/31015
|
||||
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31015
|
||||
---
|
||||
gdb/ppc-sysv-tdep.c | 6 +++++-
|
||||
1 file changed, 5 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/gdb/ppc-sysv-tdep.c b/gdb/ppc-sysv-tdep.c
|
||||
index 9cea63307e6..dc89201eed2 100644
|
||||
--- a/gdb/ppc-sysv-tdep.c
|
||||
+++ b/gdb/ppc-sysv-tdep.c
|
||||
@@ -1126,7 +1126,11 @@ ppc64_aggregate_candidate (struct type *type,
|
||||
|
||||
if (!get_array_bounds (type, &low_bound, &high_bound))
|
||||
return -1;
|
||||
- count *= high_bound - low_bound;
|
||||
+
|
||||
+ LONGEST nr_array_elements = (low_bound > high_bound
|
||||
+ ? 0
|
||||
+ : (high_bound - low_bound + 1));
|
||||
+ count *= nr_array_elements;
|
||||
|
||||
/* There must be no padding. */
|
||||
if (count == 0)
|
||||
|
||||
base-commit: b1136560e772dd4c74f1fbb41f6ba840b92fb9d6
|
||||
--
|
||||
2.35.3
|
||||
|
49
gdb-testsuite-add-wait_for_msg-arg-to-term-resize-fi.patch
Normal file
49
gdb-testsuite-add-wait_for_msg-arg-to-term-resize-fi.patch
Normal file
@ -0,0 +1,49 @@
|
||||
From 028d19e262b4086bc266b2657edd566bb4757927 Mon Sep 17 00:00:00 2001
|
||||
From: Tom de Vries <tdevries@suse.de>
|
||||
Date: Mon, 13 Nov 2023 11:33:23 +0100
|
||||
Subject: [PATCH 5/6] [gdb/testsuite] Add wait_for_msg arg to Term::resize fix
|
||||
|
||||
From commit deb1ba4e38b ("[gdb/tui] Fix TUI resizing for TERM=ansi").
|
||||
|
||||
Required for "[gdb/tui] Fix resizing of terminal to 1 or 2 lines".
|
||||
---
|
||||
gdb/testsuite/lib/tuiterm.exp | 10 +++++++---
|
||||
1 file changed, 7 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/gdb/testsuite/lib/tuiterm.exp b/gdb/testsuite/lib/tuiterm.exp
|
||||
index 591c4ca9c4c..eaac09581e9 100644
|
||||
--- a/gdb/testsuite/lib/tuiterm.exp
|
||||
+++ b/gdb/testsuite/lib/tuiterm.exp
|
||||
@@ -1066,7 +1066,7 @@ namespace eval Term {
|
||||
}
|
||||
}
|
||||
|
||||
- proc resize {rows cols} {
|
||||
+ proc resize {rows cols {wait_for_msg 1}} {
|
||||
variable _rows
|
||||
variable _cols
|
||||
variable _resize_count
|
||||
@@ -1080,14 +1080,18 @@ namespace eval Term {
|
||||
# Due to the strange column resizing behavior, and because we
|
||||
# don't care about this intermediate resize, we don't check
|
||||
# the size here.
|
||||
- wait_for "@@ resize done $_resize_count"
|
||||
+ if { $wait_for_msg } {
|
||||
+ wait_for "@@ resize done $_resize_count"
|
||||
+ }
|
||||
incr _resize_count
|
||||
# Somehow the number of columns transmitted to gdb is one less
|
||||
# than what we request from expect. We hide this weird
|
||||
# details from the caller.
|
||||
_do_resize $_rows $cols
|
||||
stty columns [expr {$_cols + 1}] < $::gdb_tty_name
|
||||
- wait_for "@@ resize done $_resize_count, size = ${_cols}x${rows}"
|
||||
+ if { $wait_for_msg } {
|
||||
+ wait_for "@@ resize done $_resize_count, size = ${_cols}x${rows}"
|
||||
+ }
|
||||
incr _resize_count
|
||||
}
|
||||
}
|
||||
--
|
||||
2.35.3
|
||||
|
65
gdb-testsuite-fix-gdb.python-py-breakpoint.exp-with-.patch
Normal file
65
gdb-testsuite-fix-gdb.python-py-breakpoint.exp-with-.patch
Normal file
@ -0,0 +1,65 @@
|
||||
From 0cb123a4157d215c80f3deb339a3ba10a188ba19 Mon Sep 17 00:00:00 2001
|
||||
From: Tom de Vries <tdevries@suse.de>
|
||||
Date: Mon, 2 Jan 2023 11:59:17 +0100
|
||||
Subject: [PATCH 1/6] [gdb/testsuite] Fix gdb.python/py-breakpoint.exp with
|
||||
libstdc++ debug info
|
||||
|
||||
On x86_64-linux, I run into:
|
||||
...
|
||||
(gdb) python hbp1 = gdb.Breakpoint("add", type=gdb.BP_HARDWARE_BREAKPOINT)^M
|
||||
Hardware assisted breakpoint 2 at 0x40072e: add. (7 locations)^M
|
||||
(gdb) FAIL: gdb.python/py-breakpoint.exp: test_hardware_breakpoints: \
|
||||
Set hardware breakpoint
|
||||
...
|
||||
due to libstdc++ debug info:
|
||||
...
|
||||
$ gdb -q -batch outputs/gdb.python/py-breakpoint/py-breakpoint \
|
||||
-ex start \
|
||||
-ex "b add" \
|
||||
-ex "info break"
|
||||
Temporary breakpoint 1 at 0x40076a: file py-breakpoint.c, line 50.
|
||||
|
||||
Temporary breakpoint 1, main (argc=1, argv=$hex) at py-breakpoint.c:50
|
||||
50 int foo = 5;
|
||||
Breakpoint 2 at 0x40072e: add. (7 locations)
|
||||
Num Type Disp Enb Address What
|
||||
2 breakpoint keep y <MULTIPLE>
|
||||
2.1 y 0x000000000040072e in add(int) at \
|
||||
py-breakpoint.c:39
|
||||
2.2 y 0x00007ffff7b131de in \
|
||||
(anonymous namespace)::fast_float::bigint::add at \
|
||||
../../../../../libstdc++-v3/src/c++17/fast_float/fast_float.h:1815
|
||||
...
|
||||
2.7 y 0x00007ffff7b137e4 in \
|
||||
(anonymous namespace)::fast_float::bigint::add at \
|
||||
../../../../../libstdc++-v3/src/c++17/fast_float/fast_float.h:1815
|
||||
...
|
||||
|
||||
Fix this by using qualified=True.
|
||||
|
||||
Tested on x86_64-linux.
|
||||
PR testsuite/29910
|
||||
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=29910
|
||||
---
|
||||
gdb/testsuite/gdb.python/py-breakpoint.exp | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/gdb/testsuite/gdb.python/py-breakpoint.exp b/gdb/testsuite/gdb.python/py-breakpoint.exp
|
||||
index 9ba6b837a41..23c6637cd3a 100644
|
||||
--- a/gdb/testsuite/gdb.python/py-breakpoint.exp
|
||||
+++ b/gdb/testsuite/gdb.python/py-breakpoint.exp
|
||||
@@ -273,7 +273,8 @@ proc_with_prefix test_hardware_breakpoints { } {
|
||||
|
||||
delete_breakpoints
|
||||
|
||||
- gdb_test "python hbp1 = gdb.Breakpoint(\"add\", type=gdb.BP_HARDWARE_BREAKPOINT)" \
|
||||
+ set bp_args {"add", type=gdb.BP_HARDWARE_BREAKPOINT, qualified=True}
|
||||
+ gdb_test "python hbp1 = gdb.Breakpoint($bp_args)" \
|
||||
".*Hardware assisted breakpoint ($decimal)+ at .*$srcfile, line ($decimal)+\." \
|
||||
"Set hardware breakpoint"
|
||||
gdb_test "python print (gdb.breakpoints()\[0\].type == gdb.BP_HARDWARE_BREAKPOINT)" \
|
||||
|
||||
base-commit: 1cd845ab3d405412aabf9b959aa527dd60143826
|
||||
--
|
||||
2.35.3
|
||||
|
80
gdb-tui-allow-command-window-of-1-or-2-lines.patch
Normal file
80
gdb-tui-allow-command-window-of-1-or-2-lines.patch
Normal file
@ -0,0 +1,80 @@
|
||||
From 02616ce7c5571e5b2680cad52f8c58b27f77b2a5 Mon Sep 17 00:00:00 2001
|
||||
From: Tom de Vries <tdevries@suse.de>
|
||||
Date: Thu, 9 Nov 2023 09:04:39 +0100
|
||||
Subject: [PATCH 4/6] [gdb/tui] Allow command window of 1 or 2 lines
|
||||
|
||||
When starting TUI in a terminal with 2 lines (likewise with 1 line):
|
||||
...
|
||||
$ echo $LINES
|
||||
2
|
||||
$ gdb -q -tui
|
||||
...
|
||||
we run into this assert in tui_apply_current_layout:
|
||||
...
|
||||
/* This should always be made visible by a layout. */
|
||||
gdb_assert (TUI_CMD_WIN != nullptr);
|
||||
...
|
||||
|
||||
The problem is that for the command window:
|
||||
- the minimum height is 3 (the default), but
|
||||
- the maximum height is only 2 because there are only 2 lines.
|
||||
|
||||
This discrepancy eventually leads to a call to newwin in make_window with:
|
||||
...
|
||||
(gdb) p height
|
||||
$1 = 3
|
||||
(gdb) p width
|
||||
$2 = 66
|
||||
(gdb) p y
|
||||
$3 = -1
|
||||
(gdb) p x
|
||||
$4 = 0
|
||||
(gdb)
|
||||
...
|
||||
which results in a nullptr, which eventually triggers the assert.
|
||||
|
||||
The easiest way to fix this is to change the minimum height of the command
|
||||
window to 1. However, that would also change behaviour for the case that the
|
||||
screen size is 3 lines or more. For instance, in gdb.tui/winheight.exp the
|
||||
number of lines in the terminal is 24, and the test-case checks that the user
|
||||
cannot increase the source window height to the point that the command window
|
||||
height would be less than 3.
|
||||
|
||||
Fix this by calculating the minimum height of the command window as follows:
|
||||
- the default (3) if max_height () allows it, and
|
||||
- max_height () otherwise.
|
||||
|
||||
Tested on x86_64-linux.
|
||||
|
||||
PR tui/31044
|
||||
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31044
|
||||
---
|
||||
gdb/tui/tui-command.h | 12 ++++++++++++
|
||||
1 file changed, 12 insertions(+)
|
||||
|
||||
diff --git a/gdb/tui/tui-command.h b/gdb/tui/tui-command.h
|
||||
index f6842880bb2..e8c96ecee30 100644
|
||||
--- a/gdb/tui/tui-command.h
|
||||
+++ b/gdb/tui/tui-command.h
|
||||
@@ -57,6 +57,18 @@ struct tui_cmd_window : public tui_win_info
|
||||
/* The command window can't be made invisible. */
|
||||
}
|
||||
|
||||
+ /* Compute the minimum height of this window. */
|
||||
+ virtual int min_height () const override
|
||||
+ {
|
||||
+ int preferred_min = tui_win_info::min_height ();
|
||||
+ int max = max_height ();
|
||||
+ /* If there is enough space to accommodate the preferred minimum height,
|
||||
+ use it. Otherwise, use as much as possible. */
|
||||
+ return (preferred_min <= max
|
||||
+ ? preferred_min
|
||||
+ : max);
|
||||
+ }
|
||||
+
|
||||
int start_line = 0;
|
||||
|
||||
protected:
|
||||
--
|
||||
2.35.3
|
||||
|
147
gdb-tui-fix-resizing-of-terminal-to-1-or-2-lines.patch
Normal file
147
gdb-tui-fix-resizing-of-terminal-to-1-or-2-lines.patch
Normal file
@ -0,0 +1,147 @@
|
||||
From c55a452eaf9390d5659d3205f762aa2cb84511e1 Mon Sep 17 00:00:00 2001
|
||||
From: Tom de Vries <tdevries@suse.de>
|
||||
Date: Thu, 9 Nov 2023 09:05:01 +0100
|
||||
Subject: [PATCH 6/6] [gdb/tui] Fix resizing of terminal to 1 or 2 lines
|
||||
|
||||
When starting TUI in a terminal with 3 lines:
|
||||
...
|
||||
$ echo $LINES
|
||||
3
|
||||
$ gdb -q -tui
|
||||
...
|
||||
and resizing the terminal to 2 lines we run into a segfault.
|
||||
|
||||
The problem is that for the source window:
|
||||
- the minimum height is 3 (the default), but
|
||||
- the maximum height is only 2 because there are only 2 lines.
|
||||
|
||||
This discrepancy eventually leads to a call to newwin in make_window with:
|
||||
...
|
||||
(gdb) p height
|
||||
$1 = 3
|
||||
(gdb) p width
|
||||
$2 = 56
|
||||
(gdb) p y
|
||||
$3 = -1
|
||||
(gdb) p x
|
||||
$4 = 0
|
||||
...
|
||||
which results in a nullptr.
|
||||
|
||||
This violates the assumption here in tui_apply_current_layout:
|
||||
....
|
||||
/* Get the new list of currently visible windows. */
|
||||
std::vector<tui_win_info *> new_tui_windows;
|
||||
applied_layout->get_windows (&new_tui_windows);
|
||||
...
|
||||
that get_windows only returns visible windows, which leads to tui_windows
|
||||
holding a dangling pointer, which results in the segfault.
|
||||
|
||||
Fix this by:
|
||||
- making sure get_windows only returns visible windows, and
|
||||
- detecting the situation and dropping windows from the layout if
|
||||
there's no room for them.
|
||||
|
||||
Tested on x86_64-linux.
|
||||
|
||||
PR tui/31044
|
||||
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31044
|
||||
---
|
||||
gdb/testsuite/gdb.tui/resize.exp | 9 +++++++++
|
||||
gdb/tui/tui-layout.c | 22 ++++++++++++++++++++--
|
||||
gdb/tui/tui-layout.h | 6 +++++-
|
||||
3 files changed, 34 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/gdb/testsuite/gdb.tui/resize.exp b/gdb/testsuite/gdb.tui/resize.exp
|
||||
index 60d5116886b..e15f8a2f507 100644
|
||||
--- a/gdb/testsuite/gdb.tui/resize.exp
|
||||
+++ b/gdb/testsuite/gdb.tui/resize.exp
|
||||
@@ -39,3 +39,12 @@ Term::check_contents "source at startup" "\\|.*21 *return 0"
|
||||
|
||||
Term::resize 40 90
|
||||
Term::check_box "source box after resize" 0 0 90 26
|
||||
+
|
||||
+# Check that resizing to less than 3 lines doesn't cause problems.
|
||||
+foreach lines { 2 1 } {
|
||||
+ with_test_prefix lines=$lines {
|
||||
+ Term::resize $lines 90 0
|
||||
+ Term::wait_for ""
|
||||
+ Term::check_region_contents "has prompt" 0 0 90 $lines "$gdb_prompt"
|
||||
+ }
|
||||
+}
|
||||
diff --git a/gdb/tui/tui-layout.c b/gdb/tui/tui-layout.c
|
||||
index 27abee02087..362c1447910 100644
|
||||
--- a/gdb/tui/tui-layout.c
|
||||
+++ b/gdb/tui/tui-layout.c
|
||||
@@ -442,6 +442,13 @@ tui_layout_window::apply (int x_, int y_, int width_, int height_,
|
||||
width = width_;
|
||||
height = height_;
|
||||
gdb_assert (m_window != nullptr);
|
||||
+ if (width == 0 || height == 0)
|
||||
+ {
|
||||
+ /* The window was dropped, so it's going to be deleted, reset the
|
||||
+ soon to be dangling pointer. */
|
||||
+ m_window = nullptr;
|
||||
+ return;
|
||||
+ }
|
||||
m_window->resize (height, width, x, y);
|
||||
}
|
||||
|
||||
@@ -823,6 +830,7 @@ tui_layout_split::apply (int x_, int y_, int width_, int height_,
|
||||
int available_size = m_vertical ? height : width;
|
||||
int last_index = -1;
|
||||
int total_weight = 0;
|
||||
+ int prev = -1;
|
||||
for (int i = 0; i < m_splits.size (); ++i)
|
||||
{
|
||||
bool cmd_win_already_exists = TUI_CMD_WIN != nullptr;
|
||||
@@ -854,6 +862,14 @@ tui_layout_split::apply (int x_, int y_, int width_, int height_,
|
||||
info[i].max_size = info[i].min_size;
|
||||
}
|
||||
|
||||
+ if (info[i].min_size > info[i].max_size)
|
||||
+ {
|
||||
+ /* There is not enough room for this window, drop it. */
|
||||
+ info[i].min_size = 0;
|
||||
+ info[i].max_size = 0;
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
if (info[i].min_size == info[i].max_size)
|
||||
available_size -= info[i].min_size;
|
||||
else
|
||||
@@ -864,10 +880,12 @@ tui_layout_split::apply (int x_, int y_, int width_, int height_,
|
||||
|
||||
/* Two adjacent boxed windows will share a border, making a bit
|
||||
more size available. */
|
||||
- if (i > 0
|
||||
- && m_splits[i - 1].layout->last_edge_has_border_p ()
|
||||
+ if (prev != -1
|
||||
+ && m_splits[prev].layout->last_edge_has_border_p ()
|
||||
&& m_splits[i].layout->first_edge_has_border_p ())
|
||||
info[i].share_box = true;
|
||||
+
|
||||
+ prev = i;
|
||||
}
|
||||
|
||||
/* If last_index is set then we have a window that is not of a fixed
|
||||
diff --git a/gdb/tui/tui-layout.h b/gdb/tui/tui-layout.h
|
||||
index 206f1117445..ec013a3f051 100644
|
||||
--- a/gdb/tui/tui-layout.h
|
||||
+++ b/gdb/tui/tui-layout.h
|
||||
@@ -185,7 +185,11 @@ class tui_layout_window : public tui_layout_base
|
||||
/* See tui_layout_base::get_windows. */
|
||||
void get_windows (std::vector<tui_win_info *> *windows) override
|
||||
{
|
||||
- windows->push_back (m_window);
|
||||
+ if (m_window != nullptr && m_window->is_visible ())
|
||||
+ {
|
||||
+ /* Only get visible windows. */
|
||||
+ windows->push_back (m_window);
|
||||
+ }
|
||||
}
|
||||
|
||||
protected:
|
||||
--
|
||||
2.35.3
|
||||
|
148
gdb-tui-fix-segfault-in-tui_find_disassembly_address.patch
Normal file
148
gdb-tui-fix-segfault-in-tui_find_disassembly_address.patch
Normal file
@ -0,0 +1,148 @@
|
||||
From 0f8f51e98c7f643b8ce32bc6f6d621ce902d7a66 Mon Sep 17 00:00:00 2001
|
||||
From: Tom de Vries <tdevries@suse.de>
|
||||
Date: Thu, 28 Sep 2023 20:17:33 +0200
|
||||
Subject: [PATCH 2/6] [gdb/tui] Fix segfault in tui_find_disassembly_address
|
||||
|
||||
PR29040 describes a FAIL for test-case gdb.threads/next-fork-other-thread.exp
|
||||
and target board unix/-m32.
|
||||
|
||||
The FAIL happens due to the test executable running into an assert, which is
|
||||
caused by a forked child segfaulting, like so:
|
||||
...
|
||||
Program terminated with signal SIGSEGV, Segmentation fault.
|
||||
#0 0x00000000 in ?? ()
|
||||
...
|
||||
|
||||
I tried to reproduce the segfault with exec next-fork-other-thread-fork, using
|
||||
TUI layout asm.
|
||||
|
||||
I set a breakpoint at fork and ran to the breakpoint, and somewhere during the
|
||||
following session I ran into a gdb segfault here in
|
||||
tui_find_disassembly_address:
|
||||
...
|
||||
/* Disassemble forward. */
|
||||
next_addr = tui_disassemble (gdbarch, asm_lines, new_low, max_lines);
|
||||
last_addr = asm_lines.back ().addr;
|
||||
...
|
||||
due to asm_lines being empty after the call to tui_disassemble, while
|
||||
asm_lines.back () assumes that it's not empty.
|
||||
|
||||
I have not been able to reproduce that segfault in that original setting, I'm
|
||||
not sure of the exact scenario (though looking back it probably involved
|
||||
"set detach-on-fork off").
|
||||
|
||||
What likely happened is that I managed to reproduce PR29040, and TUI (attempted
|
||||
to) display the disassembly for address 0, which led to the gdb segfault.
|
||||
|
||||
When gdb_print_insn encounters an insn it cannot print because it can't read
|
||||
the memory, it throws a MEMORY_ERROR that is caught by tui_disassemble.
|
||||
|
||||
The specific bit that causes the gdb segfault is that if gdb_print_insn throws
|
||||
a MEMORY_ERROR for the first insn in tui_disassemble, it returns an empty
|
||||
asm_lines.
|
||||
|
||||
FWIW, I did manage to reproduce the gdb segfault as follows:
|
||||
...
|
||||
$ gdb -q \
|
||||
-iex "set pagination off" \
|
||||
/usr/bin/rustc \
|
||||
-ex "set breakpoint pending on" \
|
||||
-ex "b dl_main" \
|
||||
-ex run \
|
||||
-ex "up 4" \
|
||||
-ex "layout asm" \
|
||||
-ex "print \$pc"
|
||||
...
|
||||
<TUI>
|
||||
...
|
||||
$1 = (void (*)()) 0x1
|
||||
(gdb)
|
||||
...
|
||||
Now press <up>, and the segfault triggers.
|
||||
|
||||
Fix the segfault by handling asm_lines.empty () results of tui_disassemble in
|
||||
tui_find_disassembly_address.
|
||||
|
||||
I've written a unit test that exercises this scenario.
|
||||
|
||||
Tested on x86_64-linux.
|
||||
|
||||
Reviewed-by: Kevin Buettner <kevinb@redhat.com>
|
||||
|
||||
PR tui/30823
|
||||
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30823
|
||||
---
|
||||
gdb/tui/tui-disasm.c | 39 +++++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 39 insertions(+)
|
||||
|
||||
diff --git a/gdb/tui/tui-disasm.c b/gdb/tui/tui-disasm.c
|
||||
index f0b55769d71..03c78aa1291 100644
|
||||
--- a/gdb/tui/tui-disasm.c
|
||||
+++ b/gdb/tui/tui-disasm.c
|
||||
@@ -41,6 +41,8 @@
|
||||
#include "objfiles.h"
|
||||
#include "cli/cli-style.h"
|
||||
#include "tui/tui-location.h"
|
||||
+#include "gdbsupport/selftest.h"
|
||||
+#include "inferior.h"
|
||||
|
||||
#include "gdb_curses.h"
|
||||
|
||||
@@ -203,6 +205,8 @@ tui_find_disassembly_address (struct gdbarch *gdbarch, CORE_ADDR pc, int from)
|
||||
instruction fails to disassemble we will take the address of the
|
||||
previous instruction that did disassemble as the result. */
|
||||
tui_disassemble (gdbarch, asm_lines, pc, max_lines + 1);
|
||||
+ if (asm_lines.empty ())
|
||||
+ return pc;
|
||||
new_low = asm_lines.back ().addr;
|
||||
}
|
||||
else
|
||||
@@ -244,6 +248,8 @@ tui_find_disassembly_address (struct gdbarch *gdbarch, CORE_ADDR pc, int from)
|
||||
|
||||
/* Disassemble forward. */
|
||||
next_addr = tui_disassemble (gdbarch, asm_lines, new_low, max_lines);
|
||||
+ if (asm_lines.empty ())
|
||||
+ break;
|
||||
last_addr = asm_lines.back ().addr;
|
||||
|
||||
/* If disassembling from the current value of NEW_LOW reached PC
|
||||
@@ -522,3 +528,36 @@ tui_disasm_window::display_start_addr (struct gdbarch **gdbarch_p,
|
||||
*gdbarch_p = m_gdbarch;
|
||||
*addr_p = m_start_line_or_addr.u.addr;
|
||||
}
|
||||
+
|
||||
+#if GDB_SELF_TEST
|
||||
+namespace selftests {
|
||||
+namespace tui {
|
||||
+namespace disasm {
|
||||
+
|
||||
+static void
|
||||
+run_tests ()
|
||||
+{
|
||||
+ if (current_inferior () != nullptr)
|
||||
+ {
|
||||
+ struct gdbarch *gdbarch = current_inferior ()->gdbarch;
|
||||
+
|
||||
+ /* Check that tui_find_disassembly_address robustly handles the case of
|
||||
+ being passed a PC for which gdb_print_insn throws a MEMORY_ERROR. */
|
||||
+ SELF_CHECK (tui_find_disassembly_address (gdbarch, 0, 1) == 0);
|
||||
+ SELF_CHECK (tui_find_disassembly_address (gdbarch, 0, -1) == 0);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+} /* namespace disasm */
|
||||
+} /* namespace tui */
|
||||
+} /* namespace selftests */
|
||||
+#endif /* GDB_SELF_TEST */
|
||||
+
|
||||
+void _initialize_tui_disasm ();
|
||||
+void
|
||||
+_initialize_tui_disasm ()
|
||||
+{
|
||||
+#if GDB_SELF_TEST
|
||||
+ selftests::register_test ("tui-disasm", selftests::tui::disasm::run_tests);
|
||||
+#endif
|
||||
+}
|
||||
--
|
||||
2.35.3
|
||||
|
57
gdb-tui-fix-wmaybe-uninitialized-in-tui_find_disasse.patch
Normal file
57
gdb-tui-fix-wmaybe-uninitialized-in-tui_find_disasse.patch
Normal file
@ -0,0 +1,57 @@
|
||||
From 0f2bdd8648e47e10334f8cc8e47b277d4064d0a2 Mon Sep 17 00:00:00 2001
|
||||
From: Tom de Vries <tdevries@suse.de>
|
||||
Date: Mon, 13 Nov 2023 09:31:20 +0100
|
||||
Subject: [PATCH 3/6] [gdb/tui] Fix Wmaybe-uninitialized in
|
||||
tui_find_disassembly_address
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
When building gdb with -O2, we run into:
|
||||
...
|
||||
gdb/tui/tui-disasm.c: In function ‘CORE_ADDR tui_find_disassembly_address \
|
||||
(gdbarch*, CORE_ADDR, int)’:
|
||||
gdb/tui/tui-disasm.c:293:7: warning: ‘last_addr’ may be used uninitialized \
|
||||
in this function [-Wmaybe-uninitialized]
|
||||
if (last_addr < pc)
|
||||
^~
|
||||
...
|
||||
|
||||
The warning triggers since commit 72535eb14bd ("[gdb/tui] Fix segfault in
|
||||
tui_find_disassembly_address").
|
||||
|
||||
Fix the warning by ensuring that last_addr is initialized at the point of
|
||||
use:
|
||||
...
|
||||
+ last_addr = asm_lines.back ().addr;
|
||||
if (last_addr < pc)
|
||||
...
|
||||
|
||||
Tested on x86_64-linux.
|
||||
---
|
||||
gdb/tui/tui-disasm.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/gdb/tui/tui-disasm.c b/gdb/tui/tui-disasm.c
|
||||
index 03c78aa1291..bbbc92c8183 100644
|
||||
--- a/gdb/tui/tui-disasm.c
|
||||
+++ b/gdb/tui/tui-disasm.c
|
||||
@@ -281,7 +281,6 @@ tui_find_disassembly_address (struct gdbarch *gdbarch, CORE_ADDR pc, int from)
|
||||
/* Take the best possible match we have. */
|
||||
new_low = *possible_new_low;
|
||||
next_addr = tui_disassemble (gdbarch, asm_lines, new_low, max_lines);
|
||||
- last_addr = asm_lines.back ().addr;
|
||||
gdb_assert (asm_lines.size () >= max_lines);
|
||||
}
|
||||
|
||||
@@ -290,6 +289,7 @@ tui_find_disassembly_address (struct gdbarch *gdbarch, CORE_ADDR pc, int from)
|
||||
We keep the disassembled instructions in the 'lines' window
|
||||
and shift it downward (increasing its addresses). */
|
||||
int pos = max_lines - 1;
|
||||
+ last_addr = asm_lines.back ().addr;
|
||||
if (last_addr < pc)
|
||||
do
|
||||
{
|
||||
--
|
||||
2.35.3
|
||||
|
20
gdb.changes
20
gdb.changes
@ -1,3 +1,23 @@
|
||||
-------------------------------------------------------------------
|
||||
Tue Oct 31 11:59:43 UTC 2023 - Tom de Vries <tdevries@suse.com>
|
||||
|
||||
- Maintenance script qa.sh:
|
||||
* Update PR28561 kfail.
|
||||
* Remove PR31015 kfail.
|
||||
* Remove PR30547 kfail.
|
||||
- Patches added (backport from master):
|
||||
* gdb-symtab-add-producer_is_gas.patch
|
||||
* gdb-symtab-work-around-gas-pr28629.patch
|
||||
* gdb-tdep-fix-nr-array-elements-in-ppc64_aggregate_ca.patch
|
||||
* gdb-testsuite-fix-gdb.python-py-breakpoint.exp-with-.patch
|
||||
* gdb-tui-fix-segfault-in-tui_find_disassembly_address.patch
|
||||
* gdb-tui-fix-wmaybe-uninitialized-in-tui_find_disasse.patch
|
||||
* gdb-testsuite-add-wait_for_msg-arg-to-term-resize-fi.patch
|
||||
- Patches added (backport from gdb-patches):
|
||||
* gdb-fix-segfault-in-for_each_block-part-2.patch
|
||||
* gdb-tui-allow-command-window-of-1-or-2-lines.patch
|
||||
* gdb-tui-fix-resizing-of-terminal-to-1-or-2-lines.patch
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Tue Oct 31 09:02:42 UTC 2023 - Tom de Vries <tdevries@suse.com>
|
||||
|
||||
|
24
gdb.spec
24
gdb.spec
@ -337,10 +337,18 @@ Patch2043: gdb-go-handle-v3-go_0-mangled-prefix.patch
|
||||
Patch2044: gdb-symtab-handle-self-reference-die.patch
|
||||
Patch2045: gdb-symtab-handle-self-reference-in-inherit_abstract.patch
|
||||
Patch2046: gdb-symtab-add-optimized-out-static-var-to-cooked-in.patch
|
||||
Patch2047: gdb-testsuite-fix-gdb.python-py-breakpoint.exp-with-.patch
|
||||
Patch2048: gdb-tui-fix-segfault-in-tui_find_disassembly_address.patch
|
||||
# Part of upstream commit deb1ba4e38b ("[gdb/tui] Fix TUI resizing for TERM=ansi").
|
||||
Patch2049: gdb-testsuite-add-wait_for_msg-arg-to-term-resize-fi.patch
|
||||
|
||||
# Backports from master, not yet available in next release.
|
||||
|
||||
Patch2070: gdb-symtab-work-around-pr-gas-29517.patch
|
||||
Patch2071: gdb-symtab-add-producer_is_gas.patch
|
||||
Patch2072: gdb-symtab-work-around-gas-pr28629.patch
|
||||
Patch2073: gdb-tdep-fix-nr-array-elements-in-ppc64_aggregate_ca.patch
|
||||
Patch2074: gdb-tui-fix-wmaybe-uninitialized-in-tui_find_disasse.patch
|
||||
|
||||
# Backport from gdb-patches
|
||||
|
||||
@ -352,6 +360,12 @@ Patch2101: gdb-testsuite-prevent-compilation-fails-with-unix-fpie-pie.patch
|
||||
Patch2104: gdb-testsuite-work-around-skip_prologue-problems-in-gdb.threads-process-dies-while-detaching.exp.patch
|
||||
# https://sourceware.org/pipermail/gdb-patches/2021-May/178990.html
|
||||
Patch2105: gdb-cli-add-ignore-errors-command.patch
|
||||
# https://sourceware.org/pipermail/gdb-patches/2023-November/203942.html
|
||||
Patch2106: gdb-fix-segfault-in-for_each_block-part-2.patch
|
||||
# https://sourceware.org/pipermail/gdb-patches/2023-November/203928.html
|
||||
Patch2107: gdb-tui-allow-command-window-of-1-or-2-lines.patch
|
||||
# https://sourceware.org/pipermail/gdb-patches/2023-November/203929.html
|
||||
Patch2108: gdb-tui-fix-resizing-of-terminal-to-1-or-2-lines.patch
|
||||
|
||||
# Debug patches.
|
||||
|
||||
@ -779,13 +793,23 @@ find -name "*.info*"|xargs rm -f
|
||||
%patch2044 -p1
|
||||
%patch2045 -p1
|
||||
%patch2046 -p1
|
||||
%patch2047 -p1
|
||||
%patch2048 -p1
|
||||
%patch2049 -p1
|
||||
|
||||
%patch2070 -p1
|
||||
%patch2071 -p1
|
||||
%patch2072 -p1
|
||||
%patch2073 -p1
|
||||
%patch2074 -p1
|
||||
|
||||
%patch2100 -p1
|
||||
%patch2101 -p1
|
||||
%patch2104 -p1
|
||||
%patch2105 -p1
|
||||
%patch2106 -p1
|
||||
%patch2107 -p1
|
||||
%patch2108 -p1
|
||||
|
||||
#unpack libipt
|
||||
%if 0%{have_libipt}
|
||||
|
10
qa.sh
10
qa.sh
@ -512,14 +512,12 @@ kfail_aarch64=(
|
||||
"FAIL: gdb.python/py-mi-.*.exp:"
|
||||
"FAIL: gdb.ada/mi.*.exp:"
|
||||
"FAIL: gdb.base/annota.*.exp:"
|
||||
|
||||
"FAIL: gdb.dwarf2/dw2-opt-structptr.exp: mi"
|
||||
|
||||
) # kfail_aarch64
|
||||
|
||||
kfail_powerpc64le=(
|
||||
|
||||
# https://sourceware.org/bugzilla/show_bug.cgi?id=31015
|
||||
"FAIL: gdb.ada/array_return.exp: value printed by finish of Create_Small_Float_Vector"
|
||||
|
||||
# https://sourceware.org/bugzilla/show_bug.cgi?id=29792
|
||||
"FAIL: gdb.opt/solib-intra-step.exp: second-hit"
|
||||
|
||||
@ -712,10 +710,6 @@ case $n in
|
||||
"UNRESOLVED: gdb.base/gcore-excessive-memory.exp: attach"
|
||||
"UNRESOLVED: gdb.base/gcore-excessive-memory.exp: verify we can get to main"
|
||||
|
||||
# https://sourceware.org/bugzilla/show_bug.cgi?id=30547
|
||||
"UNRESOLVED: gdb.base/vfork-follow-parent.exp: resolution_method=schedule-multiple: print unblock_parent = 1"
|
||||
"UNRESOLVED: gdb.base/vfork-follow-parent.exp: resolution_method=schedule-multiple: continue to break_parent"
|
||||
|
||||
# https://sourceware.org/bugzilla/show_bug.cgi?id=31001
|
||||
"UNRESOLVED: gdb.threads/async.exp: thread 1: current thread is 1"
|
||||
)
|
||||
|
Loading…
x
Reference in New Issue
Block a user