Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Bernd Edlinger <bernd.edlinger@hotmail.de>
To: "gdb-patches@sourceware.org" <gdb-patches@sourceware.org>
Subject: [PATCH] Make "skip" work on inline frames
Date: Fri, 18 Oct 2019 12:52:00 -0000	[thread overview]
Message-ID: <VI1PR03MB4528B9076FC778EF9C0B8B61E46C0@VI1PR03MB4528.eurprd03.prod.outlook.com> (raw)

[-- Attachment #1: Type: text/plain, Size: 432 bytes --]

Hi,

I noticed that skip is not working well on inlined frames which may
happen in optimized gcc stage3 binary, where step stops at functions
which are marked for skip, whenever they happen to be in-lined, where
it is ignored if the frame is marked for skip, thus currently
skipped frames are only checked when the skipped function
is not inlined, which is usually only the case in non-optimized builds.


Thanks
Bernd.

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-Check-all-inline-frames-if-they-are-marked-for-skip.patch --]
[-- Type: text/x-patch; name="0001-Check-all-inline-frames-if-they-are-marked-for-skip.patch", Size: 4418 bytes --]

From 6f24c762bf45d7b1b2d2e9285dfe2250b654b8ea Mon Sep 17 00:00:00 2001
From: Bernd Edlinger <bernd.edlinger@hotmail.de>
Date: Fri, 18 Oct 2019 14:28:45 +0200
Subject: [PATCH] Check all inline frames if they are marked for skip.

This makes the skip command work in optimized builds,
where skipped functions may be inlined.
Previously that was only working when stepping into
a non-inlined function.
---
 gdb/infcmd.c | 15 ++++++++++++++-
 gdb/infrun.c | 54 +++++++++++++++++++++++++++++++++++++++++++++++++++---
 2 files changed, 65 insertions(+), 4 deletions(-)

diff --git a/gdb/infcmd.c b/gdb/infcmd.c
index 7105774..9e4de66 100644
--- a/gdb/infcmd.c
+++ b/gdb/infcmd.c
@@ -58,6 +58,7 @@
 #include "thread-fsm.h"
 #include "top.h"
 #include "interps.h"
+#include "skip.h"
 #include "gdbsupport/gdb_optional.h"
 #include "source.h"
 #include "cli/cli-style.h"
@@ -1112,6 +1113,9 @@ prepare_one_step (struct step_command_fsm *sm)
 	      && inline_skipped_frames (tp))
 	    {
 	      ptid_t resume_ptid;
+	      const char *fn = NULL;
+	      symtab_and_line sal;
+	      struct symbol *sym;
 
 	      /* Pretend that we've ran.  */
 	      resume_ptid = user_visible_resume_ptid (1);
@@ -1119,7 +1123,16 @@ prepare_one_step (struct step_command_fsm *sm)
 
 	      step_into_inline_frame (tp);
 	      sm->count--;
-	      return prepare_one_step (sm);
+
+	      sal = find_frame_sal (frame);
+	      sym = get_frame_function (frame);
+
+	      if (sym != NULL)
+		fn = SYMBOL_PRINT_NAME (sym);
+
+	      if (sal.line == 0
+		  || !function_name_is_marked_for_skip (fn, sal))
+		return prepare_one_step (sm);
 	    }
 
 	  pc = get_frame_pc (frame);
diff --git a/gdb/infrun.c b/gdb/infrun.c
index 07aebfa..04c1eee 100644
--- a/gdb/infrun.c
+++ b/gdb/infrun.c
@@ -4041,6 +4041,45 @@ stepped_in_from (struct frame_info *frame, struct frame_id step_frame_id)
   return 0;
 }
 
