2010-04-04 Stan Shebs <stan@codesourcery.com>
authorStan Shebs <shebs@codesourcery.com>
Sun, 4 Apr 2010 23:31:29 +0000 (23:31 +0000)
committerStan Shebs <shebs@codesourcery.com>
Sun, 4 Apr 2010 23:31:29 +0000 (23:31 +0000)
* tracepoint.c (tfile_fetch_registers): Add fallback case.

* gdb.texinfo (Tracepoint Restrictions): Document PC inference.
(tdump): Explain how tdump works.

* gdb.trace/tfile.exp: Sharpen tfind test.

gdb/ChangeLog
gdb/doc/ChangeLog
gdb/doc/gdb.texinfo
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.trace/tfile.exp
gdb/tracepoint.c

index f79aa3f..8d68f7a 100644 (file)
@@ -1,3 +1,7 @@
+2010-04-04  Stan Shebs  <stan@codesourcery.com>
+
+       * tracepoint.c (tfile_fetch_registers): Add fallback case.
+
 2010-04-04  Jan Kratochvil  <jan.kratochvil@redhat.com>
 
        * infcmd.c (run_command_1): Call proceed with regcache_read_pc address.
index a792152..3d1e2cd 100644 (file)
@@ -1,3 +1,8 @@
+2010-04-04  Stan Shebs  <stan@codesourcery.com>
+
+       * gdb.texinfo (Tracepoint Restrictions): Document PC inference.
+       (tdump): Explain how tdump works.
+
 2010-04-01  Pedro Alves  <pedro@codesourcery.com>
 
        * gdb.texinfo (Break Commands): Clarify `commands' changes, and
index 5e02172..e61bd7e 100644 (file)
@@ -9938,6 +9938,16 @@ if you ask for a block so large that it goes past the bottom of the
 stack, the target agent may report an error trying to read from an
 invalid address.
 
+@item
+If you do not collect registers at a tracepoint, @value{GDBN} can
+infer that the value of @code{$pc} must be the same as the address of
+the tracepoint and use that when you are looking at a trace frame
+for that tracepoint.  However, this cannot work if the tracepoint has
+multiple locations (for instance if it was set in a function that was
+inlined), or if it has a @code{while-stepping} loop.  In those cases
+@value{GDBN} will warn you that it can't infer @code{$pc}, and default
+it to zero.
+
 @end itemize
 
 @node Analyze Collected Data
@@ -10141,6 +10151,22 @@ gdb_long_test = 17 '\021'
 (@value{GDBP})
 @end smallexample
 
+@code{tdump} works by scanning the tracepoint's current collection
+actions and printing the value of each expression listed.  So
+@code{tdump} can fail, if after a run, you change the tracepoint's
+actions to mention variables that were not collected during the run.
+
+Also, for tracepoints with @code{while-stepping} loops, @code{tdump}
+uses the collected value of @code{$pc} to distinguish between trace
+frames that were collected at the tracepoint hit, and frames that were
+collected while stepping.  This allows it to correctly choose whether
+to display the basic list of collections, or the collections from the
+body of the while-stepping loop.  However, if @code{$pc} was not collected,
+then @code{tdump} will always attempt to dump using the basic collection
+list, and may fail if a while-stepping frame does not include all the
+same data that is collected at the tracepoint hit.
+@c This is getting pretty arcane, example would be good.
+
 @node save-tracepoints
 @subsection @code{save-tracepoints @var{filename}}
 @kindex save-tracepoints
index 27054c0..8566e4a 100644 (file)
@@ -1,3 +1,7 @@
+2010-04-04  Stan Shebs  <stan@codesourcery.com>
+
+       * gdb.trace/tfile.exp: Sharpen tfind test.
+
 2010-04-04  Jan Kratochvil  <jan.kratochvil@redhat.com>
 
        * gdb.base/break-entry.exp: New.
index a3adfcc..a0a73ee 100644 (file)
@@ -69,7 +69,10 @@ gdb_test "target tfile basic.tf" "Created tracepoint.*" "target tfile"
 gdb_test "info trace" ".*tracepoint.*in write_basic_trace_file.*" \
     "info tracepoints on trace file"
 
-gdb_test "tfind 0" "Found trace frame 0.*" "tfind 0 on trace file"
+gdb_test "tfind 0" \
+    "Found trace frame 0, tracepoint \[0-9\]+.
+\#0  write_basic_trace_file ().*" \
+    "tfind 0 on trace file"
 
 gdb_test "print testglob" " = 31415" "print testglob on trace file"
 
index 1b41806..0fb0e93 100644 (file)
@@ -3671,7 +3671,7 @@ tfile_fetch_registers (struct target_ops *ops,
 {
   struct gdbarch *gdbarch = get_regcache_arch (regcache);
   char block_type;
-  int i, pos, offset, regn, regsize, gotten;
+  int i, pos, offset, regn, regsize, gotten, pc_regno;
   unsigned short mlen;
   char *regs;
 
@@ -3746,6 +3746,44 @@ tfile_fetch_registers (struct target_ops *ops,
          break;
        }
     }
+
+  /* We get here if no register data has been found.  Although we
+     don't like making up numbers, GDB has all manner of troubles when
+     the target says some register is not available.  Filling in with
+     zeroes is a reasonable fallback.  */
+  for (regn = 0; regn < gdbarch_num_regs (gdbarch); regn++)
+    regcache_raw_supply (regcache, regn, NULL);
+
+  /* We can often usefully guess that the PC is going to be the same
+     as the address of the tracepoint.  */
+  pc_regno = gdbarch_pc_regnum (gdbarch);
+  if (pc_regno >= 0 && (regno == -1 || regno == pc_regno))
+    {
+      struct breakpoint *tp = get_tracepoint (tracepoint_number);
+
+      if (tp && tp->loc)
+       {
+         /* But don't try to guess if tracepoint is multi-location...  */
+         if (tp->loc->next)
+           {
+             warning ("Tracepoint %d has multiple locations, cannot infer $pc",
+                      tp->number);
+             return;
+           }
+         /* ... or does while-stepping.  */
+         if (tp->step_count > 0)
+           {
+             warning ("Tracepoint %d does while-stepping, cannot infer $pc",
+                      tp->number);
+             return;
+           }
+
+         store_unsigned_integer (regs, register_size (gdbarch, pc_regno),
+                                 gdbarch_byte_order (gdbarch),
+                                 tp->loc->address);
+         regcache_raw_supply (regcache, pc_regno, regs);
+       }
+    }
 }
 
 static LONGEST