aboutsummaryrefslogtreecommitdiffstats
path: root/erts
diff options
context:
space:
mode:
Diffstat (limited to 'erts')
-rw-r--r--erts/emulator/beam/beam_bp.c29
-rw-r--r--erts/emulator/beam/beam_bp.h15
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;