public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
* [PATCH 0/5] Functions call history patches
@ 2022-02-10 13:52 Ari Hannula
  2022-02-10 13:52 ` [PATCH 1/5] [func_call] Add possible spelling of linker error message Ari Hannula
                   ` (4 more replies)
  0 siblings, 5 replies; 11+ messages in thread
From: Ari Hannula @ 2022-02-10 13:52 UTC (permalink / raw)
  To: gdb-patches

Hi all,

On behalf of Tim and Ravi, who no longer work at Intel, I am posting these patches
for review. They make some fixes to function call history tests and add new MI commands
to access the function call history, including tests.

Regards,
Ari

Tim Wiederhake (4):
  [func_call] Add possible spelling of linker error message.
  [func_call] Fix MI output for function call history.
  [func_call] Add function-call-history-length command to MI.
  [func_call] Add function-call-history command to MI.

ravitheja.addepally (1):
  [func_call] New tests for a btrace crash.

 gdb/mi/mi-cmds.c                              |  13 +-
 gdb/mi/mi-cmds.h                              |   2 +
 gdb/record-btrace.c                           |  38 +++-
 gdb/record.c                                  |  61 ++++++
 gdb/record.h                                  |  11 ++
 gdb/target-delegates.c                        |  23 +++
 gdb/target.c                                  |   8 +
 gdb/target.h                                  |   7 +
 ...rver-multithreaded-function-call-history.c |  70 +++++++
 ...er-multithreaded-function-call-history.exp |  61 ++++++
 .../gdb.mi/mi-function_call_history.c         |  43 ++++
 .../gdb.mi/mi-function_call_history.exp       | 183 ++++++++++++++++++
 gdb/testsuite/lib/gdb.exp                     |   3 +
 13 files changed, 513 insertions(+), 10 deletions(-)
 create mode 100644 gdb/testsuite/gdb.btrace/server-multithreaded-function-call-history.c
 create mode 100644 gdb/testsuite/gdb.btrace/server-multithreaded-function-call-history.exp
 create mode 100644 gdb/testsuite/gdb.mi/mi-function_call_history.c
 create mode 100644 gdb/testsuite/gdb.mi/mi-function_call_history.exp

-- 
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


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH 1/5] [func_call] Add possible spelling of linker error message.
  2022-02-10 13:52 [PATCH 0/5] Functions call history patches Ari Hannula
@ 2022-02-10 13:52 ` Ari Hannula
  2022-03-17 17:58   ` Metzger, Markus T
  2022-02-10 13:52 ` [PATCH 2/5] [func_call] New tests for a btrace crash Ari Hannula
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 11+ messages in thread
From: Ari Hannula @ 2022-02-10 13:52 UTC (permalink / raw)
  To: gdb-patches; +Cc: Tim Wiederhake, Ari Hannula

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

Seen with RHEL 7.5 and Fedora 26.

gdb/testsuite/ChangeLog:
2019-02-18  Tim Wiederhake  <tim.wiederhake@intel.com>

	* lib/gdb.exp (gdb_compile_pthreads): Add new error regexp.

Signed-off-by: Tim Wiederhake <tim.wiederhake@intel.com>
Signed-off-by: Ari Hannula <ari.hannula@intel.com>
---
 gdb/testsuite/lib/gdb.exp | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp
index a3717a4022..363289caa1 100644
--- a/gdb/testsuite/lib/gdb.exp
+++ b/gdb/testsuite/lib/gdb.exp
@@ -4618,6 +4618,9 @@ proc gdb_compile_pthreads {source dest type options} {
                 set why_msg "missing threads include file"
                 break
             }
+            ".*cannot find -lpthread.*" {
+                set why_msg "missing runtime threads library"
+            }
             ".*cannot open -lpthread.*" {
                 set why_msg "missing runtime threads library"
             }
-- 
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


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH 2/5] [func_call] New tests for a btrace crash.
  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-02-10 13:52 ` 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
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 11+ messages in thread
From: Ari Hannula @ 2022-02-10 13:52 UTC (permalink / raw)
  To: gdb-patches; +Cc: ravitheja.addepally, Ari Hannula

From: "ravitheja.addepally" <ravitheja.addepally@intel.com>

During remote debugging when stoppin in the start-routine of a pthread,
GDB crashes when attempting to display function-call-history.

gdb/testsuite/ChangeLog:
2015-04-27  ravitheja.addepally  <ravitheja.addepally@intel.com>

	* gdb.btrace/server-multithreaded-function-call-history.c: New file.
	* gdb.btrace/server-multithreaded-function-call-history.exp: New file.

Signed-off-by: ravitheja.addepally <ravitheja.addepally@intel.com>
Signed-off-by: Ari Hannula <ari.hannula@intel.com>
---
 ...rver-multithreaded-function-call-history.c | 70 +++++++++++++++++++
 ...er-multithreaded-function-call-history.exp | 61 ++++++++++++++++
 2 files changed, 131 insertions(+)
 create mode 100644 gdb/testsuite/gdb.btrace/server-multithreaded-function-call-history.c
 create mode 100644 gdb/testsuite/gdb.btrace/server-multithreaded-function-call-history.exp