+/* Look for an inline frame that is marked for skip.
+   If PREV_FRAME is TRUE start at the previous frame,
+   otherwise start at the current frame.  Stop at the
+   first non-inline frame, or at the frame where the
+   step started.  */
+
+static bool
+inline_frame_is_marked_for_skip (bool prev_frame, struct thread_info *tp)
+{
+  struct frame_info *frame = get_current_frame ();
+
+  if (prev_frame)
+    frame = get_prev_frame (frame);
+
+  for (; frame != NULL; frame = get_prev_frame (frame))
+    {
+      const char *fn = NULL;
+      symtab_and_line sal;
+      struct symbol *sym;
+
+      if (frame_id_eq (get_frame_id (frame), tp->control.step_frame_id))
+	break;
+      if (get_frame_type (frame) != INLINE_FRAME)
+	break;
+
+      sal = find_frame_sal (frame);
+      sym = get_frame_function (frame);
+
+      if (sym != NULL)
+	fn = SYMBOL_PRINT_NAME (sym);
+
+      if (sal.line != 0
+	  && function_name_is_marked_for_skip (fn, sal))
+	return true;
+    }
+
+  return false;
+}
+
 /* If the event thread has the stop requested flag set, pretend it
    stopped for a GDB_SIGNAL_0 (i.e., as if it stopped due to
    target_stop).  */
@@ -6531,7 +6570,8 @@ process_event_stop_test (struct execution_control_state *ecs)
 	tmp_sal = find_pc_line (ecs->stop_func_start, 0);
 	if (tmp_sal.line != 0
 	    && !function_name_is_marked_for_skip (ecs->stop_func_name,
-						  tmp_sal))
+						  tmp_sal)
+	    && !inline_frame_is_marked_for_skip (true, ecs->event_thread))
 	  {
 	    if (execution_direction == EXEC_REVERSE)
 	      handle_step_into_function_backward (gdbarch, ecs);
@@ -6697,7 +6737,14 @@ process_event_stop_test (struct execution_control_state *ecs)
 
 	  if (call_sal.line == ecs->event_thread->current_line
 	      && call_sal.symtab == ecs->event_thread->current_symtab)
-	    step_into_inline_frame (ecs->event_thread);
+	    {
+	      step_into_inline_frame (ecs->event_thread);
+	      if (inline_frame_is_marked_for_skip (false, ecs->event_thread))
+		{
+		  keep_going (ecs);
+		  return;
+		}
+	    }
 
 	  end_stepping_range (ecs);
 	  return;
@@ -6731,7 +6778,8 @@ process_event_stop_test (struct execution_control_state *ecs)
 	fprintf_unfiltered (gdb_stdlog,
 			    "infrun: stepping through inlined function\n");
 
-      if (ecs->event_thread->control.step_over_calls == STEP_OVER_ALL)
+      if (ecs->event_thread->control.step_over_calls == STEP_OVER_ALL
+	  || inline_frame_is_marked_for_skip (false, ecs->event_thread))
 	keep_going (ecs);
       else
 	end_stepping_range (ecs);
-- 
1.9.1


             reply	other threads:[~2019-10-18 12:52 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-10-18 12:52 Bernd Edlinger [this message]
2019-10-19  4:40 ` Bernd Edlinger
2019-10-20  6:48   ` [PATCHv2] " Bernd Edlinger
2019-10-26  8:06     ` [PING] " Bernd Edlinger
2019-10-27  1:52     ` Simon Marchi
2019-10-27  2:18       ` Simon Marchi
2019-10-30 21:56         ` Bernd Edlinger
2019-10-31 16:42           ` Pedro Alves
2019-10-31 16:53             ` Simon Marchi
2019-10-31 18:00               ` Pedro Alves
2019-10-31 19:19                 ` [PATCHv3] " Bernd Edlinger
2019-11-24 11:22                   ` [PATCHv4] " Bernd Edlinger
2019-12-01 20:46                     ` [PING] " Bernd Edlinger
2019-12-02  2:34                     ` Simon Marchi
2019-12-02 16:47                       ` [PATCHv5] " Bernd Edlinger
2019-12-03  4:22                         ` Simon Marchi
2019-12-14 13:55                         ` [PING] " Bernd Edlinger
2019-12-15  0:46                         ` Simon Marchi
2019-12-15 11:25                           ` [PATCHv6] " Bernd Edlinger
2019-12-15 13:12                             ` Simon Marchi
2019-12-15 18:18                               ` Bernd Edlinger
2019-12-17  2:01                                 ` Simon Marchi
2019-12-17 13:00                                   ` Bernd Edlinger
2019-10-30 20:06       ` [PATCHv2] " Bernd Edlinger
2019-10-30 20:18         ` 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=VI1PR03MB4528B9076FC778EF9C0B8B61E46C0@VI1PR03MB4528.eurprd03.prod.outlook.com \
    --to=bernd.edlinger@hotmail.de \
    --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