gdb/gdbserver: 2011-11-03 Yao Qi * tracepoint.c (gdb_collect): Loop over TPOINT. gdb/testsuite: 2011-11-03 Yao Qi * gdb.trace/trace-break.exp: Add test on setting two fast tracepoints at the same address. --- gdb/gdbserver/tracepoint.c | 83 ++++++++++++++++++------------- gdb/testsuite/gdb.trace/trace-break.exp | 1 + 2 files changed, 50 insertions(+), 34 deletions(-) diff --git a/gdb/gdbserver/tracepoint.c b/gdb/gdbserver/tracepoint.c index 0a64104..f09a7d8 100644 --- a/gdb/gdbserver/tracepoint.c +++ b/gdb/gdbserver/tracepoint.c @@ -5417,47 +5417,62 @@ gdb_collect (struct tracepoint *tpoint, unsigned char *regs) if (!tracing) return; - if (!tpoint->enabled) - return; - ctx.base.type = fast_tracepoint; ctx.regs = regs; ctx.regcache_initted = 0; - ctx.tpoint = tpoint; - /* Wrap the regblock in a register cache (in the stack, we don't - want to malloc here). */ - ctx.regspace = alloca (register_cache_size ()); - if (ctx.regspace == NULL) + ctx.tpoint = tpoint; + for (; ctx.tpoint && ctx.tpoint->address == tpoint->address; + ctx.tpoint = ctx.tpoint->next) { - trace_debug ("Trace buffer block allocation failed, skipping"); - return; - } + if (!ctx.tpoint->enabled) + continue; - /* Test the condition if present, and collect if true. */ - if (tpoint->cond == NULL - || condition_true_at_tracepoint ((struct tracepoint_hit_ctx *) &ctx, - tpoint)) - { - collect_data_at_tracepoint ((struct tracepoint_hit_ctx *) &ctx, - tpoint->address, tpoint); + /* Multiple tracepoints of different types, such as fast tracepoint and + static tracepoint, can be set at the same address. */ + if (ctx.tpoint->type != tpoint->type) + continue; - /* Note that this will cause original insns to be written back - to where we jumped from, but that's OK because we're jumping - back to the next whole instruction. This will go badly if - instruction restoration is not atomic though. */ - if (stopping_tracepoint - || trace_buffer_is_full - || expr_eval_result != expr_eval_no_error) - stop_tracing (); - } - else - { - /* If there was a condition and it evaluated to false, the only - way we would stop tracing is if there was an error during - condition expression evaluation. */ - if (expr_eval_result != expr_eval_no_error) - stop_tracing (); + /* Wrap the regblock in a register cache (in the stack, we don't + want to malloc here). */ + ctx.regspace = alloca (register_cache_size ()); + if (ctx.regspace == NULL) + { + trace_debug ("Trace buffer block allocation failed, skipping"); + continue; + } + + /* Test the condition if present, and collect if true. */ + if (ctx.tpoint->cond == NULL + || condition_true_at_tracepoint ((struct tracepoint_hit_ctx *) &ctx, + ctx.tpoint)) + { + collect_data_at_tracepoint ((struct tracepoint_hit_ctx *) &ctx, + ctx.tpoint->address, ctx.tpoint); + + /* Note that this will cause original insns to be written back + to where we jumped from, but that's OK because we're jumping + back to the next whole instruction. This will go badly if + instruction restoration is not atomic though. */ + if (stopping_tracepoint + || trace_buffer_is_full + || expr_eval_result != expr_eval_no_error) + { + stop_tracing (); + break; + } + } + else + { + /* If there was a condition and it evaluated to false, the only + way we would stop tracing is if there was an error during + condition expression evaluation. */ + if (expr_eval_result != expr_eval_no_error) + { + stop_tracing (); + break; + } + } } } diff --git a/gdb/testsuite/gdb.trace/trace-break.exp b/gdb/testsuite/gdb.trace/trace-break.exp index 4a14d32..c2d7b2c 100644 --- a/gdb/testsuite/gdb.trace/trace-break.exp +++ b/gdb/testsuite/gdb.trace/trace-break.exp @@ -234,6 +234,7 @@ if { [gdb_test "info sharedlibrary" ".*libinproctrace\.so.*" "IPA loaded"] != 0 break_trace_same_addr_1 "ftrace" ${break_always_inserted} break_trace_same_addr_2 "trace" "ftrace" ${break_always_inserted} break_trace_same_addr_2 "ftrace" "trace" ${break_always_inserted} + break_trace_same_addr_2 "ftrace" "ftrace" ${break_always_inserted} break_trace_same_addr_3 "ftrace" ${break_always_inserted} break_trace_same_addr_4 "ftrace" ${break_always_inserted} } -- 1.7.0.4