diff options
Diffstat (limited to 'erts')
-rw-r--r-- | erts/emulator/beam/beam_bp.c | 29 | ||||
-rw-r--r-- | erts/emulator/beam/beam_bp.h | 15 |
2 files changed, 36 insertions, 8 deletions
diff --git a/erts/emulator/beam/beam_bp.c b/erts/emulator/beam/beam_bp.c index 3e776fa951..7b46f073c6 100644 --- a/erts/emulator/beam/beam_bp.c +++ b/erts/emulator/beam/beam_bp.c @@ -127,6 +127,7 @@ static int clear_function_break(Module *modp, BeamInstr *pc, BeamInstr break_op); static BpData *is_break(BeamInstr *pc, BeamInstr break_op); +static BpData *get_break(BeamInstr *pc, BeamInstr break_op); /* bp_hash */ #define BP_TIME_ADD(pi0, pi1) \ @@ -684,7 +685,7 @@ void erts_schedule_time_break(Process *p, Uint schedule) { * the previous breakpoint. */ - pbdt = (BpDataTime *) is_break(pbt->pc, (Uint) BeamOp(op_i_time_breakpoint)); + pbdt = (BpDataTime *) get_break(pbt->pc, (Uint) BeamOp(op_i_time_breakpoint)); if (pbdt) { bp_time_diff(&sitem, pbt, ms, s, us); sitem.pid = p->id; @@ -782,7 +783,7 @@ void erts_trace_time_break(Process *p, BeamInstr *pc, BpDataTime *bdt, Uint type sitem.count = 0; /* previous breakpoint */ - pbdt = (BpDataTime *) is_break(pbt->pc, (Uint) BeamOp(op_i_time_breakpoint)); + pbdt = (BpDataTime *) get_break(pbt->pc, (Uint) BeamOp(op_i_time_breakpoint)); /* if null then the breakpoint was removed */ if (pbdt) { @@ -850,7 +851,7 @@ void erts_trace_time_break(Process *p, BeamInstr *pc, BpDataTime *bdt, Uint type sitem.count = 0; /* previous breakpoint */ - pbdt = (BpDataTime *) is_break(pbt->pc, (Uint) BeamOp(op_i_time_breakpoint)); + pbdt = (BpDataTime *) get_break(pbt->pc, (Uint) BeamOp(op_i_time_breakpoint)); if (pbdt) { @@ -1076,6 +1077,7 @@ static int set_function_break(Module *modp, BeamInstr *pc, *r = bd; } } + bd->this_instr = break_op; /* Init the bp type specific data */ if (break_op == (BeamInstr) BeamOp(op_i_trace_breakpoint) || break_op == (BeamInstr) BeamOp(op_i_mtrace_breakpoint)) { @@ -1296,3 +1298,24 @@ static BpData *is_break(BeamInstr *pc, BeamInstr break_op) { } return NULL; } +static BpData *get_break(BeamInstr *pc, BeamInstr break_op) { + ASSERT(pc[-5] == (BeamInstr) BeamOp(op_i_func_info_IaaI)); + if (! erts_is_native_break(pc)) { + BpData *bd = (BpData *) pc[-4]; + + if (! bd){ + return NULL; + } + + bd = bd->next; + while (bd != (BpData *) pc[-4]) { + ASSERT(bd); + if (bd->this_instr == break_op) { + ASSERT(bd); + return bd; + } + bd = bd->next; + } + } + return NULL; +} diff --git a/erts/emulator/beam/beam_bp.h b/erts/emulator/beam/beam_bp.h index 4a3d244d2f..6b339401fc 100644 --- a/erts/emulator/beam/beam_bp.h +++ b/erts/emulator/beam/beam_bp.h @@ -49,6 +49,7 @@ typedef struct bp_data { struct bp_data *next; /* Doubly linked ring pointers */ struct bp_data *prev; /* -"- */ BeamInstr orig_instr; /* The original instruction to execute */ + BeamInstr this_instr; /* key */ } BpData; /* ** All the following bp_data_.. structs must begin the same way @@ -57,21 +58,24 @@ typedef struct bp_data { typedef struct bp_data_trace { struct bp_data *next; struct bp_data *prev; - BeamInstr orig_instr; + BeamInstr orig_instr; + BeamInstr this_instr; /* key */ Binary *match_spec; - Eterm tracer_pid; + Eterm tracer_pid; } BpDataTrace; typedef struct bp_data_debug { struct bp_data *next; struct bp_data *prev; - BeamInstr orig_instr; + BeamInstr orig_instr; + BeamInstr this_instr; /* key */ } BpDataDebug; -typedef struct bp_data_count { /* Call count */ +typedef struct bp_data_count { /* Call count */ struct bp_data *next; struct bp_data *prev; BeamInstr orig_instr; + BeamInstr this_instr; /* key */ Sint count; } BpDataCount; @@ -88,10 +92,11 @@ typedef struct { bp_data_time_item_t *item; } bp_time_hash_t; -typedef struct bp_data_time { /* Call time */ +typedef struct bp_data_time { /* Call time */ struct bp_data *next; struct bp_data *prev; BeamInstr orig_instr; + BeamInstr this_instr; /* key */ Uint pause; Uint n; bp_time_hash_t *hash; |