132
132
** External interfaces
135
erts_smp_spinlock_t erts_bp_lock;
136
138
erts_bp_init(void) {
139
erts_smp_spinlock_init(&erts_bp_lock, "breakpoints");
140
143
erts_set_trace_break(Eterm mfa[3], int specified, Binary *match_spec,
141
144
Eterm tracer_pid) {
145
ERTS_SMP_LC_ASSERT(erts_smp_is_system_blocked(0));
142
146
return set_break(mfa, specified, match_spec,
143
147
(Uint) BeamOp(op_i_trace_breakpoint), 0, tracer_pid);
147
151
erts_set_mtrace_break(Eterm mfa[3], int specified, Binary *match_spec,
148
152
Eterm tracer_pid) {
153
ERTS_SMP_LC_ASSERT(erts_smp_is_system_blocked(0));
149
154
return set_break(mfa, specified, match_spec,
150
155
(Uint) BeamOp(op_i_mtrace_breakpoint), 0, tracer_pid);
154
159
erts_set_mtrace_bif(Uint *pc, Binary *match_spec, Eterm tracer_pid) {
155
160
BpDataTrace *bdt;
161
ERTS_SMP_LC_ASSERT(erts_smp_is_system_blocked(0));
157
163
bdt = (BpDataTrace *) pc[-4];
159
165
MatchSetUnref(bdt->match_spec);
174
180
erts_set_debug_break(Eterm mfa[3], int specified) {
181
ERTS_SMP_LC_ASSERT(erts_smp_is_system_blocked(0));
175
182
return set_break(mfa, specified, NULL,
176
183
(Uint) BeamOp(op_i_debug_breakpoint), 0, NIL);
180
187
erts_set_count_break(Eterm mfa[3], int specified, enum erts_break_op count_op) {
188
ERTS_SMP_LC_ASSERT(erts_smp_is_system_blocked(0));
181
189
return set_break(mfa, specified, NULL,
182
190
(Uint) BeamOp(op_i_count_breakpoint), count_op, NIL);
188
196
erts_clear_trace_break(Eterm mfa[3], int specified) {
197
ERTS_SMP_LC_ASSERT(erts_smp_is_system_blocked(0));
189
198
return clear_break(mfa, specified,
190
199
(Uint) BeamOp(op_i_trace_breakpoint));
194
203
erts_clear_mtrace_break(Eterm mfa[3], int specified) {
204
ERTS_SMP_LC_ASSERT(erts_smp_is_system_blocked(0));
195
205
return clear_break(mfa, specified,
196
206
(Uint) BeamOp(op_i_mtrace_breakpoint));
214
225
erts_clear_debug_break(Eterm mfa[3], int specified) {
226
ERTS_SMP_LC_ASSERT(erts_smp_is_system_blocked(0));
215
227
return clear_break(mfa, specified,
216
228
(Uint) BeamOp(op_i_debug_breakpoint));
220
232
erts_clear_count_break(Eterm mfa[3], int specified) {
233
ERTS_SMP_LC_ASSERT(erts_smp_is_system_blocked(0));
221
234
return clear_break(mfa, specified,
222
235
(Uint) BeamOp(op_i_count_breakpoint));
226
239
erts_clear_break(Eterm mfa[3], int specified) {
240
ERTS_SMP_LC_ASSERT(erts_smp_is_system_blocked(0));
227
241
return clear_break(mfa, specified, 0);
231
245
erts_clear_module_break(Module *modp) {
246
ERTS_SMP_LC_ASSERT(erts_smp_is_system_blocked(0));
233
248
return clear_module_break(modp, NULL, 0, 0);
237
252
erts_clear_function_break(Module *modp, Uint *pc) {
253
ERTS_SMP_LC_ASSERT(erts_smp_is_system_blocked(0));
239
255
return clear_function_break(modp, pc, 0);
261
* SMP NOTE: Process p may have become exiting on return!
245
264
erts_trace_break(Process *p, Uint *pc, Eterm *args,
246
265
Uint32 *ret_flags, Eterm *tracer_pid) {
247
267
BpDataTrace *bdt = (BpDataTrace *) pc[-4];
249
269
ASSERT(pc[-5] == (Uint) BeamOp(op_i_func_info_IaaI));
253
273
ASSERT(ret_flags);
254
274
ASSERT(tracer_pid);
255
*ret_flags = erts_call_trace(p, pc-3/*mfa*/, bdt->match_spec, args,
256
1, &bdt->tracer_pid);
257
*tracer_pid = bdt->tracer_pid;
277
tpid1 = tpid2 = bdt->tracer_pid;
278
ErtsSmpBPUnlock(bdt);
280
*ret_flags = erts_call_trace(p, pc-3/*mfa*/, bdt->match_spec, args,
283
if (tpid1 != tpid2) {
285
bdt->tracer_pid = tpid2;
286
ErtsSmpBPUnlock(bdt);
258
288
pc[-4] = (Uint) bdt;
259
289
return bdt->orig_instr;
295
* SMP NOTE: Process p may have become exiting on return!
265
298
erts_bif_mtrace(Process *p, Uint *pc, Eterm *args, int local,
266
299
Eterm *tracer_pid) {
269
302
ASSERT(tracer_pid);
271
Uint32 flags = erts_call_trace(p, pc-3/*mfa*/, bdt->match_spec, args,
272
local, &bdt->tracer_pid);
273
*tracer_pid = bdt->tracer_pid;
308
tpid1 = tpid2 = bdt->tracer_pid;
309
ErtsSmpBPUnlock(bdt);
311
flags = erts_call_trace(p, pc-3/*mfa*/, bdt->match_spec, args,
314
if (tpid1 != tpid2) {
316
bdt->tracer_pid = tpid2;
317
ErtsSmpBPUnlock(bdt);
276
321
*tracer_pid = NIL;
366
417
if ((modp = erts_get_module(mfa[0])) == NULL)
369
code_base = (Uint **) modp->code;
419
if ((code_base = (Uint **) modp->code) == NULL)
370
421
n = (Uint) code_base[MI_NUM_FUNCTIONS];
371
422
for (i = 0; i < n; ++i) {
372
423
code_ptr = code_base[MI_FUNCTIONS+i];
424
ASSERT(((Uint) BeamOp(op_i_func_info_IaaI)) == code_ptr[0]);
425
ASSERT(mfa[0] == ((Eterm) code_ptr[2]));
373
426
if (mfa[1] == ((Eterm) code_ptr[3]) &&
374
((int) mfa[2]) == ((int) code_ptr[4])) {
427
((Uint) mfa[2]) == code_ptr[4]) {
375
428
return code_ptr + 5;
388
441
static int set_break(Eterm mfa[3], int specified,
389
442
Binary *match_spec, Eterm break_op,
390
enum erts_break_op count_op, Eterm tracer_pid) {
443
enum erts_break_op count_op, Eterm tracer_pid)
392
446
int num_processed = 0;
393
447
if (!specified) {
394
448
/* Find and process all modules in the system... */
396
while ((current = index_iter(&module_table,current)) >= 0) {
397
if ((modp = module_code(current)) != NULL) {
399
set_module_break(modp, mfa, specified,
400
match_spec, break_op, count_op,
450
int last = module_code_size();
451
for (current = 0; current < last; current++) {
452
modp = module_code(current);
453
ASSERT(modp != NULL);
455
set_module_break(modp, mfa, specified,
456
match_spec, break_op, count_op,
405
460
/* Process a single module */
464
519
if (break_op == (Uint) BeamOp(op_i_trace_breakpoint)
465
520
|| break_op == (Uint) BeamOp(op_i_mtrace_breakpoint)) {
466
521
BpDataTrace *bdt = (BpDataTrace *) bd;
522
Binary *old_match_spec;
468
524
/* Update match spec and tracer */
469
MatchSetUnref(bdt->match_spec);
470
525
MatchSetRef(match_spec);
527
old_match_spec = bdt->match_spec;
471
528
bdt->match_spec = match_spec;
472
529
bdt->tracer_pid = tracer_pid;
530
ErtsSmpBPUnlock(bdt);
531
MatchSetUnref(old_match_spec);
474
533
ASSERT(! match_spec);
475
534
ASSERT(is_nil(tracer_pid));
476
535
if (break_op == (Uint) BeamOp(op_i_count_breakpoint)) {
477
536
BpDataCount *bdc = (BpDataCount *) bd;
479
539
if (count_op == erts_break_stop) {
480
540
if (bdc->count >= 0) {
481
541
bdc->count = -bdc->count-1; /* Stop call counter */
557
618
bdt->tracer_pid = tracer_pid;
558
619
} else if (break_op == (Uint) BeamOp(op_i_count_breakpoint)) {
559
620
BpDataCount *bdc = (BpDataCount *) bd;
563
++((Uint) code_base[MI_NUM_BREAKPOINTS]);
624
++(*(Uint*)&code_base[MI_NUM_BREAKPOINTS]);
567
static int clear_break(Eterm mfa[3], int specified, Uint break_op) {
628
static int clear_break(Eterm mfa[3], int specified, Uint break_op)
568
630
int num_processed = 0;
570
633
if (!specified) {
571
634
/* Iterate over all modules */
573
while ((current = index_iter(&module_table,current)) >= 0) {
574
if ((modp = module_code(current)) != NULL) {
576
clear_module_break(modp, mfa, specified, break_op);
636
int last = module_code_size();
638
for (current = 0; current < last; current++) {
639
modp = module_code(current);
640
ASSERT(modp != NULL);
641
num_processed += clear_module_break(modp, mfa, specified, break_op);
580
644
/* Process a single module */