diff --git a/gdb/testsuite/gdb.btrace/server-multithreaded-function-call-history.c b/gdb/testsuite/gdb.btrace/server-multithreaded-function-call-history.c
new file mode 100644
index 0000000000..4dbe4c1fe8
--- /dev/null
+++ b/gdb/testsuite/gdb.btrace/server-multithreaded-function-call-history.c
@@ -0,0 +1,70 @@
+/* Manythreads test program.
+   Copyright 2004-2022 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   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/>.
+
+   Copied from gdb.threads/manythreads.c  */
+
+#include <pthread.h>
+#ifdef DEBUG
+#include <stdio.h>
+#endif
+#include <limits.h>
+
+void *
+thread_function (void *arg)
+{
+  int x = * (int *) arg;
+
+#ifdef DEBUG
+  printf ("Thread <%d> executing\n", x);
+#endif /* DEBUG */
+
+  return NULL;
+}
+
+int 
+main (int argc, char **argv)
+{
+  pthread_attr_t attr;
+  pthread_t threads[256];
+  int args[256];
+  int i, j;
+
+  pthread_attr_init (&attr);
+
+#ifdef PTHREAD_STACK_MIN
+  pthread_attr_setstacksize (&attr, 2*PTHREAD_STACK_MIN);
+#endif
+
+  /* Create a ton of quick-executing threads, then wait for them to
+     complete.  */
+  for (i = 0; i < 1000; ++i) 
+    {
+      for (j = 0; j < 256; ++j)
+	{
+	  args[j] = i * 1000 + j;
+	  pthread_create (&threads[j], &attr, thread_function, &args[j]);
+	}
+
+      for (j = 0; j < 256; ++j)
+	  pthread_join (threads[j], NULL);
+    }
+
+  pthread_attr_destroy (&attr);
+
+  return 0;
+}
diff --git a/gdb/testsuite/gdb.btrace/server-multithreaded-function-call-history.exp b/gdb/testsuite/gdb.btrace/server-multithreaded-function-call-history.exp
new file mode 100644
index 0000000000..3af51c4228
--- /dev/null
+++ b/gdb/testsuite/gdb.btrace/server-multithreaded-function-call-history.exp
@@ -0,0 +1,61 @@
+# This testcase is part of GDB, the GNU debugger.
+
+# Copyright 2005-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/>.
+
+load_lib gdbserver-support.exp
+
+standard_testfile
+
+if { [skip_gdbserver_tests] } {
+    return 0
+}
+
+if { [skip_btrace_tests] } {
+    return -1
+}
+
+set opts { debug }
+if [info exists DEBUG] {
+    lappend opts "additional_flags=-DDEBUG"
+}
+
+if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable $opts] != "" } {
+    return -1
+}
+
+gdb_exit
+gdb_start
+gdb_load $binfile
+
+# Make sure we're disconnected, in case we're testing with an
+# extended-remote board, therefore already connected.
+gdb_test "disconnect" ".*"
+
+gdbserver_run ""
+gdb_reinitialize_dir $srcdir/$subdir
+
+gdb_breakpoint main
+gdb_test "continue" "Breakpoint.* main .*" "continue to main"
+
+gdb_test_no_output "record btrace"
+
+gdb_breakpoint thread_function
+gdb_test "continue" "Breakpoint.* thread_function .*" "continue to thread_function one"
+
+# test passes if this does not crash
+gdb_test "record function-call-history" ".*"
+
+gdb_test "continue" "Breakpoint.* thread_function .*" "continue to thread_function two"
-- 
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


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH 3/5] [func_call] Fix MI output for function call history.
  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-02-10 13:52 ` [PATCH 2/5] [func_call] New tests for a btrace crash Ari Hannula
@ 2022-02-10 13:52 ` Ari Hannula
  2022-03-17 17:58   ` Metzger, Markus T
  2022-02-10 13:52 ` [PATCH 4/5] [func_call] Add function-call-history-length command to MI Ari Hannula
  2022-02-10 13:52 ` [PATCH 5/5] [func_call] Add function-call-history " Ari Hannula
  4 siblings, 1 reply; 11+ messages in thread
From: Ari Hannula @ 2022-02-10 13:52 UTC (permalink / raw)
  To: gdb-patches; +Cc: Tim Wiederhake, Ari Hannula

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

"record function-call-history" formats its output as one single tuple with
the same keys for every line.  Fix by turning the output into a list of
tuples and the indentation into an optional "level" field.

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

	* record-btrace.c (btrace_call_history): Emit individual tuples.
	(record_btrace_target::call_history): Emit list instead of tuple,
	fix field name.
	(record_btrace_target::call_history_range): Emit list instead of
	tuple.

Signed-off-by: Tim Wiederhake <tim.wiederhake@intel.com>
Signed-off-by: Ari Hannula <ari.hannula@intel.com>
---
 gdb/record-btrace.c | 14 +++++++++-----
 1 file changed, 9 insertions(+), 5 deletions(-)

diff --git a/gdb/record-btrace.c b/gdb/record-btrace.c
index 3dfdf592dd..dd5f4b4dd7 100644
--- a/gdb/record-btrace.c
+++ b/gdb/record-btrace.c
@@ -1156,6 +1156,7 @@ btrace_call_history (struct ui_out *uiout,
 
   for (it = *begin; btrace_call_cmp (&it, end) < 0; btrace_call_next (&it, 1))
     {
+      ui_out_emit_tuple tuple_emitter (uiout, nullptr);
       const struct btrace_function *bfun;
       struct minimal_symbol *msym;
       struct symbol *sym;
@@ -1185,10 +1186,13 @@ btrace_call_history (struct ui_out *uiout,
 
       if ((flags & RECORD_PRINT_INDENT_CALLS) != 0)
 	{
-	  int level = bfun->level + btinfo->level, i;
+	  const int level = bfun->level + btinfo->level;
 
-	  for (i = 0; i < level; ++i)
-	    uiout->text ("  ");
+	  if (uiout->is_mi_like_p ())
+	    uiout->field_signed ("level", level);
+	  else
+	    for (int i = 0; i < level; ++i)
+	      uiout->text ("  ");
 	}
 
       if (sym != NULL)
@@ -1229,7 +1233,7 @@ record_btrace_target::call_history (int size, record_print_flags flags)
   unsigned int context, covered;
 
   uiout = current_uiout;
-  ui_out_emit_tuple tuple_emitter (uiout, "insn history");
+  ui_out_emit_list list_emitter (uiout, "func history");
   context = abs (size);
   if (context == 0)
     error (_("Bad record function-call-history-size."));
@@ -1316,7 +1320,7 @@ record_btrace_target::call_history_range (ULONGEST from, ULONGEST to,
   int found;
 
   uiout = current_uiout;
-  ui_out_emit_tuple tuple_emitter (uiout, "func history");
+  ui_out_emit_list list_emitter (uiout, "func history");
   low = from;
   high = to;
 
-- 
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


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH 4/5] [func_call] Add function-call-history-length command to MI.
  2022-02-10 13:52 [PATCH 0/5] Functions call history patches Ari Hannula
                   ` (2 preceding siblings ...)
  2022-02-10 13:52 ` [PATCH 3/5] [func_call] Fix MI output for function call history Ari Hannula
@ 2022-02-10 13:52 ` Ari Hannula
  2022-03-17 17:59   ` Metzger, Markus T
  2022-02-10 13:52 ` [PATCH 5/5] [func_call] Add function-call-history " Ari Hannula
  4 siblings, 1 reply; 11+ messages in thread
