From af54718eaed854c5e7ef4dbd6845969aa6558ef4 Mon Sep 17 00:00:00 2001 From: Stan Shebs Date: Sun, 4 Apr 2010 23:31:29 +0000 Subject: [PATCH] 2010-04-04 Stan Shebs * 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 | 4 ++++ gdb/doc/ChangeLog | 5 +++++ gdb/doc/gdb.texinfo | 26 +++++++++++++++++++++++++ gdb/testsuite/ChangeLog | 4 ++++ gdb/testsuite/gdb.trace/tfile.exp | 5 ++++- gdb/tracepoint.c | 40 ++++++++++++++++++++++++++++++++++++++- 6 files changed, 82 insertions(+), 2 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index f79aa3f..8d68f7a 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,7 @@ +2010-04-04 Stan Shebs + + * tracepoint.c (tfile_fetch_registers): Add fallback case. + 2010-04-04 Jan Kratochvil * infcmd.c (run_command_1): Call proceed with regcache_read_pc address. diff --git a/gdb/doc/ChangeLog b/gdb/doc/ChangeLog index a792152..3d1e2cd 100644 --- a/gdb/doc/ChangeLog +++ b/gdb/doc/ChangeLog @@ -1,3 +1,8 @@ +2010-04-04 Stan Shebs + + * gdb.texinfo (Tracepoint Restrictions): Document PC inference. + (tdump): Explain how tdump works. + 2010-04-01 Pedro Alves * gdb.texinfo (Break Commands): Clarify `commands' changes, and diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo index 5e02172..e61bd7e 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -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 diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 27054c0..8566e4a 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2010-04-04 Stan Shebs + + * gdb.trace/tfile.exp: Sharpen tfind test. + 2010-04-04 Jan Kratochvil * gdb.base/break-entry.exp: New. diff --git a/gdb/testsuite/gdb.trace/tfile.exp b/gdb/testsuite/gdb.trace/tfile.exp index a3adfcc..a0a73ee 100644 --- a/gdb/testsuite/gdb.trace/tfile.exp +++ b/gdb/testsuite/gdb.trace/tfile.exp @@ -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" diff --git a/gdb/tracepoint.c b/gdb/tracepoint.c index 1b41806..0fb0e93 100644 --- a/gdb/tracepoint.c +++ b/gdb/tracepoint.c @@ -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 -- 2.7.4