From: Tom de Vries <tdevries@suse.de>
To: gdb-patches@sourceware.org
Subject: [PATCH v4 10/11] [gdb] Don't stop disassembly at section hole
Date: Wed, 7 Oct 2026 11:40:56 +0200 [thread overview]
Message-ID: <20261007094057.1811886-11-tdevries@suse.de> (raw)
In-Reply-To: <20261007094057.1811886-1-tdevries@suse.de>
Consider the following session:
...
$ gdb -q -batch a.out -ex "disassemble _init,0x0000000000401030"
Dump of assembler code from 0x401000 to 0x401030:
...
0x000000000040101a <_init+26>: ret
0x000000000040101b:
Cannot access memory at address 0x40101b
...
If we disassemble with objdump instead, we get:
...
Disassembly of section .init:
0000000000401000 <_init>:
...
40101a: c3 ret
Disassembly of section .plt:
0000000000401020 <puts@plt-0x10>:
401020: ff 35 ca 2f 00 00 push 0x2fca(%rip)
401026: ff 25 cc 2f 00 00 jmp *0x2fcc(%rip)
40102c: 0f 1f 40 00 nopl 0x0(%rax)
...
The disassembling stops at the section hole, when running into a memory error.
Fix this by if necessary skipping over the section hole.
This also fixes the paradoxical situation reported in PR34399 where it's
possible to scroll forward into a section hole, but not back out of it.
Without the "Fix buglet in tui_find_disassembly_address" patch in this series,
this patch regresses as follows:
...
FAIL: gdb.tui/tui-layout-asm-short-prog.exp: check first line is back
...
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=34399
---
gdb/disasm.c | 44 ++++++++++++++++++++++++++++++++++++++++++--
gdb/disasm.h | 8 ++++++++
gdb/tui/tui-disasm.c | 42 ++++++++++++++++++++++++++++++++----------
3 files changed, 82 insertions(+), 12 deletions(-)
diff --git a/gdb/disasm.c b/gdb/disasm.c
index 23d0c880777..e847e3ee0ff 100644
--- a/gdb/disasm.c
+++ b/gdb/disasm.c
@@ -1185,6 +1185,37 @@ gdb_disassembly_1 (struct gdbarch *gdbarch, struct ui_out *uiout,
/* See disasm.h. */
+bool
+disassemble_section_p (addrmap_mutable &map,
+ struct obj_section *s, CORE_ADDR range_low,
+ CORE_ADDR range_high)
+{
+ if (s == nullptr)
+ {
+ struct obj_section *prev = (range_low == 0
+ ? nullptr
+ : (obj_section *)map.find (range_low - 1));
+ struct obj_section *next = (range_high == (CORE_ADDR)-1
+ ? nullptr
+ : (obj_section *)map.find (range_high + 1));
+ bool section_hole
+ = (prev != nullptr && next != nullptr
+ && prev->objfile == next->objfile);
+ if (section_hole)
+ {
+ /* Don't disassemble if it would trigger a memory error. */
+ return target_has_registers ();
+ }
+
+ /* Random memory not in a section; might contain JIT-ed instructions. */
+ return true;
+ }
+
+ return true;
+}
+
+/* See disasm.h. */
+
int
gdb_disassembly (struct gdbarch *gdbarch, struct ui_out *uiout,
gdb_disassembly_flags flags, int how_many,
@@ -1197,8 +1228,17 @@ gdb_disassembly (struct gdbarch *gdbarch, struct ui_out *uiout,
{
CORE_ADDR tmp_high = high;
- CORE_ADDR range_high;
- map->find (low, nullptr, &range_high);
+ CORE_ADDR range_low, range_high;
+ struct obj_section *s
+ = (obj_section *)map->find (low, &range_low, &range_high);
+ if (!disassemble_section_p (*map, s, range_low, range_high))
+ {
+ if (range_high == (CORE_ADDR)-1)
+ break;
+
+ low = range_high + 1;
+ continue;
+ }
/* Don't disassemble past a section change. */
if (range_high != (CORE_ADDR)-1)
diff --git a/gdb/disasm.h b/gdb/disasm.h
index 9109dbf0a79..0366de8f673 100644
--- a/gdb/disasm.h
+++ b/gdb/disasm.h
@@ -26,6 +26,7 @@
struct gdbarch;
struct ui_out;
struct ui_file;
+struct addrmap_mutable;
/* A wrapper around a disassemble_info and a gdbarch. This is the core
set of data that all disassembler sub-classes will need. This class
@@ -323,6 +324,13 @@ struct disasm_insn
unsigned int is_speculative:1;
};
+/* Return true if memory in [RANGE_LOW, RANGE_HIGH] should be disassembled.
+ S is either the corresponding section, or nullptr if the range doesn't
+ match a section. */
+
+extern bool disassemble_section_p (addrmap_mutable &map, struct obj_section *s,
+ CORE_ADDR range_low, CORE_ADDR range_high);
+
/* Print at most HOW_MANY instructions of the instruction stream at
[LOW, HIGH) on UIOUT using FLAGS. Return the number of the instructions
printed. */
diff --git a/gdb/tui/tui-disasm.c b/gdb/tui/tui-disasm.c
index ba11b8e8188..09136b6fc60 100644
--- a/gdb/tui/tui-disasm.c
+++ b/gdb/tui/tui-disasm.c
@@ -179,8 +179,17 @@ tui_disassemble (struct gdbarch *gdbarch,
while (count > 0)
{
- CORE_ADDR range_high;
- map.find (pc, nullptr, &range_high);
+ CORE_ADDR range_low, range_high;
+ struct obj_section *s
+ = (struct obj_section *)map.find (pc, &range_low, &range_high);
+ if (!disassemble_section_p (map, s, range_low, range_high))
+ {
+ if (range_high == (CORE_ADDR)-1)
+ break;
+
+ pc = range_high + 1;
+ continue;
+ }
/* Don't disassemble past a section change. */
std::optional<CORE_ADDR> high_pc;
@@ -206,17 +215,34 @@ tui_disassemble (struct gdbarch *gdbarch,
addresses, or the start of a section. */
static CORE_ADDR
-tui_find_backward_disassembly_start_address (CORE_ADDR addr)
+tui_find_backward_disassembly_start_address (addrmap_mutable &map, CORE_ADDR addr)
{
if (addr == 0)
{
/* We cannot go backwards from zero. */
return addr;
}
+ CORE_ADDR search_addr = addr - 1;
+
+ struct obj_section *s = nullptr;
+ CORE_ADDR range_low, range_high;
+ while (true)
+ {
+ s = (struct obj_section *)map.find (search_addr, &range_low,
+ &range_high);
+
+ if (disassemble_section_p (map, s, range_low, range_high))
+ break;
+
+ if (range_low == 0)
+ return addr;
+
+ search_addr = range_low - 1;
+ }
bound_minimal_symbol msym_prev;
bound_minimal_symbol msym
- = lookup_minimal_symbol_by_pc_section (addr - 1, nullptr,
+ = lookup_minimal_symbol_by_pc_section (search_addr, nullptr,
lookup_msym_prefer::TEXT,
&msym_prev);
if (msym.minsym != nullptr)
@@ -226,11 +252,7 @@ tui_find_backward_disassembly_start_address (CORE_ADDR addr)
/* Find the first section with start address before ADDR, and use its start
address. */
- struct obj_section *section = find_pc_section (addr - 1);
- if (section != NULL)
- return section->addr ();
-
- return addr;
+ return range_low;
}
/* Find the disassembly address that corresponds to FROM lines above
@@ -292,7 +314,7 @@ tui_find_disassembly_address (struct gdbarch *gdbarch, CORE_ADDR pc, int from)
CORE_ADDR prev_low = new_low;
/* Find an address from which we can start disassembling. */
- new_low = tui_find_backward_disassembly_start_address (new_low);
+ new_low = tui_find_backward_disassembly_start_address (*map, new_low);
if (new_low == prev_low)
break;
--
2.51.0
next prev parent reply other threads:[~2026-10-07 9:43 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-07 9:40 [PATCH v4 00/11] [gdb/tui] Some section hole handling fixes Tom de Vries
2026-10-07 9:40 ` [PATCH v4 01/11] [gdb/tui] Use early exit in tui_find_disassembly_address Tom de Vries
2026-10-07 9:40 ` [PATCH v4 02/11] [gdb/tui] Make low_prev loop-local " Tom de Vries
2026-10-07 9:40 ` [PATCH v4 03/11] [gdb/tui] Disassemble less often " Tom de Vries
2026-10-07 9:40 ` [PATCH v4 04/11] [gdb/tui] Fix buglet " Tom de Vries
2026-10-07 9:40 ` [PATCH v4 05/11] [gdb] Factor out update_section_map Tom de Vries
2026-10-07 9:40 ` [PATCH v4 06/11] [gdb] Add section_addrmap Tom de Vries
2026-10-07 9:40 ` [PATCH v4 07/11] [gdb] Extend addrmap::find with low/high results Tom de Vries
2026-10-07 9:40 ` [PATCH v4 08/11] [gdb] Make gdb_disassembly return number of insns Tom de Vries
2026-10-07 9:40 ` [PATCH v4 09/11] [gdb] Handle sections when disassembling Tom de Vries
2026-10-07 9:40 ` Tom de Vries [this message]
2026-10-07 9:40 ` [PATCH v4 11/11] [RFC, gdb/tui] Don't scroll into non-code sections Tom de Vries
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261007094057.1811886-11-tdevries@suse.de \
--to=tdevries@suse.de \
--cc=gdb-patches@sourceware.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox