Add `set print array-indexes' tests for C/C++ arrays
[binutils-gdb.git] / gdb / btrace.c
index 407f01ad740f0e43a54f157cace35fad42aa4f38..dc4d686ac4bc8c01a5803f2a663a59fb5fb02c0d 100644 (file)
@@ -1,6 +1,6 @@
 /* Branch trace support for GDB, the GNU debugger.
 
-   Copyright (C) 2013-2020 Free Software Foundation, Inc.
+   Copyright (C) 2013-2022 Free Software Foundation, Inc.
 
    Contributed by Intel Corp. <markus.t.metzger@intel.com>
 
@@ -62,7 +62,7 @@ static void btrace_add_pc (struct thread_info *tp);
   do                                                                   \
     {                                                                  \
       if (record_debug != 0)                                           \
-        fprintf_unfiltered (gdb_stdlog,                                        \
+       fprintf_unfiltered (gdb_stdlog,                                 \
                            "[btrace] " msg "\n", ##args);              \
     }                                                                  \
   while (0)
@@ -265,7 +265,7 @@ ftrace_new_function (struct btrace_thread_info *btinfo,
 static void
 ftrace_update_caller (struct btrace_function *bfun,
                      struct btrace_function *caller,
-                     enum btrace_function_flag flags)
+                     btrace_function_flags flags)
 {
   if (bfun->up != 0)
     ftrace_debug (bfun, "updating caller");
@@ -283,7 +283,7 @@ static void
 ftrace_fixup_caller (struct btrace_thread_info *btinfo,
                     struct btrace_function *bfun,
                     struct btrace_function *caller,
-                    enum btrace_function_flag flags)
+                    btrace_function_flags flags)
 {
   unsigned int prev, next;
 
@@ -1052,6 +1052,12 @@ btrace_compute_ftrace_bts (struct thread_info *tp,
                           const struct btrace_data_bts *btrace,
                           std::vector<unsigned int> &gaps)
 {
+ /* We may end up doing target calls that require the current thread to be TP,
+    for example reading memory through gdb_insn_length.  Make sure TP is the
+    current thread.  */
+  scoped_restore_current_thread restore_thread;
+  switch_to_thread (tp);
+
   struct btrace_thread_info *btinfo;
   struct gdbarch *gdbarch;
   unsigned int blk;
@@ -1222,6 +1228,9 @@ handle_pt_insn_events (struct btrace_thread_info *btinfo,
          break;
 
        case ptev_enabled:
+         if (event.status_update != 0)
+           break;
+
          if (event.variant.enabled.resumed == 0 && !btinfo->functions.empty ())
            {
              bfun = ftrace_new_gap (btinfo, BDE_PT_DISABLED, gaps);
@@ -1424,6 +1433,12 @@ btrace_compute_ftrace_pt (struct thread_info *tp,
                          const struct btrace_data_pt *btrace,
                          std::vector<unsigned int> &gaps)
 {
+ /* We may end up doing target calls that require the current thread to be TP,
+    for example reading memory through btrace_pt_readmem_callback.  Make sure
+    TP is the current thread.  */
+  scoped_restore_current_thread restore_thread;
+  switch_to_thread (tp);
+
   struct btrace_thread_info *btinfo;
   struct pt_insn_decoder *decoder;
   struct pt_config config;
@@ -1533,7 +1548,7 @@ btrace_compute_ftrace_1 (struct thread_info *tp,
       return;
     }
 
-  internal_error (__FILE__, __LINE__, _("Unkown branch trace format."));
+  internal_error (__FILE__, __LINE__, _("Unknown branch trace format."));
 }
 
 static void
@@ -1592,7 +1607,8 @@ void
 btrace_enable (struct thread_info *tp, const struct btrace_config *conf)
 {
   if (tp->btrace.target != NULL)
-    return;
+    error (_("Recording already enabled on thread %s (%s)."),
+          print_thread_id (tp), target_pid_to_str (tp->ptid).c_str ());
 
 #if !defined (HAVE_LIBIPT)
   if (conf->format == BTRACE_FORMAT_PT)
@@ -1600,13 +1616,13 @@ btrace_enable (struct thread_info *tp, const struct btrace_config *conf)
 #endif /* !defined (HAVE_LIBIPT) */
 
   DEBUG ("enable thread %s (%s)", print_thread_id (tp),
-        target_pid_to_str (tp->ptid).c_str ());
+        tp->ptid.to_string ().c_str ());
 
   tp->btrace.target = target_enable_btrace (tp->ptid, conf);
 
-  /* We're done if we failed to enable tracing.  */
   if (tp->btrace.target == NULL)
-    return;
+    error (_("Failed to enable recording on thread %s (%s)."),
+          print_thread_id (tp), target_pid_to_str (tp->ptid).c_str ());
 
   /* We need to undo the enable in case of errors.  */
   try
@@ -1651,10 +1667,11 @@ btrace_disable (struct thread_info *tp)
   struct btrace_thread_info *btp = &tp->btrace;
 
   if (btp->target == NULL)
-    return;
+    error (_("Recording not enabled on thread %s (%s)."),
+          print_thread_id (tp), target_pid_to_str (tp->ptid).c_str ());
 
   DEBUG ("disable thread %s (%s)", print_thread_id (tp),
-        target_pid_to_str (tp->ptid).c_str ());
+        tp->ptid.to_string ().c_str ());
 
   target_disable_btrace (btp->target);
   btp->target = NULL;
@@ -1673,7 +1690,7 @@ btrace_teardown (struct thread_info *tp)
     return;
 
   DEBUG ("teardown thread %s (%s)", print_thread_id (tp),
-        target_pid_to_str (tp->ptid).c_str ());
+        tp->ptid.to_string ().c_str ());
 
   target_teardown_btrace (btp->target);
   btp->target = NULL;
@@ -1791,7 +1808,7 @@ btrace_stitch_trace (struct btrace_data *btrace, struct thread_info *tp)
       return -1;
     }
 
-  internal_error (__FILE__, __LINE__, _("Unkown branch trace format."));
+  internal_error (__FILE__, __LINE__, _("Unknown branch trace format."));
 }
 
 /* Clear the branch trace histories in BTINFO.  */
@@ -1895,7 +1912,7 @@ btrace_fetch (struct thread_info *tp, const struct btrace_cpu *cpu)
   int errcode;
 
   DEBUG ("fetch thread %s (%s)", print_thread_id (tp),
-        target_pid_to_str (tp->ptid).c_str ());
+        tp->ptid.to_string ().c_str ());
 
   btinfo = &tp->btrace;
   tinfo = btinfo->target;
@@ -1908,11 +1925,12 @@ btrace_fetch (struct thread_info *tp, const struct btrace_cpu *cpu)
   if (btinfo->replay != NULL)
     return;
 
-  /* With CLI usage, TP->PTID always equals INFERIOR_PTID here.  Now that we
-     can store a gdb.Record object in Python referring to a different thread
-     than the current one, temporarily set INFERIOR_PTID.  */
-  scoped_restore save_inferior_ptid = make_scoped_restore (&inferior_ptid);
-  inferior_ptid = tp->ptid;
+  /* With CLI usage, TP is always the current thread when we get here.
+     However, since we can also store a gdb.Record object in Python
+     referring to a different thread than the current one, we need to
+     temporarily set the current thread.  */
+  scoped_restore_current_thread restore_thread;
+  switch_to_thread (tp);
 
   /* We should not be called on running or exited threads.  */
   gdb_assert (can_access_registers_thread (tp));
@@ -1971,7 +1989,7 @@ btrace_clear (struct thread_info *tp)
   struct btrace_thread_info *btinfo;
 
   DEBUG ("clear thread %s (%s)", print_thread_id (tp),
-        target_pid_to_str (tp->ptid).c_str ());
+        tp->ptid.to_string ().c_str ());
 
   /* Make sure btrace frames that may hold a pointer into the branch
      trace data are destroyed.  */
@@ -2834,122 +2852,122 @@ pt_print_packet (const struct pt_packet *packet)
   switch (packet->type)
     {
     default:
-      printf_unfiltered (("[??: %x]"), packet->type);
+      printf_filtered (("[??: %x]"), packet->type);
       break;
 
     case ppt_psb:
-      printf_unfiltered (("psb"));
+      printf_filtered (("psb"));
       break;
 
     case ppt_psbend:
-      printf_unfiltered (("psbend"));
+      printf_filtered (("psbend"));
       break;
 
     case ppt_pad:
-      printf_unfiltered (("pad"));
+      printf_filtered (("pad"));
       break;
 
     case ppt_tip:
-      printf_unfiltered (("tip %u: 0x%" PRIx64 ""),
-                        packet->payload.ip.ipc,
-                        packet->payload.ip.ip);
+      printf_filtered (("tip %u: 0x%" PRIx64 ""),
+                      packet->payload.ip.ipc,
+                      packet->payload.ip.ip);
       break;
 
     case ppt_tip_pge:
-      printf_unfiltered (("tip.pge %u: 0x%" PRIx64 ""),
-                        packet->payload.ip.ipc,
-                        packet->payload.ip.ip);
+      printf_filtered (("tip.pge %u: 0x%" PRIx64 ""),
+                      packet->payload.ip.ipc,
+                      packet->payload.ip.ip);
       break;
 
     case ppt_tip_pgd:
-      printf_unfiltered (("tip.pgd %u: 0x%" PRIx64 ""),
-                        packet->payload.ip.ipc,
-                        packet->payload.ip.ip);
+      printf_filtered (("tip.pgd %u: 0x%" PRIx64 ""),
+                      packet->payload.ip.ipc,
+                      packet->payload.ip.ip);
       break;
 
     case ppt_fup:
-      printf_unfiltered (("fup %u: 0x%" PRIx64 ""),
-                        packet->payload.ip.ipc,
-                        packet->payload.ip.ip);
+      printf_filtered (("fup %u: 0x%" PRIx64 ""),
+                      packet->payload.ip.ipc,
+                      packet->payload.ip.ip);
       break;
 
     case ppt_tnt_8:
-      printf_unfiltered (("tnt-8 %u: 0x%" PRIx64 ""),
-                        packet->payload.tnt.bit_size,
-                        packet->payload.tnt.payload);
+      printf_filtered (("tnt-8 %u: 0x%" PRIx64 ""),
+                      packet->payload.tnt.bit_size,
+                      packet->payload.tnt.payload);
       break;
 
     case ppt_tnt_64:
-      printf_unfiltered (("tnt-64 %u: 0x%" PRIx64 ""),
-                        packet->payload.tnt.bit_size,
-                        packet->payload.tnt.payload);
+      printf_filtered (("tnt-64 %u: 0x%" PRIx64 ""),
+                      packet->payload.tnt.bit_size,
+                      packet->payload.tnt.payload);
       break;
 
     case ppt_pip:
-      printf_unfiltered (("pip %" PRIx64 "%s"), packet->payload.pip.cr3,
-                        packet->payload.pip.nr ? (" nr") : (""));
+      printf_filtered (("pip %" PRIx64 "%s"), packet->payload.pip.cr3,
+                      packet->payload.pip.nr ? (" nr") : (""));
       break;
 
     case ppt_tsc:
-      printf_unfiltered (("tsc %" PRIx64 ""), packet->payload.tsc.tsc);
+      printf_filtered (("tsc %" PRIx64 ""), packet->payload.tsc.tsc);
       break;
 
     case ppt_cbr:
-      printf_unfiltered (("cbr %u"), packet->payload.cbr.ratio);
+      printf_filtered (("cbr %u"), packet->payload.cbr.ratio);
       break;
 
     case ppt_mode:
       switch (packet->payload.mode.leaf)
        {
        default:
-         printf_unfiltered (("mode %u"), packet->payload.mode.leaf);
+         printf_filtered (("mode %u"), packet->payload.mode.leaf);
          break;
 
        case pt_mol_exec:
-         printf_unfiltered (("mode.exec%s%s"),
-                            packet->payload.mode.bits.exec.csl
-                            ? (" cs.l") : (""),
-                            packet->payload.mode.bits.exec.csd
-                            ? (" cs.d") : (""));
+         printf_filtered (("mode.exec%s%s"),
+                          packet->payload.mode.bits.exec.csl
+                          ? (" cs.l") : (""),
+                          packet->payload.mode.bits.exec.csd
+                          ? (" cs.d") : (""));
          break;
 
        case pt_mol_tsx:
-         printf_unfiltered (("mode.tsx%s%s"),
-                            packet->payload.mode.bits.tsx.intx
-                            ? (" intx") : (""),
-                            packet->payload.mode.bits.tsx.abrt
-                            ? (" abrt") : (""));
+         printf_filtered (("mode.tsx%s%s"),
+                          packet->payload.mode.bits.tsx.intx
+                          ? (" intx") : (""),
+                          packet->payload.mode.bits.tsx.abrt
+                          ? (" abrt") : (""));
          break;
        }
       break;
 
     case ppt_ovf:
-      printf_unfiltered (("ovf"));
+      printf_filtered (("ovf"));
       break;
 
     case ppt_stop:
-      printf_unfiltered (("stop"));
+      printf_filtered (("stop"));
       break;
 
     case ppt_vmcs:
-      printf_unfiltered (("vmcs %" PRIx64 ""), packet->payload.vmcs.base);
+      printf_filtered (("vmcs %" PRIx64 ""), packet->payload.vmcs.base);
       break;
 
     case ppt_tma:
-      printf_unfiltered (("tma %x %x"), packet->payload.tma.ctc,
-                        packet->payload.tma.fc);
+      printf_filtered (("tma %x %x"), packet->payload.tma.ctc,
+                      packet->payload.tma.fc);
       break;
 
     case ppt_mtc:
-      printf_unfiltered (("mtc %x"), packet->payload.mtc.ctc);
+      printf_filtered (("mtc %x"), packet->payload.mtc.ctc);
       break;
 
     case ppt_cyc:
-      printf_unfiltered (("cyc %" PRIx64 ""), packet->payload.cyc.value);
+      printf_filtered (("cyc %" PRIx64 ""), packet->payload.cyc.value);
       break;
 
     case ppt_mnt:
-      printf_unfiltered (("mnt %" PRIx64 ""), packet->payload.mnt.payload);
+      printf_filtered (("mnt %" PRIx64 ""), packet->payload.mnt.payload);
       break;
     }
 }
@@ -3131,9 +3149,9 @@ btrace_maint_print_packets (struct btrace_thread_info *btinfo,
          {
            const btrace_block &block = blocks.at (blk);
 
-           printf_unfiltered ("%u\tbegin: %s, end: %s\n", blk,
-                              core_addr_to_string_nz (block.begin),
-                              core_addr_to_string_nz (block.end));
+           printf_filtered ("%u\tbegin: %s, end: %s\n", blk,
+                            core_addr_to_string_nz (block.begin),
+                            core_addr_to_string_nz (block.end));
          }
 
        btinfo->maint.variant.bts.packet_history.begin = begin;
@@ -3152,15 +3170,15 @@ btrace_maint_print_packets (struct btrace_thread_info *btinfo,
          {
            const struct btrace_pt_packet &packet = packets.at (pkt);
 
-           printf_unfiltered ("%u\t", pkt);
-           printf_unfiltered ("0x%" PRIx64 "\t", packet.offset);
+           printf_filtered ("%u\t", pkt);
+           printf_filtered ("0x%" PRIx64 "\t", packet.offset);
 
            if (packet.errcode == pte_ok)
              pt_print_packet (&packet.packet);
            else
-             printf_unfiltered ("[error: %s]", pt_errstr (packet.errcode));
+             printf_filtered ("[error: %s]", pt_errstr (packet.errcode));
 
-           printf_unfiltered ("\n");
+           printf_filtered ("\n");
          }
 
        btinfo->maint.variant.pt.packet_history.begin = begin;
@@ -3228,7 +3246,7 @@ maint_btrace_packet_history_cmd (const char *arg, int from_tty)
   struct btrace_thread_info *btinfo;
   unsigned int size, begin, end, from, to;
 
-  thread_info *tp = find_thread_ptid (inferior_ptid);
+  thread_info *tp = find_thread_ptid (current_inferior (), inferior_ptid);
   if (tp == NULL)
     error (_("No thread."));
 
@@ -3238,7 +3256,7 @@ maint_btrace_packet_history_cmd (const char *arg, int from_tty)
   btrace_maint_update_packets (btinfo, &begin, &end, &from, &to);
   if (begin == end)
     {
-      printf_unfiltered (_("No trace.\n"));
+      printf_filtered (_("No trace.\n"));
       return;
     }
 
@@ -3358,51 +3376,6 @@ maint_btrace_clear_cmd (const char *args, int from_tty)
   btrace_clear (tp);
 }
 
-/* The "maintenance btrace" command.  */
-
-static void
-maint_btrace_cmd (const char *args, int from_tty)
-{
-  help_list (maint_btrace_cmdlist, "maintenance btrace ", all_commands,
-            gdb_stdout);
-}
-
-/* The "maintenance set btrace" command.  */
-
-static void
-maint_btrace_set_cmd (const char *args, int from_tty)
-{
-  help_list (maint_btrace_set_cmdlist, "maintenance set btrace ", all_commands,
-            gdb_stdout);
-}
-
-/* The "maintenance show btrace" command.  */
-
-static void
-maint_btrace_show_cmd (const char *args, int from_tty)
-{
-  help_list (maint_btrace_show_cmdlist, "maintenance show btrace ",
-            all_commands, gdb_stdout);
-}
-
-/* The "maintenance set btrace pt" command.  */
-
-static void
-maint_btrace_pt_set_cmd (const char *args, int from_tty)
-{
-  help_list (maint_btrace_pt_set_cmdlist, "maintenance set btrace pt ",
-            all_commands, gdb_stdout);
-}
-
-/* The "maintenance show btrace pt" command.  */
-
-static void
-maint_btrace_pt_show_cmd (const char *args, int from_tty)
-{
-  help_list (maint_btrace_pt_show_cmdlist, "maintenance show btrace pt ",
-            all_commands, gdb_stdout);
-}
-
 /* The "maintenance info btrace" command.  */
 
 static void
@@ -3425,8 +3398,8 @@ maint_info_btrace_cmd (const char *args, int from_tty)
   if (conf == NULL)
     error (_("No btrace configuration."));
 
-  printf_unfiltered (_("Format: %s.\n"),
-                    btrace_format_string (conf->format));
+  printf_filtered (_("Format: %s.\n"),
+                  btrace_format_string (conf->format));
 
   switch (conf->format)
     {
@@ -3434,8 +3407,8 @@ maint_info_btrace_cmd (const char *args, int from_tty)
       break;
 
     case BTRACE_FORMAT_BTS:
-      printf_unfiltered (_("Number of packets: %zu.\n"),
-                        btinfo->data.variant.bts.blocks->size ());
+      printf_filtered (_("Number of packets: %zu.\n"),
+                      btinfo->data.variant.bts.blocks->size ());
       break;
 
 #if defined (HAVE_LIBIPT)
@@ -3444,14 +3417,14 @@ maint_info_btrace_cmd (const char *args, int from_tty)
        struct pt_version version;
 
        version = pt_library_version ();
-       printf_unfiltered (_("Version: %u.%u.%u%s.\n"), version.major,
-                          version.minor, version.build,
-                          version.ext != NULL ? version.ext : "");
+       printf_filtered (_("Version: %u.%u.%u%s.\n"), version.major,
+                        version.minor, version.build,
+                        version.ext != NULL ? version.ext : "");
 
        btrace_maint_update_pt_packets (btinfo);
-       printf_unfiltered (_("Number of packets: %zu.\n"),
-                          ((btinfo->maint.variant.pt.packets == nullptr)
-                           ? 0 : btinfo->maint.variant.pt.packets->size ()));
+       printf_filtered (_("Number of packets: %zu.\n"),
+                        ((btinfo->maint.variant.pt.packets == nullptr)
+                         ? 0 : btinfo->maint.variant.pt.packets->size ()));
       }
       break;
 #endif /* defined (HAVE_LIBIPT)  */
@@ -3471,36 +3444,32 @@ show_maint_btrace_pt_skip_pad  (struct ui_file *file, int from_tty,
 
 /* Initialize btrace maintenance commands.  */
 
+void _initialize_btrace ();
 void
-_initialize_btrace (void)
+_initialize_btrace ()
 {
   add_cmd ("btrace", class_maintenance, maint_info_btrace_cmd,
           _("Info about branch tracing data."), &maintenanceinfolist);
 
-  add_prefix_cmd ("btrace", class_maintenance, maint_btrace_cmd,
-                 _("Branch tracing maintenance commands."),
-                 &maint_btrace_cmdlist, "maintenance btrace ",
-                 0, &maintenancelist);
-
-  add_prefix_cmd ("btrace", class_maintenance, maint_btrace_set_cmd, _("\
-Set branch tracing specific variables."),
-                  &maint_btrace_set_cmdlist, "maintenance set btrace ",
-                  0, &maintenance_set_cmdlist);
-
-  add_prefix_cmd ("pt", class_maintenance, maint_btrace_pt_set_cmd, _("\
-Set Intel Processor Trace specific variables."),
-                  &maint_btrace_pt_set_cmdlist, "maintenance set btrace pt ",
-                  0, &maint_btrace_set_cmdlist);
-
-  add_prefix_cmd ("btrace", class_maintenance, maint_btrace_show_cmd, _("\
-Show branch tracing specific variables."),
-                  &maint_btrace_show_cmdlist, "maintenance show btrace ",
-                  0, &maintenance_show_cmdlist);
-
-  add_prefix_cmd ("pt", class_maintenance, maint_btrace_pt_show_cmd, _("\
-Show Intel Processor Trace specific variables."),
-                  &maint_btrace_pt_show_cmdlist, "maintenance show btrace pt ",
-                  0, &maint_btrace_show_cmdlist);
+  add_basic_prefix_cmd ("btrace", class_maintenance,
+                       _("Branch tracing maintenance commands."),
+                       &maint_btrace_cmdlist, 0, &maintenancelist);
+
+  add_setshow_prefix_cmd ("btrace", class_maintenance,
+                         _("Set branch tracing specific variables."),
+                         _("Show branch tracing specific variables."),
+                         &maint_btrace_set_cmdlist,
+                         &maint_btrace_show_cmdlist,
+                         &maintenance_set_cmdlist,
+                         &maintenance_show_cmdlist);
+
+  add_setshow_prefix_cmd ("pt", class_maintenance,
+                         _("Set Intel Processor Trace specific variables."),
+                         _("Show Intel Processor Trace specific variables."),
+                         &maint_btrace_pt_set_cmdlist,
+                         &maint_btrace_pt_show_cmdlist,
+                         &maint_btrace_set_cmdlist,
+                         &maint_btrace_show_cmdlist);
 
   add_setshow_boolean_cmd ("skip-pad", class_maintenance,
                           &maint_btrace_pt_skip_pad, _("\