aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator/beam/beam_bp.h
diff options
context:
space:
mode:
Diffstat (limited to 'erts/emulator/beam/beam_bp.h')
-rw-r--r--erts/emulator/beam/beam_bp.h165
1 files changed, 165 insertions, 0 deletions
diff --git a/erts/emulator/beam/beam_bp.h b/erts/emulator/beam/beam_bp.h
new file mode 100644
index 0000000000..44e6b294d8
--- /dev/null
+++ b/erts/emulator/beam/beam_bp.h
@@ -0,0 +1,165 @@
+/*
+ * %CopyrightBegin%
+ *
+ * Copyright Ericsson AB 2000-2009. All Rights Reserved.
+ *
+ * The contents of this file are subject to the Erlang Public License,
+ * Version 1.1, (the "License"); you may not use this file except in
+ * compliance with the License. You should have received a copy of the
+ * Erlang Public License along with this software. If not, it can be
+ * retrieved online at http://www.erlang.org/.
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ *
+ * %CopyrightEnd%
+ */
+
+
+#ifndef _BEAM_BP_H
+#define _BEAM_BP_H
+
+#include "sys.h"
+#include "erl_vm.h"
+#include "global.h"
+
+
+
+/*
+** Common struct to all bp_data_*
+**
+** Two gotchas:
+**
+** 1) The type of bp_data structure in the ring is deduced from the
+** orig_instr field of the structure _before_ in the ring, except for
+** the first structure in the ring that has its instruction in
+** pc[0] of the code to execute.
+**
+** 2) pc[-4] points to the _last_ structure in the ring before the
+** breakpoints are being executed.
+**
+** So, as an example, when a breakpointed function starts to execute,
+** the first instruction that is a breakpoint instruction at pc[0] finds
+** its data at ((BpData *) pc[-4])->next and has to cast that pointer
+** to the correct bp_data type.
+*/
+typedef struct bp_data {
+ struct bp_data *next; /* Doubly linked ring pointers */
+ struct bp_data *prev; /* -"- */
+ Uint orig_instr; /* The original instruction to execute */
+} BpData;
+/*
+** All the following bp_data_.. structs must begin the same way
+*/
+
+typedef struct bp_data_trace {
+ struct bp_data *next;
+ struct bp_data *prev;
+ Uint orig_instr;
+ Binary *match_spec;
+ Eterm tracer_pid;
+} BpDataTrace;
+
+typedef struct bp_data_debug {
+ struct bp_data *next;
+ struct bp_data *prev;
+ Uint orig_instr;
+} BpDataDebug;
+
+typedef struct bp_data_count { /* Call count */
+ struct bp_data *next;
+ struct bp_data *prev;
+ Uint orig_instr;
+ Sint count;
+} BpDataCount;
+
+extern erts_smp_spinlock_t erts_bp_lock;
+
+#ifdef ERTS_SMP
+#define ErtsSmpBPLock(BDC) erts_smp_spin_lock(&erts_bp_lock)
+#define ErtsSmpBPUnlock(BDC) erts_smp_spin_unlock(&erts_bp_lock)
+#else
+#define ErtsSmpBPLock(BDC)
+#define ErtsSmpBPUnlock(BDC)
+#endif
+
+#define ErtsCountBreak(pc,instr_result) \
+do { \
+ BpDataCount *bdc = (BpDataCount *) (pc)[-4]; \
+ \
+ ASSERT((pc)[-5] == (Uint) BeamOp(op_i_func_info_IaaI)); \
+ ASSERT(bdc); \
+ bdc = (BpDataCount *) bdc->next; \
+ ASSERT(bdc); \
+ (pc)[-4] = (Uint) bdc; \
+ ErtsSmpBPLock(bdc); \
+ if (bdc->count >= 0) bdc->count++; \
+ ErtsSmpBPUnlock(bdc); \
+ *(instr_result) = bdc->orig_instr; \
+} while (0)
+
+#define ErtsBreakSkip(pc,instr_result) \
+do { \
+ BpData *bd = (BpData *) (pc)[-4]; \
+ \
+ ASSERT((pc)[-5] == (Uint) BeamOp(op_i_func_info_IaaI)); \
+ ASSERT(bd); \
+ bd = bd->next; \
+ ASSERT(bd); \
+ (pc)[-4] = (Uint) bd; \
+ *(instr_result) = bd->orig_instr; \
+} while (0)
+
+enum erts_break_op{
+ erts_break_nop = 0, /* Must be false */
+ erts_break_set = !0, /* Must be true */
+ erts_break_reset,
+ erts_break_stop
+};
+
+
+
+/*
+** Function interface exported from beam_bp.c
+*/
+
+void erts_bp_init(void);
+
+int erts_set_trace_break(Eterm mfa[3], int specified, Binary *match_spec,
+ Eterm tracer_pid);
+int erts_clear_trace_break(Eterm mfa[3], int specified);
+int erts_set_mtrace_break(Eterm mfa[3], int specified, Binary *match_spec,
+ Eterm tracer_pid);
+int erts_clear_mtrace_break(Eterm mfa[3], int specified);
+void erts_set_mtrace_bif(Uint *pc, Binary *match_spec,
+ Eterm tracer_pid);
+void erts_clear_mtrace_bif(Uint *pc);
+int erts_set_debug_break(Eterm mfa[3], int specified);
+int erts_clear_debug_break(Eterm mfa[3], int specified);
+int erts_set_count_break(Eterm mfa[3], int specified, enum erts_break_op);
+int erts_clear_count_break(Eterm mfa[3], int specified);
+
+
+int erts_clear_break(Eterm mfa[3], int specified);
+int erts_clear_module_break(Module *modp);
+int erts_clear_function_break(Module *modp, Uint *pc);
+
+Uint erts_trace_break(Process *p, Uint *pc, Eterm *args,
+ Uint32 *ret_flags, Eterm *tracer_pid);
+Uint32 erts_bif_mtrace(Process *p, Uint *pc, Eterm *args,
+ int local, Eterm *tracer_pid);
+
+int erts_is_trace_break(Uint *pc, Binary **match_spec_ret,
+ Eterm *tracer_pid_ret);
+int erts_is_mtrace_break(Uint *pc, Binary **match_spec_ret,
+ Eterm *tracer_pid_rte);
+int erts_is_mtrace_bif(Uint *pc, Binary **match_spec_ret,
+ Eterm *tracer_pid_ret);
+int erts_is_native_break(Uint *pc);
+int erts_is_count_break(Uint *pc, Sint *count_ret);
+
+Uint *erts_find_local_func(Eterm mfa[3]);
+
+#endif /* _BEAM_BP_H */