~ubuntu-branches/debian/squeeze/erlang/squeeze

« back to all changes in this revision

Viewing changes to erts/emulator/beam/beam_bp.c

  • Committer: Bazaar Package Importer
  • Author(s): Erlang Packagers, Sergei Golovan
  • Date: 2006-12-03 17:07:44 UTC
  • mfrom: (2.1.11 feisty)
  • Revision ID: james.westby@ubuntu.com-20061203170744-rghjwupacqlzs6kv
Tags: 1:11.b.2-4
[ Sergei Golovan ]
Fixed erlang-base and erlang-base-hipe prerm scripts.

Show diffs side-by-side

added added

removed removed

Lines of Context:
132
132
** External interfaces
133
133
*/
134
134
 
 
135
erts_smp_spinlock_t erts_bp_lock;
 
136
 
135
137
void 
136
138
erts_bp_init(void) {
 
139
    erts_smp_spinlock_init(&erts_bp_lock, "breakpoints");
137
140
}
138
141
 
139
142
int 
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);
144
148
}
146
150
int 
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);
151
156
}
153
158
void
154
159
erts_set_mtrace_bif(Uint *pc, Binary *match_spec, Eterm tracer_pid) {
155
160
    BpDataTrace *bdt;
156
 
    
 
161
    ERTS_SMP_LC_ASSERT(erts_smp_is_system_blocked(0));
 
162
 
157
163
    bdt = (BpDataTrace *) pc[-4];
158
164
    if (bdt) {
159
165
        MatchSetUnref(bdt->match_spec);
172
178
 
173
179
int 
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);
177
184
}
178
185
 
179
186
int 
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);
183
191
}
186
194
 
187
195
int
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));
191
200
}
192
201
 
193
202
int
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));
197
207
}
199
209
void
200
210
erts_clear_mtrace_bif(Uint *pc) {
201
211
    BpDataTrace *bdt;
 
212
    ERTS_SMP_LC_ASSERT(erts_smp_is_system_blocked(0));
202
213
    
203
214
    bdt = (BpDataTrace *) pc[-4];
204
215
    if (bdt) {
212
223
 
213
224
int
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));
217
229
}
218
230
 
219
231
int
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));
223
236
}
224
237
 
225
238
int
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);
228
242
}
229
243
 
230
244
int 
231
245
erts_clear_module_break(Module *modp) {
 
246
    ERTS_SMP_LC_ASSERT(erts_smp_is_system_blocked(0));
232
247
    ASSERT(modp);
233
248
    return clear_module_break(modp, NULL, 0, 0);
234
249
}
235
250
 
236
251
int
237
252
erts_clear_function_break(Module *modp, Uint *pc) {
 
253
    ERTS_SMP_LC_ASSERT(erts_smp_is_system_blocked(0));
238
254
    ASSERT(modp);
239
255
    return clear_function_break(modp, pc, 0);
240
256
}
241
257
 
242
258
 
243
259
 
 
260
/*
 
261
 * SMP NOTE: Process p may have become exiting on return!
 
262
 */
244
263
Uint 
245
264
erts_trace_break(Process *p, Uint *pc, Eterm *args, 
246
265
                 Uint32 *ret_flags, Eterm *tracer_pid) {
 
266
    Eterm tpid1, tpid2;
247
267
    BpDataTrace *bdt = (BpDataTrace *) pc[-4];
248
268
    
249
269
    ASSERT(pc[-5] == (Uint) BeamOp(op_i_func_info_IaaI));
252
272
    ASSERT(bdt);
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;
 
275
 
 
276
    ErtsSmpBPLock(bdt);
 
277
    tpid1 = tpid2 = bdt->tracer_pid;
 
278
    ErtsSmpBPUnlock(bdt);
 
279
 
 
280
    *ret_flags = erts_call_trace(p, pc-3/*mfa*/, bdt->match_spec, args,
 
281
                                 1, &tpid2);
 
282
    *tracer_pid = tpid2;
 
283
    if (tpid1 != tpid2) {
 
284
        ErtsSmpBPLock(bdt);
 
285
        bdt->tracer_pid = tpid2;
 
286
        ErtsSmpBPUnlock(bdt);
 
287
    }
258
288
    pc[-4] = (Uint) bdt;
259
289
    return bdt->orig_instr;
260
290
}
261
291
 
262
292
 
263
293
 
 
294
/*
 
295
 * SMP NOTE: Process p may have become exiting on return!
 
296
 */
264
297
Uint32
265
298
erts_bif_mtrace(Process *p, Uint *pc, Eterm *args, int local, 
266
299
                Eterm *tracer_pid) {
268
301
    
269
302
    ASSERT(tracer_pid);
270
303
    if (bdt) {
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;
 
304
        Eterm tpid1, tpid2;
 
305
        Uint32 flags;
 
306
 
 
307
        ErtsSmpBPLock(bdt);
 
308
        tpid1 = tpid2 = bdt->tracer_pid;
 
309
        ErtsSmpBPUnlock(bdt);
 
310
 
 
311
        flags = erts_call_trace(p, pc-3/*mfa*/, bdt->match_spec, args,
 
312
                                local, &tpid2);
 
313
        *tracer_pid = tpid2;
 
314
        if (tpid1 != tpid2) {
 
315
            ErtsSmpBPLock(bdt);
 
316
            bdt->tracer_pid = tpid2;
 
317
            ErtsSmpBPUnlock(bdt);
 
318
        }
274
319
        return flags;
275
320
    }
276
321
    *tracer_pid = NIL;
289
334
            *match_spec_ret = bdt->match_spec;
290
335
        }
