public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
From: Jan Vrany <jan.vrany@labware.com>
To: Pedro Alves <pedro@palves.net>, gdb-patches@sourceware.org
Subject: Re: [PATCH] gdb: skip objfiles with no BFD in DWARF unwinder
Date: Wed, 06 Apr 2022 20:06:36 +0200	[thread overview]
Message-ID: <168fefbb3b9e83ebf75c126e2724912be42332cd.camel@labware.com> (raw)
In-Reply-To: <7b267fea-452e-446e-3800-1cbacd50b689@palves.net>

On Tue, 2022-04-05 at 20:08 +0100, Pedro Alves wrote:
> On 2022-04-05 11:04, Jan Vrany via Gdb-patches wrote:
> > While playing with JIT reader I experienced GDB to crash on null-pointer
> > dereference when stepping through non-jitted code.
> > 
> > The problem was that dwarf2_frame_find_fde () assumed that all objfiles
> > have BFD but that's not always true. To address this problem, this
> > commit skips such objfiles.
> > 
> > As for the test, I initially tried to use temporary breakpoint and then
> > 'continue' to get out of the jitted code but this for some reason did
> > not trigger the crash. Using 'finish' to get out of jitted code followed
> > by 'next' triggered it.
> 
> I tried it here and here's what I saw.  So "next" is stepping over the
> "function_add" function.  While "next"ing, GDB stops at the first instruction of
> function_add, and looks at the frame's type, which runs all the frame sniffers
> looking for one that claims the frame, including the DWARF unwinder, and here is
> where we run into the crash:
> 
> $ gdb ...
> (gdb) start
> ...
> Temporary breakpoint 1, main (argc=1, argv=0x7fffffffdc08) at /home/pedro/gdb/binutils-gdb/src/gdb/testsuite/gdb.base/jit-reader-host.c:58
> 58        struct jithost_abi *symfile = malloc (sizeof (struct jithost_abi));
> (gdb) jit-reader-load /home/pedro/gdb/binutils-gdb/build/gdb/testsuite/outputs/gdb.base/jit-reader/jit-reader.so
> (gdb) b 95
> Breakpoint 2 at 0x555555555322: file /home/pedro/gdb/binutils-gdb/src/gdb/testsuite/gdb.base/jit-reader-host.c, line 95.
> (gdb) c
> Continuing.
> 
> Program received signal SIGTRAP, Trace/breakpoint trap.
> 0x00007ffff7ffb001 in jit_function_stack_mangle ()
> (gdb) c
> Continuing.
> 
> Breakpoint 2, main (argc=1, argv=0x7fffffffdc08) at /home/pedro/gdb/binutils-gdb/src/gdb/testsuite/gdb.base/jit-reader-host.c:95
> 95        function_add (5, 6);
> (gdb) set debug infrun 1
> (gdb) n
> 
>   ...
>   [infrun] start_step_over: exit
>   [infrun] context_switch: Switching context from 0.0.0 to 353387.353387.0
>   [infrun] handle_signal_stop: stop_pc=0x7ffff7ffb00a
>   ...
> 
> 
> Thread 1 "gdb" received signal SIGSEGV, Segmentation fault.
> 0x00005555559886c8 in bfd_usrdata (abfd=0x0) at ../bfd/bfd.h:6919
> 6919      return abfd->usrdata;
> (top-gdb) bt
> #0  0x00005555559886c8 in bfd_usrdata (abfd=0x0) at ../bfd/bfd.h:6919
> #1  0x000055555598a65f in gdb_bfd_requires_relocations (abfd=0x0) at /home/pedro/gdb/binutils-gdb/src/gdb/gdb_bfd.c:1030
> #2  0x0000555555885dbb in find_comp_unit (objfile=0x5555565a6170) at /home/pedro/gdb/binutils-gdb/src/gdb/dwarf2/frame.c:1538
> #3  0x0000555555885efa in dwarf2_frame_find_fde (pc=0x7fffffffd008, out_per_objfile=0x0) at /home/pedro/gdb/binutils-gdb/src/gdb/dwarf2/frame.c:1568
> #4  0x0000555555885591 in dwarf2_frame_sniffer (self=0x555556426440 <dwarf2_frame_unwind>, this_frame=0x555556d6b7f0, this_cache=0x555556d6b808) at /home/pedro/gdb/binutils-gdb/src/gdb/dwarf2/frame.c:1254
> #5  0x0000555555979639 in frame_unwind_try_unwinder (this_frame=0x555556d6b7f0, this_cache=0x555556d6b808, unwinder=0x555556426440 <dwarf2_frame_unwind>) at /home/pedro/gdb/binutils-gdb/src/gdb/frame-unwind.c:131
> #6  0x000055555597991a in frame_unwind_find_by_frame (this_frame=0x555556d6b7f0, this_cache=0x555556d6b808) at /home/pedro/gdb/binutils-gdb/src/gdb/frame-unwind.c:203
> #7  0x0000555555980948 in get_frame_type (frame=0x555556d6b7f0) at /home/pedro/gdb/binutils-gdb/src/gdb/frame.c:2817
> #8  0x0000555555a2187b in process_event_stop_test (ecs=0x7fffffffd7c0) at /home/pedro/gdb/binutils-gdb/src/gdb/infrun.c:6966
> #9  0x0000555555a20b3f in handle_signal_stop (ecs=0x7fffffffd7c0) at /home/pedro/gdb/binutils-gdb/src/gdb/infrun.c:6585
> #10 0x0000555555a1ec37 in handle_inferior_event (ecs=0x7fffffffd7c0) at /home/pedro/gdb/binutils-gdb/src/gdb/infrun.c:5837
> ...
> 
> That get_frame_type call is from here:
> 
> 6963      if (ecs->event_thread->control.step_range_end != 1
> 6964          && (ecs->event_thread->control.step_over_calls == STEP_OVER_UNDEBUGGABLE
> 6965              || ecs->event_thread->control.step_over_calls == STEP_OVER_ALL)
> 6966          && get_frame_type (frame) == SIGTRAMP_FRAME)
> 6967        {
> 6968          infrun_debug_printf ("stepped into signal trampoline");
> 
> 
> 
> OK, that makes sense.  We stopped at 0x7ffff7ffb00a, which is function_add, and GDB tried to get info
> about the current frame.  
> 
> This means that we can write a more targeted testcase that does not rely on how "next" works.
> What is important is that we trigger the unwinding machinery inside the "function_add" function.
> 
Ah, I see now why I was puzzled why it did not work for me. The important bit (which I missed) is
that in the test the JIT reader unwinder does not unwind function_add, *only* jit_function_stack_mangle,
so it falls to back DWARF unwinder which then hit the objfile with no BFD. If I stop in main, it would
likely find an objfile for the PC before hitting the JIT objfile so it won't trigger the crash. Thanks! 

I'll send v2 with updated testcase and commit message shortly.

> So...
> 
> (gdb) jit-reader-load /home/pedro/gdb/binutils-gdb/build/gdb/testsuite/outputs/gdb.base/jit-reader/jit-reader.so
> (gdb) b 95
> Breakpoint 1 at 0x1322: file /home/pedro/gdb/binutils-gdb/src/gdb/testsuite/gdb.base/jit-reader-host.c, line 95.
> (gdb) r
> Starting program: /home/pedro/gdb/binutils-gdb/build/gdb/testsuite/outputs/gdb.base/jit-reader/jit-reader 
> 
> Program received signal SIGTRAP, Trace/breakpoint trap.
> 0x00007ffff7ffb001 in jit_function_stack_mangle ()
> (gdb) c
> Continuing.
> 
> Breakpoint 1, main (argc=1, argv=0x7fffffffdc08) at /home/pedro/gdb/binutils-gdb/src/gdb/testsuite/gdb.base/jit-reader-host.c:95
> 95        function_add (5, 6);
> (gdb) b *function_add
> Breakpoint 2 at 0x7ffff7ffb00a
> (gdb) c
> Continuing.
> 
> Thread 1 "gdb" received signal SIGSEGV, Segmentation fault.
> 0x00005555559886c8 in bfd_usrdata (During symbol reading: incomplete CFI data; unspecified registers (e.g., rax) at 0x5555559886d0
> abfd=0x0) at ../bfd/bfd.h:6919
> 6919      return abfd->usrdata;
> (top-gdb) 
> 
> 
> So in a nutshell, it would be better for the test to do:
> 
>  fin
>  b *function_add
>  c       << this crashes as GDB prints the current frame
>  bt      << add this for good measure.
> 
> Instead of:
> 
>  fin
>  bt    << not clear what this is for
>  next  << reaches the unwinder today, triggering the crash, but who knows the future


  reply	other threads:[~2022-04-06 18:06 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-04-05 10:04 Jan Vrany
2022-04-05 14:19 ` Lancelot SIX
2022-04-05 14:46 ` Simon Marchi
2022-04-06 17:50   ` Jan Vrany
2022-04-05 19:08 ` Pedro Alves
2022-04-06 18:06   ` Jan Vrany [this message]
2022-04-06 18:55   ` [PATCH v2] " Jan Vrany
2022-12-07 11:07     ` Jan Vraný
2022-12-07 16:07     ` Simon Marchi

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=168fefbb3b9e83ebf75c126e2724912be42332cd.camel@labware.com \
    --to=jan.vrany@labware.com \
    --cc=gdb-patches@sourceware.org \
    --cc=pedro@palves.net \
    /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;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).