From: Yao Qi Date: Fri, 18 Jan 2013 06:40:58 +0000 (+0000) Subject: gdb/gdbserver: X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=5ae4861a11c9487e991607689ebabc2e0008a670;p=binutils-gdb.git gdb/gdbserver: * ax.h (struct eval_agent_expr_context): New. (gdb_eval_agent_expr): Update declaration. * ax.c (gdb_eval_agent_expr): Remove argument REGCACHE and TFRAME. Add new argument CTX. * server.h (struct eval_agent_expr_context): Declare. (agent_mem_read, agent_tsv_read): Update declaration. (agent_mem_read_string): Likewise. * tracepoint.c (eval_tracepoint_agent_expr): Remove. (add_traceframe_block): Add new argument TPOINT. Increase TPOINT->traceframe_usage. (do_action_at_tracepoint): Call gdb_eval_agent_expr instead of eval_tracepoint_agent_expr. (condition_true_at_tracepoint): Likewise. (agent_mem_read): Remove argument TFRAME. Add argument CTX. (agent_mem_read_string, agent_tsv_read): Likewise. Callers update. gdb/testsuite: * gdb.trace/infotrace.exp: Check 'traceframe usage' in the output of 'info tracepoints'. * gdb.trace/disconnected-tracing.exp (disconnected_tracing): Likewise. * gdb.trace/tstatus.exp (run_trace_experiment): Likewise. * gdb.trace/disconnected-tracing.c (struct foo): New. --- diff --git a/gdb/gdbserver/ChangeLog b/gdb/gdbserver/ChangeLog index 494a0cd0640..5b41f7a4cdc 100644 --- a/gdb/gdbserver/ChangeLog +++ b/gdb/gdbserver/ChangeLog @@ -1,3 +1,21 @@ +2013-01-18 Yao Qi + + * ax.h (struct eval_agent_expr_context): New. + (gdb_eval_agent_expr): Update declaration. + * ax.c (gdb_eval_agent_expr): Remove argument REGCACHE and + TFRAME. Add new argument CTX. + * server.h (struct eval_agent_expr_context): Declare. + (agent_mem_read, agent_tsv_read): Update declaration. + (agent_mem_read_string): Likewise. + * tracepoint.c (eval_tracepoint_agent_expr): Remove. + (add_traceframe_block): Add new argument TPOINT. + Increase TPOINT->traceframe_usage. + (do_action_at_tracepoint): Call gdb_eval_agent_expr instead of + eval_tracepoint_agent_expr. + (condition_true_at_tracepoint): Likewise. + (agent_mem_read): Remove argument TFRAME. Add argument CTX. + (agent_mem_read_string, agent_tsv_read): Likewise. + 2013-01-16 Yao Qi * linux-low.c (linux_resume_one_lwp): Don't check diff --git a/gdb/gdbserver/ax.c b/gdb/gdbserver/ax.c index 94035e490e2..386df3ded0c 100644 --- a/gdb/gdbserver/ax.c +++ b/gdb/gdbserver/ax.c @@ -912,8 +912,7 @@ ax_printf (CORE_ADDR fn, CORE_ADDR chan, char *format, otherwise. */ enum eval_result_type -gdb_eval_agent_expr (struct regcache *regcache, - struct traceframe *tframe, +gdb_eval_agent_expr (struct eval_agent_expr_context *ctx, struct agent_expr *aexpr, ULONGEST *rslt) { @@ -1032,15 +1031,15 @@ gdb_eval_agent_expr (struct regcache *regcache, break; case gdb_agent_op_trace: - agent_mem_read (tframe, - NULL, (CORE_ADDR) stack[--sp], (ULONGEST) top); + agent_mem_read (ctx, NULL, (CORE_ADDR) stack[--sp], + (ULONGEST) top); if (--sp >= 0) top = stack[sp]; break; case gdb_agent_op_trace_quick: arg = aexpr->bytes[pc++]; - agent_mem_read (tframe, NULL, (CORE_ADDR) top, (ULONGEST) arg); + agent_mem_read (ctx, NULL, (CORE_ADDR) top, (ULONGEST) arg); break; case gdb_agent_op_log_not: @@ -1086,22 +1085,22 @@ gdb_eval_agent_expr (struct regcache *regcache, break; case gdb_agent_op_ref8: - agent_mem_read (tframe, cnv.u8.bytes, (CORE_ADDR) top, 1); + agent_mem_read (ctx, cnv.u8.bytes, (CORE_ADDR) top, 1); top = cnv.u8.val; break; case gdb_agent_op_ref16: - agent_mem_read (tframe, cnv.u16.bytes, (CORE_ADDR) top, 2); + agent_mem_read (ctx, cnv.u16.bytes, (CORE_ADDR) top, 2); top = cnv.u16.val; break; case gdb_agent_op_ref32: - agent_mem_read (tframe, cnv.u32.bytes, (CORE_ADDR) top, 4); + agent_mem_read (ctx, cnv.u32.bytes, (CORE_ADDR) top, 4); top = cnv.u32.val; break; case gdb_agent_op_ref64: - agent_mem_read (tframe, cnv.u64.bytes, (CORE_ADDR) top, 8); + agent_mem_read (ctx, cnv.u64.bytes, (CORE_ADDR) top, 8); top = cnv.u64.val; break; @@ -1160,6 +1159,7 @@ gdb_eval_agent_expr (struct regcache *regcache, arg = (arg << 8) + aexpr->bytes[pc++]; { int regnum = arg; + struct regcache *regcache = ctx->regcache; switch (register_size (regnum)) { @@ -1260,11 +1260,11 @@ gdb_eval_agent_expr (struct regcache *regcache, case gdb_agent_op_tracev: arg = aexpr->bytes[pc++]; arg = (arg << 8) + aexpr->bytes[pc++]; - agent_tsv_read (tframe, arg); + agent_tsv_read (ctx, arg); break; case gdb_agent_op_tracenz: - agent_mem_read_string (tframe, NULL, (CORE_ADDR) stack[--sp], + agent_mem_read_string (ctx, NULL, (CORE_ADDR) stack[--sp], (ULONGEST) top); if (--sp >= 0) top = stack[sp]; diff --git a/gdb/gdbserver/ax.h b/gdb/gdbserver/ax.h index f87123b6e98..b2b4e3a797e 100644 --- a/gdb/gdbserver/ax.h +++ b/gdb/gdbserver/ax.h @@ -67,8 +67,20 @@ void emit_epilogue (void); enum eval_result_type compile_bytecodes (struct agent_expr *aexpr); #endif -enum eval_result_type gdb_eval_agent_expr (struct regcache *regcache, - struct traceframe *tframe, - struct agent_expr *aexpr, - ULONGEST *rslt); +/* The context when evaluating agent expression. */ + +struct eval_agent_expr_context +{ + /* The registers when evaluating agent expression. */ + struct regcache *regcache; + /* The traceframe, if any, when evaluating agent expression. */ + struct traceframe *tframe; + /* The tracepoint, if any, when evaluating agent expression. */ + struct tracepoint *tpoint; +}; + +enum eval_result_type + gdb_eval_agent_expr (struct eval_agent_expr_context *ctx, + struct agent_expr *aexpr, + ULONGEST *rslt); #endif /* AX_H */ diff --git a/gdb/gdbserver/mem-break.c b/gdb/gdbserver/mem-break.c index 6886ab801a0..aca77408a17 100644 --- a/gdb/gdbserver/mem-break.c +++ b/gdb/gdbserver/mem-break.c @@ -840,8 +840,7 @@ gdb_condition_true_at_breakpoint (CORE_ADDR where) ULONGEST value = 0; struct point_cond_list *cl; int err = 0; - - struct regcache *regcache = get_thread_regcache (current_inferior, 1); + struct eval_agent_expr_context ctx; if (bp == NULL) return 0; @@ -851,6 +850,10 @@ gdb_condition_true_at_breakpoint (CORE_ADDR where) if (bp->cond_list == NULL) return 1; + ctx.regcache = get_thread_regcache (current_inferior, 1); + ctx.tframe = NULL; + ctx.tpoint = NULL; + /* Evaluate each condition in the breakpoint's list of conditions. Return true if any of the conditions evaluates to TRUE. @@ -860,7 +863,7 @@ gdb_condition_true_at_breakpoint (CORE_ADDR where) cl && !value && !err; cl = cl->next) { /* Evaluate the condition. */ - err = gdb_eval_agent_expr (regcache, NULL, cl->cond, &value); + err = gdb_eval_agent_expr (&ctx, cl->cond, &value); } if (err) @@ -943,17 +946,20 @@ run_breakpoint_commands (CORE_ADDR where) ULONGEST value = 0; struct point_command_list *cl; int err = 0; - - struct regcache *regcache = get_thread_regcache (current_inferior, 1); + struct eval_agent_expr_context ctx; if (bp == NULL) return; + ctx.regcache = get_thread_regcache (current_inferior, 1); + ctx.tframe = NULL; + ctx.tpoint = NULL; + for (cl = bp->command_list; cl && !value && !err; cl = cl->next) { /* Run the command. */ - err = gdb_eval_agent_expr (regcache, NULL, cl->cmd, &value); + err = gdb_eval_agent_expr (&ctx, cl->cmd, &value); /* If one command has a problem, stop digging the hole deeper. */ if (err) diff --git a/gdb/gdbserver/server.h b/gdb/gdbserver/server.h index a483cf594b8..1cbca02ed2d 100644 --- a/gdb/gdbserver/server.h +++ b/gdb/gdbserver/server.h @@ -439,11 +439,12 @@ void gdb_agent_about_to_close (int pid); #endif struct traceframe; +struct eval_agent_expr_context; /* Do memory copies for bytecodes. */ /* Do the recording of memory blocks for actions and bytecodes. */ -int agent_mem_read (struct traceframe *tframe, +int agent_mem_read (struct eval_agent_expr_context *ctx, unsigned char *to, CORE_ADDR from, ULONGEST len); @@ -452,8 +453,8 @@ void agent_set_trace_state_variable_value (int num, LONGEST val); /* Record the value of a trace state variable. */ -int agent_tsv_read (struct traceframe *tframe, int n); -int agent_mem_read_string (struct traceframe *tframe, +int agent_tsv_read (struct eval_agent_expr_context *ctx, int n); +int agent_mem_read_string (struct eval_agent_expr_context *ctx, unsigned char *to, CORE_ADDR from, ULONGEST len); diff --git a/gdb/gdbserver/tracepoint.c b/gdb/gdbserver/tracepoint.c index 0367eb4432c..51b6a0c51d1 100644 --- a/gdb/gdbserver/tracepoint.c +++ b/gdb/gdbserver/tracepoint.c @@ -1346,12 +1346,6 @@ struct trap_tracepoint_ctx #endif -static enum eval_result_type -eval_tracepoint_agent_expr (struct tracepoint_hit_ctx *ctx, - struct traceframe *tframe, - struct agent_expr *aexpr, - ULONGEST *rslt); - #ifndef IN_PROCESS_AGENT static CORE_ADDR traceframe_get_pc (struct traceframe *tframe); static int traceframe_read_tsv (int num, LONGEST *val); @@ -2216,7 +2210,8 @@ add_traceframe (struct tracepoint *tpoint) /* Add a block to the traceframe currently being worked on. */ static unsigned char * -add_traceframe_block (struct traceframe *tframe, int amt) +add_traceframe_block (struct traceframe *tframe, + struct tracepoint *tpoint, int amt) { unsigned char *block; @@ -2228,7 +2223,10 @@ add_traceframe_block (struct traceframe *tframe, int amt) if (!block) return NULL; + gdb_assert (tframe->tpnum == tpoint->number); + tframe->data_size += amt; + tpoint->traceframe_usage += amt; return block; } @@ -4705,15 +4703,19 @@ do_action_at_tracepoint (struct tracepoint_hit_ctx *ctx, case 'M': { struct collect_memory_action *maction; + struct eval_agent_expr_context ax_ctx; maction = (struct collect_memory_action *) taction; + ax_ctx.regcache = NULL; + ax_ctx.tframe = tframe; + ax_ctx.tpoint = tpoint; trace_debug ("Want to collect %s bytes at 0x%s (basereg %d)", pulongest (maction->len), paddress (maction->addr), maction->basereg); /* (should use basereg) */ - agent_mem_read (tframe, NULL, - (CORE_ADDR) maction->addr, maction->len); + agent_mem_read (&ax_ctx, NULL, (CORE_ADDR) maction->addr, + maction->len); break; } case 'R': @@ -4726,7 +4728,7 @@ do_action_at_tracepoint (struct tracepoint_hit_ctx *ctx, trace_debug ("Want to collect registers"); /* Collect all registers for now. */ - regspace = add_traceframe_block (tframe, + regspace = add_traceframe_block (tframe, tpoint, 1 + register_cache_size ()); if (regspace == NULL) { @@ -4768,12 +4770,16 @@ do_action_at_tracepoint (struct tracepoint_hit_ctx *ctx, case 'X': { struct eval_expr_action *eaction; + struct eval_agent_expr_context ax_ctx; eaction = (struct eval_expr_action *) taction; + ax_ctx.regcache = get_context_regcache (ctx); + ax_ctx.tframe = tframe; + ax_ctx.tpoint = tpoint; trace_debug ("Want to evaluate expression"); - err = eval_tracepoint_agent_expr (ctx, tframe, eaction->expr, NULL); + err = gdb_eval_agent_expr (&ax_ctx, eaction->expr, NULL); if (err != expr_eval_no_error) { @@ -4825,8 +4831,15 @@ condition_true_at_tracepoint (struct tracepoint_hit_ctx *ctx, err = ((condfn) (uintptr_t) (tpoint->compiled_cond)) (ctx, &value); else #endif - err = eval_tracepoint_agent_expr (ctx, NULL, tpoint->cond, &value); + { + struct eval_agent_expr_context ax_ctx; + ax_ctx.regcache = get_context_regcache (ctx); + ax_ctx.tframe = NULL; + ax_ctx.tpoint = tpoint; + + err = gdb_eval_agent_expr (&ax_ctx, tpoint->cond, &value); + } if (err != expr_eval_no_error) { record_tracepoint_error (tpoint, "condition", err); @@ -4840,27 +4853,11 @@ condition_true_at_tracepoint (struct tracepoint_hit_ctx *ctx, return (value ? 1 : 0); } -/* Evaluates a tracepoint agent expression with context CTX, - traceframe TFRAME, agent expression AEXPR and store the - result in RSLT. */ - -static enum eval_result_type -eval_tracepoint_agent_expr (struct tracepoint_hit_ctx *ctx, - struct traceframe *tframe, - struct agent_expr *aexpr, - ULONGEST *rslt) -{ - struct regcache *regcache; - regcache = get_context_regcache (ctx); - - return gdb_eval_agent_expr (regcache, tframe, aexpr, rslt); -} - /* Do memory copies for bytecodes. */ /* Do the recording of memory blocks for actions and bytecodes. */ int -agent_mem_read (struct traceframe *tframe, +agent_mem_read (struct eval_agent_expr_context *ctx, unsigned char *to, CORE_ADDR from, ULONGEST len) { unsigned char *mspace; @@ -4881,7 +4878,7 @@ agent_mem_read (struct traceframe *tframe, blocklen = (remaining > 65535 ? 65535 : remaining); sp = 1 + sizeof (from) + sizeof (blocklen) + blocklen; - mspace = add_traceframe_block (tframe, sp); + mspace = add_traceframe_block (ctx->tframe, ctx->tpoint, sp); if (mspace == NULL) return 1; /* Identify block as a memory block. */ @@ -4902,7 +4899,7 @@ agent_mem_read (struct traceframe *tframe, } int -agent_mem_read_string (struct traceframe *tframe, +agent_mem_read_string (struct eval_agent_expr_context *ctx, unsigned char *to, CORE_ADDR from, ULONGEST len) { unsigned char *buf, *mspace; @@ -4938,7 +4935,7 @@ agent_mem_read_string (struct traceframe *tframe, } } sp = 1 + sizeof (from) + sizeof (blocklen) + blocklen; - mspace = add_traceframe_block (tframe, sp); + mspace = add_traceframe_block (ctx->tframe, ctx->tpoint, sp); if (mspace == NULL) { xfree (buf); @@ -4964,12 +4961,12 @@ agent_mem_read_string (struct traceframe *tframe, /* Record the value of a trace state variable. */ int -agent_tsv_read (struct traceframe *tframe, int n) +agent_tsv_read (struct eval_agent_expr_context *ctx, int n) { unsigned char *vspace; LONGEST val; - vspace = add_traceframe_block (tframe, + vspace = add_traceframe_block (ctx->tframe, ctx->tpoint, 1 + sizeof (n) + sizeof (LONGEST)); if (vspace == NULL) return 1; @@ -6346,7 +6343,8 @@ upload_fast_traceframes (void) { /* Copy the whole set of blocks in one go for now. FIXME: split this in smaller blocks. */ - block = add_traceframe_block (tframe, ipa_tframe.data_size); + block = add_traceframe_block (tframe, tpoint, + ipa_tframe.data_size); if (block != NULL) { if (read_inferior_memory (tf @@ -6645,7 +6643,7 @@ collect_ust_data_at_tracepoint (struct tracepoint_hit_ctx *ctx, trace_debug ("Want to collect ust data"); /* 'S' + size + string */ - bufspace = add_traceframe_block (tframe, + bufspace = add_traceframe_block (tframe, umd->tpoint, 1 + sizeof (blocklen) + size + 1); if (bufspace == NULL) { diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index d7d7e053800..ba9de037242 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,12 @@ +2013-01-18 Yao Qi + + * gdb.trace/infotrace.exp: Check 'traceframe usage' in the + output of 'info tracepoints'. + * gdb.trace/disconnected-tracing.exp (disconnected_tracing): + Likewise. + * gdb.trace/tstatus.exp (run_trace_experiment): Likewise. + * gdb.trace/disconnected-tracing.c (struct foo): New. + 2013-01-17 Jan Kratochvil * gdb.dwarf2/dw2-dos-drive.S: New file. diff --git a/gdb/testsuite/gdb.trace/disconnected-tracing.c b/gdb/testsuite/gdb.trace/disconnected-tracing.c index 9776a611bb8..f7de31ffd96 100644 --- a/gdb/testsuite/gdb.trace/disconnected-tracing.c +++ b/gdb/testsuite/gdb.trace/disconnected-tracing.c @@ -19,6 +19,14 @@ void end (void) {} +struct foo +{ + int bar1; + long bar2; +}; + +struct foo foo; + void start (void) {} diff --git a/gdb/testsuite/gdb.trace/disconnected-tracing.exp b/gdb/testsuite/gdb.trace/disconnected-tracing.exp index 7c0e6cef2df..bb73581ea4e 100644 --- a/gdb/testsuite/gdb.trace/disconnected-tracing.exp +++ b/gdb/testsuite/gdb.trace/disconnected-tracing.exp @@ -47,6 +47,8 @@ if ![gdb_target_supports_trace] { proc disconnected_tracing { } { with_test_prefix "trace" { global executable + global decimal + global srcfile # Start with a fresh gdb. clean_restart ${executable} @@ -57,10 +59,18 @@ proc disconnected_tracing { } { with_test_prefix "trace" { gdb_test_no_output "set confirm off" gdb_test_no_output "set disconnected-tracing on" - gdb_test "trace main" ".*" + gdb_test "trace start" ".*" + gdb_trace_setactions "collect on tracepoint 2" "2" \ + "collect foo" "^$" + gdb_test "break end" "Breakpoint ${decimal} at .*" + gdb_test_no_output "tstart" - gdb_test "info tracepoints" ".*in main at.*" "first info tracepoints" + gdb_test "continue" "Continuing\\.\[ \r\n\]+Breakpoint.*" + gdb_test_no_output "tstop" + + gdb_test "info tracepoints" ".*in start at.*" \ + "first info tracepoints" gdb_test "disconnect" "Ending remote debugging\\." "first disconnect" if { [gdb_reconnect] == 0 } { @@ -69,10 +79,12 @@ proc disconnected_tracing { } { with_test_prefix "trace" { fail "first reconnect after unload" return 0 } - gdb_test "info tracepoints" ".*in main at.*" "second info tracepoints" + gdb_test "info tracepoints" ".*in start at.*" \ + "second info tracepoints" delete_breakpoints - gdb_test "info tracepoints" ".*No tracepoints..*" "third info tracepoints" + gdb_test "info tracepoints" ".*No tracepoints..*" \ + "third info tracepoints" gdb_test "disconnect" "Ending remote debugging\\." "second disconnect" if { [gdb_reconnect] == 0 } { @@ -81,7 +93,14 @@ proc disconnected_tracing { } { with_test_prefix "trace" { fail "second reconnect after unload" return 0 } - gdb_test "info tracepoints" ".*in main at.*" "fourth info tracepoints" + gdb_test "tstatus" + gdb_test "info tracepoints" \ + "Num Type\[ \]+Disp Enb Address\[ \]+What.* +\[0-9\]+\[\t \]+tracepoint keep y.* in start at .*$srcfile:\[0-9\]+. +\[\t \]+tracepoint already hit 1 time. +\[\t \]+trace buffer usage ${decimal} bytes. +\[\t \]+collect foo.*" \ + "fourth info tracepoints" }} disconnected_tracing diff --git a/gdb/testsuite/gdb.trace/infotrace.exp b/gdb/testsuite/gdb.trace/infotrace.exp index b71444bfee8..7c0f7170605 100644 --- a/gdb/testsuite/gdb.trace/infotrace.exp +++ b/gdb/testsuite/gdb.trace/infotrace.exp @@ -89,3 +89,32 @@ gdb_test "help info tracepoints" \ "Status of specified tracepoints .all tracepoints if no argument.*" \ "2.5: help info tracepoints" +# 2.6 info tracepoints (check trace buffer usage). We need a live +# tracing. +gdb_breakpoint "main" +gdb_trace_setactions "collect on tracepoint 1" "1" \ + "collect gdb_struct1_test" "^$" +gdb_run_cmd +gdb_test "" "Breakpoint ${decimal}, main.*" + +if { ![gdb_target_supports_trace] } then { + unsupported "Current target does not support trace" + return 1; +} + +gdb_test "break end" "Breakpoint \[0-9\] at .*" +gdb_test_no_output "tstart" +gdb_test "continue" "Continuing\\.\[ \r\n\]+Breakpoint.*" \ + "continue to end" +gdb_test_no_output "tstop" +gdb_test "tstatus" +gdb_test "info tracepoints" \ + "Num Type\[ \]+Disp Enb Address\[ \]+What.* +\[0-9\]+\[\t \]+tracepoint keep y.* in gdb_c_test at .*$srcfile:\[0-9\]+. +\[\t \]+tracepoint already hit 1 time. +\[\t \]+trace buffer usage ${decimal} bytes. +\[\t \]+collect gdb_struct1_test. +\tinstalled on target. +\[0-9\]+\[\t \]+tracepoint keep y.* in gdb_asm_test at .*$srcfile:\[0-9\]+. +\tinstalled on target." \ + "2.6: info tracepoints (trace buffer usage)" diff --git a/gdb/testsuite/gdb.trace/tstatus.exp b/gdb/testsuite/gdb.trace/tstatus.exp index c620a64ac42..8a0bbdfedac 100644 --- a/gdb/testsuite/gdb.trace/tstatus.exp +++ b/gdb/testsuite/gdb.trace/tstatus.exp @@ -55,6 +55,7 @@ if ![runto_main] { proc run_trace_experiment {} { global gdb_prompt + global decimal # gdb_test_no_output "set debug remote 1" "" @@ -114,14 +115,15 @@ proc run_trace_experiment {} { } } - # Tracepoint hit count is optional, so pass it either way. + # Hit count and traceframe usage of tracepoint is optional, so + # pass it either way. gdb_test_multiple "info trace" "show tracepoint state" { - -re "actions\.c:\[0-9\]+\[\r\n\]+\[\t ]+tracepoint already hit 1 time\[\r\n\]+\[\t ]+collect parm.*\r\n$gdb_prompt $" { - pass "info trace reports tracepoint hit count" + -re "actions\.c:\[0-9\]+\[\r\n\]+\[\t ]+tracepoint already hit 1 time\[\r\n\]+\[\t ]+trace buffer usage ${decimal} bytes\.\[\r\n\]+\[\t ]+collect parm.*\r\n$gdb_prompt $" { + pass "info trace reports tracepoint hit count and traceframe usage" } -re "actions\.c:\[0-9\]+\[\r\n\]+\[\t ]+collect parm.*\r\n$gdb_prompt $" { - pass "info trace does not report tracepoint hit count" + pass "info trace does not report tracepoint hit count and traceframe usage" } } }