From: Ari Hannula @ 2022-02-10 13:52 UTC (permalink / raw)
  To: gdb-patches; +Cc: Tim Wiederhake, Ari Hannula

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


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH 5/5] [func_call] Add function-call-history command to MI.
  2022-02-10 13:52 [PATCH 0/5] Functions call history patches Ari Hannula
                   ` (3 preceding siblings ...)
  2022-02-10 13:52 ` [PATCH 4/5] [func_call] Add function-call-history-length command to MI Ari Hannula
@ 2022-02-10 13:52 ` Ari Hannula
  4 siblings, 0 replies; 11+ messages in thread
From: Ari Hannula @ 2022-02-10 13:52 UTC (permalink / raw)
  To: gdb-patches; +Cc: Tim Wiederhake, Ari Hannula

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

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

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

	* mi/mi-cmds.c (mi_cmds): Add mi_cmd_record_function_call_history.
	* mi/mi-cmds.h (mi_cmd_record_function_call_history): New declaration.
	* record.c (mi_cmd_record_function_call_history): New function.
	* record.h (mi_cmd_record_function_call_hisotry): New declaration.

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

	* gdb.mi/mi-function_call_history.exp: Add tests.

Signed-off-by: Tim Wiederhake <tim.wiederhake@intel.com>
Signed-off-by: Ari Hannula <ari.hannula@intel.com>
---
 gdb/mi/mi-cmds.c                              |  1 +
 gdb/mi/mi-cmds.h                              |  1 +
 gdb/record.c                                  | 50 ++++++++++
 gdb/record.h                                  |  5 +
 .../gdb.mi/mi-function_call_history.exp       | 95 +++++++++++++++++++
 5 files changed, 152 insertions(+)

diff --git a/gdb/mi/mi-cmds.c b/gdb/mi/mi-cmds.c
index 945a439d3a..f41b5aa01a 100644
--- a/gdb/mi/mi-cmds.c
+++ b/gdb/mi/mi-cmds.c
@@ -281,6 +281,7 @@ add_builtin_mi_commands ()
 		 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 ("function-call-history", mi_cmd_record_function_call_history);
   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 63da17ed01..6256c2001b 100644
--- a/gdb/mi/mi-cmds.h
+++ b/gdb/mi/mi-cmds.h
@@ -89,6 +89,7 @@ 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_record_function_call_history;
 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.c b/gdb/record.c
index 75375b4288..191f831dec 100644
--- a/gdb/record.c
+++ b/gdb/record.c
@@ -766,6 +766,56 @@ mi_cmd_record_function_call_history_length (const char *command,
   target_call_history_length ();
 }
 
+void
+mi_cmd_record_function_call_history (const char *command, char **argv,
+				     int argc)
+{
+  record_print_flags flags = 0;
+  unsigned int low, high;
+  char *charend;
+
+  if ((argc < 0) || (argc > 3))
+    error (_("-function-call-history: Invalid number of arguments."));
+
+  require_record_target ();
+
+  if ((argc == 1) || (argc == 3))
+    {
+      const char *targv = argv[0];
+      flags = get_call_history_modifiers (&targv);
+    }
+
+  if ((argc == 0) || (argc == 1))
+    {
+      const int size = command_size_to_target_size (record_call_history_size);
+      target_call_history (size, flags);
+      return;
+    }
+
+  if (argc == 3)
+    {
+      low = strtoul (argv[1], &charend, 10);
+      if (*charend != '\0')
+	error (_("Invalid syntax of begin func id '%s'"), argv[1]);
+
+      high = strtoul (argv[2], &charend, 10);
+      if (*charend != '\0')
+	error (_("Invalid syntax of end func id '%s'"), argv[2]);
+    }
+  else
+    {
+      low = strtoul (argv[0], &charend, 10);
+      if (*charend != '\0')
+	error (_("Invalid syntax of begin func id '%s'"), argv[0]);
+
+      high = strtoul (argv[1], &charend, 10);
+      if (*charend != '\0')
+	error (_("Invalid syntax of end func id '%s'"), argv[1]);
+    }
+
+  target_call_history_range (low, high, flags);
+}
+
 void _initialize_record ();
 void
 _initialize_record ()
diff --git a/gdb/record.h b/gdb/record.h
index 174b71c67c..96825bac49 100644
--- a/gdb/record.h
+++ b/gdb/record.h
@@ -120,4 +120,9 @@ extern void mi_cmd_record_function_call_history_length (char *command,
 							char **argv,
 							int argc);
 
+/* The MI version of the command to get the function call history for record
+   targets.  */
+extern void mi_cmd_record_function_call_history (char *command, char **argv,
+						 int argc);
+
 #endif /* RECORD_H */
diff --git a/gdb/testsuite/gdb.mi/mi-function_call_history.exp b/gdb/testsuite/gdb.mi/mi-function_call_history.exp
index 948a04a5ed..7876cf9d16 100644
--- a/gdb/testsuite/gdb.mi/mi-function_call_history.exp
+++ b/gdb/testsuite/gdb.mi/mi-function_call_history.exp
@@ -69,10 +69,57 @@ 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 "121-function-call-history" \
+    "121\\^done,func history=\\\[\{index=\"12\",function=\"inc\"\},\{index=\"13\",function=\"main\"\},\{index=\"14\",function=\"inc\"\},\{index=\"15\",function=\"main\"\},\{index=\"16\",function=\"inc\"\},\{index=\"17\",function=\"main\"\},\{index=\"18\",function=\"inc\"\},\{index=\"19\",function=\"main\"\},\{index=\"20\",function=\"inc\"\},\{index=\"21\",function=\"main\"\}\\\]" \
+    "121 function call history default without flags"
+
+send_gdb "122-function-call-history\n"
+gdb_expect {
+    -re "\"At the end of the branch trace record..*\\^done,func history=[].*$mi_gdb_prompt$" {
+	#Done
+    }
+    default {
+	perror "122 Function call history failed"
+	return -1
+    }
+}
+
+mi_gdb_test "123-function-call-history 12 16" \
+    "123\\^done,func history=\\\[\{index=\"12\",function=\"inc\"\},\{index=\"13\",function=\"main\"\},\{index=\"14\",function=\"inc\"\},\{index=\"15\",function=\"main\"\},\{index=\"16\",function=\"inc\"\}\\\]" \
+    "123 function call history range without flags"
+
+mi_gdb_test "124-function-call-history 12 13" \
+    "124\\^done,func history=\\\[\{index=\"12\",function=\"inc\"\},\{index=\"13\",function=\"main\"\}\\\]" \
+    "124 function call history range without flags"
+
 mi_gdb_test "125-function-call-history-length" \
     "125\\^done,func history length=\\\[\{end=\"21\"\}\\\]" \
     "125 function call history length"
 
+mi_gdb_test "126-function-call-history 22 23" \
+    "126\\^error,msg=\"Range out of bounds.\"" \
+    "126 function call history range error check"
+
+mi_gdb_test "127-function-call-history /lc" \
+    "127\\^done,func history=\\\[\{index=\"14\",level=\"1\",function=\"inc\"\,file=\"$srcdir/$subdir/$testfile.c\",.*},\{index=\"15\",level=\"0\",function=\"main\"\,file=\"$srcdir/$subdir/$testfile.c\",.*},\{index=\"16\",level=\"1\",function=\"inc\"\,file=\"$srcdir/$subdir/$testfile.c\",.*},\{index=\"17\",level=\"0\",function=\"main\"\,file=\"$srcdir/$subdir/$testfile.c\",.*},\{index=\"18\",level=\"1\",function=\"inc\"\,file=\"$srcdir/$subdir/$testfile.c\",.*},\{index=\"19\",level=\"0\",function=\"main\"\,file=\"$srcdir/$subdir/$testfile.c\",.*},\{index=\"20\",level=\"1\",function=\"inc\"\,file=\"$srcdir/$subdir/$testfile.c\",.*},\{index=\"21\",level=\"0\",function=\"main\",file=\"$srcdir/$subdir/$testfile.c\",.*\}\\\]" \
+    "127 function call history default with flags"
+
+mi_gdb_test "128-function-call-history /lc 14 20" \
+    "128\\^done,func history=\\\[\{index=\"14\",level=\"1\",function=\"inc\"\,file=\"$srcdir/$subdir/$testfile.c\",.*},\{index=\"15\",level=\"0\",function=\"main\"\,file=\"$srcdir/$subdir/$testfile.c\",.*},\{index=\"16\",level=\"1\",function=\"inc\"\,file=\"$srcdir/$subdir/$testfile.c\",.*},\{index=\"17\",level=\"0\",function=\"main\"\,file=\"$srcdir/$subdir/$testfile.c\",.*},\{index=\"18\",level=\"1\",function=\"inc\"\,file=\"$srcdir/$subdir/$testfile.c\",.*},\{index=\"19\",level=\"0\",function=\"main\"\,file=\"$srcdir/$subdir/$testfile.c\",.*},\{index=\"20\",level=\"1\",function=\"inc\"\,file=\"$srcdir/$subdir/$testfile.c\",.*\}\\\]" \
+    "128 function call history range with flags"
+
+mi_gdb_test "129-function-call-history /lc 1 5" \
+    "129\\^done,func history=\\\[\{index=\"1\",level=\"0\",function=\"main\"\,file=\"$srcdir/$subdir/$testfile.c\",.*},\{index=\"2\",level=\"1\",function=\"inc\"\,file=\"$srcdir/$subdir/$testfile.c\",.*},\{index=\"3\",level=\"0\",function=\"main\"\,file=\"$srcdir/$subdir/$testfile.c\",.*},\{index=\"4\",level=\"1\",function=\"inc\"\,file=\"$srcdir/$subdir/$testfile.c\",.*},\{index=\"5\",level=\"0\",function=\"main\"\,file=\"$srcdir/$subdir/$testfile.c\",.*\}\\\]" \
+    "129 function call history range with flags"
+
+mi_gdb_test "130-function-call-history /l 1 5" \
+    "130\\^done,func history=\\\[\{index=\"1\",function=\"main\"\,file=\"$srcdir/$subdir/$testfile.c\",.*},\{index=\"2\",function=\"inc\"\,file=\"$srcdir/$subdir/$testfile.c\",.*},\{index=\"3\",function=\"main\"\,file=\"$srcdir/$subdir/$testfile.c\",.*},\{index=\"4\",function=\"inc\"\,file=\"$srcdir/$subdir/$testfile.c\",.*},\{index=\"5\",function=\"main\"\,file=\"$srcdir/$subdir/$testfile.c\",.*\}\\\]" \
+    "130 function call history range with flags"
+
+mi_gdb_test "131-function-call-history /c 1 5" \
+    "131\\^done,func history=\\\[\{index=\"1\",level=\"0\",function=\"main\"\},\{index=\"2\",level=\"1\",function=\"inc\"\},\{index=\"3\",level=\"0\",function=\"main\"\},\{index=\"4\",level=\"1\",function=\"inc\"\},\{index=\"5\",level=\"0\",function=\"main\"\}\\\]" \
+    "131 function call history range with flags"
+
 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
 
@@ -81,8 +128,56 @@ 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 "221-function-call-history" \
+    "221\\^done,func history=\\\[\{index=\"366\",function=\"fib\"\},\{index=\"367\",function=\"fib\"\},\{index=\"368\",function=\"fib\"\},\{index=\"369\",function=\"fib\"\},\{index=\"370\",function=\"fib\"\},\{index=\"371\",function=\"fib\"\},\{index=\"372\",function=\"fib\"\},\{index=\"373\",function=\"fib\"\},\{index=\"374\",function=\"fib\"\},\{index=\"375\",function=\"main\"\}\\\]" \
+    "221 function call history default without flags"
+
+send_gdb "222-function-call-history\n"
+
+gdb_expect {
+    -re "\"At the end of the branch trace record..*\\^done,func history=[].*$mi_gdb_prompt$" {
+	#Done
+    }
+    default {
+	perror "222 Function call history failed"
+	return -1
+    }
+}
+
+mi_gdb_test "223-function-call-history 12 16" \
+    "223\\^done,func history=\\\[\{index=\"12\",function=\"inc\"\},\{index=\"13\",function=\"main\"\},\{index=\"14\",function=\"inc\"\},\{index=\"15\",function=\"main\"\},\{index=\"16\",function=\"inc\"\}\\\]" \
+    "223 function call history range without flags"
+
+mi_gdb_test "224-function-call-history 366 368" \
+    "224\\^done,func history=\\\[\{index=\"366\",function=\"fib\"\},\{index=\"367\",function=\"fib\"\},\{index=\"368\",function=\"fib\"\}\\\]" \
+    "224 function call history range without flags"
+
 mi_gdb_test "225-function-call-history-length" \
     "225\\^done,func history length=\\\[\{end=\"375\"\}\\\]" \
     "225 function call history length"
 
+mi_gdb_test "226-function-call-history 376 400" \
+    "226\\^error,msg=\"Range out of bounds.\"" \
+    "226 function call history range error check"
+
+mi_gdb_test "227-function-call-history /lc" \
+    "227\\^done,func history=\\\[\{index=\"369\",level=\"6\",function=\"fib\"\,file=\"$srcdir/$subdir/$testfile.c\",.*},\{index=\"370\",level=\"5\",function=\"fib\"\,file=\"$srcdir/$subdir/$testfile.c\",.*},\{index=\"371\",level=\"4\",function=\"fib\"\,file=\"$srcdir/$subdir/$testfile.c\",.*},\{index=\"372\",level=\"3\",function=\"fib\"\,file=\"$srcdir/$subdir/$testfile.c\",.*},\{index=\"373\",level=\"2\",function=\"fib\"\,file=\"$srcdir/$subdir/$testfile.c\",.*},\{index=\"374\",level=\"1\",function=\"fib\"\,file=\"$srcdir/$subdir/$testfile.c\",.*},\{index=\"375\",level=\"0\",function=\"main\"\,file=\"$srcdir/$subdir/$testfile.c\",.*}\\\]" \
+    "227 function call history default with flags"
+
+mi_gdb_test "228-function-call-history /lc 14 20" \
+    "228\\^done,func history=\\\[\{index=\"14\",level=\"1\",function=\"inc\"\,file=\"$srcdir/$subdir/$testfile.c\",.*},\{index=\"15\",level=\"0\",function=\"main\"\,file=\"$srcdir/$subdir/$testfile.c\",.*},\{index=\"16\",level=\"1\",function=\"inc\"\,file=\"$srcdir/$subdir/$testfile.c\",.*},\{index=\"17\",level=\"0\",function=\"main\"\,file=\"$srcdir/$subdir/$testfile.c\",.*},\{index=\"18\",level=\"1\",function=\"inc\"\,file=\"$srcdir/$subdir/$testfile.c\",.*},\{index=\"19\",level=\"0\",function=\"main\"\,file=\"$srcdir/$subdir/$testfile.c\",.*},\{index=\"20\",level=\"1\",function=\"inc\"\,file=\"$srcdir/$subdir/$testfile.c\",.*\}\\\]" \
+    "228 function call history range with flags"
+
+mi_gdb_test "229-function-call-history /lc 1 5" \
+    "229\\^done,func history=\\\[\{index=\"1\",level=\"0\",function=\"main\"\,file=\"$srcdir/$subdir/$testfile.c\",.*},\{index=\"2\",level=\"1\",function=\"inc\"\,file=\"$srcdir/$subdir/$testfile.c\",.*},\{index=\"3\",level=\"0\",function=\"main\"\,file=\"$srcdir/$subdir/$testfile.c\",.*},\{index=\"4\",level=\"1\",function=\"inc\"\,file=\"$srcdir/$subdir/$testfile.c\",.*},\{index=\"5\",level=\"0\",function=\"main\"\,file=\"$srcdir/$subdir/$testfile.c\",.*\}\\\]" \
+    "229 function call history range with flags"
+
+mi_gdb_test "230-function-call-history /l 1 5" \
+    "230\\^done,func history=\\\[\{index=\"1\",function=\"main\"\,file=\"$srcdir/$subdir/$testfile.c\",.*},\{index=\"2\",function=\"inc\"\,file=\"$srcdir/$subdir/$testfile.c\",.*},\{index=\"3\",function=\"main\"\,file=\"$srcdir/$subdir/$testfile.c\",.*},\{index=\"4\",function=\"inc\"\,file=\"$srcdir/$subdir/$testfile.c\",.*},\{index=\"5\",function=\"main\"\,file=\"$srcdir/$subdir/$testfile.c\",.*\}\\\]" \
+    "230 function call history range with flags"
+
+mi_gdb_test "231-function-call-history /c 1 5" \
+    "231\\^done,func history=\\\[\{index=\"1\",level=\"0\",function=\"main\"\},\{index=\"2\",level=\"1\",function=\"inc\"\},\{index=\"3\",level=\"0\",function=\"main\"\},\{index=\"4\",level=\"1\",function=\"inc\"\},\{index=\"5\",level=\"0\",function=\"main\"\}\\\]" \
+    "231 function call history range with flags"
+
 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


^ permalink raw reply	[flat|nested] 11+ messages in thread

* RE: [PATCH 1/5] [func_call] Add possible spelling of linker error message.
  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
  0 siblings, 1 reply; 11+ messages in thread
From: Metzger, Markus T @ 2022-03-17 17:58 UTC (permalink / raw)
  To: Hannula, Ari; +Cc: Tim Wiederhake, gdb-patches, keiths

Hello Ari,

>Seen with RHEL 7.5 and Fedora 26.
>
>gdb/testsuite/ChangeLog:
>2019-02-18  Tim Wiederhake  <tim.wiederhake@intel.com>
>
>	* lib/gdb.exp (gdb_compile_pthreads): Add new error regexp.
>
>Signed-off-by: Tim Wiederhake <tim.wiederhake@intel.com>
>Signed-off-by: Ari Hannula <ari.hannula@intel.com>
>---
> gdb/testsuite/lib/gdb.exp | 3 +++
> 1 file changed, 3 insertions(+)
>
>diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp
>index a3717a4022..363289caa1 100644
>--- a/gdb/testsuite/lib/gdb.exp
>+++ b/gdb/testsuite/lib/gdb.exp
>@@ -4618,6 +4618,9 @@ proc gdb_compile_pthreads {source dest type options}
>{
>                 set why_msg "missing threads include file"
>                 break
>             }
>+            ".*cannot find -lpthread.*" {
>+                set why_msg "missing runtime threads library"
>+            }
>             ".*cannot open -lpthread.*" {
>                 set why_msg "missing runtime threads library"
>             }
>--
>2.25.1

LGTM but you need Keith or a global maintainer to approve this.

Regards,
Markus.
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


^ permalink raw reply	[flat|nested] 11+ messages in thread

* RE: [PATCH 2/5] [func_call] New tests for a btrace crash.
  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
  0 siblings, 0 replies; 11+ messages in thread
From: Metzger, Markus T @ 2022-03-17 17:58 UTC (permalink / raw)
  To: Hannula, Ari; +Cc: gdb-patches, ravitheja.addepally

Hello Ari,

>During remote debugging when stoppin in the start-routine of a pthread,

Typo: stoppin

>GDB crashes when attempting to display function-call-history.
>
>gdb/testsuite/ChangeLog:
>2015-04-27  ravitheja.addepally  <ravitheja.addepally@intel.com>
>
>	* gdb.btrace/server-multithreaded-function-call-history.c: New file.
>	* gdb.btrace/server-multithreaded-function-call-history.exp: New file.

GDB is no longer using change logs.

This patch is quite old.  Is GDB still crashing?  Is there a fix for the crash in
your patch series?

We shouldn't introduce failing tests before the fix.  This hurts bisecting.
It would be better to fix an issue and add a regression test in the same patch.


>diff --git a/gdb/testsuite/gdb.btrace/server-multithreaded-function-call-
>history.exp b/gdb/testsuite/gdb.btrace/server-multithreaded-function-call-
>history.exp
>new file mode 100644
>index 0000000000..3af51c4228
>--- /dev/null
>+++ b/gdb/testsuite/gdb.btrace/server-multithreaded-function-call-history.exp
>@@ -0,0 +1,61 @@
>+# This testcase is part of GDB, the GNU debugger.
>+
>+# Copyright 2005-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/>.

Could you briefly describe what this test is doing in an initial comment?

>+
>+load_lib gdbserver-support.exp
>+
>+standard_testfile
>+
>+if { [skip_gdbserver_tests] } {

There should be an untested message here...

>+    return 0
>+}
>+
>+if { [skip_btrace_tests] } {

...and here.

>+    return -1

Not sure it matters but why are there different return values for the
different skip checks?

>+}
>+
>+set opts { debug }
>+if [info exists DEBUG] {
>+    lappend opts "additional_flags=-DDEBUG"
>+}
>+
>+if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable
>$opts] != "" } {
>+    return -1
>+}

I think you should be able to use prepare_for_testing and pass pthreads as
build option similar to debug.

>+
>+gdb_exit
>+gdb_start
>+gdb_load $binfile
>+
>+# Make sure we're disconnected, in case we're testing with an
>+# extended-remote board, therefore already connected.
>+gdb_test "disconnect" ".*"
>+
>+gdbserver_run ""
>+gdb_reinitialize_dir $srcdir/$subdir
>+
>+gdb_breakpoint main
>+gdb_test "continue" "Breakpoint.* main .*" "continue to main"
>+
>+gdb_test_no_output "record btrace"
>+
>+gdb_breakpoint thread_function
>+gdb_test "continue" "Breakpoint.* thread_function .*" "continue to
>thread_function one"

How about gdb_continue_to_breakpoint?

>+
>+# test passes if this does not crash
>+gdb_test "record function-call-history" ".*"
>+
>+gdb_test "continue" "Breakpoint.* thread_function .*" "continue to
>thread_function two"

Is this last continue still necessary?

Regards,
Markus.
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


^ permalink raw reply	[flat|nested] 11+ messages in thread

* RE: [PATCH 3/5] [func_call] Fix MI output for function call history.
  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
  0 siblings, 0 replies; 11+ messages in thread
From: Metzger, Markus T @ 2022-03-17 17:58 UTC (permalink / raw)
  To: Hannula, Ari; +Cc: Tim Wiederhake, gdb-patches

Hello Ari,

>"record function-call-history" formats its output as one single tuple with
>the same keys for every line.  Fix by turning the output into a list of
>tuples and the indentation into an optional "level" field.
>
>gdb/ChangeLog:
>2018-12-27  Tim Wiederhake  <tim.wiederhake@intel.com>
>
>	* record-btrace.c (btrace_call_history): Emit individual tuples.
>	(record_btrace_target::call_history): Emit list instead of tuple,
>	fix field name.
>	(record_btrace_target::call_history_range): Emit list instead of
>	tuple.
>
>Signed-off-by: Tim Wiederhake <tim.wiederhake@intel.com>
>Signed-off-by: Ari Hannula <ari.hannula@intel.com>
>---
> gdb/record-btrace.c | 14 +++++++++-----
> 1 file changed, 9 insertions(+), 5 deletions(-)

LGTM.

Note that GDB is no longer using changelogs.

Regards,
Markus.
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


^ permalink raw reply	[flat|nested] 11+ messages in thread

* RE: [PATCH 4/5] [func_call] Add function-call-history-length command to MI.
  2022-02-10 13:52 ` [PATCH 4/5] [func_call] Add function-call-history-length command to MI Ari Hannula
