public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
From: Ari Hannula <ari.hannula@intel.com>
To: gdb-patches@sourceware.org
Cc: Tim Wiederhake <tim.wiederhake@intel.com>,
	Ari Hannula <ari.hannula@intel.com>
Subject: [PATCH 4/5] [func_call] Add function-call-history-length command to MI.
Date: Thu, 10 Feb 2022 14:52:42 +0100	[thread overview]
Message-ID: <20220210135243.3127629-5-ari.hannula@intel.com> (raw)
In-Reply-To: <20220210135243.3127629-1-ari.hannula@intel.com>

From: Tim Wiederhake <tim.wiederhake@intel.com>

This allows MI clients like Eclipse to retrieve the length of the function
call history.

gdb/ChangeLog:
2018-12-21  Tim Wiederhake  <tim.wiederhake@intel.com>

	* mi/mi-cmds.c (mi_cmds): Add
	mi_cmd_record_function_call_history_length.
	* mi/mi-cmds.h (mi_cmd_record_function_call_history_length): New
	declaration.
	* record-btrace.c (record_btrace_target) <call_history_length>:
	New declaration.
	(record_btrace_target::call_history_length): New function.
	* record.c (mi_cmd_record_function_call_history_length): New
	function.
	* record.h (mi_cmd_record_function_call_hisotry_length): New
	declaration.
	* target-delegates.c: Regenerated.
	* target.c (target_call_hisotry_length): New function.
	* target.h (target_ops) <call_history_length>: New declaration.
	(target_call_history_length): New declaration.

gdb/testsuite/ChangeLog:
2018-12-21  Tim Wiederhake  <tim.wiederhake@intel.com>

	* gdb.mi/mi-function_call_history.c: New file.
	* gdb.mi/mi-function_call_history.exp: New file.

Signed-off-by: Tim Wiederhake <tim.wiederhake@intel.com>
Signed-off-by: Ari Hannula <ari.hannula@intel.com>
---
 gdb/mi/mi-cmds.c                              | 12 +--
 gdb/mi/mi-cmds.h                              |  1 +
 gdb/record-btrace.c                           | 24 +++++
 gdb/record.c                                  | 11 +++
 gdb/record.h                                  |  6 ++
 gdb/target-delegates.c                        | 23 +++++
 gdb/target.c                                  |  8 ++
 gdb/target.h                                  |  7 ++
 .../gdb.mi/mi-function_call_history.c         | 43 +++++++++
 .../gdb.mi/mi-function_call_history.exp       | 88 +++++++++++++++++++
 10 files changed, 218 insertions(+), 5 deletions(-)
 create mode 100644 gdb/testsuite/gdb.mi/mi-function_call_history.c
 create mode 100644 gdb/testsuite/gdb.mi/mi-function_call_history.exp

diff --git a/gdb/mi/mi-cmds.c b/gdb/mi/mi-cmds.c
index cd7cabdda9..945a439d3a 100644
--- a/gdb/mi/mi-cmds.c
+++ b/gdb/mi/mi-cmds.c
@@ -227,11 +227,11 @@ add_builtin_mi_commands ()
   add_mi_cmd_mi ("catch-unload", mi_cmd_catch_unload,
 		 &mi_suppress_notification.breakpoint);
   add_mi_cmd_mi ("catch-throw", mi_cmd_catch_throw,
-                 &mi_suppress_notification.breakpoint),
+                 &mi_suppress_notification.breakpoint);
   add_mi_cmd_mi ("catch-rethrow", mi_cmd_catch_rethrow,
-                 &mi_suppress_notification.breakpoint),
+                 &mi_suppress_notification.breakpoint);
   add_mi_cmd_mi ("catch-catch", mi_cmd_catch_catch,
-                 &mi_suppress_notification.breakpoint),
+                 &mi_suppress_notification.breakpoint);
   add_mi_cmd_mi ("complete", mi_cmd_complete);
   add_mi_cmd_mi ("data-disassemble", mi_cmd_disassemble);
   add_mi_cmd_mi ("data-evaluate-expression", mi_cmd_data_evaluate_expression);
