1 /*
2  * %CopyrightBegin%
3  *
4  * Copyright Ericsson AB 2000-2020. All Rights Reserved.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  * %CopyrightEnd%
19  */
20 
21 
22 #ifndef _BEAM_BP_H
23 #define _BEAM_BP_H
24 
25 #include "sys.h"
26 #include "erl_vm.h"
27 #include "global.h"
28 
29 typedef struct {
30     Eterm pid;
31     Sint  count;
32     ErtsMonotonicTime time;
33 } bp_data_time_item_t;
34 
35 typedef struct {
36     Uint n;
37     Uint used;
38     bp_data_time_item_t *item;
39 } bp_time_hash_t;
40 
41 typedef struct bp_data_time {     /* Call time */
42     Uint n;
43     bp_time_hash_t *hash;
44     erts_refc_t refc;
45 } BpDataTime;
46 
47 typedef struct {
48     const ErtsCodeInfo *ci;
49     ErtsMonotonicTime time;
50 } process_breakpoint_time_t; /* used within psd */
51 
52 typedef struct {
53     erts_atomic_t acount;
54     erts_refc_t refc;
55 } BpCount;
56 
57 typedef struct {
58     erts_atomic_t tracer;
59     erts_refc_t refc;
60 } BpMetaTracer;
61 
62 typedef struct generic_bp_data {
63     Uint flags;
64     Binary* local_ms;		/* Match spec for local call trace */
65     Binary* meta_ms;		/* Match spec for meta trace */
66     BpMetaTracer* meta_tracer;	/* Meta tracer */
67     BpCount* count;		/* For call count */
68     BpDataTime* time;		/* For time trace */
69 } GenericBpData;
70 
71 #define ERTS_NUM_BP_IX 2
72 
73 typedef struct generic_bp {
74     BeamInstr orig_instr;
75     GenericBpData data[ERTS_NUM_BP_IX];
76 } GenericBp;
77 
78 #define ERTS_BP_CALL_TIME_SCHEDULE_IN      (0)
79 #define ERTS_BP_CALL_TIME_SCHEDULE_OUT     (1)
80 #define ERTS_BP_CALL_TIME_SCHEDULE_EXITING (2)
81 
82 extern erts_mtx_t erts_dirty_bp_ix_mtx;
83 
84 enum erts_break_op{
85     ERTS_BREAK_NOP   =  0, /* Must be false */
86     ERTS_BREAK_SET   = !0, /* Must be true */
87     ERTS_BREAK_RESTART,
88     ERTS_BREAK_PAUSE
89 };
90 
91 typedef Uint32 ErtsBpIndex;
92 
93 typedef struct {
94     ErtsCodeInfo *ci;
95     Module* mod;
96 } BpFunction;
97 
98 typedef struct {
99     Uint matched;		/* Number matched */
100     BpFunction* matching;	/* Matching functions */
101 } BpFunctions;
102 
103 /*
104 ** Function interface exported from beam_bp.c
105 */
106 
107 void erts_bp_init(void);
108 
109 void erts_prepare_bp_staging(void);
110 void erts_commit_staged_bp(void);
111 
112 ERTS_GLB_INLINE ErtsBpIndex erts_active_bp_ix(void);
113 ERTS_GLB_INLINE ErtsBpIndex erts_staging_bp_ix(void);
114 
115 void erts_bp_match_functions(BpFunctions* f, ErtsCodeMFA *mfa, int specified);
116 void erts_bp_match_export(BpFunctions* f, ErtsCodeMFA *mfa, int specified);
117 void erts_bp_free_matched_functions(BpFunctions* f);
118 
119 void erts_install_breakpoints(BpFunctions* f);
120 void erts_uninstall_breakpoints(BpFunctions* f);
121 void erts_consolidate_bp_data(BpFunctions* f, int local);
122 
123 void erts_set_trace_break(BpFunctions *f, Binary *match_spec);
124 void erts_clear_trace_break(BpFunctions *f);
125 
126 void erts_set_export_trace(ErtsCodeInfo *ci, Binary *match_spec, int local);
127 void erts_clear_export_trace(ErtsCodeInfo *ci, int local);
128 
129 void erts_set_mtrace_break(BpFunctions *f, Binary *match_spec,
130 			  ErtsTracer tracer);
131 void erts_clear_mtrace_break(BpFunctions *f);
132 
133 void erts_set_debug_break(BpFunctions *f);
134 void erts_clear_debug_break(BpFunctions *f);
135 void erts_set_count_break(BpFunctions *f, enum erts_break_op);
136 void erts_clear_count_break(BpFunctions *f);
137 
138 
139 void erts_clear_all_breaks(BpFunctions* f);
140 int erts_clear_module_break(Module *modp);
141 void erts_clear_export_break(Module *modp, Export *ep);
142 
143 BeamInstr erts_generic_breakpoint(Process* c_p, ErtsCodeInfo *ci, Eterm* reg);
144 BeamInstr erts_trace_break(Process *p, ErtsCodeInfo *ci, Eterm *args,
145                            Uint32 *ret_flags, ErtsTracer *tracer);
146 
147 int erts_is_trace_break(const ErtsCodeInfo *ci, Binary **match_spec_ret, int local);
148 int erts_is_mtrace_break(const ErtsCodeInfo *ci, Binary **match_spec_ret,
149 			 ErtsTracer *tracer_ret);
150 
151 int erts_is_count_break(const ErtsCodeInfo *ci, Uint *count_ret);
152 int erts_is_time_break(Process *p, const ErtsCodeInfo *ci, Eterm *call_time);
153 
154 const ErtsCodeInfo* erts_trace_time_call(Process* c_p,
155                                          const ErtsCodeInfo *ci,
156                                          BpDataTime* bdt);
157 void erts_trace_time_return(Process* c_p, const ErtsCodeInfo *ci);
158 void erts_schedule_time_break(Process *p, Uint out);
159 void erts_set_time_break(BpFunctions *f, enum erts_break_op);
160 void erts_clear_time_break(BpFunctions *f);
161 
162 const ErtsCodeInfo *erts_find_local_func(const ErtsCodeMFA *mfa);
163 
164 #if ERTS_GLB_INLINE_INCL_FUNC_DEF
165 
166 extern erts_atomic32_t erts_active_bp_index;
167 extern erts_atomic32_t erts_staging_bp_index;
168 
erts_active_bp_ix(void)169 ERTS_GLB_INLINE ErtsBpIndex erts_active_bp_ix(void)
170 {
171     return erts_atomic32_read_nob(&erts_active_bp_index);
172 }
173 
erts_staging_bp_ix(void)174 ERTS_GLB_INLINE ErtsBpIndex erts_staging_bp_ix(void)
175 {
176     return erts_atomic32_read_nob(&erts_staging_bp_index);
177 }
178 #endif
179 
180 #endif /* _BEAM_BP_H */
181