]>
sourceware.org Git - systemtap.git/blob - tapset-been.cxx
1 // tapset for begin/end/error/never
2 // Copyright (C) 2005-2010 Red Hat Inc.
3 // Copyright (C) 2005-2007 Intel Corporation.
4 // Copyright (C) 2008 James.Bottomley@HansenPartnership.com
6 // This file is part of systemtap, and is free software. You can
7 // redistribute it and/or modify it under the terms of the GNU General
8 // Public License (GPL); either version 2, or (at your option) any
13 #include "translate.h"
21 using namespace __gnu_cxx
;
24 static const string
TOK_BEGIN("begin");
25 static const string
TOK_END("end");
26 static const string
TOK_ERROR("error");
27 static const string
TOK_NEVER("never");
30 // ------------------------------------------------------------------------
31 // begin/end/error probes are run right during registration / deregistration
32 // ------------------------------------------------------------------------
34 enum be_t
{ BEGIN
, END
, ERROR
};
36 struct be_derived_probe
: public derived_probe
41 be_derived_probe (probe
* p
, probe_point
* l
, be_t t
, int64_t pr
):
42 derived_probe (p
, l
), type (t
), priority (pr
) {}
44 void join_group (systemtap_session
& s
);
46 static inline bool comp(be_derived_probe
const *a
,
47 be_derived_probe
const *b
)
49 // This allows the BEGIN/END/ERROR probes to intermingle.
50 // But that's OK - they're always treversed with a nested
51 // "if (type==FOO)" conditional.
52 return a
->priority
< b
->priority
;
55 // No assertion need be emitted, since these probes are allowed for
56 // unprivileged users.
57 void emit_privilege_assertion (translator_output
*) {}
59 void print_dupe_stamp(ostream
& o
) { print_dupe_stamp_unprivileged (o
); }
61 bool needs_global_locks () { return false; }
62 // begin/end probes don't need locks around global variables, since
63 // they aren't run concurrently with any other probes
67 struct be_derived_probe_group
: public generic_dpg
<be_derived_probe
>
70 void emit_module_decls (systemtap_session
& s
);
71 void emit_module_init (systemtap_session
& s
);
72 void emit_module_exit (systemtap_session
& s
);
75 struct be_builder
: public derived_probe_builder
79 be_builder(be_t t
) : type(t
) {}
81 virtual void build(systemtap_session
&,
83 probe_point
* location
,
84 literal_map_t
const & parameters
,
85 vector
<derived_probe
*> & finished_results
)
88 if ((type
== BEGIN
&& !get_param(parameters
, TOK_BEGIN
, priority
)) ||
89 (type
== END
&& !get_param(parameters
, TOK_END
, priority
)) ||
90 (type
== ERROR
&& !get_param(parameters
, TOK_ERROR
, priority
)))
92 finished_results
.push_back
93 (new be_derived_probe(base
, location
, type
, priority
));
99 be_derived_probe::join_group (systemtap_session
& s
)
101 if (! s
.be_derived_probes
)
102 s
.be_derived_probes
= new be_derived_probe_group ();
103 s
.be_derived_probes
->enroll (this);
108 be_derived_probe_group::emit_module_decls (systemtap_session
& s
)
110 if (probes
.empty()) return;
112 map
<be_t
, const char *> states
;
113 states
[BEGIN
] = "STAP_SESSION_STARTING";
114 states
[END
] = "STAP_SESSION_STOPPING";
115 states
[ERROR
] = "STAP_SESSION_ERROR";
117 s
.op
->newline() << "/* ---- begin/end/error probes ---- */";
119 // NB: We emit the table in sorted order here, so we don't have to
120 // store the priority numbers as integers and sort at run time.
122 sort(probes
.begin(), probes
.end(), be_derived_probe::comp
);
124 s
.op
->newline() << "static struct stap_be_probe {";
125 s
.op
->newline(1) << "struct stap_probe * const probe;";
126 s
.op
->newline() << "int state, type;";
127 s
.op
->newline(-1) << "} stap_be_probes[] = {";
130 for (unsigned i
=0; i
< probes
.size(); i
++)
132 s
.op
->newline () << "{";
133 s
.op
->line() << " .probe=" << common_probe_init (probes
[i
]) << ",";
134 s
.op
->line() << " .state=" << states
[probes
[i
]->type
] << ",";
135 s
.op
->line() << " .type=" << probes
[i
]->type
;
136 s
.op
->line() << " },";
138 s
.op
->newline(-1) << "};";
140 s
.op
->newline() << "static void enter_be_probe (struct stap_be_probe *stp) {";
142 common_probe_entryfn_prologue (s
.op
, "stp->state", "stp->probe",
143 "_STP_PROBE_HANDLER_BEEN", false);
144 s
.op
->newline() << "(*stp->probe->ph) (c);";
145 common_probe_entryfn_epilogue (s
.op
, false);
146 s
.op
->newline(-1) << "}";
150 be_derived_probe_group::emit_module_init (systemtap_session
& s
)
152 if (probes
.empty()) return;
154 s
.op
->newline() << "for (i=0; i<" << probes
.size() << "; i++) {";
155 s
.op
->newline(1) << "struct stap_be_probe* stp = & stap_be_probes [i];";
156 s
.op
->newline() << "if (stp->type == " << BEGIN
<< ")";
157 s
.op
->newline(1) << "enter_be_probe (stp); /* rc = 0 */";
158 // NB: begin probes that cause errors do not constitute registration
159 // failures. An error message will probably get printed and if
160 // MAXERRORS was left at 1, we'll get an stp_exit. The
161 // error-handling probes will be run during the ordinary
162 // unregistration phase.
163 s
.op
->newline(-2) << "}";
167 be_derived_probe_group::emit_module_exit (systemtap_session
& s
)
169 if (probes
.empty()) return;
171 s
.op
->newline() << "for (i=0; i<" << probes
.size() << "; i++) {";
172 s
.op
->newline(1) << "struct stap_be_probe* stp = & stap_be_probes [i];";
173 s
.op
->newline() << "if (stp->type == " << END
<< ")";
174 s
.op
->newline(1) << "enter_be_probe (stp);";
175 s
.op
->newline(-2) << "}";
177 s
.op
->newline() << "for (i=0; i<" << probes
.size() << "; i++) {";
178 s
.op
->newline(1) << "struct stap_be_probe* stp = & stap_be_probes [i];";
179 s
.op
->newline() << "if (stp->type == " << ERROR
<< ")";
180 s
.op
->newline(1) << "enter_be_probe (stp);";
181 s
.op
->newline(-2) << "}";
186 // ------------------------------------------------------------------------
187 // never probes are never run
188 // ------------------------------------------------------------------------
190 struct never_derived_probe
: public derived_probe
192 never_derived_probe (probe
* p
, probe_point
* l
): derived_probe (p
, l
) {}
193 void join_group (systemtap_session
&) { /* thus no probe_group */ }
194 void emit_privilege_assertion (translator_output
*) {}
195 void print_dupe_stamp(ostream
& o
) { print_dupe_stamp_unprivileged (o
); }
199 struct never_builder
: public derived_probe_builder
202 virtual void build(systemtap_session
&,
204 probe_point
* location
,
205 literal_map_t
const &,
206 vector
<derived_probe
*> & finished_results
)
208 finished_results
.push_back(new never_derived_probe(base
, location
));
214 // ------------------------------------------------------------------------
215 // unified registration for begin/end/error/never
216 // ------------------------------------------------------------------------
219 register_tapset_been(systemtap_session
& s
)
221 match_node
* root
= s
.pattern_root
;
223 root
->bind(TOK_BEGIN
)
224 ->bind_privilege(pr_stapusr
)
225 ->bind(new be_builder(BEGIN
));
226 root
->bind_num(TOK_BEGIN
)
227 ->bind_privilege(pr_stapusr
)
228 ->bind(new be_builder(BEGIN
));
231 ->bind_privilege(pr_stapusr
)
232 ->bind(new be_builder(END
));
233 root
->bind_num(TOK_END
)
234 ->bind_privilege(pr_stapusr
)
235 ->bind(new be_builder(END
));
237 root
->bind(TOK_ERROR
)
238 ->bind_privilege(pr_stapusr
)
239 ->bind(new be_builder(ERROR
));
240 root
->bind_num(TOK_ERROR
)
241 ->bind_privilege(pr_stapusr
)
242 ->bind(new be_builder(ERROR
));
244 root
->bind(TOK_NEVER
)
245 ->bind_privilege(pr_stapusr
)
246 ->bind(new never_builder());
249 /* vim: set sw=2 ts=8 cino=>4,n-2,{2,^-2,t0,(0,u0,w1,M1 : */
This page took 0.048862 seconds and 5 git commands to generate.