@@ -275,10 +275,12 @@ add_builtin_mi_commands ()
   add_mi_cmd_mi ("file-list-exec-source-files",
 		 mi_cmd_file_list_exec_source_files);
   add_mi_cmd_mi ("file-list-shared-libraries",
-     mi_cmd_file_list_shared_libraries),
+     mi_cmd_file_list_shared_libraries);
   add_mi_cmd_cli ("file-symbol-file", "symbol-file", 1);
   add_mi_cmd_mi ("fix-multi-location-breakpoint-output",
-		 mi_cmd_fix_multi_location_breakpoint_output),
+		 mi_cmd_fix_multi_location_breakpoint_output);
+  add_mi_cmd_mi ("function-call-history-length",
+		 mi_cmd_record_function_call_history_length);
   add_mi_cmd_mi ("gdb-exit", mi_cmd_gdb_exit);
   add_mi_cmd_cli ("gdb-set", "set", 1,
 		  &mi_suppress_notification.cmd_param_changed);
diff --git a/gdb/mi/mi-cmds.h b/gdb/mi/mi-cmds.h
index 2a93a9f547..63da17ed01 100644
--- a/gdb/mi/mi-cmds.h
+++ b/gdb/mi/mi-cmds.h
@@ -88,6 +88,7 @@ extern mi_cmd_argv_ftype mi_cmd_interpreter_exec;
 extern mi_cmd_argv_ftype mi_cmd_list_features;
 extern mi_cmd_argv_ftype mi_cmd_list_target_features;
 extern mi_cmd_argv_ftype mi_cmd_list_thread_groups;
+extern mi_cmd_argv_ftype mi_cmd_record_function_call_history_length;
 extern mi_cmd_argv_ftype mi_cmd_remove_inferior;
 extern mi_cmd_argv_ftype mi_cmd_stack_info_depth;
 extern mi_cmd_argv_ftype mi_cmd_stack_info_frame;
diff --git a/gdb/record-btrace.c b/gdb/record-btrace.c
index dd5f4b4dd7..97025fefe3 100644
--- a/gdb/record-btrace.c
+++ b/gdb/record-btrace.c
@@ -85,6 +85,7 @@ class record_btrace_target final : public target_ops
 			  gdb_disassembly_flags flags) override;
   void insn_history_range (ULONGEST begin, ULONGEST end,
 			   gdb_disassembly_flags flags) override;
+  void call_history_length () override;
   void call_history (int size, record_print_flags flags) override;
   void call_history_from (ULONGEST begin, int size, record_print_flags flags)
     override;
@@ -1221,6 +1222,29 @@ btrace_call_history (struct ui_out *uiout,
     }
 }
 
+/* The call_history_length method of target record-btrace.  */
+
+void
+record_btrace_target::call_history_length ()
+{
+  struct btrace_call_iterator end;
+  btrace_call_end (&end, require_btrace ());
+
+  const int length = btrace_call_number (&end) - 1;
+
+  if (current_uiout->is_mi_like_p ())
+    {
+      ui_out_emit_list list_emitter (current_uiout, "func history length");
+      ui_out_emit_tuple tuple_emitter (current_uiout, nullptr);
+      current_uiout->field_unsigned ("end", length);
+    }
+  else
+    {
+      ui_out_emit_tuple tuple_emitter (current_uiout, "func history length");
+      current_uiout->field_unsigned ("end", length);
+    }
+}
+
 /* The call_history method of target record-btrace.  */
 
 void
diff --git a/gdb/record.c b/gdb/record.c
index 3c936811fe..75375b4288 100644
--- a/gdb/record.c
+++ b/gdb/record.c
@@ -755,6 +755,17 @@ set_record_call_history_size (const char *args, int from_tty,
 			 &record_call_history_size);
 }
 
+void
+mi_cmd_record_function_call_history_length (const char *command,
+					    char **argv,
+					    int argc)
+{
+  if (argc != 0)
+    error (_("-function-call-history-length: Invalid number of arguments."));
+
+  target_call_history_length ();
+}
+
 void _initialize_record ();
 void
 _initialize_record ()
