Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Pedro Alves <palves@redhat.com>
To: gdb-patches@sourceware.org
Subject: [PATCH 1/8] watch_command_1: Fix dangling frame access
Date: Tue, 11 Apr 2017 23:51:00 -0000	[thread overview]
Message-ID: <1491954673-29172-2-git-send-email-palves@redhat.com> (raw)
In-Reply-To: <1491954673-29172-1-git-send-email-palves@redhat.com>

While working on some changes to switch_to_thread, I inadvertently
make switch_to_thread call reinit_frame_cache more frequently, even
when the thread didn't change.  This exposed a latent bug in
watch_command_1, where we're referencing a frame after
creating/inserting breakpoints, which potentially calls
reinit_frame_cache if it needs to install breakpoints with a different
thread selected.

Handle this similarly to how it's already handled in other similar
cases.  I.e., save any frame-related information we might need before
creating a breakpoint.

gdb/ChangeLog:
yyyy-mm-dd  Pedro Alves  <palves@redhat.com>

	* breakpoint.c (watch_command_1): Save watchpoint-frame info
	before calling create_internal_breakpoint.
---
 gdb/breakpoint.c | 34 +++++++++++++++++++++-------------
 1 file changed, 21 insertions(+), 13 deletions(-)

diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
index 3925ec6..b2f6d6e 100644
--- a/gdb/breakpoint.c
+++ b/gdb/breakpoint.c
@@ -11100,7 +11100,6 @@ watch_command_1 (const char *arg, int accessflag, int from_tty,
   const struct block *exp_valid_block = NULL, *cond_exp_valid_block = NULL;
   struct value *val, *mark, *result;
   int saved_bitpos = 0, saved_bitsize = 0;
-  struct frame_info *frame;
   const char *exp_start = NULL;
   const char *exp_end = NULL;
   const char *tok, *end_tok;
@@ -11278,35 +11277,44 @@ watch_command_1 (const char *arg, int accessflag, int from_tty,
   if (*tok)
     error (_("Junk at end of command."));
 
-  frame = block_innermost_frame (exp_valid_block);
+  frame_info *wp_frame = block_innermost_frame (exp_valid_block);
+
+  /* Save this because create_internal_breakpoint below invalidates
+     'wp_frame'.  */
+  frame_id watchpoint_frame = get_frame_id (wp_frame);
 
   /* If the expression is "local", then set up a "watchpoint scope"
      breakpoint at the point where we've left the scope of the watchpoint
      expression.  Create the scope breakpoint before the watchpoint, so
      that we will encounter it first in bpstat_stop_status.  */
-  if (exp_valid_block && frame)
+  if (exp_valid_block && wp_frame)
     {
-      if (frame_id_p (frame_unwind_caller_id (frame)))
+      struct frame_id caller_frame_id = frame_unwind_caller_id (wp_frame);
+
+      if (frame_id_p (caller_frame_id))
 	{
+	  gdbarch *caller_arch = frame_unwind_caller_arch (wp_frame);
+	  CORE_ADDR caller_pc = frame_unwind_caller_pc (wp_frame);
+
  	  scope_breakpoint
-	    = create_internal_breakpoint (frame_unwind_caller_arch (frame),
-					  frame_unwind_caller_pc (frame),
+	    = create_internal_breakpoint (caller_arch, caller_pc,
 					  bp_watchpoint_scope,
 					  &momentary_breakpoint_ops);
 
+	  /* create_internal_breakpoint could invalidate WP_FRAME.  */
+	  wp_frame = NULL;
+
 	  scope_breakpoint->enable_state = bp_enabled;
 
 	  /* Automatically delete the breakpoint when it hits.  */
 	  scope_breakpoint->disposition = disp_del;
 
 	  /* Only break in the proper frame (help with recursion).  */
-	  scope_breakpoint->frame_id = frame_unwind_caller_id (frame);
+	  scope_breakpoint->frame_id = caller_frame_id;
 
 	  /* Set the address at which we will stop.  */
-	  scope_breakpoint->loc->gdbarch
-	    = frame_unwind_caller_arch (frame);
-	  scope_breakpoint->loc->requested_address
-	    = frame_unwind_caller_pc (frame);
+	  scope_breakpoint->loc->gdbarch = caller_arch;
+	  scope_breakpoint->loc->requested_address = caller_pc;
 	  scope_breakpoint->loc->address
 	    = adjust_breakpoint_address (scope_breakpoint->loc->gdbarch,
 					 scope_breakpoint->loc->requested_address,
@@ -11378,9 +11386,9 @@ watch_command_1 (const char *arg, int accessflag, int from_tty,
   else
     b->cond_string = 0;
 
-  if (frame)
+  if (frame_id_p (watchpoint_frame))
     {
-      w->watchpoint_frame = get_frame_id (frame);
+      w->watchpoint_frame = watchpoint_frame;
       w->watchpoint_thread = inferior_ptid;
     }
   else
-- 
2.5.5


  parent reply	other threads:[~2017-04-11 23:51 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-04-11 23:51 [PATCH 0/8] Fix removing inferiors from within "thread apply" commands Pedro Alves
2017-04-11 23:51 ` [PATCH 3/8] C++fy thread_apply_all_command Pedro Alves
2017-04-13 10:06   ` Yao Qi
2017-04-11 23:51 ` [PATCH 7/8] Make inferior::detaching a bool, and introduce scoped_restore::release() Pedro Alves
2017-04-11 23:51 ` [PATCH 2/8] Fix follow-fork latent bug Pedro Alves
2017-04-13  9:58   ` Yao Qi
2017-04-13 12:09     ` Pedro Alves
2017-04-13 15:33       ` Yao Qi
2017-04-11 23:51 ` Pedro Alves [this message]
2017-04-13  9:34   ` [PATCH 1/8] watch_command_1: Fix dangling frame access Yao Qi
2017-04-13 15:26     ` Pedro Alves
2017-04-11 23:51 ` [PATCH 6/8] Make inferior a class with cdtors, and use new/delete Pedro Alves
2017-04-13 10:24   ` Yao Qi
2017-04-11 23:51 ` [PATCH 8/8] Fix removing inferiors from within "thread apply" commands Pedro Alves
2017-04-13 11:33   ` Yao Qi
2017-04-13 12:22     ` Pedro Alves
2017-04-13 14:49       ` Pedro Alves
2017-04-19  8:23         ` Yao Qi
2017-04-19 12:15           ` Pedro Alves
2017-04-19 12:20             ` Pedro Alves
2017-04-13 15:31       ` Yao Qi
2017-04-11 23:56 ` [PATCH 4/8] Improve coverage of the PR threads/13217 regression test Pedro Alves
2017-04-13 10:09   ` Yao Qi
2017-04-11 23:56 ` [PATCH 5/8] GC inferior.c:init_inferior_list Pedro Alves
2017-04-13 10:10   ` Yao Qi

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=1491954673-29172-2-git-send-email-palves@redhat.com \
    --to=palves@redhat.com \
    --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