Skip to content

Commit 084e7e3

Browse files
committed
remain enabled and line specified trace points
If two or more tracepoints enabled with the same target and with different target lines, the only last line is activated. This patch fixes this issue by remaining existing trace instructions. [Bug #17302]
1 parent 1271782 commit 084e7e3

File tree

2 files changed

+33
-5
lines changed

2 files changed

+33
-5
lines changed

iseq.c

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3168,13 +3168,16 @@ rb_vm_insn_addr2insn(const void *addr)
31683168
}
31693169

31703170
static inline int
3171-
encoded_iseq_trace_instrument(VALUE *iseq_encoded_insn, rb_event_flag_t turnon)
3171+
encoded_iseq_trace_instrument(VALUE *iseq_encoded_insn, rb_event_flag_t turnon, bool remain_current_trace)
31723172
{
31733173
st_data_t key = (st_data_t)*iseq_encoded_insn;
31743174
st_data_t val;
31753175

31763176
if (st_lookup(encoded_insn_data, key, &val)) {
31773177
insn_data_t *e = (insn_data_t *)val;
3178+
if (remain_current_trace && key == (st_data_t)e->trace_encoded_insn) {
3179+
turnon = 1;
3180+
}
31783181
*iseq_encoded_insn = (VALUE) (turnon ? e->trace_encoded_insn : e->notrace_encoded_insn);
31793182
return e->insn_len;
31803183
}
@@ -3187,7 +3190,7 @@ rb_iseq_trace_flag_cleared(const rb_iseq_t *iseq, size_t pos)
31873190
{
31883191
const struct rb_iseq_constant_body *const body = iseq->body;
31893192
VALUE *iseq_encoded = (VALUE *)body->iseq_encoded;
3190-
encoded_iseq_trace_instrument(&iseq_encoded[pos], 0);
3193+
encoded_iseq_trace_instrument(&iseq_encoded[pos], 0, false);
31913194
}
31923195

31933196
static int
@@ -3216,7 +3219,7 @@ iseq_add_local_tracepoint(const rb_iseq_t *iseq, rb_event_flag_t turnon_events,
32163219
if (pc_events & target_events) {
32173220
n++;
32183221
}
3219-
pc += encoded_iseq_trace_instrument(&iseq_encoded[pc], pc_events & (target_events | iseq->aux.exec.global_trace_events));
3222+
pc += encoded_iseq_trace_instrument(&iseq_encoded[pc], pc_events & (target_events | iseq->aux.exec.global_trace_events), true);
32203223
}
32213224

32223225
if (n > 0) {
@@ -3281,7 +3284,7 @@ iseq_remove_local_tracepoint(const rb_iseq_t *iseq, VALUE tpval)
32813284

32823285
for (pc = 0; pc<body->iseq_size;) {
32833286
rb_event_flag_t pc_events = rb_iseq_event_flags(iseq, pc);
3284-
pc += encoded_iseq_trace_instrument(&iseq_encoded[pc], pc_events & (local_events | iseq->aux.exec.global_trace_events));
3287+
pc += encoded_iseq_trace_instrument(&iseq_encoded[pc], pc_events & (local_events | iseq->aux.exec.global_trace_events), false);
32853288
}
32863289
}
32873290
return n;
@@ -3333,7 +3336,7 @@ rb_iseq_trace_set(const rb_iseq_t *iseq, rb_event_flag_t turnon_events)
33333336

33343337
for (pc=0; pc<body->iseq_size;) {
33353338
rb_event_flag_t pc_events = rb_iseq_event_flags(iseq, pc);
3336-
pc += encoded_iseq_trace_instrument(&iseq_encoded[pc], pc_events & enabled_events);
3339+
pc += encoded_iseq_trace_instrument(&iseq_encoded[pc], pc_events & enabled_events, true);
33373340
}
33383341
}
33393342
}

test/ruby/test_settracefunc.rb

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2175,6 +2175,31 @@ def test_tracepoint_enable_with_target_line
21752175
assert_equal 'target_line is specified, but line event is not specified', e.message
21762176
end
21772177

2178+
def test_tracepoint_enable_with_target_line_two_times
2179+
events = []
2180+
line_0 = __LINE__
2181+
code1 = proc{
2182+
events << 1 # tp1
2183+
events << 2
2184+
events << 3 # tp2
2185+
}
2186+
2187+
tp1 = TracePoint.new(:line) do |tp|
2188+
events << :tp1
2189+
end
2190+
tp2 = TracePoint.new(:line) do |tp|
2191+
events << :tp2
2192+
end
2193+
2194+
tp1.enable(target: code1, target_line: line_0 + 2) do
2195+
tp2.enable(target: code1, target_line: line_0 + 4) do
2196+
# two hooks
2197+
code1.call
2198+
end
2199+
end
2200+
assert_equal [:tp1, 1, 2, :tp2, 3], events
2201+
end
2202+
21782203
def test_script_compiled
21792204
events = []
21802205
tp = TracePoint.new(:script_compiled){|tp|

0 commit comments

Comments
 (0)