diff --git a/gdb/record.h b/gdb/record.h
index 0fbca9d44c..174b71c67c 100644
--- a/gdb/record.h
+++ b/gdb/record.h
@@ -114,4 +114,10 @@ extern void record_start (const char *method, const char *format,
 /* Stop recording.  Throw on failure.  */
 extern void record_stop (int from_tty);
 
+/* The MI version of the command to get the length of the function call history
+   for record targets.  */
+extern void mi_cmd_record_function_call_history_length (char *command,
+							char **argv,
+							int argc);
+
 #endif /* RECORD_H */
diff --git a/gdb/target-delegates.c b/gdb/target-delegates.c
index ca1734f86b..c0ed5f3227 100644
--- a/gdb/target-delegates.c
+++ b/gdb/target-delegates.c
@@ -165,6 +165,7 @@ struct dummy_target : public target_ops
   void insn_history (int arg0, gdb_disassembly_flags arg1) override;
   void insn_history_from (ULONGEST arg0, int arg1, gdb_disassembly_flags arg2) override;
   void insn_history_range (ULONGEST arg0, ULONGEST arg1, gdb_disassembly_flags arg2) override;
+  void call_history_length () override;
   void call_history (int arg0, record_print_flags arg1) override;
   void call_history_from (ULONGEST arg0, int arg1, record_print_flags arg2) override;
   void call_history_range (ULONGEST arg0, ULONGEST arg1, record_print_flags arg2) override;
@@ -339,6 +340,7 @@ struct debug_target : public target_ops
   void insn_history (int arg0, gdb_disassembly_flags arg1) override;
   void insn_history_from (ULONGEST arg0, int arg1, gdb_disassembly_flags arg2) override;
   void insn_history_range (ULONGEST arg0, ULONGEST arg1, gdb_disassembly_flags arg2) override;
+  void call_history_length () override;
   void call_history (int arg0, record_print_flags arg1) override;
   void call_history_from (ULONGEST arg0, int arg1, record_print_flags arg2) override;
   void call_history_range (ULONGEST arg0, ULONGEST arg1, record_print_flags arg2) override;
@@ -4236,6 +4238,27 @@ debug_target::insn_history_range (ULONGEST arg0, ULONGEST arg1, gdb_disassembly_
   fputs_unfiltered (")\n", gdb_stdlog);
 }
 
+void
+target_ops::call_history_length ()
+{
+  this->beneath ()->call_history_length ();
+}
+
+void
+dummy_target::call_history_length ()
+{
+  tcomplain ();
+}
+
+void
+debug_target::call_history_length ()
+{
+  fprintf_unfiltered (gdb_stdlog, "-> %s->call_history_length (...)\n", this->beneath ()->shortname ());
+  this->beneath ()->call_history_length ();
+  fprintf_unfiltered (gdb_stdlog, "<- %s->call_history_length (", this->beneath ()->shortname ());
+  fputs_unfiltered (")\n", gdb_stdlog);
+}
+
 void
 target_ops::call_history (int arg0, record_print_flags arg1)
 {
diff --git a/gdb/target.c b/gdb/target.c
index 548cfad06b..70ca8e0835 100644
--- a/gdb/target.c
+++ b/gdb/target.c
@@ -4217,6 +4217,14 @@ target_insn_history_range (ULONGEST begin, ULONGEST end,
 
 /* See target.h.  */
 
+void
+target_call_history_length ()
+{
+  current_inferior ()->top_target ()->call_history_length ();
+}
+
+/* See target.h.  */
+
 void
 target_call_history (int size, record_print_flags flags)
 {
diff --git a/gdb/target.h b/gdb/target.h
index 4cc79df05b..524a7e0335 100644
--- a/gdb/target.h
+++ b/gdb/target.h
@@ -1249,6 +1249,10 @@ struct target_ops
 				     gdb_disassembly_flags flags)
       TARGET_DEFAULT_NORETURN (tcomplain ());
 
+    /* Print the number of functions in the recorded execution trace.  */
+    virtual void call_history_length ()
+      TARGET_DEFAULT_NORETURN (tcomplain ());
+
     /* Print a function trace of the recorded execution trace.
        If SIZE < 0, print abs (SIZE) preceding functions; otherwise, print SIZE
        succeeding functions.  */
@@ -2563,6 +2567,9 @@ extern void target_insn_history_from (ULONGEST from, int size,
 extern void target_insn_history_range (ULONGEST begin, ULONGEST end,
 				       gdb_disassembly_flags flags);
 
+/* See to_call_history_length.  */
+extern void target_call_history_length ();
+
 /* See to_call_history.  */
 extern void target_call_history (int size, record_print_flags flags);
 
diff --git a/gdb/testsuite/gdb.mi/mi-function_call_history.c b/gdb/testsuite/gdb.mi/mi-function_call_history.c
new file mode 100644
index 0000000000..3f82e21f8d
--- /dev/null
+++ b/gdb/testsuite/gdb.mi/mi-function_call_history.c
@@ -0,0 +1,43 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2013-2022 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+int
+inc (int i)
+{
+  return i + 1;
+}
+
+int
+fib (int n)
+{
+  if (n <= 1)
+    return n;
+
+  return fib (n - 2) + fib (n - 1);
+}
+
+int
+main ()
+{
+  int i, j;
+
+  for (i = 0; i < 10; i++)
+    j += inc (i);
+
+  j += fib (10); /* bp.1 */
+  return j; /* bp.2 */
+}
diff --git a/gdb/testsuite/gdb.mi/mi-function_call_history.exp b/gdb/testsuite/gdb.mi/mi-function_call_history.exp
new file mode 100644
index 0000000000..948a04a5ed
--- /dev/null
+++ b/gdb/testsuite/gdb.mi/mi-function_call_history.exp
@@ -0,0 +1,88 @@
+# This testcase is part of GDB, the GNU debugger.
+#
+# Copyright 2013-2022 Free Software Foundation, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+set errorInfo
+
+if [skip_btrace_tests] {
+    return 0
+}
+
+load_lib mi-support.exp
+set MIFLAGS "-i=mi"
+
+gdb_exit
+if [mi_gdb_start] {
+    continue
+}
+
+# start inferior
+standard_testfile mi-function_call_history.c
+
+if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
+     untested mi-function_call_history.exp
+     return -1
+}
+
+mi_delete_breakpoints
+mi_gdb_reinitialize_dir $srcdir/$subdir
+mi_gdb_load ${binfile}
+
+if {[mi_runto_main] < 0} {
+    return -1
+}
+
+# start btrace
+send_gdb "record btrace\n"
+
+gdb_expect {
+    -re "=record-started,thread-group=\".*\"\r\n\\^done\r\n$mi_gdb_prompt$" {
+	# Done
+    }
+    -re "\\^error,msg=\"Target does not support branch tracing.\"" {
+	perror "Branch tracing not supported"
+	return -1
+    }
+    timeout {
+	perror "Unable to start branch tracing"
+	return -1
+    }
+}
+
+mi_create_breakpoint "-t $testfile.c:41" "insert temp breakpoint at $testfile.c:41" \
+    -number 2 -disp del -func main -file "$srcdir/$subdir/$testfile.c" -line 41
+
+mi_send_resuming_command "exec-continue" "continue to bp.1"
+
+mi_expect_stop "breakpoint-hit" "main" ".*" "$testfile.c" 41 \
+    {"" "disp=\".*\"" } "run to breakpoint bp.1"
+
+mi_gdb_test "125-function-call-history-length" \
+    "125\\^done,func history length=\\\[\{end=\"21\"\}\\\]" \
+    "125 function call history length"
+
+mi_create_breakpoint "-t $testfile.c:42" "insert temp breakpoint at $testfile.c:42" \
+    -number 3 -disp del -func main -file "$srcdir/$subdir/$testfile.c" -line 42
+
+mi_send_resuming_command "exec-continue" "continue to bp.2"
+
+mi_expect_stop "breakpoint-hit" "main" ".*" "$testfile.c" 42 \
+    {"" "disp=\".*\"" } "run to breakpoint bp.2"
+
+mi_gdb_test "225-function-call-history-length" \
+    "225\\^done,func history length=\\\[\{end=\"375\"\}\\\]" \
+    "225 function call history length"
+
+mi_gdb_exit
-- 
2.25.1

Intel Deutschland GmbH
Registered Address: Am Campeon 10, 85579 Neubiberg, Germany
Tel: +49 89 99 8853-0, www.intel.de <http://www.intel.de>
Managing Directors: Christin Eisenschmid, Sharon Heck, Tiffany Doon Silva  
Chairperson of the Supervisory Board: Nicole Lau
Registered Office: Munich
Commercial Register: Amtsgericht Muenchen HRB 186928


  parent reply	other threads:[~2022-02-10 13:53 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-02-10 13:52 [PATCH 0/5] Functions call history patches Ari Hannula
2022-02-10 13:52 ` [PATCH 1/5] [func_call] Add possible spelling of linker error message Ari Hannula
2022-03-17 17:58   ` Metzger, Markus T
2022-03-17 18:45     ` Keith Seitz
2022-02-10 13:52 ` [PATCH 2/5] [func_call] New tests for a btrace crash Ari Hannula
2022-03-17 17:58   ` Metzger, Markus T
2022-02-10 13:52 ` [PATCH 3/5] [func_call] Fix MI output for function call history Ari Hannula
2022-03-17 17:58   ` Metzger, Markus T
2022-02-10 13:52 ` Ari Hannula [this message]
2022-03-17 17:59   ` [PATCH 4/5] [func_call] Add function-call-history-length command to MI Metzger, Markus T
2022-02-10 13:52 ` [PATCH 5/5] [func_call] Add function-call-history " Ari Hannula

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=20220210135243.3127629-5-ari.hannula@intel.com \
    --to=ari.hannula@intel.com \
    --cc=gdb-patches@sourceware.org \
    --cc=tim.wiederhake@intel.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).