@ 2022-03-17 17:59   ` Metzger, Markus T
  0 siblings, 0 replies; 11+ messages in thread
From: Metzger, Markus T @ 2022-03-17 17:59 UTC (permalink / raw)
  To: Hannula, Ari; +Cc: Tim Wiederhake, gdb-patches

Hello Ari,

>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);

Those changes appear to be unrelated.  You may want to
send them in a separate patch.

>   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);

Those, as well.

>@@ -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;

You'd want to check that the trace is not empty.

Also, the end iterator points one beyond the last function.

There is similar code in record_btrace_target::info_record().
Let's extract that into a separate function so we're sure we
report the same numbers in 'info record' and here.


>+
>+  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);
>+    }

Could we use the same code for both MI and CLI?
Should the field be called 'length' instead of 'end'?


>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 */

Why would this go into record.[hc] and not, say, some gdb/mi/mi-cmd-*.[hc]?


>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/>.

Would you please briefly comment what this test does?

>+set errorInfo
>+
>+if [skip_btrace_tests] {

There should be an untested message.

>+    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}]
>!= "" } {

I think the default should be to use prepare_for_testing.

>+     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
>+    }
>+}

Would this work with gdb_test_multiple instead of separate send and expect?

Looks like this might be used more often if we want to test btrace over MI.
Would it make sense to put this into some mi_gdb_record function?

>+
>+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

Regards,
Markus.
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


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 1/5] [func_call] Add possible spelling of linker error message.
  2022-03-17 17:58   ` Metzger, Markus T
