diff options
Diffstat (limited to 'gdb/gdbserver')
-rw-r--r-- | gdb/gdbserver/ChangeLog | 5 | ||||
-rw-r--r-- | gdb/gdbserver/tracepoint.c | 68 |
2 files changed, 46 insertions, 27 deletions
diff --git a/gdb/gdbserver/ChangeLog b/gdb/gdbserver/ChangeLog index cb2412e..72b0e68 100644 --- a/gdb/gdbserver/ChangeLog +++ b/gdb/gdbserver/ChangeLog @@ -1,3 +1,8 @@ +2011-11-05 Yao Qi <yao@codesourcery.com> + + * tracepoint.c (gdb_collect): Loop over tracepoints of same + address as TPOINT's. + 2011-11-02 Stan Shebs <stan@codesourcery.com> * tracepoint.c (agent_mem_read_string): New function. diff --git a/gdb/gdbserver/tracepoint.c b/gdb/gdbserver/tracepoint.c index 139e30e..95119d3 100644 --- a/gdb/gdbserver/tracepoint.c +++ b/gdb/gdbserver/tracepoint.c @@ -5480,14 +5480,9 @@ 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 ()); @@ -5497,30 +5492,49 @@ gdb_collect (struct tracepoint *tpoint, unsigned char *regs) return; } - /* Test the condition if present, and collect if true. */ - if (tpoint->cond == NULL - || condition_true_at_tracepoint ((struct tracepoint_hit_ctx *) &ctx, - tpoint)) + for (ctx.tpoint = tpoint; + ctx.tpoint != NULL && ctx.tpoint->address == tpoint->address; + ctx.tpoint = ctx.tpoint->next) { - collect_data_at_tracepoint ((struct tracepoint_hit_ctx *) &ctx, - tpoint->address, tpoint); + if (!ctx.tpoint->enabled) + 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 (); + /* 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; + + /* 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; + } + } } } |