2 // Copyright (C) 2005-2014 Red Hat Inc.
3 // Copyright (C) 2005-2007 Intel Corporation.
5 // This file is part of systemtap, and is free software. You can
6 // redistribute it and/or modify it under the terms of the GNU General
7 // Public License (GPL); either version 2, or (at your option) any
13 #include "task_finder.h"
14 #include "tapset-dynprobe.h"
15 #include "translate.h"
23 using namespace __gnu_cxx
;
26 static const string
TOK_PROCESS("process");
27 static const string
TOK_BEGIN("begin");
28 static const string
TOK_END("end");
29 static const string
TOK_THREAD("thread");
30 static const string
TOK_SYSCALL("syscall");
31 static const string
TOK_RETURN("return");
34 // ------------------------------------------------------------------------
35 // utrace user-space probes
36 // ------------------------------------------------------------------------
38 // Note that these flags don't match up exactly with UTRACE_EVENT
39 // flags (and that's OK).
40 enum utrace_derived_probe_flags
{
42 UDPF_BEGIN
, // process begin
43 UDPF_END
, // process end
44 UDPF_THREAD_BEGIN
, // thread begin
45 UDPF_THREAD_END
, // thread end
46 UDPF_SYSCALL
, // syscall entry
47 UDPF_SYSCALL_RETURN
, // syscall exit
51 struct utrace_derived_probe
: public derived_probe
56 interned_string library
;
58 enum utrace_derived_probe_flags flags
;
59 bool target_symbol_seen
;
61 utrace_derived_probe (systemtap_session
&s
, probe
* p
, probe_point
* l
,
62 bool hp
, interned_string pn
, int64_t pd
,
63 enum utrace_derived_probe_flags f
);
64 void join_group (systemtap_session
& s
);
66 void emit_privilege_assertion (translator_output
*);
67 void print_dupe_stamp(ostream
& o
);
68 void getargs (std::list
<std::string
> &arg_set
) const;
72 struct utrace_derived_probe_group
: public generic_dpg
<utrace_derived_probe
>
75 map
<string
, vector
<utrace_derived_probe
*> > probes_by_path
;
76 typedef map
<string
, vector
<utrace_derived_probe
*> >::iterator p_b_path_iterator
;
77 map
<int64_t, vector
<utrace_derived_probe
*> > probes_by_pid
;
78 typedef map
<int64_t, vector
<utrace_derived_probe
*> >::iterator p_b_pid_iterator
;
80 bool flags_seen
[UDPF_NFLAGS
];
82 // Using the linux backend
83 void emit_linux_probe_decl (systemtap_session
& s
, utrace_derived_probe
*p
);
84 void emit_module_linux_decls (systemtap_session
& s
);
85 void emit_module_linux_init (systemtap_session
& s
);
86 void emit_module_linux_exit (systemtap_session
& s
);
88 // Using the dyninst backend (via stapdyn)
89 void emit_dyninst_probe_decl (systemtap_session
& s
, const string
& path
,
90 utrace_derived_probe
*p
);
91 void emit_module_dyninst_decls (systemtap_session
& s
);
92 void emit_module_dyninst_init (systemtap_session
& s
);
93 void emit_module_dyninst_exit (systemtap_session
& s
);
96 utrace_derived_probe_group(): num_probes(0), flags_seen() { }
98 void enroll (utrace_derived_probe
* probe
);
99 void emit_module_decls (systemtap_session
& s
);
100 void emit_module_init (systemtap_session
& s
);
101 void emit_module_exit (systemtap_session
& s
);
105 struct utrace_var_expanding_visitor
: public var_expanding_visitor
107 utrace_var_expanding_visitor(systemtap_session
& s
, probe_point
* l
,
108 enum utrace_derived_probe_flags f
):
109 var_expanding_visitor (s
),
110 base_loc (l
), flags (f
),
111 target_symbol_seen (false), add_block(NULL
), add_probe(NULL
) {}
113 probe_point
* base_loc
;
114 enum utrace_derived_probe_flags flags
;
115 bool target_symbol_seen
;
118 std::map
<std::string
, symbol
*> return_ts_map
;
120 void visit_target_symbol_arg (target_symbol
* e
);
121 void visit_target_symbol_context (target_symbol
* e
);
122 void visit_target_symbol_cached (target_symbol
* e
);
123 void visit_target_symbol (target_symbol
* e
);
128 utrace_derived_probe::utrace_derived_probe (systemtap_session
&s
,
129 probe
* p
, probe_point
* l
,
130 bool hp
, interned_string pn
, int64_t pd
,
131 enum utrace_derived_probe_flags f
):
132 derived_probe (p
, l
, true /* .components soon rewritten */ ),
133 has_path(hp
), path(pn
), has_library(false), pid(pd
), flags(f
),
134 target_symbol_seen(false)
136 if (!s
.runtime_usermode_p())
137 check_process_probe_kernel_support(s
);
139 // Expand local variables in the probe body
140 utrace_var_expanding_visitor
v (s
, l
, flags
);
141 var_expand_const_fold_loop (s
, this->body
, v
);
142 target_symbol_seen
= v
.target_symbol_seen
;
144 // If during target-variable-expanding the probe, we added a new block
145 // of code, add it to the start of the probe.
147 this->body
= new block(v
.add_block
, this->body
);
148 // If when target-variable-expanding the probe, we added a new
149 // probe, add it in a new file to the list of files to be processed.
152 stapfile
*f
= new stapfile
;
153 f
->probes
.push_back(v
.add_probe
);
154 s
.files
.push_back(f
);
157 // Reset the sole element of the "locations" vector as a
158 // "reverse-engineered" form of the incoming (q.base_loc) probe
159 // point. This allows a user to see what program etc.
160 // number any particular match of the wildcards.
162 vector
<probe_point::component
*> comps
;
164 comps
.push_back (new probe_point::component(TOK_PROCESS
, new literal_string(path
)));
166 comps
.push_back (new probe_point::component(TOK_PROCESS
, new literal_number(pid
)));
168 comps
.push_back (new probe_point::component(TOK_PROCESS
));
172 case UDPF_THREAD_BEGIN
:
173 comps
.push_back (new probe_point::component(TOK_THREAD
));
174 comps
.push_back (new probe_point::component(TOK_BEGIN
));
176 case UDPF_THREAD_END
:
177 comps
.push_back (new probe_point::component(TOK_THREAD
));
178 comps
.push_back (new probe_point::component(TOK_END
));
181 comps
.push_back (new probe_point::component(TOK_SYSCALL
));
183 case UDPF_SYSCALL_RETURN
:
184 comps
.push_back (new probe_point::component(TOK_SYSCALL
));
185 comps
.push_back (new probe_point::component(TOK_RETURN
));
188 comps
.push_back (new probe_point::component(TOK_BEGIN
));
191 comps
.push_back (new probe_point::component(TOK_END
));
198 this->sole_location()->components
= comps
;
203 utrace_derived_probe::join_group (systemtap_session
& s
)
205 if (! s
.utrace_derived_probes
)
207 s
.utrace_derived_probes
= new utrace_derived_probe_group ();
209 s
.utrace_derived_probes
->enroll (this);
210 this->group
= s
.utrace_derived_probes
;
212 if (s
.runtime_usermode_p())
215 enable_task_finder(s
);
220 utrace_derived_probe::emit_privilege_assertion (translator_output
* o
)
222 // Process end probes can fire for unprivileged users even if the process
223 // does not belong to the user. On example is that process.end will fire
224 // at the end of a process which executes execve on an executable which
225 // has the setuid bit set. When the setuid executable ends, the process.end
226 // will fire even though the owner of the process is different than the
228 // Unprivileged users must use check is_myproc() from within any
229 // process.end variant in their script before doing anything "dangerous".
230 if (flags
== UDPF_END
)
233 // Other process probes should only fire for unprivileged users in the
234 // context of processes which they own. Generate an assertion to this effect
236 emit_process_owner_assertion (o
);
240 utrace_derived_probe::print_dupe_stamp(ostream
& o
)
242 // Process end probes can fire for unprivileged users even if the process
243 // does not belong to the user. On example is that process.end will fire
244 // at the end of a process which executes execve on an executable which
245 // has the setuid bit set. When the setuid executable ends, the process.end
246 // will fire even though the owner of the process is different than the
248 // Unprivileged users must use check is_myproc() from within any
249 // process.end variant in their script before doing anything "dangerous".
251 // Other process probes should only fire for unprivileged users in the
252 // context of processes which they own.
253 if (flags
== UDPF_END
)
254 print_dupe_stamp_unprivileged (o
);
256 print_dupe_stamp_unprivileged_process_owner (o
);
260 utrace_derived_probe::getargs(std::list
<std::string
> &arg_set
) const
262 arg_set
.push_back("$syscall:long");
263 arg_set
.push_back("$arg1:long");
264 arg_set
.push_back("$arg2:long");
265 arg_set
.push_back("$arg3:long");
266 arg_set
.push_back("$arg4:long");
267 arg_set
.push_back("$arg5:long");
268 arg_set
.push_back("$arg6:long");
272 utrace_var_expanding_visitor::visit_target_symbol_cached (target_symbol
* e
)
274 // Get the full name of the target symbol.
275 stringstream ts_name_stream
;
276 e
->print(ts_name_stream
);
277 string ts_name
= ts_name_stream
.str();
279 // Check and make sure we haven't already seen this target
280 // variable in this return probe. If we have, just return our
282 map
<string
, symbol
*>::iterator i
= return_ts_map
.find(ts_name
);
283 if (i
!= return_ts_map
.end())
289 // We've got to do several things here to handle target
290 // variables in return probes.
292 // (1) Synthesize a global array which is the cache of the
293 // target variable value. We don't need a nesting level counter
294 // like the dwarf_var_expanding_visitor::visit_target_symbol()
295 // does since a particular thread can only be in one system
296 // calls at a time. The array will look like this:
298 // _utrace_tvar_{name}_{num}
299 string aname
= (string("__global_utrace_tvar_")
301 + "_" + lex_cast(tick
++));
302 vardecl
* vd
= new vardecl
;
305 sess
.globals
.push_back (vd
);
307 // (2) Create a new code block we're going to insert at the
308 // beginning of this probe to get the cached value into a
309 // temporary variable. We'll replace the target variable
310 // reference with the temporary variable reference. The code
311 // will look like this:
313 // _utrace_tvar_tid = tid()
314 // _utrace_tvar_{name}_{num}_tmp
315 // = _utrace_tvar_{name}_{num}[_utrace_tvar_tid]
316 // delete _utrace_tvar_{name}_{num}[_utrace_tvar_tid]
318 // (2a) Synthesize the tid temporary expression, which will look
321 // _utrace_tvar_tid = tid()
322 symbol
* tidsym
= new symbol
;
323 tidsym
->name
= string("_utrace_tvar_tid");
324 tidsym
->tok
= e
->tok
;
326 if (add_block
== NULL
)
328 add_block
= new block
;
329 add_block
->tok
= e
->tok
;
331 // Synthesize a functioncall to grab the thread id.
332 functioncall
* fc
= new functioncall
;
334 fc
->function
= string("tid");
336 // Assign the tid to '_utrace_tvar_tid'.
337 assignment
* a
= new assignment
;
343 expr_statement
* es
= new expr_statement
;
346 add_block
->statements
.push_back (es
);
349 // (2b) Synthesize an array reference and assign it to a
350 // temporary variable (that we'll use as replacement for the
351 // target variable reference). It will look like this:
353 // _utrace_tvar_{name}_{num}_tmp
354 // = _utrace_tvar_{name}_{num}[_utrace_tvar_tid]
356 arrayindex
* ai_tvar
= new arrayindex
;
357 ai_tvar
->tok
= e
->tok
;
359 symbol
* sym
= new symbol
;
364 ai_tvar
->indexes
.push_back(tidsym
);
366 symbol
* tmpsym
= new symbol
;
367 tmpsym
->name
= aname
+ "_tmp";
368 tmpsym
->tok
= e
->tok
;
370 assignment
* a
= new assignment
;
376 expr_statement
* es
= new expr_statement
;
380 add_block
->statements
.push_back (es
);
382 // (2c) Delete the array value. It will look like this:
384 // delete _utrace_tvar_{name}_{num}[_utrace_tvar_tid]
386 delete_statement
* ds
= new delete_statement
;
389 add_block
->statements
.push_back (ds
);
391 // (3) We need an entry probe that saves the value for us in the
392 // global array we created. Create the entry probe, which will
395 // probe process(PATH_OR_PID).syscall {
396 // _utrace_tvar_tid = tid()
397 // _utrace_tvar_{name}_{num}[_utrace_tvar_tid] = ${param}
400 // Why the temporary for tid()? If we end up caching more
401 // than one target variable, we can reuse the temporary instead
402 // of calling tid() multiple times.
404 if (add_probe
== NULL
)
406 add_probe
= new probe
;
407 add_probe
->tok
= e
->tok
;
409 // We need the name of the current probe point, minus the
410 // ".return". Create a new probe point, copying all the
411 // components, stopping when we see the ".return"
413 probe_point
* pp
= new probe_point
;
414 for (unsigned c
= 0; c
< base_loc
->components
.size(); c
++)
416 if (base_loc
->components
[c
]->functor
== "return")
419 pp
->components
.push_back(base_loc
->components
[c
]);
421 pp
->optional
= base_loc
->optional
;
422 add_probe
->locations
.push_back(pp
);
424 add_probe
->body
= new block
;
425 add_probe
->body
->tok
= e
->tok
;
427 // Synthesize a functioncall to grab the thread id.
428 functioncall
* fc
= new functioncall
;
430 fc
->function
= string("tid");
432 // Assign the tid to '_utrace_tvar_tid'.
433 assignment
* a
= new assignment
;
439 expr_statement
* es
= new expr_statement
;
442 add_probe
->body
= new block(add_probe
->body
, es
);
444 vardecl
* vd
= new vardecl
;
446 vd
->name
= tidsym
->name
;
448 vd
->set_arity(0, e
->tok
);
449 add_probe
->locals
.push_back(vd
);
452 // Save the value, like this:
454 // _utrace_tvar_{name}_{num}[_utrace_tvar_tid] = ${param}
461 es
= new expr_statement
;
465 add_probe
->body
= new block(add_probe
->body
, es
);
467 // (4) Provide the '_utrace_tvar_{name}_{num}_tmp' variable to
468 // our parent so it can be used as a substitute for the target
472 // (5) Remember this replacement since we might be able to reuse
473 // it later if the same return probe references this target
475 return_ts_map
[ts_name
] = tmpsym
;
481 utrace_var_expanding_visitor::visit_target_symbol_arg (target_symbol
* e
)
483 if (flags
!= UDPF_SYSCALL
)
484 throw SEMANTIC_ERROR (_("only \"process(PATH_OR_PID).syscall\" support $argN or $$parms."), e
->tok
);
486 if (e
->name
== "$$parms")
488 // copy from tracepoint
489 print_format
* pf
= print_format::create(e
->tok
, "sprintf");
491 target_symbol_seen
= true;
493 for (unsigned i
= 0; i
< 6; ++i
)
496 pf
->raw_components
+= " ";
497 pf
->raw_components
+= "$arg" + lex_cast(i
+1);
498 target_symbol
*tsym
= new target_symbol
;
500 tsym
->name
= "$arg" + lex_cast(i
+1);
501 tsym
->saved_conversion_error
= 0;
502 pf
->raw_components
+= "=%#x"; //FIXME: missing type info
504 functioncall
* n
= new functioncall
; //same as the following
506 n
->function
= "_utrace_syscall_arg";
507 n
->referents
.clear();
508 literal_number
*num
= new literal_number(i
);
510 n
->args
.push_back(num
);
512 pf
->args
.push_back(n
);
514 pf
->components
= print_format::string_to_components(pf
->raw_components
);
520 string argnum_s
= (string
)e
->name
.substr(4,e
->name
.length()-4);
524 argnum
= lex_cast
<int>(argnum_s
);
526 catch (const runtime_error
& f
) // non-integral $arg suffix: e.g. $argKKKSDF
528 throw SEMANTIC_ERROR (_("invalid syscall argument number (1-6)"), e
->tok
);
531 e
->assert_no_components("utrace");
533 // FIXME: max argnument number should not be hardcoded.
534 if (argnum
< 1 || argnum
> 6)
535 throw SEMANTIC_ERROR (_("invalid syscall argument number (1-6)"), e
->tok
);
537 bool lvalue
= is_active_lvalue(e
);
539 throw SEMANTIC_ERROR(_("utrace '$argN' variable is read-only"), e
->tok
);
541 // Remember that we've seen a target variable.
542 target_symbol_seen
= true;
544 // We're going to substitute a synthesized '_utrace_syscall_arg'
545 // function call for the '$argN' reference.
546 functioncall
* n
= new functioncall
;
548 n
->function
= "_utrace_syscall_arg";
549 n
->referents
.clear(); // NB: must not resolve yet, to ensure inclusion in session
551 literal_number
*num
= new literal_number(argnum
- 1);
553 n
->args
.push_back(num
);
560 utrace_var_expanding_visitor::visit_target_symbol_context (target_symbol
* e
)
562 string sname
= e
->name
;
564 e
->assert_no_components("utrace");
566 bool lvalue
= is_active_lvalue(e
);
568 throw SEMANTIC_ERROR(_F("utrace '%s' variable is read-only", sname
.c_str()), e
->tok
);
571 if (sname
== "$return")
573 if (flags
!= UDPF_SYSCALL_RETURN
)
574 throw SEMANTIC_ERROR (_("only \"process(PATH_OR_PID).syscall.return\" support $return."), e
->tok
);
575 fname
= "_utrace_syscall_return";
577 else if (sname
== "$syscall")
579 // If we've got a syscall entry probe, we can just call the
581 if (flags
== UDPF_SYSCALL
) {
582 fname
= "_utrace_syscall_nr";
584 // If we're in a syscal return probe, we can't really access
585 // $syscall. So, similar to what
586 // dwarf_var_expanding_visitor::visit_target_symbol() does,
587 // we'll create an syscall entry probe to cache $syscall, then
588 // we'll access the cached value in the syscall return probe.
590 visit_target_symbol_cached (e
);
592 // Remember that we've seen a target variable.
593 target_symbol_seen
= true;
599 throw SEMANTIC_ERROR (_("unknown target variable"), e
->tok
);
602 // Remember that we've seen a target variable.
603 target_symbol_seen
= true;
605 // We're going to substitute a synthesized '_utrace_syscall_nr'
606 // function call for the '$syscall' reference.
607 functioncall
* n
= new functioncall
;
610 n
->referents
.clear(); // NB: must not resolve yet, to ensure inclusion in session
616 utrace_var_expanding_visitor::visit_target_symbol (target_symbol
* e
)
618 assert(e
->name
.size() > 0 && e
->name
[0] == '$');
622 if (flags
!= UDPF_SYSCALL
&& flags
!= UDPF_SYSCALL_RETURN
)
623 throw SEMANTIC_ERROR (_("only \"process(PATH_OR_PID).syscall\""
624 " and \"process(PATH_OR_PID).syscall.return\" probes support target symbols"),
628 throw SEMANTIC_ERROR(_("cannot take address of utrace variable"), e
->tok
);
630 if (startswith(e
->name
, "$arg") || e
->name
== "$$parms")
631 visit_target_symbol_arg(e
);
632 else if (e
->name
== "$syscall" || e
->name
== "$return")
633 visit_target_symbol_context(e
);
635 throw SEMANTIC_ERROR (_("invalid target symbol for utrace probe,"
636 " $syscall, $return, $argN or $$parms expected"),
639 catch (const semantic_error
&er
)
648 struct utrace_builder
: public derived_probe_builder
651 virtual void build(systemtap_session
& sess
,
653 probe_point
* location
,
654 literal_map_t
const & parameters
,
655 vector
<derived_probe
*> & finished_results
)
657 interned_string path
, path_tgt
;
660 bool has_path
= get_param (parameters
, TOK_PROCESS
, path
);
661 bool has_pid
= get_param (parameters
, TOK_PROCESS
, pid
);
662 enum utrace_derived_probe_flags flags
= UDPF_NONE
;
664 if (has_null_param (parameters
, TOK_THREAD
))
666 if (has_null_param (parameters
, TOK_BEGIN
))
667 flags
= UDPF_THREAD_BEGIN
;
668 else if (has_null_param (parameters
, TOK_END
))
669 flags
= UDPF_THREAD_END
;
671 else if (has_null_param (parameters
, TOK_SYSCALL
))
673 if (sess
.runtime_usermode_p())
674 throw SEMANTIC_ERROR (_("process.syscall probes not available with the dyninst runtime"));
676 if (has_null_param (parameters
, TOK_RETURN
))
677 flags
= UDPF_SYSCALL_RETURN
;
679 flags
= UDPF_SYSCALL
;
681 else if (has_null_param (parameters
, TOK_BEGIN
))
683 else if (has_null_param (parameters
, TOK_END
))
686 // Check that if a pid was given, then it corresponds to a running process.
687 if (has_pid
|| sess
.target_pid
)
690 if (!is_valid_pid(has_pid
? pid
: sess
.target_pid
, pid_err_msg
))
691 throw SEMANTIC_ERROR(pid_err_msg
);
694 // If we didn't get a path or pid, this means to probe everything.
695 // Convert this to a pid-based probe.
696 if (! has_path
&& ! has_pid
)
706 throw SEMANTIC_ERROR (_("empty module"));
707 path
= find_executable (path
, sess
.sysroot
, sess
.sysenv
);
708 sess
.unwindsym_modules
.insert (path
);
709 path_tgt
= path_remove_sysroot(sess
, path
);
712 finished_results
.push_back(new utrace_derived_probe(sess
, base
, location
,
713 has_path
, path_tgt
, pid
,
717 virtual string
name() { return "utrace builder"; }
722 utrace_derived_probe_group::enroll (utrace_derived_probe
* p
)
725 probes_by_path
[p
->path
].push_back(p
);
727 probes_by_pid
[p
->pid
].push_back(p
);
729 flags_seen
[p
->flags
] = true;
731 // XXX: multiple exec probes (for instance) for the same path (or
732 // pid) should all share a utrace report function, and have their
733 // handlers executed sequentially.
738 utrace_derived_probe_group::emit_linux_probe_decl (systemtap_session
& s
,
739 utrace_derived_probe
*p
)
741 s
.op
->newline() << "{";
742 s
.op
->line() << " .tgt={";
743 s
.op
->line() << " .purpose=\"lifecycle tracking\",";
746 s
.op
->line() << " .procname=\"" << p
->path
<< "\",";
747 s
.op
->line() << " .pid=0,";
751 s
.op
->line() << " .procname=NULL,";
752 s
.op
->line() << " .pid=" << p
->pid
<< ",";
755 s
.op
->line() << " .callback=&_stp_utrace_probe_cb,";
756 s
.op
->line() << " .mmap_callback=NULL,";
757 s
.op
->line() << " .munmap_callback=NULL,";
758 s
.op
->line() << " .mprotect_callback=NULL,";
759 s
.op
->line() << " },";
760 s
.op
->line() << " .probe=" << common_probe_init (p
) << ",";
765 // Notice that we'll just call the probe directly when we get
766 // notified, since the task_finder layer stops the thread for us.
767 case UDPF_BEGIN
: // process begin
768 s
.op
->line() << " .flags=(UDPF_BEGIN),";
770 case UDPF_THREAD_BEGIN
: // thread begin
771 s
.op
->line() << " .flags=(UDPF_THREAD_BEGIN),";
774 // Notice we're not setting up a .ops/.report_death handler for
775 // either UDPF_END or UDPF_THREAD_END. Instead, we'll just call
776 // the probe directly when we get notified.
777 case UDPF_END
: // process end
778 s
.op
->line() << " .flags=(UDPF_END),";
780 case UDPF_THREAD_END
: // thread end
781 s
.op
->line() << " .flags=(UDPF_THREAD_END),";
784 // For UDPF_SYSCALL/UDPF_SYSCALL_RETURN probes, the .report_death
785 // handler isn't strictly necessary. However, it helps to keep
786 // our attaches/detaches symmetrical. Since the task_finder layer
787 // stops the thread, that works around bug 6841.
789 s
.op
->line() << " .flags=(UDPF_SYSCALL),";
790 s
.op
->newline() << "#if !defined(CONFIG_UTRACE)";
791 s
.op
->newline() << " .ops={ .report_syscall_entry=stap_utrace_probe_syscall, .report_death=stap_utrace_task_finder_report_death },";
792 s
.op
->line() << " .events=(UTRACE_EVENT(SYSCALL_ENTRY)|UTRACE_EVENT(DEATH)),";
793 s
.op
->newline() << "#else";
794 s
.op
->newline() << " .ops={ .report_syscall_entry=stap_utrace_probe_syscall, .report_exit=stap_utrace_task_finder_report_exit },";
795 s
.op
->line() << " .events=(UTRACE_EVENT(SYSCALL_ENTRY)|UTRACE_EVENT(EXIT)),";
796 s
.op
->newline() << "#endif";
799 case UDPF_SYSCALL_RETURN
:
800 s
.op
->line() << " .flags=(UDPF_SYSCALL_RETURN),";
801 s
.op
->newline() << "#if !defined(CONFIG_UTRACE)";
802 s
.op
->newline() << " .ops={ .report_syscall_exit=stap_utrace_probe_syscall, .report_death=stap_utrace_task_finder_report_death },";
803 s
.op
->line() << " .events=(UTRACE_EVENT(SYSCALL_EXIT)|UTRACE_EVENT(DEATH)),";
804 s
.op
->newline() << "#else";
805 s
.op
->newline() << " .ops={ .report_syscall_exit=stap_utrace_probe_syscall, .report_exit=stap_utrace_task_finder_report_exit },";
806 s
.op
->line() << " .events=(UTRACE_EVENT(SYSCALL_EXIT)|UTRACE_EVENT(EXIT)),";
807 s
.op
->newline() << "#endif";
812 s
.op
->line() << " .flags=(UDPF_NONE),";
813 s
.op
->line() << " .ops={ },";
814 s
.op
->line() << " .events=0,";
817 throw SEMANTIC_ERROR ("bad utrace probe flag");
820 s
.op
->line() << " .engine_attached=0,";
821 s
.op
->line() << " },";
826 utrace_derived_probe_group::emit_module_linux_decls (systemtap_session
& s
)
828 if (probes_by_path
.empty() && probes_by_pid
.empty())
832 s
.op
->newline() << "/* ---- utrace probes ---- */";
834 s
.op
->newline() << "enum utrace_derived_probe_flags {";
836 s
.op
->newline() << "UDPF_NONE,";
837 s
.op
->newline() << "UDPF_BEGIN,";
838 s
.op
->newline() << "UDPF_END,";
839 s
.op
->newline() << "UDPF_THREAD_BEGIN,";
840 s
.op
->newline() << "UDPF_THREAD_END,";
841 s
.op
->newline() << "UDPF_SYSCALL,";
842 s
.op
->newline() << "UDPF_SYSCALL_RETURN,";
843 s
.op
->newline() << "UDPF_NFLAGS";
844 s
.op
->newline(-1) << "};";
846 s
.op
->newline() << "struct stap_utrace_probe {";
848 s
.op
->newline() << "struct stap_task_finder_target tgt;";
849 s
.op
->newline() << "const struct stap_probe * const probe;";
850 s
.op
->newline() << "int engine_attached;";
851 s
.op
->newline() << "enum utrace_derived_probe_flags flags;";
852 s
.op
->newline() << "struct utrace_engine_ops ops;";
853 s
.op
->newline() << "unsigned long events;";
854 s
.op
->newline(-1) << "};";
857 // Output handler function for UDPF_BEGIN, UDPF_THREAD_BEGIN,
858 // UDPF_END, and UDPF_THREAD_END
859 if (flags_seen
[UDPF_BEGIN
] || flags_seen
[UDPF_THREAD_BEGIN
]
860 || flags_seen
[UDPF_END
] || flags_seen
[UDPF_THREAD_END
])
862 s
.op
->newline() << "static void stap_utrace_probe_handler(struct task_struct *tsk, struct stap_utrace_probe *p) {";
865 common_probe_entryfn_prologue (s
, "STAP_SESSION_RUNNING", "p->probe",
866 "stp_probe_type_utrace");
868 // call probe function
869 s
.op
->newline() << "(*p->probe->ph) (c);";
870 common_probe_entryfn_epilogue (s
, true, otf_safe_context(s
));
872 s
.op
->newline() << "return;";
873 s
.op
->newline(-1) << "}";
876 // Output handler function for SYSCALL_ENTRY and SYSCALL_EXIT events
877 if (flags_seen
[UDPF_SYSCALL
] || flags_seen
[UDPF_SYSCALL_RETURN
])
879 s
.op
->newline() << "#ifdef UTRACE_ORIG_VERSION";
880 s
.op
->newline() << "static u32 stap_utrace_probe_syscall(struct utrace_engine *engine, struct task_struct *tsk, struct pt_regs *regs) {";
881 s
.op
->newline() << "#else";
882 s
.op
->newline() << "#if defined(UTRACE_API_VERSION) && (UTRACE_API_VERSION >= 20091216)";
883 s
.op
->newline() << "static u32 stap_utrace_probe_syscall(u32 action, struct utrace_engine *engine, struct pt_regs *regs) {";
884 s
.op
->newline() << "#else";
885 s
.op
->newline() << "static u32 stap_utrace_probe_syscall(enum utrace_resume_action action, struct utrace_engine *engine, struct task_struct *tsk, struct pt_regs *regs) {";
886 s
.op
->newline() << "#endif";
887 s
.op
->newline() << "#endif";
890 s
.op
->newline() << "struct stap_utrace_probe *p = (struct stap_utrace_probe *)engine->data;";
892 common_probe_entryfn_prologue (s
, "STAP_SESSION_RUNNING", "p->probe",
893 "stp_probe_type_utrace_syscall");
894 s
.op
->newline() << "c->uregs = regs;";
895 s
.op
->newline() << "c->user_mode_p = 1;";
897 // call probe function
898 s
.op
->newline() << "(*p->probe->ph) (c);";
899 common_probe_entryfn_epilogue (s
, true, otf_safe_context(s
));
901 s
.op
->newline() << "if ((atomic_read (session_state()) != STAP_SESSION_STARTING) && (atomic_read (session_state()) != STAP_SESSION_RUNNING)) {";
903 s
.op
->newline() << "debug_task_finder_detach();";
904 s
.op
->newline() << "return UTRACE_DETACH;";
905 s
.op
->newline(-1) << "}";
906 s
.op
->newline() << "return UTRACE_RESUME;";
907 s
.op
->newline(-1) << "}";
910 // Output task_finder callback routine that gets called for all
911 // utrace probe types.
912 s
.op
->newline() << "static int _stp_utrace_probe_cb(struct stap_task_finder_target *tgt, struct task_struct *tsk, int register_p, int process_p) {";
914 s
.op
->newline() << "int rc = 0;";
915 s
.op
->newline() << "struct stap_utrace_probe *p = container_of(tgt, struct stap_utrace_probe, tgt);";
916 s
.op
->newline() << "struct utrace_engine *engine;";
918 s
.op
->newline() << "if (register_p) {";
921 s
.op
->newline() << "switch (p->flags) {";
924 // When receiving a UTRACE_EVENT(CLONE) event, we can't call the
925 // begin/thread.begin probe directly. So, we'll just attach an
926 // engine that waits for the thread to quiesce. When the thread
927 // quiesces, then call the probe.
928 if (flags_seen
[UDPF_BEGIN
])
930 s
.op
->newline() << "case UDPF_BEGIN:";
932 s
.op
->newline() << "if (process_p) {";
934 s
.op
->newline() << "stap_utrace_probe_handler(tsk, p);";
935 s
.op
->newline(-1) << "}";
936 s
.op
->newline() << "break;";
939 if (flags_seen
[UDPF_THREAD_BEGIN
])
941 s
.op
->newline() << "case UDPF_THREAD_BEGIN:";
943 s
.op
->newline() << "if (! process_p) {";
945 s
.op
->newline() << "stap_utrace_probe_handler(tsk, p);";
946 s
.op
->newline(-1) << "}";
947 s
.op
->newline() << "break;";
951 // For end/thread_end probes, do nothing at registration time.
952 // We'll handle these in the 'register_p == 0' case.
953 if (flags_seen
[UDPF_END
] || flags_seen
[UDPF_THREAD_END
])
955 s
.op
->newline() << "case UDPF_END:";
956 s
.op
->newline() << "case UDPF_THREAD_END:";
958 s
.op
->newline() << "break;";
962 // Attach an engine for SYSCALL_ENTRY and SYSCALL_EXIT events.
963 if (flags_seen
[UDPF_SYSCALL
] || flags_seen
[UDPF_SYSCALL_RETURN
])
965 s
.op
->newline() << "case UDPF_SYSCALL:";
966 s
.op
->newline() << "case UDPF_SYSCALL_RETURN:";
968 s
.op
->newline() << "rc = stap_utrace_attach(tsk, &p->ops, p, p->events);";
969 s
.op
->newline() << "if (rc == 0) {";
971 s
.op
->newline() << "p->engine_attached = 1;";
972 s
.op
->newline(-1) << "}";
973 s
.op
->newline() << "break;";
977 s
.op
->newline() << "default:";
979 s
.op
->newline() << "_stp_error(\"unhandled flag value %d at %s:%d\", p->flags, __FUNCTION__, __LINE__);";
980 s
.op
->newline() << "break;";
982 s
.op
->newline(-1) << "}";
983 s
.op
->newline(-1) << "}";
985 // Since this engine could be attached to multiple threads, don't
986 // call stap_utrace_detach_ops() here, only call
987 // stap_utrace_detach() as necessary.
988 s
.op
->newline() << "else {";
990 s
.op
->newline() << "switch (p->flags) {";
992 // For end probes, go ahead and call the probe directly.
993 if (flags_seen
[UDPF_END
])
995 s
.op
->newline() << "case UDPF_END:";
997 s
.op
->newline() << "if (process_p) {";
999 s
.op
->newline() << "stap_utrace_probe_handler(tsk, p);";
1000 s
.op
->newline(-1) << "}";
1001 s
.op
->newline() << "break;";
1004 if (flags_seen
[UDPF_THREAD_END
])
1006 s
.op
->newline() << "case UDPF_THREAD_END:";
1008 s
.op
->newline() << "if (! process_p) {";
1010 s
.op
->newline() << "stap_utrace_probe_handler(tsk, p);";
1011 s
.op
->newline(-1) << "}";
1012 s
.op
->newline() << "break;";
1016 // For begin/thread_begin probes, we don't need to do anything.
1017 if (flags_seen
[UDPF_BEGIN
] || flags_seen
[UDPF_THREAD_BEGIN
])
1019 s
.op
->newline() << "case UDPF_BEGIN:";
1020 s
.op
->newline() << "case UDPF_THREAD_BEGIN:";
1022 s
.op
->newline() << "break;";
1026 if (flags_seen
[UDPF_SYSCALL
] || flags_seen
[UDPF_SYSCALL_RETURN
])
1028 s
.op
->newline() << "case UDPF_SYSCALL:";
1029 s
.op
->newline() << "case UDPF_SYSCALL_RETURN:";
1031 s
.op
->newline() << "stap_utrace_detach(tsk, &p->ops);";
1032 s
.op
->newline() << "break;";
1036 s
.op
->newline() << "default:";
1038 s
.op
->newline() << "_stp_error(\"unhandled flag value %d at %s:%d\", p->flags, __FUNCTION__, __LINE__);";
1039 s
.op
->newline() << "break;";
1041 s
.op
->newline(-1) << "}";
1042 s
.op
->newline(-1) << "}";
1043 s
.op
->newline() << "return rc;";
1044 s
.op
->newline(-1) << "}";
1046 s
.op
->newline() << "static struct stap_utrace_probe stap_utrace_probes[] = {";
1049 // Set up 'process(PATH)' probes
1050 if (! probes_by_path
.empty())
1052 for (p_b_path_iterator it
= probes_by_path
.begin();
1053 it
!= probes_by_path
.end(); it
++)
1055 for (unsigned i
= 0; i
< it
->second
.size(); i
++)
1057 utrace_derived_probe
*p
= it
->second
[i
];
1058 emit_linux_probe_decl(s
, p
);
1063 // Set up 'process(PID)' probes
1064 if (! probes_by_pid
.empty())
1066 for (p_b_pid_iterator it
= probes_by_pid
.begin();
1067 it
!= probes_by_pid
.end(); it
++)
1069 for (unsigned i
= 0; i
< it
->second
.size(); i
++)
1071 utrace_derived_probe
*p
= it
->second
[i
];
1072 emit_linux_probe_decl(s
, p
);
1076 s
.op
->newline(-1) << "};";
1081 utrace_derived_probe_group::emit_dyninst_probe_decl (systemtap_session
& s
,
1083 utrace_derived_probe
*p
)
1090 case UDPF_BEGIN
: // process begin
1091 flags_str
= "STAPDYN_PROBE_FLAG_PROC_BEGIN";
1093 case UDPF_THREAD_BEGIN
: // thread begin
1094 flags_str
= "STAPDYN_PROBE_FLAG_THREAD_BEGIN";
1096 case UDPF_END
: // process end
1097 flags_str
= "STAPDYN_PROBE_FLAG_PROC_END";
1099 case UDPF_THREAD_END
: // thread end
1100 flags_str
= "STAPDYN_PROBE_FLAG_THREAD_END";
1103 // FIXME: No handling of syscall probes for dyninst yet.
1107 case UDPF_SYSCALL_RETURN
:
1111 s
.op
->line() << " .flags=(UDPF_NONE),";
1112 s
.op
->line() << " .ops={ },";
1113 s
.op
->line() << " .events=0,";
1117 throw SEMANTIC_ERROR ("bad utrace probe flag");
1122 dynprobe_add_utrace_path(s
, path
, flags_str
, common_probe_init(p
));
1124 dynprobe_add_utrace_pid(s
, p
->pid
, flags_str
, common_probe_init(p
));
1128 utrace_derived_probe_group::emit_module_dyninst_decls (systemtap_session
& s
)
1130 if (probes_by_path
.empty() && probes_by_pid
.empty())
1134 s
.op
->newline() << "/* ---- dyninst utrace probes ---- */";
1135 s
.op
->newline() << "#include \"dyninst/uprobes.h\"";
1136 s
.op
->newline() << "#define STAPDYN_UTRACE_PROBES";
1138 // Let the dynprobe_derived_probe_group handle outputting targets
1139 // and probes. This allows us to merge different types of probes.
1140 s
.op
->newline() << "static struct stapdu_probe stapdu_probes[];";
1142 // Set up 'process(PATH)' probes
1143 if (! probes_by_path
.empty())
1145 for (p_b_path_iterator it
= probes_by_path
.begin();
1146 it
!= probes_by_path
.end(); it
++)
1148 for (unsigned i
= 0; i
< it
->second
.size(); i
++)
1150 utrace_derived_probe
*p
= it
->second
[i
];
1151 emit_dyninst_probe_decl(s
, it
->first
, p
);
1155 // Set up 'process(PID)' probes
1156 if (! probes_by_pid
.empty())
1158 for (p_b_pid_iterator it
= probes_by_pid
.begin();
1159 it
!= probes_by_pid
.end(); it
++)
1161 for (unsigned i
= 0; i
< it
->second
.size(); i
++)
1163 utrace_derived_probe
*p
= it
->second
[i
];
1164 emit_dyninst_probe_decl(s
, "", p
);
1169 // loc2c-generated code assumes pt_regs are available, so use this to make
1170 // sure we always have *something* for it to dereference...
1171 s
.op
->newline() << "static struct pt_regs stapdu_dummy_uregs;";
1173 // Write the probe handler.
1174 // NB: not static, so dyninst can find it
1175 s
.op
->newline() << "int enter_dyninst_utrace_probe "
1176 << "(uint64_t index, struct pt_regs *regs) {";
1177 s
.op
->newline(1) << "struct stapdu_probe *sup = &stapdu_probes[index];";
1179 common_probe_entryfn_prologue (s
, "STAP_SESSION_RUNNING", "sup->probe",
1180 "stp_probe_type_utrace");
1181 s
.op
->newline() << "c->uregs = regs ?: &stapdu_dummy_uregs;";
1182 s
.op
->newline() << "c->user_mode_p = 1;";
1183 // XXX: once we have regs, check how dyninst sets the IP
1184 // XXX: the way that dyninst rewrites stuff is probably going to be
1185 // ... very confusing to our backtracer (at least if we stay in process)
1186 s
.op
->newline() << "(*sup->probe->ph) (c);";
1187 common_probe_entryfn_epilogue (s
, true, otf_safe_context(s
));
1188 s
.op
->newline() << "return 0;";
1189 s
.op
->newline(-1) << "}";
1190 s
.op
->assert_0_indent();
1195 utrace_derived_probe_group::emit_module_decls (systemtap_session
& s
)
1197 if (s
.runtime_usermode_p())
1198 emit_module_dyninst_decls (s
);
1200 emit_module_linux_decls (s
);
1205 utrace_derived_probe_group::emit_module_linux_init (systemtap_session
& s
)
1207 if (probes_by_path
.empty() && probes_by_pid
.empty())
1210 s
.op
->newline() << "/* ---- utrace probes ---- */";
1211 s
.op
->newline() << "for (i=0; i<ARRAY_SIZE(stap_utrace_probes); i++) {";
1212 s
.op
->newline(1) << "struct stap_utrace_probe *p = &stap_utrace_probes[i];";
1213 s
.op
->newline() << "probe_point = p->probe->pp;"; // for error messages
1214 s
.op
->newline() << "rc = stap_register_task_finder_target(&p->tgt);";
1216 // NB: if (rc), there is no need (XXX: nor any way) to clean up any
1217 // finders already registered, since mere registration does not
1218 // cause any utrace or memory allocation actions. That happens only
1219 // later, once the task finder engine starts running. So, for a
1220 // partial initialization requiring unwind, we need do nothing.
1221 s
.op
->newline() << "if (rc) break;";
1223 s
.op
->newline(-1) << "}";
1228 utrace_derived_probe_group::emit_module_dyninst_init (systemtap_session
& s
)
1230 if (probes_by_path
.empty() && probes_by_pid
.empty())
1233 /* stapdyn handles the dirty work via dyninst */
1234 s
.op
->newline() << "/* ---- dyninst utrace probes ---- */";
1235 s
.op
->newline() << "/* this section left intentionally blank */";
1240 utrace_derived_probe_group::emit_module_init (systemtap_session
& s
)
1242 if (s
.runtime_usermode_p())
1243 emit_module_dyninst_init (s
);
1245 emit_module_linux_init(s
);
1250 utrace_derived_probe_group::emit_module_linux_exit (systemtap_session
& s
)
1252 if (probes_by_path
.empty() && probes_by_pid
.empty()) return;
1255 s
.op
->newline() << "/* ---- utrace probes ---- */";
1256 s
.op
->newline() << "for (i=0; i<ARRAY_SIZE(stap_utrace_probes); i++) {";
1257 s
.op
->newline(1) << "struct stap_utrace_probe *p = &stap_utrace_probes[i];";
1259 s
.op
->newline() << "if (p->engine_attached) {";
1260 s
.op
->newline(1) << "stap_utrace_detach_ops(&p->ops);";
1262 s
.op
->newline(-1) << "}";
1263 s
.op
->newline(-1) << "}";
1268 utrace_derived_probe_group::emit_module_dyninst_exit (systemtap_session
& s
)
1270 if (probes_by_path
.empty() && probes_by_pid
.empty())
1273 /* stapdyn handles the dirty work via dyninst */
1274 s
.op
->newline() << "/* ---- dyninst utrace probes ---- */";
1275 s
.op
->newline() << "/* this section left intentionally blank */";
1280 utrace_derived_probe_group::emit_module_exit (systemtap_session
& s
)
1282 if (s
.runtime_usermode_p())
1283 emit_module_dyninst_exit (s
);
1285 emit_module_linux_exit(s
);
1290 register_tapset_utrace(systemtap_session
& s
)
1292 match_node
* root
= s
.pattern_root
;
1293 derived_probe_builder
*builder
= new utrace_builder();
1295 vector
<match_node
*> roots
;
1296 roots
.push_back(root
->bind(TOK_PROCESS
));
1297 roots
.push_back(root
->bind_str(TOK_PROCESS
));
1298 roots
.push_back(root
->bind_num(TOK_PROCESS
));
1300 for (unsigned i
= 0; i
< roots
.size(); ++i
)
1302 roots
[i
]->bind(TOK_BEGIN
)
1303 ->bind_privilege(pr_all
)
1305 roots
[i
]->bind(TOK_END
)
1306 ->bind_privilege(pr_all
)
1308 roots
[i
]->bind(TOK_THREAD
)->bind(TOK_BEGIN
)
1309 ->bind_privilege(pr_all
)
1311 roots
[i
]->bind(TOK_THREAD
)->bind(TOK_END
)
1312 ->bind_privilege(pr_all
)
1314 roots
[i
]->bind(TOK_SYSCALL
)
1315 ->bind_privilege(pr_all
)
1317 roots
[i
]->bind(TOK_SYSCALL
)->bind(TOK_RETURN
)
1318 ->bind_privilege(pr_all
)
1323 /* vim: set sw=2 ts=8 cino=>4,n-2,{2,^-2,t0,(0,u0,w1,M1 : */