[binutils-gdb] gdb: z80: Guard against missing symtab in skip_prologue

Simon Marchi via Gdb-cvs <[email protected]> Thu, 4 Jun 2026 19:48:27 +0000 (GMT)
Newsgroups gmane.comp.gdb.cvs
Message-ID <[email protected]>
https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=f08f36984176d9f22345b19f5c4fbe52f699a83f

commit f08f36984176d9f22345b19f5c4fbe52f699a83f
Author: Simon Marchi <[email protected]>
Date:   Thu Jun 4 15:46:48 2026 -0400

    gdb: z80: Guard against missing symtab in skip_prologue
    
    With a Z80 ELF binary, "break main" crashes GDB internally.
    "break *main" works.
    
    The crash happens in z80_skip_prologue after find_sal_for_pc returns
    a symtab_and_line whose symtab is NULL.  The code unconditionally calls:
    
      prologue_sal.symtab->compunit()->debugformat()
    
    ----- Backtrace -----
    0x6385f3c7fc41 gdb_internal_backtrace_1
            ../../gdb/bt-utils.c:122
    0x6385f3c7fc41 _Z22gdb_internal_backtracev
            ../../gdb/bt-utils.c:173
    0x6385f3dd2313 handle_fatal_signal
            ../../gdb/event-top.c:1008
    0x6385f3dd28b9 handle_sigsegv
            ../../gdb/event-top.c:1085
    0x757e7704532f ???
            ./signal/../sysdeps/unix/sysv/linux/x86_64/libc_sigaction.c:0
    0x6385f40f8207 _ZNK15compunit_symtab11debugformatEv
            ../../gdb/symtab.h:1857
    0x6385f40f8207 z80_skip_prologue
            ../../gdb/z80-tdep.c:499
    0x6385f3c250bc _Z30gdbarch_skip_prologue_noexceptP7gdbarchm
            ../../gdb/arch-utils.c:1046
    0x6385f3ff46f5 _Z17skip_prologue_salP15symtab_and_line
            ../../gdb/symtab.c:3765
    0x6385f3ff4bba find_function_start_sal_1
            ../../gdb/symtab.c:3538
    0x6385f3ff4c83 _Z23find_function_start_salmP11obj_sectionb
            ../../gdb/symtab.c:3549
    0x6385f3e73c9e minsym_found
            ../../gdb/linespec.c:4078
    0x6385f3e73c9e convert_linespec_to_sals
            ../../gdb/linespec.c:2290
    0x6385f3e755f8 parse_linespec
            ../../gdb/linespec.c:2655
    0x6385f3e76d35 location_spec_to_sals
            ../../gdb/linespec.c:3053
    0x6385f3e771b0 _Z16decode_line_fullP13location_speciP13program_spaceP6symtabiP15linespec_resultPKcS8_
            ../../gdb/linespec.c:3129
    0x6385f3c671d3 parse_breakpoint_sals
            ../../gdb/breakpoint.c:9084
    0x6385f3c6b490 _Z17create_breakpointP7gdbarchP13location_specPKciiS4_bii6bptypei12auto_booleanPK14breakpoint_opsiiij
            ../../gdb/breakpoint.c:9319
    0x6385f3c6be42 break_command_1
            ../../gdb/breakpoint.c:9478
    0x6385f3cbe834 _Z8cmd_funcP16cmd_list_elementPKci
            ../../gdb/cli/cli-decode.c:2810
    0x6385f4047c44 _Z15execute_commandPKci
            ../../gdb/top.c:632
    0x6385f3dd3158 _Z15command_handlerPKc
            ../../gdb/event-top.c:611
    0x6385f3dd4b60 _Z20command_line_handlerOSt10unique_ptrIcN3gdb13xfree_deleterIcEEE
            ../../gdb/event-top.c:844
    0x6385f3dd3d74 gdb_rl_callback_handler
            ../../gdb/event-top.c:288
    0x6385f41173e8 rl_callback_read_char
            ../../../readline/readline/callback.c:302
    0x6385f3dd3eed gdb_rl_callback_read_char_wrapper_sjlj
            ../../gdb/event-top.c:197
    0x6385f3dd40b3 gdb_rl_callback_read_char_wrapper_noexcept
            ../../gdb/event-top.c:240
    0x6385f3dd40b3 gdb_rl_callback_read_char_wrapper
            ../../gdb/event-top.c:252
    0x6385f4085c8f stdin_event_handler
            ../../gdb/ui.c:161
    0x6385f41d7f85 gdb_wait_for_event
            ../../gdbsupport/event-loop.cc:694
    0x6385f41d87e1 _Z16gdb_do_one_eventi
            ../../gdbsupport/event-loop.cc:263
    0x6385f3e8be39 _ZN6interp12do_one_eventEi
            ../../gdb/interps.h:90
    0x6385f3e8be39 start_event_loop
            ../../gdb/main.c:400
    0x6385f3e8be39 captured_command_loop
            ../../gdb/main.c:465
    0x6385f3e8e2c4 captured_main
            ../../gdb/main.c:1373
    0x6385f3e8e2c4 _Z8gdb_mainP18captured_main_args
            ../../gdb/main.c:1392
    0x6385f3bbf5bb main
            ../../gdb/gdb.c:38
    ---------------------
    A fatal error internal to GDB has been detected, further
    debugging is not possible.  GDB will now terminate.
    
    How to reproduce:
      z80-...-gdb hello.elf
      (gdb) break main
    
    Expected:
    GDB should either set the breakpoint or fall back gracefully.
    
    Actual:
    GDB terminates with an internal segmentation fault.
    
    Tested fix:
    Adding null check for prologue_sal.symtab prevents the crash.
    
    Change-Id: Iaaf0e1602127de08b85b3ed18e3c4877c89b8efd
    Approved-By: Simon Marchi <[email protected]>

Diff:
---
 gdb/z80-tdep.c | 14 +++++++++-----
 1 file changed, 9 insertions(+), 5 deletions(-)

diff --git a/gdb/z80-tdep.c b/gdb/z80-tdep.c
index f7e207d02ec..3a0d5f7e393 100644
--- a/gdb/z80-tdep.c
+++ b/gdb/z80-tdep.c
@@ -495,12 +495,16 @@ z80_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
   if (prologue_end != 0)
     {
       struct symtab_and_line prologue_sal = find_sal_for_pc (func_addr, 0);
-      struct compunit_symtab *compunit = prologue_sal.symtab->compunit ();
-      const char *debug_format = compunit->debugformat ();
 
-      if (debug_format != NULL &&
-	  !strncasecmp ("dwarf", debug_format, strlen("dwarf")))
-	return std::max (pc, prologue_end);
+      if (prologue_sal.symtab != nullptr)
+	{
+	  struct compunit_symtab *compunit = prologue_sal.symtab->compunit ();
+	  const char *debug_format = compunit->debugformat ();
+
+	  if (debug_format != nullptr
+	      && !strncasecmp ("dwarf", debug_format, strlen ("dwarf")))
+	    return std::max (pc, prologue_end);
+	}
     }
 
   return pc;