291
336
        if (tracer_pid_ret) {
 
337
            ErtsSmpBPLock(bdt);
292
338
            *tracer_pid_ret = bdt->tracer_pid;
 
339
            ErtsSmpBPUnlock(bdt);
293
340
        }
294
341
        return !0;
295
342
    }
306
353
            *match_spec_ret = bdt->match_spec;
307
354
        }
308
355
        if (tracer_pid_ret) {
 
356
            ErtsSmpBPLock(bdt);
309
357
            *tracer_pid_ret = bdt->tracer_pid;
 
358
            ErtsSmpBPUnlock(bdt);
310
359
        }
311
360
        return !0;
312
361
    }
322
371
            *match_spec_ret = bdt->match_spec;
323
372
        }
324
373
        if (tracer_pid_ret) {
 
374
            ErtsSmpBPLock(bdt);
325
375
            *tracer_pid_ret = bdt->tracer_pid;
 
376
            ErtsSmpBPUnlock(bdt);
326
377
        }
327
378
        return !0;
328
379
    }
347
398
    
348
399
    if (bdc) {
349
400
        if (count_ret) {
 
401
            ErtsSmpBPLock(bdc);
350
402
            *count_ret = bdc->count;
 
403
            ErtsSmpBPUnlock(bdc);
351
404
        }
352
405
        return !0;
353
406
    }
354
407
    return 0;
355
408
}
356
409
 
357
 
 
358
 
 
359
410
Uint *
360
411
erts_find_local_func(Eterm mfa[3]) {
361
412
    Module *modp;
365
416
 
366
417
    if ((modp = erts_get_module(mfa[0])) == NULL)
367
418
        return NULL;
368
 
    
369
 
    code_base = (Uint **) modp->code;
 
419
    if ((code_base = (Uint **) modp->code) == NULL)
 
420
        return 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;
376
429
        }
377
430
    }
387
440
 
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)
 
444
{
391
445
    Module *modp;
392
446
    int num_processed = 0;
393
447
    if (!specified) {
394
448
        /* Find and process all modules in the system... */
395
 
        int current = -1;
396
 
        while ((current = index_iter(&module_table,current)) >= 0) {
397
 
            if ((modp = module_code(current)) != NULL) {
398
 
                num_processed += 
399
 
                    set_module_break(modp, mfa, specified, 
400
 
                                     match_spec, break_op, count_op, 
401
 
                                     tracer_pid);
402
 
            }
 
449
        int current;
 
450
        int last = module_code_size();
 
451
        for (current = 0; current < last; current++) {
 
452
            modp = module_code(current);
 
453
            ASSERT(modp != NULL);
 
454
            num_processed += 
 
455
                set_module_break(modp, mfa, specified, 
 
456
                                 match_spec, break_op, count_op, 
 
457
                                 tracer_pid);
403
458
        }
404
459
    } else {
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;
467
523
            
468
524
            /* Update match spec and tracer */
469
 
            MatchSetUnref(bdt->match_spec);
470
525
            MatchSetRef(match_spec);
 
526
            ErtsSmpBPLock(bdt);
 
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);
473
532
        } else {
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;
478
537
                
 
538
                ErtsSmpBPLock(bdc);
479
539
                if (count_op == erts_break_stop) {
480
540
                    if (bdc->count >= 0) {
481
541
                        bdc->count = -bdc->count-1; /* Stop call counter */
483
543
                } else {
484
544
                    bdc->count = 0; /* Reset call counter */
485
545
                }
 
546
                ErtsSmpBPUnlock(bdc);
486
547
            } else {
487
548
                ASSERT (! count_op);
488
549
            }
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;
560
 
                
 
621
 
561
622
        bdc->count = 0;
562
623
    }
563
 
    ++((Uint) code_base[MI_NUM_BREAKPOINTS]);
 
624
    ++(*(Uint*)&code_base[MI_NUM_BREAKPOINTS]);
564
625
    return 1;
565
626
}
566
627
 
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)
 
629
{
568
630
    int num_processed = 0;
569
631
    Module *modp;
 
632
 
570
633
    if (!specified) {
571
634
        /* Iterate over all modules */
572
 
        int current = -1;
573
 
        while ((current = index_iter(&module_table,current)) >= 0) {
574
 
            if ((modp = module_code(current)) != NULL) {
575
 
                num_processed += 
576
 
                    clear_module_break(modp, mfa, specified, break_op);
577
 
            }
 
635
        int current;
 
636
        int last = module_code_size();
 
637
 
 
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);
578
642
        }
579
643
    } else {
580
644
        /* Process a single module */
675
739
        }
676
740
        Free(bd);
677
741
        ASSERT(((Uint) code_base[MI_NUM_BREAKPOINTS]) > 0);
678
 
        --((Uint) code_base[MI_NUM_BREAKPOINTS]);
 
742
        --(*(Uint*)&code_base[MI_NUM_BREAKPOINTS]);
679
743
    }
680
744
    return 1;
681
745
}