From: "Metzger, Markus T" <markus.t.metzger@intel.com>
To: Pedro Alves <palves@redhat.com>
Cc: "gdb-patches@sourceware.org" <gdb-patches@sourceware.org>
Subject: RE: [PATCH v2 3/3] btrace, frame: fix crash in get_frame_type
Date: Wed, 10 Feb 2016 10:29:00 -0000 [thread overview]
Message-ID: <A78C989F6D9628469189715575E55B233325FFC6@IRSMSX104.ger.corp.intel.com> (raw)
In-Reply-To: <56BB0A0D.80502@redhat.com>
> -----Original Message-----
> From: Pedro Alves [mailto:palves@redhat.com]
> Sent: Wednesday, February 10, 2016 11:00 AM
> To: Metzger, Markus T <markus.t.metzger@intel.com>
> Cc: gdb-patches@sourceware.org
> Subject: Re: [PATCH v2 3/3] btrace, frame: fix crash in get_frame_type
> >>>>> CORE_ADDR frame_unwind_pc (struct frame_info *this_frame) {
> >>>>> + if (this_frame == NULL)
> >>>>> + throw_error (NOT_AVAILABLE_ERROR, _("PC not available"));
> >>>>
> >>>> How can this happen?
> >>>
> >>> One of its callers, frame_unwind_caller_pc, calls it with the result
> >>> of skip_artificial_frames like this:
> >>>
> >>> CORE_ADDR
> >>> frame_unwind_caller_pc (struct frame_info *this_frame) {
> >>> return frame_unwind_pc (skip_artificial_frames (this_frame)); }
> >>>
> >>> Rather than handling the skip_artificial_frames() NULL return here,
> >>> I made frame_unwind_pc handle a NULL frame argument.
> >>>
> >>> I can move the check into frame_unwind_caller_pc if you prefer.
> >>
> >> Yes, please.
> >>
> >> Though, I think all these frame_unwind_caller_XXX methods should be
> >> consistent in how they handle skip_artificial_frames (this_frame)
> >> returning NULL, because they're all called together, assuming they're
> >> referring to the same frame. If we throw error here, then I think we
> >> should throw in frame_unwind_caller_arch too, instead of having that
> >> one return the arch of the next frame.
> >
> > get_frame_arch and frame_unwind_arch don't seem to throw any error
> today.
>
> Because they assume there is always a prev frame.
>
> The case under discussion is different, it's about getting at the "real caller
> frame". Something has to change.
>
> > I'd rather not introduce new exceptions if not strictly necessary.
> > Its callers may not be prepared to handle them.
>
> Callers shouldn't be handed back potentially bogus results. If there's no
> return that makes sense, then throw and let the callers handle it (or don't
> handle it and let the user know what she tried to do doesn't make sense), or
> internal-error.
>
> >
> > In the absence of an arch unwinder, frame_unwind_arch uses the gdbarch
> > of the next frame. And DWARF tailcall frames use the gdbarch of the
> > bottom non-tailcall frame. This is consistent with the proposed changes.
>
> In that case, there _is_ a prev frame, and then we default to assuming the
> unwound arch is the same as the next frame's arch. But in this situation at
> hand, the difference is that we found that there's _no_ "real caller frame" at
> all.
>
> >
> > We may want to return frame_unwind_arch (next_frame) instead of
> > get_frame_arch (next_frame). OTOH gdb/dwarf2-frame-tailcall.c's
> > tailcall_frame_prev_arch returns get_frame_arch (cache-
> >next_bottom_frame).
> > I'm currently mimicking that behavior.
>
> See above. That situation looks similar on the surface, but the distinction is
> important. The "frame_unwind_CALLER" methods want to drill down past
> artificial frames, and return info on the "real caller", while the
> "frame_unwind" methods want to unwind one frame only, no matter
> artificial or not.
>
> All the frame_unwind_caller_XXX methods should retrieve information
> about the same frame that frame_unwind_caller_id returns. They should all
> really be guarded by a frame_unwind_caller_id check, like:
>
> if (frame_id_p (frame_unwind_caller_id (frame)))
> {
> scope_breakpoint
> = create_internal_breakpoint (frame_unwind_caller_arch (frame),
> frame_unwind_caller_pc (frame),
> bp_watchpoint_scope,
> &momentary_breakpoint_ops);
>
> and indeed most are. Those that aren't, either should be, or are not because
> they're called when we know the current frame is a non-artificial frame.
>
> Put another way, all the frame_unwind_caller_xxx methods should behave
> merely as convenience to writing the alternative form that has the caller skip
> artificial frames itself:
>
> frame = skip_artificial_frames (frame);
> if (frame_id_p (get_frame_id (frame)))
> {
> scope_breakpoint
> = create_internal_breakpoint (get_frame_arch (frame),
> get_frame_pc (frame),
> bp_watchpoint_scope,
> &momentary_breakpoint_ops);
>
>
> As such, if something calls frame_unwind_caller_pc|arch directly without
> checking whether frame_unwind_caller_id returns a valid frame, then the
> caller code should not continue as if there was indeed a valid caller frame.
> Throwing an error in that case is better than silently continuing with mocked
> info.
>
> So, what would break if we internal_error'ed in
> frame_unwind_caller_arch/pc instead or normal error, in the case that
> there's no non-artificial frame?
Likely nothing. The case of only-artificial-frames is not covered by the test
suite. I'm not sure it is even possible during live debug (ignoring the discussion
about get_prev_frame_always).
The changes were not motivated by fails but by my attempt to make the callers
of skip_artificial_frames handle the now-possible NULL return gracefully.
I ran the btrace suite including the new tests I added to cover the record btrace
tailcall-only-frames case and they pass. I'm running the full test suite now.
Regards,
Markus.
Intel Deutschland GmbH
Registered Address: Am Campeon 10-12, 85579 Neubiberg, Germany
Tel: +49 89 99 8853-0, www.intel.de
Managing Directors: Christin Eisenschmid, Christian Lamprechter
Chairperson of the Supervisory Board: Nicole Lau
Registered Office: Munich
Commercial Register: Amtsgericht Muenchen HRB 186928
next prev parent reply other threads:[~2016-02-10 10:29 UTC|newest]
Thread overview: 27+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-02-05 14:18 [PATCH v2 1/3] frame: add skip_tailcall_frames Markus Metzger
2016-02-05 14:18 ` [PATCH v2 2/3] frame: use get_prev_frame_always in skip_tailcall_frames Markus Metzger
2016-02-07 13:01 ` Joel Brobecker
2016-02-08 8:14 ` Metzger, Markus T
2016-02-09 11:42 ` Pedro Alves
2016-02-09 11:58 ` Joel Brobecker
2016-02-09 14:25 ` Metzger, Markus T
2016-02-09 14:41 ` Pedro Alves
[not found] ` <A78C989F6D9628469189715575E55B233325FCA0@IRSMSX104.ger.corp.intel.com>
2016-02-15 9:51 ` Metzger, Markus T
2016-02-17 15:32 ` Pedro Alves
2016-02-19 11:36 ` Metzger, Markus T
2016-02-09 14:44 ` Joel Brobecker
2016-02-05 14:19 ` [PATCH v2 3/3] btrace, frame: fix crash in get_frame_type Markus Metzger
2016-02-09 12:05 ` Pedro Alves
2016-02-09 14:43 ` Metzger, Markus T
2016-02-09 22:01 ` Pedro Alves
2016-02-10 7:40 ` Metzger, Markus T
2016-02-10 9:59 ` Pedro Alves
2016-02-10 10:29 ` Metzger, Markus T [this message]
2016-02-10 15:02 ` Metzger, Markus T
2016-02-10 15:34 ` Pedro Alves
2016-02-11 9:51 ` Metzger, Markus T
2016-02-11 13:39 ` Pedro Alves
2016-02-11 15:42 ` Metzger, Markus T
2016-02-11 15:58 ` Pedro Alves
2016-02-11 16:07 ` Metzger, Markus T
2016-02-07 13:00 ` [PATCH v2 1/3] frame: add skip_tailcall_frames Joel Brobecker
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=A78C989F6D9628469189715575E55B233325FFC6@IRSMSX104.ger.corp.intel.com \
--to=markus.t.metzger@intel.com \
--cc=gdb-patches@sourceware.org \
--cc=palves@redhat.com \
/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