@ 2022-03-17 18:45     ` Keith Seitz
  0 siblings, 0 replies; 11+ messages in thread
From: Keith Seitz @ 2022-03-17 18:45 UTC (permalink / raw)
  To: Metzger, Markus T, Hannula, Ari; +Cc: Tim Wiederhake, gdb-patches

On 3/17/22 10:58, Metzger, Markus T wrote:
> Hello Ari,
> 
>> Seen with RHEL 7.5 and Fedora 26.
>>

Is there a little more that can be said? I gather this patch is
desired because the error message is simply different on some systems?

>> gdb/testsuite/ChangeLog:
>> 2019-02-18  Tim Wiederhake  <tim.wiederhake@intel.com>
>>
>> 	* lib/gdb.exp (gdb_compile_pthreads): Add new error regexp.
>>

As mentioned, you can drop these ChangeLog entries.

>> Signed-off-by: Tim Wiederhake <tim.wiederhake@intel.com>
>> Signed-off-by: Ari Hannula <ari.hannula@intel.com>
>> ---
>> gdb/testsuite/lib/gdb.exp | 3 +++
>> 1 file changed, 3 insertions(+)
>>
>> diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp
>> index a3717a4022..363289caa1 100644
>> --- a/gdb/testsuite/lib/gdb.exp
>> +++ b/gdb/testsuite/lib/gdb.exp
>> @@ -4618,6 +4618,9 @@ proc gdb_compile_pthreads {source dest type options}
>> {
>>                  set why_msg "missing threads include file"
>>                  break
>>              }
>> +            ".*cannot find -lpthread.*" {
>> +                set why_msg "missing runtime threads library"
>> +            }
>>              ".*cannot open -lpthread.*" {
>>                  set why_msg "missing runtime threads library"
>>              }

If these are truly the same error condition, then since this switch statement
uses regexp-matching, we should be able to merge the two "missing runtime
threads library" cases with "(find|open)".

If they are actually different errors, I'd like to see `why_msg' reflect the
distinction.

> LGTM but you need Keith or a global maintainer to approve this.

This otherwise looks okay to me, too, but I am unable to officially approve
patches.

Keith


^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2022-03-17 18:45 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
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 ` [PATCH 4/5] [func_call] Add function-call-history-length command to MI Ari Hannula
2022-03-17 17:59   ` Metzger, Markus T
2022-02-10 13:52 ` [PATCH 5/5] [func_call] Add function-call-history " Ari Hannula

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).