public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
From: Bruno Larsen <blarsen@redhat.com>
To: Tom Tromey <tom@tromey.com>,
	Bruno Larsen via Gdb-patches <gdb-patches@sourceware.org>
Subject: Re: [PATCH v2] gdb/stack.c: avoid stale pointers when printing frame arguments
Date: Mon, 20 Jun 2022 10:12:31 -0300	[thread overview]
Message-ID: <3ff0c39a-ed56-2f58-d81a-9af7b9252bae@redhat.com> (raw)
In-Reply-To: <87letyx78l.fsf@tromey.com>



On 6/15/22 12:43, Tom Tromey wrote:
>>>>>> "Bruno" == Bruno Larsen via Gdb-patches <gdb-patches@sourceware.org> writes:
> 
> Bruno> @@ -738,8 +738,17 @@ call_function_by_hand (struct value *function,
> Bruno>  		       type *default_return_type,
> Bruno>  		       gdb::array_view<value *> args)
> Bruno>  {
> Bruno> -  return call_function_by_hand_dummy (function, default_return_type,
> Bruno> -				      args, NULL, NULL);
> Bruno> +  scoped_restore_selected_frame restore_frame;
> Bruno> +  struct value *ret = call_function_by_hand_dummy (function,
> Bruno> +						   default_return_type,
> Bruno> +						   args, NULL, NULL);
> Bruno> +  /* Ensure that the frame cache does not contain any frames that were
> Bruno> +     specific to the handmade function call.  If something is leftover
> Bruno> +     while GDB has kept a reference to a frame (for instance, when a
> Bruno> +     stacktrace is being printed and a pretty printed called an inferior
> Bruno> +     function), GDB could crash.  */
> Bruno> +  reinit_frame_cache ();
> 
> I don't understand the need for this call.
> It seems like it must be redundant, because the frame cache should be
> reset by causing the inferior to run during the inferior call.

Oh yes, it must be from an earlier iteration (or me just not understanding how frames work).

All the changes to the function will be reverted locally, as the scoped_restore was here
because of the re-initialization of the frame cache.

> 
> Bruno> +      struct frame_id id = get_frame_id (get_selected_frame (NULL));
> Bruno>        if (execution_direction == EXEC_REVERSE)
> Bruno>  	gdb_printf (_("Run back to call of "));
> Bruno>        else
> Bruno> @@ -1866,6 +1867,10 @@ finish_command (const char *arg, int from_tty)
> Bruno>  	}
>   
> Bruno>        print_stack_frame (get_selected_frame (NULL), 1, LOCATION, 0);
> Bruno> +      frame = frame_find_by_id (id);
> Bruno> +      if (frame == nullptr)
> Bruno> +	  error (_("frames disappeared mid-printing."));
> Bruno> +      frame = get_prev_frame (frame);
> 
> This code probably needs a comment since it's non-obvious why 'finish'
> would need to do the frame-id thing.

I'll add a comment too, but as an explanation to you: Everywhere that prints a frame
will need this because if a frame is printed, it may call a function by hand, which
makes this pointer stale.

> 
> I think error text normally does not end in ".".
> I see a lot of these though, I wonder if we ought to remove them all.

A very rough 'grep error.*\.\" ' showed 32 lines with this.

Since I'm already making a new version, I can change this on my patch, no problem

> 
> Bruno> +	    error (_("frames disappeared mid-printing."));
> 
> Here too.
> 
> Bruno> +  /* print_frame can invalidate frame, so cache the frame_id to rebuild
> Bruno> +     the whole stack later, if needed.  */
> Bruno> +  struct frame_id frame_id = get_frame_id (frame);
> 
> This repeated code makes me wonder if perhaps the print_frame_info API
> ought to be changed instead.

print_frame_info could return an updated pointer to the frame being printed, or receive a
frame_info** and update it in-place.  However, We'll still need to check for a null pointer
after calling, since we won't want print_frame_info to error out if a frame no longer
exists.  We might not care when printing.

Does any of these options sound like a better option? Or would we always want to error out
if the frame disappears from under us?


Cheers!
Bruno Larsen
> 
> Tom
> 


  reply	other threads:[~2022-06-20 13:12 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-05-04 19:10 Bruno Larsen
2022-05-18 11:24 ` [PING] " Bruno Larsen
2022-05-24 11:25   ` [PINGv2] " Bruno Larsen
2022-05-30 11:16     ` [PINGv3] " Bruno Larsen
2022-06-06 12:46       ` [PINGv4] " Bruno Larsen
2022-06-13 20:02         ` [PINGv5] " Bruno Larsen
2022-06-15 15:43 ` Tom Tromey
2022-06-20 13:12   ` Bruno Larsen [this message]
2022-06-27 18:52     ` Bruno Larsen

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=3ff0c39a-ed56-2f58-d81a-9af7b9252bae@redhat.com \
    --to=blarsen@redhat.com \
    --cc=gdb-patches@sourceware.org \
    --cc=tom@tromey.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;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).