summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--ChangeLog349
-rw-r--r--HACKING9
-rw-r--r--Makefile.am24
-rw-r--r--Makefile.in83
-rw-r--r--NEWS34
-rw-r--r--buildrun.cxx6
-rwxr-xr-xconfigure188
-rw-r--r--configure.ac35
-rw-r--r--cscope.files181
-rw-r--r--doc/Makefile.in1
-rw-r--r--doc/langref.tex10
-rw-r--r--dwarf_wrappers.cxx46
-rw-r--r--dwarf_wrappers.h93
-rw-r--r--elaborate.cxx568
-rw-r--r--elaborate.h13
-rw-r--r--main.cxx17
-rw-r--r--parse.cxx188
-rw-r--r--parse.h4
-rw-r--r--runtime/ChangeLog114
-rw-r--r--runtime/Makefile15
-rw-r--r--runtime/autoconf-probe-kernel.c7
-rw-r--r--runtime/loc2c-runtime.h125
-rw-r--r--runtime/map.c130
-rw-r--r--runtime/probes/ChangeLog113
-rw-r--r--runtime/probes/Makefile.template21
-rw-r--r--runtime/probes/README10
-rw-r--r--runtime/probes/agg/README3
-rwxr-xr-xruntime/probes/agg/build2
-rw-r--r--runtime/probes/agg/count1.c102
-rw-r--r--runtime/probes/agg/count2.c81
-rw-r--r--runtime/probes/agg/stat1.c72
-rw-r--r--runtime/probes/agg/targets3
-rw-r--r--runtime/probes/bench/Makefile10
-rw-r--r--runtime/probes/bench/README18
-rw-r--r--runtime/probes/bench/bench.c51
-rw-r--r--runtime/probes/bench/bench_io1.c46
-rw-r--r--runtime/probes/bench/bench_io2.c47
-rw-r--r--runtime/probes/bench/bench_io3.c44
-rw-r--r--runtime/probes/bench/bench_io4.c45
-rw-r--r--runtime/probes/bench/bench_multi.c73
-rw-r--r--runtime/probes/bench/bench_ret.c61
-rwxr-xr-xruntime/probes/bench/build2
-rwxr-xr-xruntime/probes/bench/check_modules28
-rw-r--r--runtime/probes/bench/itest.c71
-rwxr-xr-xruntime/probes/bench/run_bench136
-rw-r--r--runtime/probes/bench/targets7
-rwxr-xr-xruntime/probes/bench/trans_bench186
-rw-r--r--runtime/probes/bench/ttest.c74
-rwxr-xr-xruntime/probes/build40
-rwxr-xr-xruntime/probes/build_probe154
-rwxr-xr-xruntime/probes/os_timer/build2
-rw-r--r--runtime/probes/os_timer/os_timer.c126
-rwxr-xr-xruntime/probes/os_timer/stp2
-rw-r--r--runtime/probes/os_timer/targets1
-rw-r--r--runtime/probes/scf/README12
-rwxr-xr-xruntime/probes/scf/build2
-rw-r--r--runtime/probes/scf/scf.c50
-rw-r--r--runtime/probes/scf/targets1
-rw-r--r--runtime/probes/shellsnoop/README73
-rwxr-xr-xruntime/probes/shellsnoop/build2
-rw-r--r--runtime/probes/shellsnoop/shellsnoop.c161
-rw-r--r--runtime/probes/shellsnoop/targets1
-rw-r--r--runtime/probes/tasklet/README9
-rwxr-xr-xruntime/probes/tasklet/build2
-rw-r--r--runtime/probes/tasklet/stp_tasklet.c40
-rw-r--r--runtime/probes/tasklet/targets1
-rw-r--r--runtime/probes/test4/README24
-rwxr-xr-xruntime/probes/test4/build2
-rw-r--r--runtime/probes/test4/targets1
-rw-r--r--runtime/probes/test4/test4.c79
-rw-r--r--runtime/probes/where_func/README29
-rwxr-xr-xruntime/probes/where_func/build2
-rw-r--r--runtime/probes/where_func/kprobe_where_funct.c62
-rw-r--r--runtime/probes/where_func/targets1
-rw-r--r--runtime/regs.c7
-rw-r--r--runtime/regs.h4
-rw-r--r--runtime/staprun/ChangeLog5
-rw-r--r--runtime/staprun/mainloop.c12
-rw-r--r--runtime/staprun/unwind_data.c97
-rw-r--r--runtime/stat-common.c35
-rw-r--r--runtime/stat.c50
-rw-r--r--runtime/syscall.h160
-rw-r--r--runtime/task_finder.c601
-rw-r--r--runtime/task_finder_vma.c112
-rw-r--r--runtime/tests/ChangeLog112
-rw-r--r--runtime/tests/Makefile3
-rw-r--r--runtime/tests/README7
-rw-r--r--runtime/tests/agg/Makefile5
-rw-r--r--runtime/tests/agg/agg.test169
-rw-r--r--runtime/tests/agg/all.tcl4
-rw-r--r--runtime/tests/agg/count.c72
-rw-r--r--runtime/tests/agg/stats.c62
-rw-r--r--runtime/tests/all.tcl12
-rw-r--r--runtime/tests/maps/Makefile5
-rw-r--r--runtime/tests/maps/README4
-rw-r--r--runtime/tests/maps/all.tcl5
-rw-r--r--runtime/tests/maps/ii.c96
-rw-r--r--runtime/tests/maps/iiiiii.c36
-rw-r--r--runtime/tests/maps/iiss.c45
-rw-r--r--runtime/tests/maps/is.c119
-rw-r--r--runtime/tests/maps/issii.c34
-rw-r--r--runtime/tests/maps/isx.c41
-rw-r--r--runtime/tests/maps/map.test999
-rw-r--r--runtime/tests/maps/map_format.c72
-rw-r--r--runtime/tests/maps/setadd.c245
-rw-r--r--runtime/tests/maps/si.c125
-rw-r--r--runtime/tests/maps/size.c103
-rw-r--r--runtime/tests/maps/sort.c105
-rw-r--r--runtime/tests/maps/sort2.c105
-rw-r--r--runtime/tests/maps/sort_stat.c90
-rw-r--r--runtime/tests/maps/ssssss.c37
-rw-r--r--runtime/tests/math/Makefile5
-rw-r--r--runtime/tests/math/all.tcl4
-rw-r--r--runtime/tests/math/div64.c182
-rw-r--r--runtime/tests/math/math.test19
-rw-r--r--runtime/tests/pmaps/Makefile5
-rw-r--r--runtime/tests/pmaps/all.tcl5
-rw-r--r--runtime/tests/pmaps/ii.c59
-rw-r--r--runtime/tests/pmaps/ii2.c48
-rw-r--r--runtime/tests/pmaps/ii3.c59
-rw-r--r--runtime/tests/pmaps/is.c67
-rw-r--r--runtime/tests/pmaps/ix.c61
-rw-r--r--runtime/tests/pmaps/ix2.c64
-rw-r--r--runtime/tests/pmaps/ix_log.c62
-rw-r--r--runtime/tests/pmaps/ix_none.c62
-rw-r--r--runtime/tests/pmaps/map_format.c92
-rw-r--r--runtime/tests/pmaps/pmap.test678
-rw-r--r--runtime/tests/pmaps/si.c62
-rw-r--r--runtime/tests/pmaps/size.c72
-rw-r--r--runtime/tests/string/Makefile5
-rw-r--r--runtime/tests/string/all.tcl4
-rw-r--r--runtime/tests/string/print_cstr.c56
-rw-r--r--runtime/tests/string/printf_A.c56
-rw-r--r--runtime/tests/string/printf_B.c37
-rw-r--r--runtime/tests/string/string.test89
-rw-r--r--runtime/tests/string/string1.c44
-rw-r--r--runtime/tests/string/string2.c68
-rw-r--r--runtime/tests/string/string3.c45
-rw-r--r--runtime/transport/ChangeLog11
-rw-r--r--runtime/transport/control.c7
-rw-r--r--runtime/transport/symbols.c22
-rw-r--r--runtime/transport/transport_msgs.h2
-rw-r--r--session.h8
-rwxr-xr-xstap-client606
-rwxr-xr-xstap-server436
-rw-r--r--stap.1.in7
-rw-r--r--stapfuncs.5.in24
-rw-r--r--stapprobes.5.in41
-rw-r--r--stapvars.5.in51
-rw-r--r--tapset/ChangeLog87
-rw-r--r--tapset/argv.stp48
-rw-r--r--tapset/aux_syscalls.stp27
-rw-r--r--tapset/context.stp16
-rw-r--r--tapset/ctime.stp2
-rw-r--r--tapset/dev.stp33
-rw-r--r--tapset/i686/registers.stp36
-rw-r--r--tapset/inet.stp12
-rw-r--r--tapset/memory.stp3
-rw-r--r--tapset/nd_syscalls.stp2
-rw-r--r--tapset/nfs.stp162
-rw-r--r--tapset/nfs_proc.stp3
-rw-r--r--tapset/ppc64/registers.stp108
-rw-r--r--tapset/rpc.stp167
-rw-r--r--tapset/s390x/syscalls.stp2
-rw-r--r--tapset/signal.stp22
-rw-r--r--tapset/syscalls.stp114
-rw-r--r--tapset/syscalls2.stp14
-rw-r--r--tapset/task.stp3
-rw-r--r--tapset/x86_64/registers.stp20
-rw-r--r--tapsets.cxx1041
-rw-r--r--testsuite/.gitignore2
-rw-r--r--testsuite/ChangeLog108
-rw-r--r--testsuite/Makefile.am24
-rw-r--r--testsuite/Makefile.in52
-rwxr-xr-xtestsuite/buildok/nfs-all-probes.stp2
-rwxr-xr-xtestsuite/buildok/rpc-all-probes.stp2
-rwxr-xr-xtestsuite/configure25
-rw-r--r--testsuite/configure.ac15
-rwxr-xr-xtestsuite/execrc5
-rw-r--r--testsuite/lib/stap_run.exp1
-rw-r--r--testsuite/lib/systemtap.exp5
-rwxr-xr-xtestsuite/parseko/preprocess08.stp4
-rwxr-xr-xtestsuite/parseko/preprocess08b.stp4
-rwxr-xr-xtestsuite/semok/syscall_return.stp4
-rw-r--r--testsuite/systemtap.base/cache.exp5
-rw-r--r--testsuite/systemtap.base/cmd_parse.exp37
-rw-r--r--testsuite/systemtap.base/debugpath.exp3
-rw-r--r--testsuite/systemtap.base/error_fn.exp7
-rw-r--r--testsuite/systemtap.base/error_fn.stp17
-rw-r--r--testsuite/systemtap.base/optim_arridx.exp2
-rw-r--r--testsuite/systemtap.base/optim_arridx.stp2
-rw-r--r--testsuite/systemtap.base/optim_voidstmt.exp5
-rw-r--r--testsuite/systemtap.base/optim_voidstmt.stp95
-rw-r--r--testsuite/systemtap.base/stmt_rel.exp9
-rw-r--r--testsuite/systemtap.base/stmt_rel.stp71
-rw-r--r--testsuite/systemtap.base/stmtvars.exp10
-rw-r--r--testsuite/systemtap.base/utrace_p4.exp27
-rw-r--r--testsuite/systemtap.base/utrace_p5.exp92
-rw-r--r--testsuite/systemtap.base/utrace_p5_multi.c45
-rw-r--r--testsuite/systemtap.base/warnings.exp2
-rw-r--r--testsuite/systemtap.base/warnings.stp11
-rw-r--r--testsuite/systemtap.context/backtrace.tcl34
-rw-r--r--testsuite/systemtap.context/context.exp2
-rw-r--r--testsuite/systemtap.context/num_args.stp53
-rw-r--r--testsuite/systemtap.context/num_args.tcl62
-rw-r--r--testsuite/systemtap.examples/ChangeLog20
-rw-r--r--testsuite/systemtap.examples/graphs.meta13
-rw-r--r--testsuite/systemtap.examples/graphs.stp60
-rw-r--r--testsuite/systemtap.examples/sleepingBeauties.meta13
-rw-r--r--testsuite/systemtap.examples/sleepingBeauties.stp58
-rw-r--r--testsuite/systemtap.examples/thread-times.meta13
-rw-r--r--testsuite/systemtap.examples/thread-times.stp32
-rw-r--r--testsuite/systemtap.examples/traceio2.meta13
-rw-r--r--testsuite/systemtap.examples/traceio2.stp20
-rw-r--r--testsuite/systemtap.pass1-4/buildok.exp3
-rw-r--r--testsuite/systemtap.samples/profile.exp2
-rw-r--r--translate.cxx393
218 files changed, 6167 insertions, 8685 deletions
diff --git a/.gitignore b/.gitignore
index b70c9e21..961fba32 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,6 +3,7 @@
*#
.#*
autom4te.*
+cscope.files
cscope*out
config.h
config.log
diff --git a/ChangeLog b/ChangeLog
index 4d02db5f..f66ffda7 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,344 @@
+2008-06-23 Frank Ch. Eigler <fche@elastic.org>
+
+ * session.h (module_cache): Add field here.
+ * tapsets.cxx (dwflpp): Remove static field from here.
+ (pathname_caching_callback): Use hacky micro-static to get to it.
+ (*): Update other users of module_cache.
+ * elaborate.cxx (systemtap_session ctor): Corresponding changes.
+
+2008-06-23 David Smith <dsmith@redhat.com>
+
+ * tapsets.cxx (utrace_derived_probe_group::emit_probe_decl):
+ Handles UDPF_NONE value.
+ (utrace_derived_probe_group::emit_vm_callback_probe_decl): New
+ function.
+ (utrace_derived_probe_group::emit_module_decls): Calls
+ emit_vm_callback_probe_decl() to set up vm_callbacks.
+
+2008-06-23 Stan Cox <scox@redhat.com>
+
+ * NEWS: Updated .statement line number wildcard and line number range.
+ * stapprobes.5.in: Likewise.
+ * doc/langref.tex: Likewise.
+ * tapsets.cxx (enum line_t): Add RANGE and WILDCARD.
+ (iterate_over_srcfile_lines): Change lineno parm to lines[].
+ Support RANGE and WILDCARD.
+ (dwarf_query): Change line to line[]
+ (dwarf_query::parse_function_spec): Parse RANGE and WILDCARD.
+
+2008-06-20 wcohen <wcohen@redhat.com>
+
+ * stapfuncs.5.in: Add documentation for tapset/dev.stp functions.
+
+2008-06-18 Josh Stone <joshua.i.stone@intel.com>
+
+ PR 6644
+ * elaborate.cxx (dead_stmtexpr_remover::visit_block): Flatten nested
+ block statements into a single block.
+ (dead_stmtexpr_remover::visit_if_statement): Remove the possibility
+ of if_statements with a null thenblock. When an if lacks both then
+ and else, either remove it completely or reduce it to a simple
+ statment evaluating the condition. With an else and no then, invert
+ the condition and else becomes then.
+ (void_statement_reducer): New optimization visitor that breaks
+ statements in void context into smaller pieces, to expose more
+ optimization opportunities.
+ (semantic_pass_opt5, semantic_pass_opt6): Bump opt5 to opt6, and
+ create a new opt5 that runs through void_statement_reducer.
+
+2008-06-16 Frank Ch. Eigler <fche@elastic.org>
+
+ * tapsets.cxx (print_locals): Produce nothing instead of
+ "(alternatives: (none found))" if no alternatives were found.
+
+2008-06-16 Frank Ch. Eigler <fche@elastic.org>
+
+ * elaborate.cxx (session::print_warning): Change to take optional
+ token as argument.
+ (*): Adjust callers of print_warning() to pass a token.
+ (print_token): New function, eliminate recent file name duplication.
+ (print_error): Use it too.
+ (semantic_pass_opt2): Tweak way read-only vars' alternatives are
+ printed. Eliminate relaxation-loop duplicates by printing warnings
+ only on first iteration. Print alternatives for globals too.
+ * session.h: Corresponding changes.
+
+2008-06-16 Stan Cox <scox@redhat.com>
+
+ * elaborate.cxx (semantic_pass_opt2): Only create function
+ alternatives if needed. Overload compare.
+
+2008-06-13 Stan Cox <scox@redhat.com>
+
+ * elaborate.cxx (print_warning): Add optional_str parameter.
+ (semantic_pass_opt2): List variable alternatives for probes and
+ functions.
+ * session.h (print_warning): Add optional_str parameter.
+
+2008-06-13 Josh Stone <joshua.i.stone@intel.com>
+
+ * translate.cxx: Jump out directly after setting last_error, rather
+ than passively checking last_error everywhere.
+ * translate.cxx: Only make actionremaining checks at control points,
+ i.e. roughly at the end of basic blocks, or after executing a few
+ statements in a row.
+
+2008-06-13 Frank Ch. Eigler <fche@elastic.org>
+
+ * main.cxx (main): Print generated module name for "-m FOO"
+ runs also. Stop warning about this implying uncached operation.
+
+2008-06-12 Stan Cox <scox@redhat.com>
+
+ * elaborate.cxx (print_warning): Make parameter a const.
+
+2008-06-11 Frank Ch. Eigler <fche@elastic.org>
+
+ * Makefile.am (EXTRA_DIST): Add dwarf_wrappers.h.
+
+2008-06-11 Mark Wielaard <mwielaard@redhat.com>
+
+ * elaborate.cxx (print_warning): Only output WARNING, don't put it
+ in the message_str and seen_warnings.
+ * session.h (print_warning): Reindent.
+
+2008-06-11 Frank Ch. Eigler <fche@elastic.org>
+
+ * elaborate.cxx (print_warning): Use session.seen_warnings[].
+
+2008-06-10 Stan Cox <scox@redhat.com>
+
+ * elaborate.cxx (print_warning): New.
+ * elaborate.cxx (semantic_pass_opt1): Use it.
+
+2008-06-11 Tim Moore <timoore@redhat.com>
+
+ * dwarf_wrappers.h (dwfl_assert): Add overload with boolean value
+ for assertion test.
+ * dwarf_wrappers.cxx (dwfl_assert): Write boolean condition
+ version.
+ * tapsets.cxx (emit_address): Fix up dwfl_asserts that got negated
+ in changes to dwfl_assert.
+
+ PR 2608
+ * dwarf_wrappers.h, dwarf_wrappers.cxx: New files.
+ * Makefile.in: Regenerated.
+ * tapsets.cxx (dwarf_assert, dwfl_assert): Move to
+ dwarf_wrappers.h.
+ (iterate_over_srcfile_lines, has_single_line_record,
+ query_srcfile_line): Use dwarf_line_t wrapper.
+ (die_has_pc): Take a reference to a Dwarf_Die instead of a
+ pointer. Clean up use of dwfl_assert.
+ (query_cu): Check that statement raw address matches the beginning
+ of a statement record.
+ * elaborate.h: Include iosfwd instead of iostream.
+ (literal_map_t, resolve_prologue_endings,): New typedef.
+
+
+2008-06-10 Jim Keniston <jkenisto@us.ibm.com>
+
+ * testsuite/systemtap.context/num_args.tcl: Run twice --
+ once with dwarf (default) and once with --kelf --ignore-dwarf.
+ * testsuite/systemtap.context/context.exp: Add num_args to
+ testlist. :-}
+
+2008-06-10 David Smith <dsmith@redhat.com>
+
+ * tapsets.cxx (utrace_derived_probe_group::emit_probe_decl):
+ Initializes .vm_callback.
+
+2008-06-10 Frank Ch. Eigler <fche@elastic.org>
+
+ PR 6470
+ * NEWS: Note argv[] tapset.
+ * parse.cxx (scan_pp): Better handle premature EOF.
+ * stapvars.5.in: New file.
+ * stap.1.in: Mention it.
+ * Makefile.am (dist_man_MANS): Add stapvars.5.
+ * configure.ac (AC_CONFIG_FILES): Add stapvars.5.in.
+ * Makefile.in, configure: Regenerated.
+
+2008-06-10 Frank Ch. Eigler <fche@elastic.org>
+
+ PR 6470
+ * parse.cxx (scan_pp): Eliminate expand_args argument to control
+ nested preprocess evaluation. Rewrite to use a combination of
+ exceptions and non-recursion.
+ (lexer::scan): Ditto. Interpret "$#" as the argc value in all
+ cases.
+ * parse.h: Corresponding decl changes.
+
+2008-06-10 Frank Ch. Eigler <fche@elastic.org>
+
+ PR 6470
+ * parse.cxx (eval_comparison): New template function.
+ (eval_pp_conditional): Call it separately for string/string and
+ int64/int64 cases.
+ (lexer::scan): Provide better error message for invalid $NNN.
+
+2008-06-09 Jim Keniston <jkenisto@us.ibm.com>
+
+ PR 6601
+ * tapsets.cxx: For powerpc, reject symbols in .opd
+ (function descriptor) section.
+
+2008-06-09 Stan Cox <scox@redhat.com>
+
+ * NEWS: Updated kernel.statement relative line number.
+ * stapprobes.5.in: Likewise.
+
+2008-06-09 David Smith <dsmith@redhat.com>
+
+ * tapsets.cxx
+ (utrace_var_expanding_copy_visitor::visit_target_symbol): Calls
+ 'syscall_nr' to get the value of '$syscall'.
+
+ * tapsets.cxx (utrace_derived_probe::join_group): Removed
+ generated inclusion of tracehook.h.
+ (utrace_var_expanding_copy_visitor::visit_target_symbol): Uses
+ '_stp_arg(0)' to get value of '$syscall'.
+
+2008-06-06 Stan Cox <scox@redhat.com>
+
+ * tapsets.cxx (dwflpp::iterate_over_srcfile_lines):
+ Add parameter line_type_relative.
+ (enum line_t): New.
+ (dwarf_query::line_type): New.
+ (dwarf_query::parse_function_spec): Set line_type.
+
+2008-06-06 David Smith <dsmith@redhat.com>
+
+ * NEWS: Updated utrace probes descriptions.
+ * stapprobes.5.in: Ditto.
+
+ * tapsets.cxx (enum utrace_derived_probe_flags): Redefined in
+ terms of probe types instead of utrace events.
+ (utrace_var_expanding_copy_visitor::visit_target_symbol): Uses new
+ utrace_derived_probes_flags values.
+ (utrace_builder::build): Handles new probe types and new
+ utrace_derived_probes_flags values.
+ (utrace_derived_probe_group::emit_probe_decl): Updated to handle
+ new utrace_derived_probe_flags values.
+ (utrace_derived_probe_group::emit_module_decls): Ditto. Also
+ correctly handles 'begin' events correctly by installing a quiesce
+ handler (instead of running the probe directly).
+ (register_standard_tapsets): Registers updated utrace probe
+ types.
+
+2008-06-05 Srinivasa DS <srinivasa@in.ibm.com>
+ *configure,configure.ac: -fpie option puts limit on GOT size
+ and hence systemtap build fails on s390. So use -fPIE which
+ doesn't put limit on GOT size.
+
+2008-06-04 Jim Keniston <jkenisto@us.ibm.com>
+
+ * testsuite/systemtap.context/num_args.{stp,tcl}: Added.
+ Same as args.{stp,tcl}, but refs args using *_arg().
+
+2008-06-04 Jim Keniston <jkenisto@us.ibm.com>
+
+ PR 6588
+ * tapset/syscalls.stp: Remove return aliases for exit and exit_group.
+ * testsuite/semok/syscalls_return.stp: Regression test
+
+2008-06-03 David Smith <dsmith@redhat.com>
+
+ * tapsets.cxx: Added several string tokens that are used instead
+ of hard-coded strings.
+ (register_standard_tapsets): Uses new string tokens.
+
+2008-06-03 Frank Ch. Eigler <fche@elastic.org>
+
+ PR 6429.
+ * Makefile.am: Don't link stapio with -ldw.
+ * Makefile.in: Regenerated.
+
+2008-05-29 Mark Wielaard <mwielaard@redhat.com>
+
+ * Makefile.am (installcheck): Check that make install was run.
+ * Makefile.in: Regenerated.
+
+2008-06-02 Frank Ch. Eigler <fche@elastic.org>
+
+ PR6534
+ * translate.cxx (c_unparser::emit_module_init): Use UTS_RELEASE
+ instead of uts_sem/utsname() as kernel version-checking hack.
+
+2008-06-02 <brolley@redhat.com>
+
+ * stap-client (initialization): port is no longer hard coded.
+ Initialize avahi_service_tag to _stap._tcp.
+ (find_and_connect_to_server): Handle server/port returned by
+ match_server.
+ (match_server): Obtain server ip address and port from output
+ of the -r option to avahi-browse. Echo a server/port pair.
+
+2008-06-02 Zhaolei <zhaolei@cn.fujitsu.com>
+
+ * main.cxx (main): Fix the problem that kernel module compile
+ failure when runtime directory is set to relative path(stap -R).
+
+2008-05-30 Dave Brolley <brolley@redhat.com>
+
+ * stap-client, stap-server: New compile server and client scripts.
+
+2008-05-30 Srinivasa DS <srinivasa@in.ibm.com>
+ PR 6562
+ * tapsets.cxx, translate.cxx: modified one argument for
+ dwfl_linux_kernel_report_offline().
+ * testsuite/systemtap.base/debugpath.exp: Modified testsuite for new
+ SYSTEMTAP_DEBUGINFO_PATH behaviour.
+ * stap.1.in: Modified manpage for new SYSTEMTAP_DEBUGINFO_PATH behaviour.
+
+2008-05-29 Jim Keniston <jkenisto@us.ibm.com>
+
+ PR 6582
+ * tapset/context.stp: Added registers_valid().
+ * stapfuncs.5.in: Ditto.
+ * tapset/x86_64/registers.stp: Added registers_valid() check.
+ * tapset/ppc64/registers.stp: Ditto.
+ * tapset/i686/registers.stp: Ditto. Also fixed warnings due to
+ sp_offset and ss_offset not being global.
+
+2008-05-29 Ananth N Mavinakayanahalli <ananth@in.ibm.com>
+
+ PR 6563
+ * tapset/ppc64/registers.stp: Fix powerpc dwarfless argument access
+
+2008-05-28 Josh Stone <joshua.i.stone@intel.com>
+
+ PR 6529
+ * translate.cxx (c_unparser::visit_return_statement): Make sure we
+ notice errors from evaluating return values.
+
+2008-05-28 David Smith <dsmith@redhat.com>
+
+ * tapsets.cxx (utrace_derived_probe_group::emit_module_decls):
+ Removed debug print.
+
+ * tapsets.cxx (utrace_derived_probe_group::emit_probe_decl):
+ Instead of adding clone handlers, just call the probes directly.
+ (utrace_derived_probe_group::emit_module_decls): For syscall
+ probes, on exec detach the parent's utrace engine from the child.
+
+2008-05-27 Josh Stone <joshua.i.stone@intel.com>
+
+ PR 6432
+ * buildrun.cxx (compile_pass): Add the autoconf test for probe_kernel_*
+ functions, but leave it #if-0'ed for now.
+
+2008-05-23 Jim Keniston <jkenisto@us.ibm.com>
+
+ PR 4311, cont. Address powerpc dwarfless test failures.
+ * tapsets.cxx: Convert .funcname to funcname when adding it
+ to our symbol table. Accept all weak symbols except those
+ that map to sys_ni_syscall.
+
+2008-05-23 Srinivasa DS <srinivasa@in.ibm.com>
+ PR 6429: Inerim fix to avoid compilation error of systemtap module
+ * runtime/transport/symbols.c: added definitions of struct
+ module_sect_attr, struct module_sect_attrs for 2.6.25 above kernels.
+
2008-05-22 Wenji Huang <wenji.huang@oracle.com>
* tapsets.cxx (iterate_over_functions): Fix .statement(NUM) regression.
@@ -7,6 +348,12 @@
* tapset/ppc64/registers.stp: Support powerpc register + arg lookup
* stapfuncs.5.in: Add powerpc bits; indicate scope of uarg_* access
+2008-05-21 David Smith <dsmith@redhat.com>
+
+ * tapsets.cxx (utrace_derived_probe_group::emit_module_decls):
+ Added new 'event_flag' parameter to task_finder callback. Only
+ calls probe handlers if we received the correct event.
+
2008-05-20 Frank Ch. Eigler <fche@elastic.org>
PR 6538
@@ -176,8 +523,6 @@
* systemtap.spec.in: Simplify configuration defaults.
-2008-04-29 David Smith <dsmith@redhat.com>:ChangeLog
-
2008-04-25 David Smith <dsmith@redhat.com>
PR 6455.
diff --git a/HACKING b/HACKING
index de8b94b4..98c19e7f 100644
--- a/HACKING
+++ b/HACKING
@@ -56,6 +56,15 @@ the <systemtap@sources.redhat.com> mailing list.
Tests that execute probes (pass 5) should include their own .exp/.stp
files under any other appropriate systemtap.* testsuite subdirectory.
+ To run a particular test or set of tests, do:
+ cd testsuite
+ make check RUNTESTFLAGS=testname.exp
+ or
+ make installcheck RUNTESTFLAGS=testname.exp
+ To disambiguate among multiple tests with the same name, specify
+ the directory as well -- for example:
+ make installcheck RUNTESTFLAGS=systemtap.base/print.exp
+
- translator
Translator changes can easily invalidate tapsets and user script
diff --git a/Makefile.am b/Makefile.am
index 4eb1335b..3e5bd6c9 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -10,12 +10,12 @@ AM_CPPFLAGS = -DBINDIR='"$(bindir)"' -DPKGDATADIR='"${pkgdatadir}"' -DPKGLIBDIR=
AM_CFLAGS = -D_GNU_SOURCE -fexceptions -Wall -Werror -Wunused -Wformat=2 -W
AM_CXXFLAGS = -Wall -Werror
-dist_man_MANS = stap.1 stapprobes.5 stapfuncs.5 stapex.5 staprun.8 man/stapprobes.iosched.5 man/stapprobes.netdev.5 man/stapprobes.nfs.5 man/stapprobes.nfsd.5 man/stapprobes.pagefault.5 man/stapprobes.process.5 man/stapprobes.rpc.5 man/stapprobes.scsi.5 man/stapprobes.signal.5 man/stapprobes.socket.5 man/stapprobes.tcp.5 man/stapprobes.udp.5
+dist_man_MANS = stap.1 stapprobes.5 stapfuncs.5 stapvars.5 stapex.5 staprun.8 man/stapprobes.iosched.5 man/stapprobes.netdev.5 man/stapprobes.nfs.5 man/stapprobes.nfsd.5 man/stapprobes.pagefault.5 man/stapprobes.process.5 man/stapprobes.rpc.5 man/stapprobes.scsi.5 man/stapprobes.signal.5 man/stapprobes.socket.5 man/stapprobes.tcp.5 man/stapprobes.udp.5
bin_PROGRAMS = stap staprun
stap_SOURCES = main.cxx \
parse.cxx staptree.cxx elaborate.cxx translate.cxx \
tapsets.cxx buildrun.cxx loc2c.c hash.cxx mdfour.c \
- cache.cxx util.cxx coveragedb.cxx
+ cache.cxx util.cxx coveragedb.cxx dwarf_wrappers.cxx
stap_LDADD = @stap_LIBS@ @sqlite3_LIBS@
BUILT_SOURCES =
@@ -59,6 +59,10 @@ dist-gitversion: git_version.stamp
git_version.h:
$(srcdir)/git_version.sh -k --srcdir $(srcdir) -o git_version.h
+cscope:
+ cd $(srcdir) && \
+ (echo -q ; git ls-files '*.cxx' '*.c' '*.h' | grep -v '^testsuite' ) > cscope.files && \
+ cscope -b -q
stap_CXXFLAGS = $(AM_CXXFLAGS)
@@ -75,9 +79,6 @@ DISTCHECK_CONFIGURE_FLAGS = --with-elfutils=$(elfutils_abs_srcdir)
stap_CPPFLAGS += -Iinclude-elfutils
stap_LDFLAGS += -Llib-elfutils -Wl,-rpath-link,lib-elfutils \
-Wl,--enable-new-dtags,-rpath,$(pkglibdir)
-stapio_CPPFLAGS += -Iinclude-elfutils
-stapio_LDFLAGS += -Llib-elfutils -Wl,-rpath-link,lib-elfutils \
- -Wl,--enable-new-dtags,-rpath,$(pkglibdir)
BUILT_SOURCES += stamp-elfutils
@@ -110,10 +111,10 @@ staprun_LDADD = @PROCFLAGS@ @cap_LIBS@
stapio_SOURCES = runtime/staprun/stapio.c \
runtime/staprun/mainloop.c runtime/staprun/common.c \
- runtime/staprun/ctl.c runtime/staprun/unwind_data.c \
+ runtime/staprun/ctl.c \
runtime/staprun/relay.c runtime/staprun/relay_old.c
stapio_CFLAGS = @PROCFLAGS@ $(AM_CFLAGS)
-stapio_LDADD = @PROCFLAGS@ -ldw -lpthread
+stapio_LDADD = @PROCFLAGS@ -lpthread
install-exec-hook:
if [ `id -u` -eq 0 ]; then chmod 04111 "$(DESTDIR)$(bindir)/staprun"; fi
@@ -151,6 +152,7 @@ EXTRA_DIST = buildrun.h elaborate.h loc2c.h session.h \
parse.h staptree.h tapsets.h translate.h \
cache.h hash.h mdfour.h util.h staplog.c coveragedb.h \
testsuite systemtap.spec runtime tapset \
+ dwarf_wrappers.h \
git_version.h git_version.sh
EXAMPLE_DEST_DIR = $(distdir)/examples
@@ -229,6 +231,14 @@ check:
$(MAKE) -C testsuite check SYSTEMTAP_RUNTIME=$$SRCDIR/runtime SYSTEMTAP_TAPSET=$$SRCDIR/tapset LD_LIBRARY_PATH=$(PWD)/lib-elfutils:$(PWD)/lib-elfutils/systemtap SYSTEMTAP_PATH=$(PWD) RUNTESTFLAGS="$(RUNTESTFLAGS)"
installcheck:
+ if test \! -e $(DESTDIR)$(bindir)/stap; then \
+ echo $(DESTDIR)$(bindir)/stap doesn\'t exist, run make install; \
+ exit -1; \
+ fi
+ if test $(builddir)/stap -nt $(DESTDIR)$(bindir)/stap; then \
+ echo "$(DESTDIR)$(bindir)/stap is not recent, run make install"; \
+ exit -1; \
+ fi
$(MAKE) -C testsuite installcheck RUNTESTFLAGS="$(RUNTESTFLAGS)"
rpm: systemtap.spec dist
diff --git a/Makefile.in b/Makefile.in
index 8ff882b4..675edde2 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -37,12 +37,8 @@ bin_PROGRAMS = stap$(EXEEXT) staprun$(EXEEXT)
@BUILD_ELFUTILS_TRUE@am__append_2 = -Llib-elfutils -Wl,-rpath-link,lib-elfutils \
@BUILD_ELFUTILS_TRUE@ -Wl,--enable-new-dtags,-rpath,$(pkglibdir)
-@BUILD_ELFUTILS_TRUE@am__append_3 = -Iinclude-elfutils
-@BUILD_ELFUTILS_TRUE@am__append_4 = -Llib-elfutils -Wl,-rpath-link,lib-elfutils \
-@BUILD_ELFUTILS_TRUE@ -Wl,--enable-new-dtags,-rpath,$(pkglibdir)
-
-@BUILD_ELFUTILS_TRUE@am__append_5 = stamp-elfutils
-@BUILD_ELFUTILS_TRUE@am__append_6 = stamp-elfutils
+@BUILD_ELFUTILS_TRUE@am__append_3 = stamp-elfutils
+@BUILD_ELFUTILS_TRUE@am__append_4 = stamp-elfutils
@BUILD_ELFUTILS_FALSE@stap_DEPENDENCIES =
pkglibexec_PROGRAMS = stapio$(EXEEXT)
noinst_PROGRAMS = loc2c-test$(EXEEXT)
@@ -51,8 +47,8 @@ DIST_COMMON = README $(am__configure_deps) $(dist_man_MANS) \
$(srcdir)/Makefile.am $(srcdir)/Makefile.in \
$(srcdir)/config.in $(srcdir)/stap.1.in $(srcdir)/stapex.5.in \
$(srcdir)/stapfuncs.5.in $(srcdir)/stapprobes.5.in \
- $(srcdir)/staprun.8.in $(srcdir)/systemtap.spec.in \
- $(top_srcdir)/configure \
+ $(srcdir)/staprun.8.in $(srcdir)/stapvars.5.in \
+ $(srcdir)/systemtap.spec.in $(top_srcdir)/configure \
$(top_srcdir)/man/stapprobes.iosched.5.in \
$(top_srcdir)/man/stapprobes.netdev.5.in \
$(top_srcdir)/man/stapprobes.nfs.5.in \
@@ -76,7 +72,7 @@ am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = config.h
CONFIG_CLEAN_FILES = systemtap.spec stap.1 stapprobes.5 stapfuncs.5 \
- stapex.5 staprun.8 man/stapprobes.iosched.5 \
+ stapvars.5 stapex.5 staprun.8 man/stapprobes.iosched.5 \
man/stapprobes.netdev.5 man/stapprobes.nfs.5 \
man/stapprobes.nfsd.5 man/stapprobes.pagefault.5 \
man/stapprobes.process.5 man/stapprobes.rpc.5 \
@@ -101,14 +97,14 @@ am_stap_OBJECTS = stap-main.$(OBJEXT) stap-parse.$(OBJEXT) \
stap-translate.$(OBJEXT) stap-tapsets.$(OBJEXT) \
stap-buildrun.$(OBJEXT) stap-loc2c.$(OBJEXT) \
stap-hash.$(OBJEXT) stap-mdfour.$(OBJEXT) stap-cache.$(OBJEXT) \
- stap-util.$(OBJEXT) stap-coveragedb.$(OBJEXT)
+ stap-util.$(OBJEXT) stap-coveragedb.$(OBJEXT) \
+ stap-dwarf_wrappers.$(OBJEXT)
stap_OBJECTS = $(am_stap_OBJECTS)
stap_LINK = $(CXXLD) $(stap_CXXFLAGS) $(CXXFLAGS) $(stap_LDFLAGS) \
$(LDFLAGS) -o $@
am_stapio_OBJECTS = stapio-stapio.$(OBJEXT) stapio-mainloop.$(OBJEXT) \
stapio-common.$(OBJEXT) stapio-ctl.$(OBJEXT) \
- stapio-unwind_data.$(OBJEXT) stapio-relay.$(OBJEXT) \
- stapio-relay_old.$(OBJEXT)
+ stapio-relay.$(OBJEXT) stapio-relay_old.$(OBJEXT)
stapio_OBJECTS = $(am_stapio_OBJECTS)
stapio_DEPENDENCIES =
stapio_LINK = $(CCLD) $(stapio_CFLAGS) $(CFLAGS) $(stapio_LDFLAGS) \
@@ -176,6 +172,7 @@ CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CXX = @CXX@
+CXXCPP = @CXXCPP@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
@@ -274,11 +271,11 @@ pkglibexecdir = ${libexecdir}/${PACKAGE}
AM_CPPFLAGS = -DBINDIR='"$(bindir)"' -DPKGDATADIR='"${pkgdatadir}"' -DPKGLIBDIR='"$(pkglibexecdir)"'
AM_CFLAGS = -D_GNU_SOURCE -fexceptions -Wall -Werror -Wunused -Wformat=2 -W
AM_CXXFLAGS = -Wall -Werror
-dist_man_MANS = stap.1 stapprobes.5 stapfuncs.5 stapex.5 staprun.8 man/stapprobes.iosched.5 man/stapprobes.netdev.5 man/stapprobes.nfs.5 man/stapprobes.nfsd.5 man/stapprobes.pagefault.5 man/stapprobes.process.5 man/stapprobes.rpc.5 man/stapprobes.scsi.5 man/stapprobes.signal.5 man/stapprobes.socket.5 man/stapprobes.tcp.5 man/stapprobes.udp.5
+dist_man_MANS = stap.1 stapprobes.5 stapfuncs.5 stapvars.5 stapex.5 staprun.8 man/stapprobes.iosched.5 man/stapprobes.netdev.5 man/stapprobes.nfs.5 man/stapprobes.nfsd.5 man/stapprobes.pagefault.5 man/stapprobes.process.5 man/stapprobes.rpc.5 man/stapprobes.scsi.5 man/stapprobes.signal.5 man/stapprobes.socket.5 man/stapprobes.tcp.5 man/stapprobes.udp.5
stap_SOURCES = main.cxx \
parse.cxx staptree.cxx elaborate.cxx translate.cxx \
tapsets.cxx buildrun.cxx loc2c.c hash.cxx mdfour.c \
- cache.cxx util.cxx coveragedb.cxx
+ cache.cxx util.cxx coveragedb.cxx dwarf_wrappers.cxx
stap_LDADD = @stap_LIBS@ @sqlite3_LIBS@
@@ -290,15 +287,15 @@ stap_LDADD = @stap_LIBS@ @sqlite3_LIBS@
# of foo-bar.c if it is newer than the foo-bar.o file. Using noinst_foo_SOURCES
# instead of foo_SOURCES prevents shipping git_version.h in dist tarballs,
# which may cause false GIT_FOO readings.
-BUILT_SOURCES = git_version.stamp $(am__append_5)
-CLEANFILES = git_version.h $(am__append_6) $(pkglibexec_PROGRAMS)
+BUILT_SOURCES = git_version.stamp $(am__append_3)
+CLEANFILES = git_version.h $(am__append_4) $(pkglibexec_PROGRAMS)
GIT_VERSION_CMD = $(SHELL) $(top_srcdir)/git_version.sh
stap_CXXFLAGS = $(AM_CXXFLAGS)
stap_CPPFLAGS = $(AM_CPPFLAGS) $(am__append_1)
stap_LDFLAGS = $(AM_LDFLAGS) @PIELDFLAGS@ $(am__append_2)
staprun_LDFLAGS = $(AM_LDFLAGS) @PIELDFLAGS@
-stapio_CPPFLAGS = $(AM_CPPFLAGS) $(am__append_3)
-stapio_LDFLAGS = $(AM_LDFLAGS) @PIELDFLAGS@ $(am__append_4)
+stapio_CPPFLAGS = $(AM_CPPFLAGS)
+stapio_LDFLAGS = $(AM_LDFLAGS) @PIELDFLAGS@
# This tells automake's "make distcheck" what we need to compile.
@BUILD_ELFUTILS_TRUE@DISTCHECK_CONFIGURE_FLAGS = --with-elfutils=$(elfutils_abs_srcdir)
@@ -312,11 +309,11 @@ staprun_CFLAGS = @PROCFLAGS@ $(AM_CFLAGS) -DSINGLE_THREADED
staprun_LDADD = @PROCFLAGS@ @cap_LIBS@
stapio_SOURCES = runtime/staprun/stapio.c \
runtime/staprun/mainloop.c runtime/staprun/common.c \
- runtime/staprun/ctl.c runtime/staprun/unwind_data.c \
+ runtime/staprun/ctl.c \
runtime/staprun/relay.c runtime/staprun/relay_old.c
stapio_CFLAGS = @PROCFLAGS@ $(AM_CFLAGS)
-stapio_LDADD = @PROCFLAGS@ -ldw -lpthread
+stapio_LDADD = @PROCFLAGS@ -lpthread
loc2c_test_SOURCES = loc2c-test.c loc2c.c
loc2c_test_CPPFLAGS = $(stap_CPPFLAGS)
loc2c_test_LDFLAGS = $(stap_LDFLAGS)
@@ -331,6 +328,7 @@ EXTRA_DIST = buildrun.h elaborate.h loc2c.h session.h \
parse.h staptree.h tapsets.h translate.h \
cache.h hash.h mdfour.h util.h staplog.c coveragedb.h \
testsuite systemtap.spec runtime tapset \
+ dwarf_wrappers.h \
git_version.h git_version.sh
EXAMPLE_DEST_DIR = $(distdir)/examples
@@ -410,6 +408,8 @@ stapprobes.5: $(top_builddir)/config.status $(srcdir)/stapprobes.5.in
cd $(top_builddir) && $(SHELL) ./config.status $@
stapfuncs.5: $(top_builddir)/config.status $(srcdir)/stapfuncs.5.in
cd $(top_builddir) && $(SHELL) ./config.status $@
+stapvars.5: $(top_builddir)/config.status $(srcdir)/stapvars.5.in
+ cd $(top_builddir) && $(SHELL) ./config.status $@
stapex.5: $(top_builddir)/config.status $(srcdir)/stapex.5.in
cd $(top_builddir) && $(SHELL) ./config.status $@
staprun.8: $(top_builddir)/config.status $(srcdir)/staprun.8.in
@@ -511,6 +511,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stap-buildrun.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stap-cache.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stap-coveragedb.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stap-dwarf_wrappers.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stap-elaborate.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stap-hash.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stap-loc2c.Po@am__quote@
@@ -527,7 +528,6 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stapio-relay.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stapio-relay_old.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stapio-stapio.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stapio-unwind_data.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/staprun-cap.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/staprun-common.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/staprun-ctl.Po@am__quote@
@@ -660,20 +660,6 @@ stapio-ctl.obj: runtime/staprun/ctl.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(stapio_CPPFLAGS) $(CPPFLAGS) $(stapio_CFLAGS) $(CFLAGS) -c -o stapio-ctl.obj `if test -f 'runtime/staprun/ctl.c'; then $(CYGPATH_W) 'runtime/staprun/ctl.c'; else $(CYGPATH_W) '$(srcdir)/runtime/staprun/ctl.c'; fi`
-stapio-unwind_data.o: runtime/staprun/unwind_data.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(stapio_CPPFLAGS) $(CPPFLAGS) $(stapio_CFLAGS) $(CFLAGS) -MT stapio-unwind_data.o -MD -MP -MF $(DEPDIR)/stapio-unwind_data.Tpo -c -o stapio-unwind_data.o `test -f 'runtime/staprun/unwind_data.c' || echo '$(srcdir)/'`runtime/staprun/unwind_data.c
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/stapio-unwind_data.Tpo $(DEPDIR)/stapio-unwind_data.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='runtime/staprun/unwind_data.c' object='stapio-unwind_data.o' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(stapio_CPPFLAGS) $(CPPFLAGS) $(stapio_CFLAGS) $(CFLAGS) -c -o stapio-unwind_data.o `test -f 'runtime/staprun/unwind_data.c' || echo '$(srcdir)/'`runtime/staprun/unwind_data.c
-
-stapio-unwind_data.obj: runtime/staprun/unwind_data.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(stapio_CPPFLAGS) $(CPPFLAGS) $(stapio_CFLAGS) $(CFLAGS) -MT stapio-unwind_data.obj -MD -MP -MF $(DEPDIR)/stapio-unwind_data.Tpo -c -o stapio-unwind_data.obj `if test -f 'runtime/staprun/unwind_data.c'; then $(CYGPATH_W) 'runtime/staprun/unwind_data.c'; else $(CYGPATH_W) '$(srcdir)/runtime/staprun/unwind_data.c'; fi`
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/stapio-unwind_data.Tpo $(DEPDIR)/stapio-unwind_data.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='runtime/staprun/unwind_data.c' object='stapio-unwind_data.obj' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(stapio_CPPFLAGS) $(CPPFLAGS) $(stapio_CFLAGS) $(CFLAGS) -c -o stapio-unwind_data.obj `if test -f 'runtime/staprun/unwind_data.c'; then $(CYGPATH_W) 'runtime/staprun/unwind_data.c'; else $(CYGPATH_W) '$(srcdir)/runtime/staprun/unwind_data.c'; fi`
-
stapio-relay.o: runtime/staprun/relay.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(stapio_CPPFLAGS) $(CPPFLAGS) $(stapio_CFLAGS) $(CFLAGS) -MT stapio-relay.o -MD -MP -MF $(DEPDIR)/stapio-relay.Tpo -c -o stapio-relay.o `test -f 'runtime/staprun/relay.c' || echo '$(srcdir)/'`runtime/staprun/relay.c
@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/stapio-relay.Tpo $(DEPDIR)/stapio-relay.Po
@@ -939,6 +925,20 @@ stap-coveragedb.obj: coveragedb.cxx
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='coveragedb.cxx' object='stap-coveragedb.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(stap_CPPFLAGS) $(CPPFLAGS) $(stap_CXXFLAGS) $(CXXFLAGS) -c -o stap-coveragedb.obj `if test -f 'coveragedb.cxx'; then $(CYGPATH_W) 'coveragedb.cxx'; else $(CYGPATH_W) '$(srcdir)/coveragedb.cxx'; fi`
+
+stap-dwarf_wrappers.o: dwarf_wrappers.cxx
+@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(stap_CPPFLAGS) $(CPPFLAGS) $(stap_CXXFLAGS) $(CXXFLAGS) -MT stap-dwarf_wrappers.o -MD -MP -MF $(DEPDIR)/stap-dwarf_wrappers.Tpo -c -o stap-dwarf_wrappers.o `test -f 'dwarf_wrappers.cxx' || echo '$(srcdir)/'`dwarf_wrappers.cxx
+@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/stap-dwarf_wrappers.Tpo $(DEPDIR)/stap-dwarf_wrappers.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='dwarf_wrappers.cxx' object='stap-dwarf_wrappers.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(stap_CPPFLAGS) $(CPPFLAGS) $(stap_CXXFLAGS) $(CXXFLAGS) -c -o stap-dwarf_wrappers.o `test -f 'dwarf_wrappers.cxx' || echo '$(srcdir)/'`dwarf_wrappers.cxx
+
+stap-dwarf_wrappers.obj: dwarf_wrappers.cxx
+@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(stap_CPPFLAGS) $(CPPFLAGS) $(stap_CXXFLAGS) $(CXXFLAGS) -MT stap-dwarf_wrappers.obj -MD -MP -MF $(DEPDIR)/stap-dwarf_wrappers.Tpo -c -o stap-dwarf_wrappers.obj `if test -f 'dwarf_wrappers.cxx'; then $(CYGPATH_W) 'dwarf_wrappers.cxx'; else $(CYGPATH_W) '$(srcdir)/dwarf_wrappers.cxx'; fi`
+@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/stap-dwarf_wrappers.Tpo $(DEPDIR)/stap-dwarf_wrappers.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='dwarf_wrappers.cxx' object='stap-dwarf_wrappers.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(stap_CPPFLAGS) $(CPPFLAGS) $(stap_CXXFLAGS) $(CXXFLAGS) -c -o stap-dwarf_wrappers.obj `if test -f 'dwarf_wrappers.cxx'; then $(CYGPATH_W) 'dwarf_wrappers.cxx'; else $(CYGPATH_W) '$(srcdir)/dwarf_wrappers.cxx'; fi`
install-man1: $(man1_MANS) $(man_MANS)
@$(NORMAL_INSTALL)
test -z "$(man1dir)" || $(MKDIR_P) "$(DESTDIR)$(man1dir)"
@@ -1505,6 +1505,11 @@ dist-gitversion: git_version.stamp
git_version.h:
$(srcdir)/git_version.sh -k --srcdir $(srcdir) -o git_version.h
+
+cscope:
+ cd $(srcdir) && \
+ (echo -q ; git ls-files '*.cxx' '*.c' '*.h' | grep -v '^testsuite' ) > cscope.files && \
+ cscope -b -q
@BUILD_ELFUTILS_TRUE@stamp-elfutils: config.status
@BUILD_ELFUTILS_TRUE@ $(MAKE) $(AM_MAKEFLAGS) -C build-elfutils all
@BUILD_ELFUTILS_TRUE@ for dir in libelf libebl libdw libdwfl backends; do \
@@ -1590,6 +1595,14 @@ check:
$(MAKE) -C testsuite check SYSTEMTAP_RUNTIME=$$SRCDIR/runtime SYSTEMTAP_TAPSET=$$SRCDIR/tapset LD_LIBRARY_PATH=$(PWD)/lib-elfutils:$(PWD)/lib-elfutils/systemtap SYSTEMTAP_PATH=$(PWD) RUNTESTFLAGS="$(RUNTESTFLAGS)"
installcheck:
+ if test \! -e $(DESTDIR)$(bindir)/stap; then \
+ echo $(DESTDIR)$(bindir)/stap doesn\'t exist, run make install; \
+ exit -1; \
+ fi
+ if test $(builddir)/stap -nt $(DESTDIR)$(bindir)/stap; then \
+ echo "$(DESTDIR)$(bindir)/stap is not recent, run make install"; \
+ exit -1; \
+ fi
$(MAKE) -C testsuite installcheck RUNTESTFLAGS="$(RUNTESTFLAGS)"
rpm: systemtap.spec dist
diff --git a/NEWS b/NEWS
index 5d45b4a8..434c9c71 100644
--- a/NEWS
+++ b/NEWS
@@ -1,5 +1,25 @@
* What's new in version 0.7
+- .statement("func@file:*") and .statement("func@file:M-N") probes are now
+ supported to allow matching a range of lines in a function. This allows
+ tracing the execution of a function.
+
+- Scripts relying on probe point wildcards like "syscall.*" that expand
+ to distinct kprobes are processed significantly faster than before.
+
+- The vector of script command line arguments is available in a
+ tapset-provided global array argv[]. It is indexed 1 ... argc,
+ another global. This can substitute for of preprocessor
+ directives @NNN that fail at parse time if there are not
+ enough arguments.
+
+ printf("argv: %s %s %s", argv[1], argv[2], argv[3])
+
+- .statement("func@file+line") probes are now supported to allow a
+ match relative to the entry of the function incremented by line
+ number. This allows using the same systemtap script if the rest
+ of the file.c source only changes slightly.
+
- Stack backtraces for x86 and x86-64 are generated by a dwarf
debuginfo-based unwinder based on the code from <jbeulich@novell.com>.
This should give more accurate backtraces.
@@ -15,12 +35,14 @@
- More user-space probe types are added:
- probe process(PID).clone { }
- probe process("PATH").clone { }
- probe process(PID).exec { }
- probe process("PATH").exec { }
- probe process(PID).death { }
- probe process("PATH").death { }
+ probe process(PID).begin { }
+ probe process("PATH").begin { }
+ probe process(PID).thread.begin { }
+ probe process("PATH").thread.begin { }
+ probe process(PID).end { }
+ probe process("PATH").end { }
+ probe process(PID).thread.end { }
+ probe process("PATH").thread.end { }
probe process(PID).syscall { }
probe process("PATH").syscall { }
probe process(PID).syscall.return { }
diff --git a/buildrun.cxx b/buildrun.cxx
index 76efe7c0..a39f2b63 100644
--- a/buildrun.cxx
+++ b/buildrun.cxx
@@ -96,6 +96,12 @@ compile_pass (systemtap_session& s)
o << module_cflags << " += $(call stap_check_build, $(SYSTEMTAP_RUNTIME)/autoconf-nameidata.c, -DSTAPCONF_NAMEIDATA_CLEANUP,)" << endl;
o << module_cflags << " += $(call stap_check_build, $(SYSTEMTAP_RUNTIME)/autoconf-unregister-kprobes.c, -DSTAPCONF_UNREGISTER_KPROBES,)" << endl;
o << module_cflags << " += $(call stap_check_build, $(SYSTEMTAP_RUNTIME)/autoconf-module-nsections.c, -DSTAPCONF_MODULE_NSECTIONS,)" << endl;
+#if 0
+ /* NB: For now, the performance hit of probe_kernel_read/write (vs. our
+ * homegrown safe-access functions) is deemed undesireable, so we'll skip
+ * this autoconf. */
+ o << module_cflags << " += $(call stap_check_build, $(SYSTEMTAP_RUNTIME)/autoconf-probe-kernel.c, -DSTAPCONF_PROBE_KERNEL,)" << endl;
+#endif
for (unsigned i=0; i<s.macros.size(); i++)
o << "EXTRA_CFLAGS += -D " << lex_cast_qstring(s.macros[i]) << endl;
diff --git a/configure b/configure
index 7d2a0b41..e05e7321 100755
--- a/configure
+++ b/configure
@@ -1336,6 +1336,7 @@ Optional Features:
location).
--enable-docs enable building documentation (default on if latex
etc. found).
+ --enable-staticdw support distributions with static libdw
Optional Packages:
--with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
@@ -6022,8 +6023,8 @@ if test "x$enable_pie" != xno; then
save_CFLAGS="$CFLAGS"
save_CXXFLAGS="$CXXFLAGS"
save_LDFLAGS="$LDFLAGS"
- CFLAGS="$CFLAGS -fpie"
- CXXFLAGS="$CXXFLAGS -fpie"
+ CFLAGS="$CFLAGS -fPIE"
+ CXXFLAGS="$CXXFLAGS -fPIE"
LDFLAGS="$LDFLAGS -pie -Wl,-z,relro -Wl,-z,now"
cat >conftest.$ac_ext <<_ACEOF
void main () {}
@@ -6604,9 +6605,17 @@ fi
`
+# Check whether --enable-staticdw was given.
+if test "${enable_staticdw+set}" = set; then
+ enableval=$enable_staticdw;
+fi
+
+
if test $build_elfutils = no; then
# Need libdwfl-capable recent elfutils from Fedora
save_LIBS="$LIBS"
+ if test "x$enable_staticdw" != xyes; then
+
{ echo "$as_me:$LINENO: checking for dwfl_module_getsym in -ldw" >&5
echo $ECHO_N "checking for dwfl_module_getsym in -ldw... $ECHO_C" >&6; }
@@ -6678,7 +6687,7 @@ _ACEOF
else
- { { echo "$as_me:$LINENO: error: missing elfutils development headers/libraries (dw 0.123+)" >&5
+ { { echo "$as_me:$LINENO: error: missing elfutils development headers/libraries (dw 0.123+)" >&5
echo "$as_me: error: missing elfutils development headers/libraries (dw 0.123+)" >&2;}
{ (exit 1); exit 1; }; }
fi
@@ -6754,17 +6763,183 @@ _ACEOF
else
- { { echo "$as_me:$LINENO: error: missing elfutils development headers/libraries (ebl 0.123+)" >&5
+ { { echo "$as_me:$LINENO: error: missing elfutils development headers/libraries (ebl 0.123+)" >&5
+echo "$as_me: error: missing elfutils development headers/libraries (ebl 0.123+)" >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+
+ stap_LIBS="$LIBS"
+
+else
+
+ # Debian ships with a static libdw, which has a circular dependency on libebl
+
+{ echo "$as_me:$LINENO: checking for dwfl_module_getsym in -ldw" >&5
+echo $ECHO_N "checking for dwfl_module_getsym in -ldw... $ECHO_C" >&6; }
+if test "${ac_cv_lib_dw_dwfl_module_getsym+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldw -Wl,--start-group -ldw -lebl -Wl,--end-group -lelf $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dwfl_module_getsym ();
+int
+main ()
+{
+return dwfl_module_getsym ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_link") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext &&
+ $as_test_x conftest$ac_exeext; then
+ ac_cv_lib_dw_dwfl_module_getsym=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_cv_lib_dw_dwfl_module_getsym=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_lib_dw_dwfl_module_getsym" >&5
+echo "${ECHO_T}$ac_cv_lib_dw_dwfl_module_getsym" >&6; }
+if test $ac_cv_lib_dw_dwfl_module_getsym = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBDW 1
+_ACEOF
+
+ LIBS="-ldw $LIBS"
+
+else
+
+ { { echo "$as_me:$LINENO: error: missing elfutils development headers/libraries (dw 0.123+)" >&5
+echo "$as_me: error: missing elfutils development headers/libraries (dw 0.123+)" >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+
+{ echo "$as_me:$LINENO: checking for ebl_openbackend in -lebl" >&5
+echo $ECHO_N "checking for ebl_openbackend in -lebl... $ECHO_C" >&6; }
+if test "${ac_cv_lib_ebl_ebl_openbackend+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lebl -lelf $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char ebl_openbackend ();
+int
+main ()
+{
+return ebl_openbackend ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_link") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext &&
+ $as_test_x conftest$ac_exeext; then
+ ac_cv_lib_ebl_ebl_openbackend=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_cv_lib_ebl_ebl_openbackend=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_lib_ebl_ebl_openbackend" >&5
+echo "${ECHO_T}$ac_cv_lib_ebl_ebl_openbackend" >&6; }
+if test $ac_cv_lib_ebl_ebl_openbackend = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBEBL 1
+_ACEOF
+
+ LIBS="-lebl $LIBS"
+
+else
+
+ { { echo "$as_me:$LINENO: error: missing elfutils development headers/libraries (ebl 0.123+)" >&5
echo "$as_me: error: missing elfutils development headers/libraries (ebl 0.123+)" >&2;}
{ (exit 1); exit 1; }; }
fi
- stap_LIBS="$LIBS"
+ stap_LIBS="-Wl,--start-group -ldw -lebl -Wl,--end-group -lelf"
+
+fi
+
LIBS="$save_LIBS"
else
# We built our own and stap_LDFLAGS points at the install.
+ if test "x$enable_staticdw" != xyes; then
stap_LIBS="-ldw -lebl"
+else
+ stap_LIBS="-Wl,--start-group -ldw -lebl -Wl,--end-group -lelf"
+fi
+
fi
@@ -7267,7 +7442,7 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
ac_config_headers="$ac_config_headers config.h:config.in"
-ac_config_files="$ac_config_files Makefile doc/Makefile systemtap.spec stap.1 stapprobes.5 stapfuncs.5 stapex.5 staprun.8 man/stapprobes.iosched.5 man/stapprobes.netdev.5 man/stapprobes.nfs.5 man/stapprobes.nfsd.5 man/stapprobes.pagefault.5 man/stapprobes.process.5 man/stapprobes.rpc.5 man/stapprobes.scsi.5 man/stapprobes.signal.5 man/stapprobes.socket.5 man/stapprobes.tcp.5 man/stapprobes.udp.5"
+ac_config_files="$ac_config_files Makefile doc/Makefile systemtap.spec stap.1 stapprobes.5 stapfuncs.5 stapvars.5 stapex.5 staprun.8 man/stapprobes.iosched.5 man/stapprobes.netdev.5 man/stapprobes.nfs.5 man/stapprobes.nfsd.5 man/stapprobes.pagefault.5 man/stapprobes.process.5 man/stapprobes.rpc.5 man/stapprobes.scsi.5 man/stapprobes.signal.5 man/stapprobes.socket.5 man/stapprobes.tcp.5 man/stapprobes.udp.5"
subdirs="$subdirs testsuite"
@@ -7899,6 +8074,7 @@ do
"stap.1") CONFIG_FILES="$CONFIG_FILES stap.1" ;;
"stapprobes.5") CONFIG_FILES="$CONFIG_FILES stapprobes.5" ;;
"stapfuncs.5") CONFIG_FILES="$CONFIG_FILES stapfuncs.5" ;;
+ "stapvars.5") CONFIG_FILES="$CONFIG_FILES stapvars.5" ;;
"stapex.5") CONFIG_FILES="$CONFIG_FILES stapex.5" ;;
"staprun.8") CONFIG_FILES="$CONFIG_FILES staprun.8" ;;
"man/stapprobes.iosched.5") CONFIG_FILES="$CONFIG_FILES man/stapprobes.iosched.5" ;;
diff --git a/configure.ac b/configure.ac
index b7c1bc47..ed099702 100644
--- a/configure.ac
+++ b/configure.ac
@@ -87,8 +87,8 @@ AS_IF([test "x$enable_pie" != xno],[
save_CFLAGS="$CFLAGS"
save_CXXFLAGS="$CXXFLAGS"
save_LDFLAGS="$LDFLAGS"
- CFLAGS="$CFLAGS -fpie"
- CXXFLAGS="$CXXFLAGS -fpie"
+ CFLAGS="$CFLAGS -fPIE"
+ CXXFLAGS="$CXXFLAGS -fPIE"
LDFLAGS="$LDFLAGS -pie -Wl,-z,relro -Wl,-z,now"
AC_LINK_IFELSE([void main () {}], [
AC_MSG_NOTICE([Compiling with gcc pie et al.])
@@ -180,19 +180,36 @@ AM_CONDITIONAL(BUILD_ELFUTILS, test $build_elfutils = yes)
AC_SUBST(elfutils_abs_srcdir, `AS_IF([test $build_elfutils = yes],
[cd $with_elfutils && pwd])`)
+AC_ARG_ENABLE([staticdw],
+ [AS_HELP_STRING([--enable-staticdw], [support distributions with static libdw])])
+
if test $build_elfutils = no; then
# Need libdwfl-capable recent elfutils from Fedora
save_LIBS="$LIBS"
- AC_CHECK_LIB(dw, dwfl_module_getsym,,[
- AC_MSG_ERROR([missing elfutils development headers/libraries (dw 0.123+)])])
- AC_CHECK_LIB(ebl, ebl_openbackend,,[
- AC_MSG_ERROR([missing elfutils development headers/libraries (ebl 0.123+)])])
+ AS_IF([test "x$enable_staticdw" != xyes],[
+ AC_CHECK_LIB(dw, dwfl_module_getsym,,[
+ AC_MSG_ERROR([missing elfutils development headers/libraries (dw 0.123+)])])
+ AC_CHECK_LIB(ebl, ebl_openbackend,,[
+ AC_MSG_ERROR([missing elfutils development headers/libraries (ebl 0.123+)])])
+
+ stap_LIBS="$LIBS"
+ ],[
+ # Debian ships with a static libdw, which has a circular dependency on libebl
+ AC_CHECK_LIB(dw, dwfl_module_getsym,[],[
+ AC_MSG_ERROR([missing elfutils development headers/libraries (dw 0.123+)])],
+ [-Wl,--start-group -ldw -lebl -Wl,--end-group -lelf])
+ dnl XXX Do we need the ebl check, since it was referenced above?
+ AC_CHECK_LIB(ebl, ebl_openbackend,[],[
+ AC_MSG_ERROR([missing elfutils development headers/libraries (ebl 0.123+)])],
+ [-lelf])
- stap_LIBS="$LIBS"
+ stap_LIBS="-Wl,--start-group -ldw -lebl -Wl,--end-group -lelf"
+ ])
LIBS="$save_LIBS"
else
# We built our own and stap_LDFLAGS points at the install.
- stap_LIBS="-ldw -lebl"
+ AS_IF([test "x$enable_staticdw" != xyes],[stap_LIBS="-ldw -lebl"],
+ [stap_LIBS="-Wl,--start-group -ldw -lebl -Wl,--end-group -lelf"])
fi
AC_SUBST(stap_LIBS)
@@ -233,7 +250,7 @@ AC_CHECK_HEADERS([tr1/unordered_map])
AC_LANG_POP(C++)
AC_CONFIG_HEADERS([config.h:config.in])
-AC_CONFIG_FILES(Makefile doc/Makefile systemtap.spec stap.1 stapprobes.5 stapfuncs.5 stapex.5 staprun.8 man/stapprobes.iosched.5 man/stapprobes.netdev.5 man/stapprobes.nfs.5 man/stapprobes.nfsd.5 man/stapprobes.pagefault.5 man/stapprobes.process.5 man/stapprobes.rpc.5 man/stapprobes.scsi.5 man/stapprobes.signal.5 man/stapprobes.socket.5 man/stapprobes.tcp.5 man/stapprobes.udp.5)
+AC_CONFIG_FILES(Makefile doc/Makefile systemtap.spec stap.1 stapprobes.5 stapfuncs.5 stapvars.5 stapex.5 staprun.8 man/stapprobes.iosched.5 man/stapprobes.netdev.5 man/stapprobes.nfs.5 man/stapprobes.nfsd.5 man/stapprobes.pagefault.5 man/stapprobes.process.5 man/stapprobes.rpc.5 man/stapprobes.scsi.5 man/stapprobes.signal.5 man/stapprobes.socket.5 man/stapprobes.tcp.5 man/stapprobes.udp.5)
AC_CONFIG_SUBDIRS(testsuite)
AC_OUTPUT
diff --git a/cscope.files b/cscope.files
deleted file mode 100644
index d2d0e462..00000000
--- a/cscope.files
+++ /dev/null
@@ -1,181 +0,0 @@
--q
-./buildrun.cxx
-./buildrun.h
-./cache.cxx
-./cache.h
-./config.h
-./coveragedb.cxx
-./coveragedb.h
-./elaborate.cxx
-./elaborate.h
-./git_version.h
-./hash.cxx
-./hash.h
-./loc2c.c
-./loc2c.h
-./loc2c-test.c
-./main.cxx
-./mdfour.c
-./mdfour.h
-./parse.cxx
-./parse.h
-./runtime/alloc.c
-./runtime/arith.c
-./runtime/autoconf-constant-tsc.c
-./runtime/autoconf-hrtimer-rel.c
-./runtime/autoconf-inode-private.c
-./runtime/autoconf-ktime-get-real.c
-./runtime/autoconf-module-nsections.c
-./runtime/autoconf-nameidata.c
-./runtime/autoconf-tsc-khz.c
-./runtime/autoconf-unregister-kprobes.c
-./runtime/autoconf-x86-uniregs.c
-./runtime/bench2/itest.c
-./runtime/copy.c
-./runtime/counter.c
-./runtime/debug.h
-./runtime/docs/examples/argv.c
-./runtime/docs/examples/foreach.c
-./runtime/docs/examples/list.c
-./runtime/docs/examples/map.c
-./runtime/docs/examples/template.c
-./runtime/io.c
-./runtime/loc2c-runtime.h
-./runtime/map.c
-./runtime/map-gen.c
-./runtime/map.h
-./runtime/map-stat.c
-./runtime/mempool.c
-./runtime/perf.c
-./runtime/perf.h
-./runtime/pmap-gen.c
-./runtime/print.c
-./runtime/print_new.c
-./runtime/print_old.c
-./runtime/probes/agg/count1.c
-./runtime/probes/agg/count2.c
-./runtime/probes/agg/stat1.c
-./runtime/probes/bench/bench.c
-./runtime/probes/bench/bench_io1.c
-./runtime/probes/bench/bench_io2.c
-./runtime/probes/bench/bench_io3.c
-./runtime/probes/bench/bench_io4.c
-./runtime/probes/bench/bench_multi.c
-./runtime/probes/bench/bench_ret.c
-./runtime/probes/bench/itest.c
-./runtime/probes/bench/ttest.c
-./runtime/probes.c
-./runtime/probes/os_timer/os_timer.c
-./runtime/probes/scf/scf.c
-./runtime/probes/shellsnoop/shellsnoop.c
-./runtime/probes/tasklet/stp_tasklet.c
-./runtime/probes/test4/test4.c
-./runtime/probes/where_func/kprobe_where_funct.c
-./runtime/procfs.c
-./runtime/regs.c
-./runtime/regs.h
-./runtime/regs-ia64.c
-./runtime/runtime.h
-./runtime/stack-arm.c
-./runtime/stack.c
-./runtime/stack-i386.c
-./runtime/stack-ia64.c
-./runtime/stack-ppc64.c
-./runtime/stack-s390.c
-./runtime/stack-x86_64.c
-./runtime/staprun/cap.c
-./runtime/staprun/common.c
-./runtime/staprun/ctl.c
-./runtime/staprun/mainloop.c
-./runtime/staprun/relay.c
-./runtime/staprun/relay_old.c
-./runtime/staprun/stapio.c
-./runtime/staprun/stap_merge.c
-./runtime/staprun/staprun.c
-./runtime/staprun/staprun_funcs.c
-./runtime/staprun/staprun.h
-./runtime/staprun/symbols.c
-./runtime/staprun/unwind_data.c
-./runtime/stat.c
-./runtime/stat-common.c
-./runtime/stat.h
-./runtime/string.c
-./runtime/string.h
-./runtime/sym.c
-./runtime/sym.h
-./runtime/task_finder.c
-./runtime/tests/agg/count.c
-./runtime/tests/agg/stats.c
-./runtime/tests/maps/ii.c
-./runtime/tests/maps/iiiiii.c
-./runtime/tests/maps/iiss.c
-./runtime/tests/maps/is.c
-./runtime/tests/maps/issii.c
-./runtime/tests/maps/isx.c
-./runtime/tests/maps/map_format.c
-./runtime/tests/maps/setadd.c
-./runtime/tests/maps/si.c
-./runtime/tests/maps/size.c
-./runtime/tests/maps/sort2.c
-./runtime/tests/maps/sort.c
-./runtime/tests/maps/sort_stat.c
-./runtime/tests/maps/ssssss.c
-./runtime/tests/math/div64.c
-./runtime/tests/pmaps/ii2.c
-./runtime/tests/pmaps/ii3.c
-./runtime/tests/pmaps/ii.c
-./runtime/tests/pmaps/is.c
-./runtime/tests/pmaps/ix2.c
-./runtime/tests/pmaps/ix.c
-./runtime/tests/pmaps/ix_log.c
-./runtime/tests/pmaps/ix_none.c
-./runtime/tests/pmaps/map_format.c
-./runtime/tests/pmaps/si.c
-./runtime/tests/pmaps/size.c
-./runtime/tests/string/print_cstr.c
-./runtime/tests/string/printf_A.c
-./runtime/tests/string/printf_B.c
-./runtime/tests/string/string1.c
-./runtime/tests/string/string2.c
-./runtime/tests/string/string3.c
-./runtime/time.c
-./runtime/transport/control.c
-./runtime/transport/procfs.c
-./runtime/transport/relayfs.c
-./runtime/transport/relayfs.h
-./runtime/transport/symbols.c
-./runtime/transport/transport.c
-./runtime/transport/transport.h
-./runtime/transport/transport_msgs.h
-./runtime/transport/utt.c
-./runtime/transport/utt.h
-./runtime/unwind.c
-./runtime/unwind/i386.h
-./runtime/unwind/unwind.h
-./runtime/unwind/x86_64.h
-./runtime/uprobes/uprobes_arch.c
-./runtime/uprobes/uprobes_arch.h
-./runtime/uprobes/uprobes.c
-./runtime/uprobes/uprobes.h
-./runtime/uprobes/uprobes_i386.c
-./runtime/uprobes/uprobes_i386.h
-./runtime/uprobes/uprobes_ppc64.c
-./runtime/uprobes/uprobes_ppc64.h
-./runtime/uprobes/uprobes_s390.c
-./runtime/uprobes/uprobes_s390.h
-./runtime/uprobes/uprobes_x86_64.c
-./runtime/uprobes/uprobes_x86_64.h
-./runtime/uprobes/uprobes_x86.c
-./runtime/uprobes/uprobes_x86.h
-./runtime/vsprintf.c
-./session.h
-./staplog.c
-./staptree.cxx
-./staptree.h
-./tapsets.cxx
-./tapsets.h
-./tapset/test/master.c
-./translate.cxx
-./translate.h
-./util.cxx
-./util.h
diff --git a/doc/Makefile.in b/doc/Makefile.in
index a2700d3c..a31d76f0 100644
--- a/doc/Makefile.in
+++ b/doc/Makefile.in
@@ -55,6 +55,7 @@ CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CXX = @CXX@
+CXXCPP = @CXXCPP@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
diff --git a/doc/langref.tex b/doc/langref.tex
index 46d350f6..e2c630d4 100644
--- a/doc/langref.tex
+++ b/doc/langref.tex
@@ -751,7 +751,13 @@ In most cases, the path should be relative to the top of the
linux source directory, although an absolute path may be necessary for some kernels.
If a relative pathname doesn't work, try absolute.
\item The third part is optional if the file name part was given. It identifies
-the line number in the source file, preceded by a colon.
+the line number in the source file, preceded by a ``:'' or ``+''.
+The line number is assumed to be an
+absolute line number if preceded by a ``:'', or relative to the entry of
+the function if preceded by a ``+''.
+All the lines in the function can be matched with ``:*''.
+A range of lines x through y can be matched with ``:x-y''.
+
\end{enumerate}
Alternately, specify PATTERN as a numeric constant to indicate a relative
module address or an absolute kernel address.
@@ -825,6 +831,8 @@ Example:
# Refers to the statement at line 2917 within the
# kernel/sched.c file:
kernel.statement("*@kernel/sched.c:2917")
+# Refers to the statement at line bio_init+3 within the fs/bio.c file:
+kernel.statement("bio_init@fs/bio.c+3")
\end{verbatim}
\end{vindent}
diff --git a/dwarf_wrappers.cxx b/dwarf_wrappers.cxx
new file mode 100644
index 00000000..93cb36a2
--- /dev/null
+++ b/dwarf_wrappers.cxx
@@ -0,0 +1,46 @@
+// -*- C++ -*-
+// Copyright (C) 2008 Red Hat Inc.
+//
+// This file is part of systemtap, and is free software. You can
+// redistribute it and/or modify it under the terms of the GNU General
+// Public License (GPL); either version 2, or (at your option) any
+// later version.
+
+#include "dwarf_wrappers.h"
+#include "staptree.h"
+
+#include <cstring>
+#include <string>
+#include <elfutils/libdwfl.h>
+
+using std::string;
+
+void dwfl_assert(const string& desc, int rc)
+{
+ if (rc == 0)
+ return;
+ string msg = "libdwfl failure (" + desc + "): ";
+ if (rc < 0)
+ msg += dwfl_errmsg (rc);
+ else
+ msg += std::strerror (rc);
+ throw semantic_error (msg);
+}
+
+void dwarf_assert(const string& desc, int rc)
+{
+ if (rc == 0)
+ return;
+ string msg = "libdw failure (" + desc + "): ";
+ if (rc < 0)
+ msg += dwarf_errmsg (rc);
+ else
+ msg += std::strerror (rc);
+ throw semantic_error (msg);
+}
+
+void dwfl_assert(const std::string& desc, bool condition)
+{
+ if (!condition)
+ dwarf_assert(desc, -1);
+}
diff --git a/dwarf_wrappers.h b/dwarf_wrappers.h
new file mode 100644
index 00000000..c498de05
--- /dev/null
+++ b/dwarf_wrappers.h
@@ -0,0 +1,93 @@
+// -*- C++ -*-
+// Copyright (C) 2008 Red Hat Inc.
+//
+// This file is part of systemtap, and is free software. You can
+// redistribute it and/or modify it under the terms of the GNU General
+// Public License (GPL); either version 2, or (at your option) any
+// later version.
+
+#ifndef DWARF_WRAPPERS_H
+#define DWARF_WRAPPERS_H 1
+#include <elfutils/libdw.h>
+
+#include <string>
+
+// NB: "rc == 0" means OK in this case
+void dwfl_assert(const std::string& desc, int rc);
+
+// Throw error if pointer is NULL.
+template <typename T>
+void dwfl_assert(const std::string& desc, T* ptr)
+{
+ if (!ptr)
+ dwfl_assert(desc, -1);
+}
+
+// Throw error if pointer is NULL
+template <typename T>
+void dwfl_assert(const std::string& desc, const T* ptr)
+{
+ if (!ptr)
+ dwfl_assert(desc, -1);
+}
+
+// Throw error if condition is false
+void dwfl_assert(const std::string& desc, bool condition);
+
+// NB: "rc == 0" means OK in this case
+void dwarf_assert(const std::string& desc, int rc);
+
+// Throw error if pointer is NULL
+template <typename T>
+void dwarf_assert(const std::string& desc, T* ptr)
+{
+ if (!ptr)
+ dwarf_assert(desc, -1);
+}
+
+
+class dwarf_line_t
+{
+public:
+ const Dwarf_Line* line;
+ dwarf_line_t() : line(0) {}
+ dwarf_line_t(const Dwarf_Line* line_) : line(line_) {}
+
+ dwarf_line_t& operator= (const Dwarf_Line* line_)
+ {
+ line = (line_);
+ return *this;
+ }
+
+ operator bool() const
+ {
+ return line != 0;
+ }
+
+ int lineno() const
+ {
+ int lineval;
+ if (!line)
+ dwarf_assert("dwarf_line_t::lineno", -1);
+ dwarf_lineno(const_cast<Dwarf_Line*>(line), &lineval);
+ return lineval;
+ }
+ Dwarf_Addr addr() const
+ {
+ Dwarf_Addr addrval;
+ if (!line)
+ dwarf_assert("dwarf_line_t::addr", -1);
+ dwarf_lineaddr(const_cast<Dwarf_Line*>(line), &addrval);
+ return addrval;
+ }
+ const char* linesrc(Dwarf_Word* mtime = 0, Dwarf_Word* length = 0)
+ {
+ const char* retval = dwarf_linesrc(const_cast<Dwarf_Line*>(line), mtime,
+ length);
+ dwarf_assert("dwarf_line_t::linesrc", retval);
+ return retval;
+ }
+};
+
+
+#endif
diff --git a/elaborate.cxx b/elaborate.cxx
index 2f246e2c..73358a1d 100644
--- a/elaborate.cxx
+++ b/elaborate.cxx
@@ -1,5 +1,6 @@
// elaboration functions
// Copyright (C) 2005-2008 Red Hat Inc.
+// Copyright (C) 2008 Intel Corporation
//
// This file is part of systemtap, and is free software. You can
// redistribute it and/or modify it under the terms of the GNU General
@@ -322,7 +323,7 @@ match_node::find_and_build (systemtap_session& s,
throw semantic_error (string("probe point truncated at position ") +
lex_cast<string> (pos) +
- " (follow:" + alternatives + ")");
+ " (follow:" + alternatives + ")", loc->tok);
}
map<string, literal *> param_map;
@@ -394,7 +395,8 @@ match_node::find_and_build (systemtap_session& s,
throw semantic_error(string("probe point mismatch at position ") +
lex_cast<string> (pos) +
- " (alternatives:" + alternatives + ")");
+ " (alternatives:" + alternatives + ")",
+ loc->tok);
}
}
else
@@ -409,7 +411,8 @@ match_node::find_and_build (systemtap_session& s,
throw semantic_error (string("probe point mismatch at position ") +
lex_cast<string> (pos) +
- " (alternatives:" + alternatives + ")");
+ " (alternatives:" + alternatives + ")",
+ loc->tok);
}
match_node* subnode = i->second;
@@ -1194,11 +1197,40 @@ systemtap_session::systemtap_session ():
op (0), up (0),
sym_kprobes_text_start (0),
sym_kprobes_text_end (0),
- sym_stext (0)
+ sym_stext (0),
+ module_cache (0),
+ last_token (0)
{
}
+// Print this given token, but abbreviate it if the last one had the
+// same file name.
+void
+systemtap_session::print_token (ostream& o, const token* tok)
+{
+ assert (tok);
+
+ if (last_token && last_token->location.file == tok->location.file)
+ {
+ stringstream tmpo;
+ tmpo << *tok;
+ string ts = tmpo.str();
+ // search & replace the file name with nothing
+ size_t idx = ts.find (tok->location.file);
+ if (idx != string::npos)
+ ts.replace (idx, tok->location.file.size(), "");
+
+ o << ts;
+ }
+ else
+ o << *tok;
+
+ last_token = tok;
+}
+
+
+
void
systemtap_session::print_error (const semantic_error& e)
{
@@ -1211,9 +1243,9 @@ systemtap_session::print_error (const semantic_error& e)
message << "semantic error: " << e.what ();
if (e.tok1 || e.tok2)
message << ": ";
- if (e.tok1) message << *e.tok1;
+ if (e.tok1) print_token (message, e.tok1);
message << e.msg2;
- if (e.tok2) message << *e.tok2;
+ if (e.tok2) print_token (message, e.tok2);
message << endl;
message_str = message.str();
@@ -1228,6 +1260,19 @@ systemtap_session::print_error (const semantic_error& e)
print_error (* e.chain);
}
+void
+systemtap_session::print_warning (const string& message_str, const token* tok)
+{
+ // Duplicate elimination
+ if (seen_warnings.find (message_str) == seen_warnings.end())
+ {
+ seen_warnings.insert (message_str);
+ clog << "WARNING: " << message_str;
+ if (tok) { clog << ": "; print_token (clog, tok); }
+ clog << endl;
+ }
+}
+
// ------------------------------------------------------------------------
// semantic processing: symbol resolution
@@ -1558,7 +1603,7 @@ void semantic_pass_opt1 (systemtap_session& s, bool& relaxed_p)
{
if (s.functions[i]->tok->location.file == s.user_file->name && // !tapset
! s.suppress_warnings)
- clog << "WARNING: eliding unused function " << *s.functions[i]->tok << endl;
+ s.print_warning ("eliding unused function '" + s.functions[i]->name + "'", s.functions[i]->tok);
else if (s.verbose>2)
clog << "Eliding unused function " << s.functions[i]->name
<< endl;
@@ -1579,10 +1624,10 @@ void semantic_pass_opt1 (systemtap_session& s, bool& relaxed_p)
// Do away with local & global variables that are never
// written nor read.
-void semantic_pass_opt2 (systemtap_session& s, bool& relaxed_p)
+void semantic_pass_opt2 (systemtap_session& s, bool& relaxed_p, unsigned iterations)
{
varuse_collecting_visitor vut;
-
+
for (unsigned i=0; i<s.probes.size(); i++)
{
s.probes[i]->body->visit (& vut);
@@ -1601,7 +1646,7 @@ void semantic_pass_opt2 (systemtap_session& s, bool& relaxed_p)
// Now in vut.read/written, we have a mixture of all locals, globals
- for (unsigned i=0; i<s.probes.size(); i++)
+ for (unsigned i=0; i<s.probes.size(); i++)
for (unsigned j=0; j<s.probes[i]->locals.size(); /* see below */)
{
vardecl* l = s.probes[i]->locals[j];
@@ -1611,7 +1656,7 @@ void semantic_pass_opt2 (systemtap_session& s, bool& relaxed_p)
{
if (l->tok->location.file == s.user_file->name && // !tapset
! s.suppress_warnings)
- clog << "WARNING: eliding unused variable " << *l->tok << endl;
+ s.print_warning ("eliding unused variable '" + l->name + "'", l->tok);
else if (s.verbose>2)
clog << "Eliding unused local variable "
<< l->name << " in " << s.probes[i]->name << endl;
@@ -1626,12 +1671,24 @@ void semantic_pass_opt2 (systemtap_session& s, bool& relaxed_p)
else
{
if (vut.written.find (l) == vut.written.end())
- if (! s.suppress_warnings)
- clog << "WARNING: read-only local variable " << *l->tok << endl;
-
+ if (iterations == 0 && ! s.suppress_warnings)
+ {
+ stringstream o;
+ vector<vardecl*>::iterator it;
+ for (it = s.probes[i]->locals.begin(); it != s.probes[i]->locals.end(); it++)
+ if (l->name != (*it)->name)
+ o << " " << (*it)->name;
+ for (it = s.globals.begin(); it != s.globals.end(); it++)
+ if (l->name != (*it)->name)
+ o << " " << (*it)->name;
+
+ s.print_warning ("read-only local variable '" + l->name + "' " +
+ (o.str() == "" ? "" : ("(alternatives:" + o.str() + ")")), l->tok);
+ }
j++;
}
}
+
for (unsigned i=0; i<s.functions.size(); i++)
for (unsigned j=0; j<s.functions[i]->locals.size(); /* see below */)
{
@@ -1641,7 +1698,7 @@ void semantic_pass_opt2 (systemtap_session& s, bool& relaxed_p)
{
if (l->tok->location.file == s.user_file->name && // !tapset
! s.suppress_warnings)
- clog << "WARNING: eliding unused variable " << *l->tok << endl;
+ s.print_warning ("eliding unused variable '" + l->name + "'", l->tok);
else if (s.verbose>2)
clog << "Eliding unused local variable "
<< l->name << " in function " << s.functions[i]->name
@@ -1657,8 +1714,25 @@ void semantic_pass_opt2 (systemtap_session& s, bool& relaxed_p)
else
{
if (vut.written.find (l) == vut.written.end())
- if (! s.suppress_warnings)
- clog << "WARNING: read-only local variable " << *l->tok << endl;
+ if (iterations == 0 && ! s.suppress_warnings)
+ {
+ stringstream o;
+ vector<vardecl*>::iterator it;
+ for ( it = s.functions[i]->formal_args.begin() ;
+ it != s.functions[i]->formal_args.end(); it++)
+ if (l->name != (*it)->name)
+ o << " " << (*it)->name;
+ for (it = s.functions[i]->locals.begin(); it != s.functions[i]->locals.end(); it++)
+ if (l->name != (*it)->name)
+ o << " " << (*it)->name;
+ for (it = s.globals.begin(); it != s.globals.end(); it++)
+ if (l->name != (*it)->name)
+ o << " " << (*it)->name;
+
+ s.print_warning ("read-only local variable '" + l->name + "' " +
+ (o.str() == "" ? "" : ("(alternatives:" + o.str() + ")")), l->tok);
+ }
+
j++;
}
}
@@ -1670,7 +1744,7 @@ void semantic_pass_opt2 (systemtap_session& s, bool& relaxed_p)
{
if (l->tok->location.file == s.user_file->name && // !tapset
! s.suppress_warnings)
- clog << "WARNING: eliding unused variable " << *l->tok << endl;
+ s.print_warning ("eliding unused variable '" + l->name + "'", l->tok);
else if (s.verbose>2)
clog << "Eliding unused global variable "
<< l->name << endl;
@@ -1683,10 +1757,19 @@ void semantic_pass_opt2 (systemtap_session& s, bool& relaxed_p)
}
else
{
- if (vut.written.find (l) == vut.written.end() &&
- ! l->init) // no initializer
- if (! s.suppress_warnings)
- clog << "WARNING: read-only global variable " << *l->tok << endl;
+ if (vut.written.find (l) == vut.written.end() && ! l->init) // no initializer
+ if (iterations == 0 && ! s.suppress_warnings)
+ {
+ stringstream o;
+ vector<vardecl*>::iterator it;
+ for (it = s.globals.begin(); it != s.globals.end(); it++)
+ if (l->name != (*it)->name)
+ o << " " << (*it)->name;
+
+ s.print_warning ("read-only global variable '" + l->name + "' " +
+ (o.str() == "" ? "" : ("(alternatives:" + o.str() + ")")), l->tok);
+ }
+
i++;
}
}
@@ -1912,7 +1995,20 @@ dead_stmtexpr_remover::visit_block (block *s)
current_stmt = & s->statements[i];
s->statements[i]->visit (this);
if (*current_stmt != 0)
- new_stmts.push_back (*current_stmt);
+ {
+ // flatten nested blocks into this one
+ block *b = dynamic_cast<block *>(*current_stmt);
+ if (b)
+ {
+ if (session.verbose>2)
+ clog << "Flattening nested block " << *b->tok << endl;
+ new_stmts.insert(new_stmts.end(),
+ b->statements.begin(), b->statements.end());
+ relaxed_p = false;
+ }
+ else
+ new_stmts.push_back (*current_stmt);
+ }
current_stmt = last_stmt;
}
if (new_stmts.size() == 0)
@@ -1948,27 +2044,49 @@ dead_stmtexpr_remover::visit_if_statement (if_statement *s)
}
current_stmt = last_stmt;
- if (s->elseblock == 0 && s->thenblock == 0)
+ if (s->thenblock == 0)
{
- // We may be able to elide this statement, if the condition
- // expression is side-effect-free.
- varuse_collecting_visitor vct;
- s->condition->visit(& vct);
- if (vct.side_effect_free ())
+ if (s->elseblock == 0)
+ {
+ // We may be able to elide this statement, if the condition
+ // expression is side-effect-free.
+ varuse_collecting_visitor vct;
+ s->condition->visit(& vct);
+ if (vct.side_effect_free ())
+ {
+ if (session.verbose>2)
+ clog << "Eliding side-effect-free if statement "
+ << *s->tok << endl;
+ *current_stmt = 0; // yeah, baby
+ }
+ else
+ {
+ // We can still turn it into a simple expr_statement though...
+ if (session.verbose>2)
+ clog << "Creating simple evaluation from if statement "
+ << *s->tok << endl;
+ expr_statement *es = new expr_statement;
+ es->value = s->condition;
+ es->tok = es->value->tok;
+ *current_stmt = es;
+ }
+ }
+ else
{
+ // For an else without a then, we can invert the condition logic to
+ // avoid having a null statement in the thenblock
if (session.verbose>2)
- clog << "Eliding side-effect-free if statement " << *s->tok << endl;
- *current_stmt = 0; // yeah, baby
- return;
+ clog << "Inverting the condition of if statement "
+ << *s->tok << endl;
+ unary_expression *ue = new unary_expression;
+ ue->operand = s->condition;
+ ue->tok = ue->operand->tok;
+ ue->op = "!";
+ s->condition = ue;
+ s->thenblock = s->elseblock;
+ s->elseblock = 0;
}
}
-
- if (s->thenblock == 0)
- {
- // Can't elide this whole if/else statement; put a null in there.
- s->thenblock = new null_statement();
- s->thenblock->tok = s->tok;
- }
}
void
@@ -2084,8 +2202,7 @@ void semantic_pass_opt4 (systemtap_session& s, bool& relaxed_p)
if (p->body == 0)
{
if (! s.suppress_warnings)
- clog << "WARNING: side-effect-free probe '" << p->name << "' "
- << *p->tok << endl;
+ s.print_warning ("side-effect-free probe '" + p->name + "'", p->tok);
p->body = new null_statement();
p->body->tok = p->tok;
@@ -2109,8 +2226,7 @@ void semantic_pass_opt4 (systemtap_session& s, bool& relaxed_p)
if (fn->body == 0)
{
if (! s.suppress_warnings)
- clog << "WARNING: side-effect-free function '" << fn->name << "' "
- << *fn->tok << endl;
+ s.print_warning ("side-effect-free function '" + fn->name + "'", fn->tok);
fn->body = new null_statement();
fn->body->tok = fn->tok;
@@ -2124,6 +2240,362 @@ void semantic_pass_opt4 (systemtap_session& s, bool& relaxed_p)
}
}
+
+// ------------------------------------------------------------------------
+
+// The goal of this visitor is to reduce top-level expressions in void context
+// into separate statements that evaluate each subcomponent of the expression.
+// The dead-statement-remover can later remove some parts if they have no side
+// effects.
+struct void_statement_reducer: public traversing_visitor
+{
+ systemtap_session& session;
+ bool& relaxed_p;
+ statement** current_stmt; // pointer to current stmt* being iterated
+ expr_statement* current_expr; // pointer to current expr being iterated
+ set<vardecl*> focal_vars; // vars considered subject to side-effects
+
+ void_statement_reducer(systemtap_session& s, bool& r):
+ session(s), relaxed_p(r), current_stmt(0), current_expr(0) {}
+
+ // these just maintain current_stmt while recursing, but don't visit
+ // expressions in the conditional / loop controls.
+ void visit_expr_statement (expr_statement* s);
+ void visit_block (block *s);
+ void visit_if_statement (if_statement* s);
+ void visit_for_loop (for_loop* s);
+ void visit_foreach_loop (foreach_loop* s);
+
+ // these expressions get rewritten into their statement equivalents
+ void visit_logical_or_expr (logical_or_expr* e);
+ void visit_logical_and_expr (logical_and_expr* e);
+ void visit_ternary_expression (ternary_expression* e);
+
+ // all of these can be reduced into simpler statements
+ void visit_binary_expression (binary_expression* e);
+ void visit_unary_expression (unary_expression* e);
+ void visit_comparison (comparison* e);
+ void visit_concatenation (concatenation* e);
+ void visit_functioncall (functioncall* e);
+ void visit_print_format (print_format* e);
+
+ // these are a bit hairy to grok due to the intricacies of indexables and
+ // stats, so I'm chickening out and skipping them...
+ void visit_array_in (array_in* e) {}
+ void visit_arrayindex (arrayindex* e) {}
+ void visit_stat_op (stat_op* e) {}
+ void visit_hist_op (hist_op* e) {}
+
+ // these can't be reduced because they always have an effect
+ void visit_return_statement (return_statement* s) {}
+ void visit_delete_statement (delete_statement* s) {}
+ void visit_pre_crement (pre_crement* e) {}
+ void visit_post_crement (post_crement* e) {}
+ void visit_assignment (assignment* e) {}
+};
+
+
+void
+void_statement_reducer::visit_expr_statement (expr_statement* s)
+{
+ assert(!current_expr); // it shouldn't be possible to have nested expr's
+ current_expr = s;
+ s->value->visit (this);
+ current_expr = NULL;
+}
+
+void
+void_statement_reducer::visit_block (block *s)
+{
+ statement** last_stmt = current_stmt;
+ for (unsigned i=0; i<s->statements.size(); i++ )
+ {
+ current_stmt = & s->statements[i];
+ s->statements[i]->visit (this);
+ }
+ current_stmt = last_stmt;
+}
+
+void
+void_statement_reducer::visit_if_statement (if_statement* s)
+{
+ statement** last_stmt = current_stmt;
+ current_stmt = & s->thenblock;
+ s->thenblock->visit (this);
+
+ if (s->elseblock)
+ {
+ current_stmt = & s->elseblock;
+ s->elseblock->visit (this);
+ }
+ current_stmt = last_stmt;
+}
+
+void
+void_statement_reducer::visit_for_loop (for_loop* s)
+{
+ statement** last_stmt = current_stmt;
+ current_stmt = & s->block;
+ s->block->visit (this);
+ current_stmt = last_stmt;
+}
+
+void
+void_statement_reducer::visit_foreach_loop (foreach_loop* s)
+{
+ statement** last_stmt = current_stmt;
+ current_stmt = & s->block;
+ s->block->visit (this);
+ current_stmt = last_stmt;
+}
+
+void
+void_statement_reducer::visit_logical_or_expr (logical_or_expr* e)
+{
+ // In void context, the evaluation of "a || b" is exactly like
+ // "if (!a) b", so let's do that instead.
+
+ assert(current_expr && current_expr->value == e);
+
+ if (session.verbose>2)
+ clog << "Creating if statement from unused logical-or "
+ << *e->tok << endl;
+
+ if_statement *is = new if_statement;
+ is->tok = e->tok;
+ is->elseblock = 0;
+ *current_stmt = is;
+ current_expr = NULL;
+
+ unary_expression *ue = new unary_expression;
+ ue->operand = e->left;
+ ue->tok = e->tok;
+ ue->op = "!";
+ is->condition = ue;
+
+ expr_statement *es = new expr_statement;
+ es->value = e->right;
+ es->tok = es->value->tok;
+ is->thenblock = es;
+
+ is->visit(this);
+ relaxed_p = false;
+}
+
+void
+void_statement_reducer::visit_logical_and_expr (logical_and_expr* e)
+{
+ // In void context, the evaluation of "a && b" is exactly like
+ // "if (a) b", so let's do that instead.
+
+ assert(current_expr && current_expr->value == e);
+
+ if (session.verbose>2)
+ clog << "Creating if statement from unused logical-and "
+ << *e->tok << endl;
+
+ if_statement *is = new if_statement;
+ is->tok = e->tok;
+ is->elseblock = 0;
+ is->condition = e->left;
+ *current_stmt = is;
+ current_expr = NULL;
+
+ expr_statement *es = new expr_statement;
+ es->value = e->right;
+ es->tok = es->value->tok;
+ is->thenblock = es;
+
+ is->visit(this);
+ relaxed_p = false;
+}
+
+void
+void_statement_reducer::visit_ternary_expression (ternary_expression* e)
+{
+ // In void context, the evaluation of "a ? b : c" is exactly like
+ // "if (a) b else c", so let's do that instead.
+
+ assert(current_expr && current_expr->value == e);
+
+ if (session.verbose>2)
+ clog << "Creating if statement from unused ternary expression "
+ << *e->tok << endl;
+
+ if_statement *is = new if_statement;
+ is->tok = e->tok;
+ is->condition = e->cond;
+ *current_stmt = is;
+ current_expr = NULL;
+
+ expr_statement *es = new expr_statement;
+ es->value = e->truevalue;
+ es->tok = es->value->tok;
+ is->thenblock = es;
+
+ es = new expr_statement;
+ es->value = e->falsevalue;
+ es->tok = es->value->tok;
+ is->elseblock = es;
+
+ is->visit(this);
+ relaxed_p = false;
+}
+
+void
+void_statement_reducer::visit_binary_expression (binary_expression* e)
+{
+ // When the result of a binary operation isn't needed, it's just as good to
+ // evaluate the operands as sequential statements in a block.
+
+ assert(current_expr && current_expr->value == e);
+
+ if (session.verbose>2)
+ clog << "Eliding unused binary " << *e->tok << endl;
+
+ block *b = new block;
+ b->tok = current_expr->tok;
+ *current_stmt = b;
+ current_expr = NULL;
+
+ expr_statement *es = new expr_statement;
+ es->value = e->left;
+ es->tok = es->value->tok;
+ b->statements.push_back(es);
+
+ es = new expr_statement;
+ es->value = e->right;
+ es->tok = es->value->tok;
+ b->statements.push_back(es);
+
+ b->visit(this);
+ relaxed_p = false;
+}
+
+void
+void_statement_reducer::visit_unary_expression (unary_expression* e)
+{
+ // When the result of a unary operation isn't needed, it's just as good to
+ // evaluate the operand directly
+
+ assert(current_expr && current_expr->value == e);
+
+ if (session.verbose>2)
+ clog << "Eliding unused unary " << *e->tok << endl;
+
+ current_expr->value = e->operand;
+ current_expr->tok = current_expr->value->tok;
+ current_expr->value->visit(this);
+
+ relaxed_p = false;
+}
+
+void
+void_statement_reducer::visit_comparison (comparison* e)
+{
+ visit_binary_expression(e);
+}
+
+void
+void_statement_reducer::visit_concatenation (concatenation* e)
+{
+ visit_binary_expression(e);
+}
+
+void
+void_statement_reducer::visit_functioncall (functioncall* e)
+{
+ // If a function call is pure and its result ignored, we can elide the call
+ // and just evaluate the arguments in sequence
+
+ if (!e->args.size())
+ return;
+
+ varuse_collecting_visitor vut;
+ vut.traversed.insert (e->referent);
+ vut.current_function = e->referent;
+ e->referent->body->visit (& vut);
+ if (!vut.side_effect_free_wrt (focal_vars))
+ return;
+
+ assert(current_expr && current_expr->value == e);
+
+ if (session.verbose>2)
+ clog << "Eliding side-effect-free function call " << *e->tok << endl;
+
+ block *b = new block;
+ b->tok = e->tok;
+ *current_stmt = b;
+ current_expr = NULL;
+
+ for (unsigned i=0; i<e->args.size(); i++ )
+ {
+ expr_statement *es = new expr_statement;
+ es->value = e->args[i];
+ es->tok = es->value->tok;
+ b->statements.push_back(es);
+ }
+
+ b->visit(this);
+ relaxed_p = false;
+}
+
+void
+void_statement_reducer::visit_print_format (print_format* e)
+{
+ // When an sprint's return value is ignored, we can simply evaluate the
+ // arguments in sequence
+
+ if (e->print_to_stream || !e->args.size())
+ return;
+
+ assert(current_expr && current_expr->value == e);
+
+ if (session.verbose>2)
+ clog << "Eliding unused print " << *e->tok << endl;
+
+ block *b = new block;
+ b->tok = e->tok;
+ *current_stmt = b;
+ current_expr = NULL;
+
+ for (unsigned i=0; i<e->args.size(); i++ )
+ {
+ expr_statement *es = new expr_statement;
+ es->value = e->args[i];
+ es->tok = es->value->tok;
+ b->statements.push_back(es);
+ }
+
+ b->visit(this);
+ relaxed_p = false;
+}
+
+
+void semantic_pass_opt5 (systemtap_session& s, bool& relaxed_p)
+{
+ // Let's simplify statements with unused computed values.
+
+ void_statement_reducer vuv (s, relaxed_p);
+ // This instance may be reused for multiple probe/function body trims.
+
+ vuv.focal_vars.insert (s.globals.begin(), s.globals.end());
+
+ for (unsigned i=0; i<s.probes.size(); i++)
+ {
+ derived_probe* p = s.probes[i];
+ vuv.current_stmt = & p->body;
+ p->body->visit (& vuv);
+ }
+ for (unsigned i=0; i<s.functions.size(); i++)
+ {
+ functiondecl* fn = s.functions[i];
+ vuv.current_stmt = & fn->body;
+ fn->body->visit (& vuv);
+ }
+}
+
+
struct duplicate_function_remover: public functioncall_traversing_visitor
{
systemtap_session& s;
@@ -2176,7 +2648,7 @@ get_functionsig (functiondecl* f)
return str;
}
-void semantic_pass_opt5 (systemtap_session& s, bool& relaxed_p)
+void semantic_pass_opt6 (systemtap_session& s, bool& relaxed_p)
{
// Walk through all the functions, looking for duplicates.
map<string, functiondecl*> functionsig_map;
@@ -2232,6 +2704,7 @@ semantic_pass_optimize1 (systemtap_session& s)
int rc = 0;
bool relaxed_p = false;
+ unsigned iterations = 0;
while (! relaxed_p)
{
if (pending_interrupts) break;
@@ -2239,9 +2712,12 @@ semantic_pass_optimize1 (systemtap_session& s)
relaxed_p = true; // until proven otherwise
semantic_pass_opt1 (s, relaxed_p);
- semantic_pass_opt2 (s, relaxed_p);
+ semantic_pass_opt2 (s, relaxed_p, iterations); // produce some warnings only on iteration=0
semantic_pass_opt3 (s, relaxed_p);
semantic_pass_opt4 (s, relaxed_p);
+ semantic_pass_opt5 (s, relaxed_p);
+
+ iterations ++;
}
return rc;
@@ -2263,7 +2739,7 @@ semantic_pass_optimize2 (systemtap_session& s)
if (pending_interrupts) break;
relaxed_p = true; // until proven otherwise
- semantic_pass_opt5 (s, relaxed_p);
+ semantic_pass_opt6 (s, relaxed_p);
}
return rc;
diff --git a/elaborate.h b/elaborate.h
index 30bf5bce..c0e35477 100644
--- a/elaborate.h
+++ b/elaborate.h
@@ -13,7 +13,8 @@
#include "parse.h"
#include <string>
#include <vector>
-#include <iostream>
+//#include <iostream>
+#include <iosfwd>
#include <sstream>
#include <map>
@@ -175,21 +176,23 @@ struct derived_probe_group
// ------------------------------------------------------------------------
+typedef std::map<std::string, literal*> literal_map_t;
+
struct derived_probe_builder
{
virtual void build(systemtap_session & sess,
probe* base,
probe_point* location,
- std::map<std::string, literal*> const & parameters,
+ literal_map_t const & parameters,
std::vector<derived_probe*> & finished_results) = 0;
virtual ~derived_probe_builder() {}
virtual void build_no_more (systemtap_session &) {}
- static bool has_null_param (std::map<std::string, literal*> const & parameters,
+ static bool has_null_param (literal_map_t const & parameters,
const std::string& key);
- static bool get_param (std::map<std::string, literal*> const & parameters,
+ static bool get_param (literal_map_t const & parameters,
const std::string& key, std::string& value);
- static bool get_param (std::map<std::string, literal*> const & parameters,
+ static bool get_param (literal_map_t const & parameters,
const std::string& key, int64_t& value);
};
diff --git a/main.cxx b/main.cxx
index 81935207..23ab3b2f 100644
--- a/main.cxx
+++ b/main.cxx
@@ -26,6 +26,7 @@
#include <sstream>
#include <cerrno>
#include <cstdlib>
+#include <limits.h>
extern "C" {
#include <glob.h>
@@ -513,7 +514,6 @@ main (int argc, char * const argv [])
}
}
- cerr << "Warning: using '-m' disables cache support." << endl;
s.use_cache = false;
break;
@@ -677,6 +677,16 @@ main (int argc, char * const argv [])
usage(s, 1);
}
+ // translate path of runtime to absolute path
+ if (s.runtime_path[0] != '/')
+ {
+ char cwd[PATH_MAX];
+ if (getcwd(cwd, sizeof(cwd)))
+ {
+ s.runtime_path = string(cwd) + "/" + s.runtime_path;
+ }
+ }
+
int rc = 0;
// override PATH and LC_ALL
@@ -976,7 +986,10 @@ main (int argc, char * const argv [])
rc = compile_pass (s);
if (rc == 0 && s.last_pass == 4)
- cout << s.hash_path << endl;
+ {
+ cout << ((s.hash_path == "") ? (s.module_name + string(".ko")) : s.hash_path);
+ cout << endl;
+ }
times (& tms_after);
gettimeofday (&tv_after, NULL);
diff --git a/parse.cxx b/parse.cxx
index 82116009..59f3cb8a 100644
--- a/parse.cxx
+++ b/parse.cxx
@@ -150,6 +150,27 @@ parser::last ()
}
+
+template <typename OPERAND>
+bool eval_comparison (const OPERAND& lhs, const token* op, const OPERAND& rhs)
+{
+ if (op->type == tok_operator && op->content == "<=")
+ { return lhs <= rhs; }
+ else if (op->type == tok_operator && op->content == ">=")
+ { return lhs >= rhs; }
+ else if (op->type == tok_operator && op->content == "<")
+ { return lhs < rhs; }
+ else if (op->type == tok_operator && op->content == ">")
+ { return lhs > rhs; }
+ else if (op->type == tok_operator && op->content == "==")
+ { return lhs == rhs; }
+ else if (op->type == tok_operator && op->content == "!=")
+ { return lhs != rhs; }
+ else
+ throw parse_error ("expected comparison operator", op);
+}
+
+
// Here, we perform on-the-fly preprocessing.
// The basic form is %( CONDITION %? THEN-TOKENS %: ELSE-TOKENS %)
// where CONDITION is: kernel_v[r] COMPARISON-OP "version-string"
@@ -159,7 +180,7 @@ parser::last ()
// The %: ELSE-TOKENS part is optional.
//
// e.g. %( kernel_v > "2.5" %? "foo" %: "baz" %)
-// e.g. %( arch != "i686" %? "foo" %: "baz" %)
+// e.g. %( arch != "i?86" %? "foo" %: "baz" %)
//
// Up to an entire %( ... %) expression is processed by a single call
// to this function. Tokens included by any nested conditions are
@@ -241,35 +262,19 @@ bool eval_pp_conditional (systemtap_session& s,
return result;
}
- else if ((l->type == tok_string && r->type == tok_string)
- || (l->type == tok_number && r->type == tok_number))
+ else if (l->type == tok_string && r->type == tok_string)
{
- // collect acceptable strverscmp results.
- int rvc_ok1, rvc_ok2;
- if (op->type == tok_operator && op->content == "<=")
- { rvc_ok1 = -1; rvc_ok2 = 0; }
- else if (op->type == tok_operator && op->content == ">=")
- { rvc_ok1 = 1; rvc_ok2 = 0; }
- else if (op->type == tok_operator && op->content == "<")
- { rvc_ok1 = -1; rvc_ok2 = -1; }
- else if (op->type == tok_operator && op->content == ">")
- { rvc_ok1 = 1; rvc_ok2 = 1; }
- else if (op->type == tok_operator && op->content == "==")
- { rvc_ok1 = 0; rvc_ok2 = 0; }
- else if (op->type == tok_operator && op->content == "!=")
- { rvc_ok1 = -1; rvc_ok2 = 1; }
- else
- throw parse_error ("expected comparison operator", op);
-
- int rvc_result = l->content.compare(r->content);
-
- // normalize rvc_result
- if (rvc_result < 0) rvc_result = -1;
- if (rvc_result > 0) rvc_result = 1;
-
+ string lhs = l->content;
+ string rhs = r->content;
+ return eval_comparison (lhs, op, rhs);
+ // NB: no wildcarding option here
+ }
+ else if (l->type == tok_number && r->type == tok_number)
+ {
+ int64_t lhs = lex_cast<int64_t>(l->content);
+ int64_t rhs = lex_cast<int64_t>(r->content);
+ return eval_comparison (lhs, op, rhs);
// NB: no wildcarding option here
-
- return (rvc_result == rvc_ok1 || rvc_result == rvc_ok2);
}
else if (l->type == tok_string && r->type == tok_number
&& op->type == tok_operator)
@@ -277,17 +282,18 @@ bool eval_pp_conditional (systemtap_session& s,
else if (l->type == tok_number && r->type == tok_string
&& op->type == tok_operator)
throw parse_error ("expected number literal as right value", r);
+
// XXX: support other forms? "CONFIG_SMP" ?
+
else
throw parse_error ("expected 'arch' or 'kernel_v' or 'kernel_vr'\n"
" or comparison between strings or integers", l);
}
-// expand_args is used to know if we must expand $x and @x identifiers.
// Only tokens corresponding to the TRUE statement must be expanded
const token*
-parser::scan_pp (bool wildcard, bool expand_args)
+parser::scan_pp (bool wildcard)
{
while (true)
{
@@ -298,7 +304,7 @@ parser::scan_pp (bool wildcard, bool expand_args)
return t;
}
- const token* t = input.scan (wildcard, expand_args); // NB: not recursive!
+ const token* t = input.scan (wildcard); // NB: not recursive!
if (t == 0) // EOF
return t;
@@ -308,77 +314,108 @@ parser::scan_pp (bool wildcard, bool expand_args)
// We have a %( - it's time to throw a preprocessing party!
const token *l, *op, *r;
- l = input.scan (false, expand_args); // NB: not recursive, though perhaps could be
- op = input.scan (false, expand_args);
- r = input.scan (false, expand_args);
+ l = input.scan (false); // NB: not recursive, though perhaps could be
+ op = input.scan (false);
+ r = input.scan (false);
if (l == 0 || op == 0 || r == 0)
throw parse_error ("incomplete condition after '%('", t);
// NB: consider generalizing to consume all tokens until %?, and
// passing that as a vector to an evaluator.
// Do not evaluate the condition if we haven't expanded everything.
- // This may occured when having several recursive conditionals.
- bool result = expand_args && eval_pp_conditional (session, l, op, r);
+ // This may occur when having several recursive conditionals.
+ bool result = eval_pp_conditional (session, l, op, r);
delete l;
delete op;
delete r;
-
+
+ /*
+ clog << "PP eval (" << *t << ") == " << result << endl;
+ */
+
const token *m = input.scan (); // NB: not recursive
if (! (m && m->type == tok_operator && m->content == "%?"))
throw parse_error ("expected '%?' marker for conditional", t);
delete m; // "%?"
vector<const token*> my_enqueued_pp;
- bool have_token = false;
-
+
+ int nesting = 0;
while (true) // consume THEN tokens
{
- m = scan_pp (wildcard, result); // NB: recursive
- if (m == 0)
- throw parse_error (have_token ?
- "incomplete conditional - missing %: or %)" :
- "missing THEN tokens for conditional",
- t);
-
- have_token = true;
- if (m->type == tok_operator && (m->content == "%:" || // ELSE
- m->content == "%)")) // END
+ try
+ {
+ m = result ? scan_pp (wildcard) : input.scan (wildcard);
+ }
+ catch (const parse_error &e)
+ {
+ if (result) throw e; // propagate errors if THEN branch taken
+ continue;
+ }
+
+ if (m && m->type == tok_operator && m->content == "%(") // nested %(
+ nesting ++;
+ if (nesting == 0 && m && (m->type == tok_operator && (m->content == "%:" || // ELSE
+ m->content == "%)"))) // END
break;
- // enqueue token
- if (result)
+ if (nesting && m && m->type == tok_operator && m->content == "%)") // nested %)
+ nesting --;
+
+ if (!m)
+ throw parse_error ("incomplete conditional - missing '%:' or '%)'", t);
+ if (result)
my_enqueued_pp.push_back (m);
- else
- delete m; // unused token
- // continue
+ if (!result)
+ delete m; // do nothing, just dispose of unkept THEN token
+
+ continue;
}
- have_token = false;
if (m && m->type == tok_operator && m->content == "%:") // ELSE
{
delete m; // "%:"
+ int nesting = 0;
while (true)
{
- m = scan_pp (wildcard, expand_args && !result); // NB: recursive
- if (m == 0)
- throw parse_error (have_token ?
- "incomplete conditional - missing %)" :
- "missing ELSE tokens for conditional",
- t);
-
- have_token = true;
- if (m->type == tok_operator && m->content == "%)") // END
+ try
+ {
+ m = result ? input.scan (wildcard) : scan_pp (wildcard);
+ }
+ catch (const parse_error& e)
+ {
+ if (!result) throw e; // propagate errors if ELSE branch taken
+ continue;
+ }
+
+ if (m && m->type == tok_operator && m->content == "%(") // nested %(
+ nesting ++;
+ if (nesting == 0 && m && m->type == tok_operator && m->content == "%)") // END
break;
- // enqueue token
- if (! result)
- my_enqueued_pp.push_back (m);
- else
- delete m; // unused token
- // continue
+ if (nesting && m && m->type == tok_operator && m->content == "%)") // nested %)
+ nesting --;
+
+ if (!m)
+ throw parse_error ("incomplete conditional - missing %)", t);
+ if (!result)
+ my_enqueued_pp.push_back (m);
+ if (result)
+ delete m; // do nothing, just dispose of unkept ELSE token
+
+ continue;
}
}
+
+ /*
+ clog << "PP eval (" << *t << ") == " << result << " tokens: " << endl;
+ for (unsigned k=0; k<my_enqueued_pp.size(); k++)
+ clog << * my_enqueued_pp[k] << endl;
+ clog << endl;
+ */
+
delete t; // "%("
delete m; // "%)"
+
// NB: we transcribe the retained tokens here, and not inside
// the THEN/ELSE while loops. If it were done there, each loop
// would become infinite (each iteration consuming an ordinary
@@ -598,7 +635,7 @@ lexer::input_put (const string& chars)
token*
-lexer::scan (bool wildcard, bool expand_args)
+lexer::scan (bool wildcard)
{
token* n = new token;
n->location.file = input_name;
@@ -633,8 +670,7 @@ lexer::scan (bool wildcard, bool expand_args)
// characters; @1..@999 are quoted/escaped as strings.
// $# and @# expand to the number of arguments, similarly
// raw or quoted.
- if (expand_args &&
- (c == '$' || c == '@') &&
+ if ((c == '$' || c == '@') &&
(c2 == '#'))
{
input_get(); // swallow '#'
@@ -645,8 +681,7 @@ lexer::scan (bool wildcard, bool expand_args)
semiskipped_p ++;
goto semiskip;
}
- else if (expand_args &&
- (c == '$' || c == '@') &&
+ else if ((c == '$' || c == '@') &&
(isdigit (c2)))
{
unsigned idx = 0;
@@ -660,7 +695,8 @@ lexer::scan (bool wildcard, bool expand_args)
idx <= session.args.size()); // prevent overflow
if (idx == 0 ||
idx-1 >= session.args.size())
- throw parse_error ("command line argument index invalid or out of range", n);
+ throw parse_error ("command line argument index " + lex_cast<string>(idx)
+ + " out of range [1-" + lex_cast<string>(session.args.size()) + "]", n);
string arg = session.args[idx-1];
if (c == '$') input_put (arg);
diff --git a/parse.h b/parse.h
index 557fa4c5..ae1ac67f 100644
--- a/parse.h
+++ b/parse.h
@@ -69,7 +69,7 @@ struct systemtap_session;
class lexer
{
public:
- token* scan (bool wildcard=false, bool expand_args=true);
+ token* scan (bool wildcard=false);
lexer (std::istream&, const std::string&, systemtap_session&);
private:
@@ -132,7 +132,7 @@ private:
// preprocessing subordinate
std::vector<const token*> enqueued_pp;
- const token* scan_pp (bool wildcard=false, bool expand_args=true);
+ const token* scan_pp (bool wildcard=false);
// scanning state
const token* last ();
diff --git a/runtime/ChangeLog b/runtime/ChangeLog
index bdf6e56d..fb92dccc 100644
--- a/runtime/ChangeLog
+++ b/runtime/ChangeLog
@@ -1,3 +1,117 @@
+2008-06-23 David Smith <dsmith@redhat.com>
+
+ * task_finder.c (__stp_utrace_task_finder_report_exec): Handles
+ relative exec paths correctly.
+
+ * task_finder_vma.c (__stp_tf_vma_hash): Improved determination of
+ whether this is a 64-bit platform.
+ * syscall.h: Handles kernels with older style register
+ definitions.
+
+ * task_finder.c (__stp_tf_vm_cb): New function.
+ (stap_register_task_finder_target): Sets up syscall entry and
+ syscall exit handlers.
+ (__stp_find_file_based_vma): New function.
+ (__stp_utrace_task_finder_target_syscall_entry): New function.
+ Saves vma information off at syscall entry.
+ (__stp_target_call_vm_callback): New function.
+ (__stp_utrace_task_finder_target_syscall_exit): New function.
+ Handles changes to memory maps based on information saved at
+ syscall entry.
+ * syscall.h: New file containing syscall function.
+ * task_finder_vma.c: New file containing saved vma information
+ handling functions.
+
+ * regs.h: Removed trailing semicolons from macro definitions.
+
+2008-06-17 David Smith <dsmith@redhat.com>
+
+ * task_finder.c (__stp_utrace_attach_match_filename): Uses new
+ __STP_ATTACHED_TASK_EVENTS macro to determine which events to set
+ on a newly found process based on whether the
+ stap_task_finder_target structure has a vm_callback defined.
+ (stap_start_task_finder): Ditto.
+
+2008-06-16 David Smith <dsmith@redhat.com>
+
+ * task_finder.c (stap_start_task_finder): Improved callback
+ handling.
+
+2008-06-10 David Smith <dsmith@redhat.com>
+
+ * task_finder.c (struct stap_task_finder_target): Added
+ vm_callback public field.
+ (stap_register_task_finder_target): Sets up .report_quiesce
+ handler.
+ (__stp_utrace_task_finder_target_quiesce): New function.
+
+2008-06-09 David Smith <dsmith@redhat.com>
+
+ * task_finder.c (__stp_utrace_task_finder_report_exec): Handles
+ 2.6.25 kernels.
+
+2008-06-06 David Smith <dsmith@redhat.com>
+
+ * task_finder.c: Added some debug logic. Use
+ '-DDEBUG_TASK_FINDER' to enable.
+ (stap_utrace_attach): Renamed from '__stp_utrace_attach'.
+ (__stp_utrace_attach_match_filename): Calls callback with
+ notification that this is a process or thread event.
+ (__stp_utrace_attach_match_tsk): Ditto.
+ (__stp_utrace_task_finder_report_clone): Ditto.
+ (__stp_utrace_task_finder_report_exec): Ditto.
+ (stap_utrace_task_finder_report_death): Ditto.
+ (stap_start_task_finder): Ditto.
+ (stap_stop_task_finder): Added debug logic.
+
+2008-05-29 Stan Cox <scox@redhat.com>
+
+ * map.c (print_keytype): Remove.
+ (print_valtype): Remove.
+ (_stp_map_printn): Remove.
+ (_stp_map_print): Remove.
+ (_stp_pmap_printn): Remove.
+ * stat-common.c (_stp_stat_print_valtype): Remove.
+ * stat.c (__stp_stat_print): Remove.
+ (_stp_stat_print_cpu): Remove.
+ (_stp_stat_print): Remove.
+ * Makefile: Delete.
+ * tests: Delete.
+ * probes: Delete.
+
+2008-05-28 David Smith <dsmith@redhat.com>
+
+ * task_finder.c (__stp_utrace_attach_match_filename): Added
+ register_p parameter, which is passed on to the callback. Only
+ adds death notification if register_p is 1. If register_p is 0,
+ removes death notification.
+ (__stp_utrace_attach_match_tsk): Moved code from
+ __stp_utrace_task_finder_report_clone that handles the details of
+ grabbing a task's path.
+ (__stp_utrace_task_finder_report_clone): Calls new
+ __stp_utrace_attach_match_tsk().
+ (__stp_utrace_task_finder_report_exec): Notifies upper layer that
+ it might need to detach from newly exec'ed process.`
+
+2008-05-27 Josh Stone <joshua.i.stone@intel.com>
+
+ PR 6432
+ * loc2c-runtime.h (kread, kwrite, deref, store_deref): Add
+ architecture-neutral implementations, using probe_kernel_*
+ facilites (controlled by autoconf).
+ * autoconf-probe-kernel.c: test for above.
+
+2008-05-21 David Smith <dsmith@redhat.com>
+
+ * task_finder.c (__stp_utrace_attach_match_filename): Added
+ event_flag parameter of event to pass to callback.
+ (__stp_utrace_task_finder_target_death): Ditto.
+ (__stp_utrace_task_finder_report_clone): Calls
+ __stp_utrace_attach_match_filename() with new argument.
+ (__stp_utrace_task_finder_report_exec): Ditto.
+ (stap_start_task_finder): Calls callback with an invalid
+ event_flag since this callback call isn't related to an event.
+
2008-05-16 David Smith <dsmith@redhat.com>
PR 6499.
diff --git a/runtime/Makefile b/runtime/Makefile
deleted file mode 100644
index 22d25ff9..00000000
--- a/runtime/Makefile
+++ /dev/null
@@ -1,15 +0,0 @@
-#
-# Makefile for SystemTap runtime and example probes
-#
-
-all:
- make -w -C stpd
- cd probes; ./build
-
-relayfs:
- make -w -C relayfs
-
-clean:
- make -w -C relayfs clean
- make -w -C stpd clean
- cd probes; ./build clean
diff --git a/runtime/autoconf-probe-kernel.c b/runtime/autoconf-probe-kernel.c
new file mode 100644
index 00000000..93fbaae6
--- /dev/null
+++ b/runtime/autoconf-probe-kernel.c
@@ -0,0 +1,7 @@
+#include <linux/uaccess.h>
+
+void probe_kernel(void *dst, void *src, size_t size)
+{
+ (void)probe_kernel_read(dst, src, size);
+ (void)probe_kernel_write(dst, src, size);
+}
diff --git a/runtime/loc2c-runtime.h b/runtime/loc2c-runtime.h
index 66fd1e43..a7472691 100644
--- a/runtime/loc2c-runtime.h
+++ b/runtime/loc2c-runtime.h
@@ -9,6 +9,7 @@
* later version.
*/
+#include <linux/uaccess.h>
#include <linux/types.h>
#define intptr_t long
#define uintptr_t unsigned long
@@ -31,9 +32,6 @@
<< (sizeof (base) * 8 - (higherbits) - (nbits))))
-/* These operations are target-specific. */
-#include <asm/uaccess.h>
-
/* Given a DWARF register number, fetch its intptr_t (long) value from the
probe context, or store a new value into the probe context.
@@ -173,6 +171,61 @@
#endif
+
+/* NB: this autoconf is always disabled, pending further performance eval. */
+#if defined STAPCONF_PROBE_KERNEL
+
+/* Kernel 2.6.26 adds probe_kernel_{read,write}, which lets us write
+ * architecture-neutral implementations of kread, kwrite, deref, and
+ * store_deref.
+ *
+ * NB: deref and store_deref shouldn't be used with 64-bit values on 32-bit
+ * platforms, because they will lose data in the conversion to intptr_t. We
+ * generally want to encourage using kread and kwrite instead.
+ */
+
+#define kread(ptr) ({ \
+ typeof(*(ptr)) _v; \
+ if (probe_kernel_read((void *)&_v, (void *)(ptr), sizeof(*(ptr)))) \
+ DEREF_FAULT(ptr); \
+ _v; \
+ })
+
+#define kwrite(ptr, value) ({ \
+ typeof(*(ptr)) _v; \
+ _v = (typeof(*(ptr)))(value); \
+ if (probe_kernel_write((void *)(ptr), (void *)&_v, sizeof(*(ptr)))) \
+ STORE_DEREF_FAULT(ptr); \
+ })
+
+#define deref(size, addr) ({ \
+ intptr_t _i; \
+ switch (size) { \
+ case 1: _i = kread((u8 *)(addr)); break; \
+ case 2: _i = kread((u16 *)(addr)); break; \
+ case 4: _i = kread((u32 *)(addr)); break; \
+ case 8: _i = kread((u64 *)(addr)); break; \
+ default: __deref_bad(); \
+ /* uninitialized _i should also be caught by -Werror */ \
+ } \
+ _i; \
+ })
+
+#define store_deref(size, addr, value) ({ \
+ switch (size) { \
+ case 1: kwrite((u8 *)(addr), (value)); break; \
+ case 2: kwrite((u16 *)(addr), (value)); break; \
+ case 4: kwrite((u32 *)(addr), (value)); break; \
+ case 8: kwrite((u64 *)(addr), (value)); break; \
+ default: __store_deref_bad(); \
+ } \
+ })
+
+extern void __deref_bad(void);
+extern void __store_deref_bad(void);
+
+#else /* !STAPCONF_PROBE_KERNEL */
+
#if defined __i386__
#define deref(size, addr) \
@@ -614,38 +667,6 @@
#endif /* (s390) || (s390x) */
-#define deref_string(dst, addr, maxbytes) \
- ({ \
- uintptr_t _addr; \
- size_t _len; \
- unsigned char _c; \
- char *_d = (dst); \
- for (_len = (maxbytes), _addr = (uintptr_t)(addr); \
- _len > 1 && (_c = deref (1, _addr)) != '\0'; \
- --_len, ++_addr) \
- if (_d) \
- *_d++ = _c; \
- if (_d) \
- *_d = '\0'; \
- (dst); \
- })
-
-#define deref_buffer(dst, addr, numbytes) \
- ({ \
- uintptr_t _addr; \
- size_t _len; \
- unsigned char _c; \
- char *_d = (dst); \
- for (_len = (numbytes), _addr = (uintptr_t)(addr); \
- _len >= 1; \
- --_len, ++_addr) { \
- _c = deref (1, _addr); \
- if (_d) \
- *_d++ = _c; \
- } \
- (dst); \
- })
-
#if defined __i386__
@@ -678,6 +699,40 @@
#endif
+#endif /* STAPCONF_PROBE_KERNEL */
+
+#define deref_string(dst, addr, maxbytes) \
+ ({ \
+ uintptr_t _addr; \
+ size_t _len; \
+ unsigned char _c; \
+ char *_d = (dst); \
+ for (_len = (maxbytes), _addr = (uintptr_t)(addr); \
+ _len > 1 && (_c = deref (1, _addr)) != '\0'; \
+ --_len, ++_addr) \
+ if (_d) \
+ *_d++ = _c; \
+ if (_d) \
+ *_d = '\0'; \
+ (dst); \
+ })
+
+#define deref_buffer(dst, addr, numbytes) \
+ ({ \
+ uintptr_t _addr; \
+ size_t _len; \
+ unsigned char _c; \
+ char *_d = (dst); \
+ for (_len = (numbytes), _addr = (uintptr_t)(addr); \
+ _len >= 1; \
+ --_len, ++_addr) { \
+ _c = deref (1, _addr); \
+ if (_d) \
+ *_d++ = _c; \
+ } \
+ (dst); \
+ })
+
#define CATCH_DEREF_FAULT() \
if (0) { \
deref_fault: ; \
diff --git a/runtime/map.c b/runtime/map.c
index a436d7ed..bb221cd2 100644
--- a/runtime/map.c
+++ b/runtime/map.c
@@ -1,6 +1,6 @@
/* -*- linux-c -*-
* Map Functions
- * Copyright (C) 2005, 2006, 2007 Red Hat Inc.
+ * Copyright (C) 2005, 2006, 2007, 2008 Red Hat Inc.
*
* This file is part of systemtap, and is free software. You can
* redistribute it and/or modify it under the terms of the GNU General
@@ -631,130 +631,6 @@ void _stp_map_sortn(MAP map, int n, int keynum, int dir)
}
}
-static int print_keytype (char *fmt, int type, key_data *kd)
-{
- //dbug ("*fmt = %c\n", *fmt);
- switch (type) {
- case STRING:
- if (*fmt != 's')
- return 1;
- _stp_print (kd->strp);
- break;
- case INT64:
- if (*fmt == 'x')
- _stp_printf("%llx", kd->val);
- else if (*fmt == 'X')
- _stp_printf("%llX", kd->val);
- else if (*fmt == 'd')
- _stp_printf("%lld", kd->val);
- else if (*fmt == 'p') {
-#if BITS_PER_LONG == 64
- _stp_printf("%016llx", kd->val);
-#else
- _stp_printf("%08llx", kd->val);
-#endif
- } else if (*fmt == 'P')
- _stp_symbol_print ((unsigned long)kd->val);
- else
- return 1;
- break;
- default:
- return 1;
- break;
- }
- return 0;
-}
-
-static void print_valtype (MAP map, char *fmt, struct map_node *ptr)
-{
- switch (map->type) {
- case STRING:
- if (*fmt == 's')
- _stp_print (_stp_get_str(ptr));
- break;
- case INT64:
- {
- int64_t val = _stp_get_int64(ptr);
- if (*fmt == 'x')
- _stp_printf("%llx", val);
- else if (*fmt == 'X')
- _stp_printf("%llX", val);
- else if (*fmt == 'd')
- _stp_printf("%lld", val);
- else if (*fmt == 'p') {
-#if BITS_PER_LONG == 64
- _stp_printf("%016llx", val);
-#else
- _stp_printf("%08llx", val);
-#endif
- } else if (*fmt == 'P')
- _stp_symbol_print ((unsigned long)val);
- break;
- }
- case STAT:
- {
- stat *sd = _stp_get_stat(ptr);
- _stp_stat_print_valtype (fmt, &map->hist, sd, 0);
- break;
- }
- default:
- break;
- }
-}
-
-/** Print a Map.
- * Print a Map using a format string.
- *
- * @param map Map
- * @param fmt @ref format_string
- */
-void _stp_map_printn (MAP map, int n, const char *fmt)
-{
- struct map_node *ptr;
- int type, num;
- key_data kd;
-
- if (n < 0)
- return;
-
- foreach (map, ptr) {
- char *f = (char *)fmt;
- while (*f) {
- f = next_fmt (f, &num);
- if (num) {
- /* key */
- kd = (*map->get_key)(ptr, num, &type);
- if (type != END)
- print_keytype (f, type, &kd);
- } else {
- /* value */
- print_valtype (map, f, ptr);
- }
- if (*f)
- f++;
- }
- _stp_print_char ('\n');
- if (n && (--n <= 0))
- break;
- }
- _stp_print_char ('\n');
- _stp_print_flush();
-}
-
-/** Print a Map.
- * Print a Map using a format string.
- *
- * @param map Map
- * @param fmt @ref format_string
- */
-#define _stp_map_print(map,fmt) _stp_map_printn(map,0,fmt)
-
-void _stp_pmap_printn_cpu (PMAP pmap, int n, const char *fmt, int cpu)
-{
- MAP m = per_cpu_ptr (pmap->map, cpu);
- _stp_map_printn (m, n, fmt);
-}
-
static struct map_node *_stp_new_agg(MAP agg, struct hlist_head *ahead, struct map_node *ptr)
{
struct map_node *aptr;
@@ -911,8 +787,8 @@ MAP _stp_pmap_agg (PMAP pmap)
*/
#define _stp_pmap_get_agg(pmap) (&pmap->agg)
-#define _stp_pmap_printn(map,n,fmt) _stp_map_printn (_stp_pmap_agg(map), n, fmt)
-#define _stp_pmap_print(map,fmt) _stp_map_printn(_stp_pmap_agg(map),0,fmt)
+/* #define _stp_pmap_printn(map,n,fmt) _stp_map_printn (_stp_pmap_agg(map), n, fmt) */
+/* #define _stp_pmap_print(map,fmt) _stp_map_printn(_stp_pmap_agg(map),0,fmt) */
static void _new_map_clear_node (struct map_node *m)
{
diff --git a/runtime/probes/ChangeLog b/runtime/probes/ChangeLog
deleted file mode 100644
index 47976f5c..00000000
--- a/runtime/probes/ChangeLog
+++ /dev/null
@@ -1,113 +0,0 @@
-2006-09-26 David Smith <dsmith@redhat.com>
-
- * bench/run_bench: Changed 'stpd' references to 'staprun'.
- * bench/trans_bench: Ditto.
- * where_func/README: Ditto.
-
-2005-11-08 Martin Hunt <hunt@redhat.com>
-
- * shellsnoop/shellsnoop.c: Updated to use new map API.
- * where_func/kprobe_where_funct.c: Ditto.
- * os_timer/os_timer.c (probe_start): Ditto.
- * test4/test4.c: Ditto.
- * scf/scf.c: Ditto.
-
-2005-09-08 Martin Hunt <hunt@redhat.com>
-
- * scf/scf.c (inst_smp_call_function): Add new verbose arg
- to _stp_stack_sprint() call.
-
-2005-08-31 Martin Hunt <hunt@redhat.com>
-
- * Makefile.template: Remove KTA, KALLSYMS_LOOKUP,
- and KALLSYMS_LOOKUP_NAME
-
-2005-08-19 Martin Hunt <hunt@redhat.com>
-
- * shellsnoop/shellsnoop.c: Remove STP_NETLINK_ONLY.
- * stp: Deleted. Use stpd directly.
-
-
-2005-08-01 Martin Hunt <hunt@redhat.com>
-
- * agg/stat1.c (probe_exit): Remove "static"
- * agg/count1.c (probe_exit): Ditto.
- * agg/count2.c (probe_exit): Ditto.
- * bench/bench_io2.c (probe_exit): Ditto.
- * bench/bench_io1.c (probe_exit): Ditto.
- * bench/bench.c (probe_exit): Ditto.
- * bench/bench_ret.c (probe_exit): Ditto.
- * bench/bench_multi.c (probe_exit): Ditto.
- * where_func/kprobe_where_funct.c (probe_exit): Ditto.
- * test4/test4.c (probe_exit): Ditto.
- * tasklet/stp_tasklet.c (probe_exit): Ditto.
- * os_timer/os_timer.c (probe_exit): Ditto.
- * scf/scf.c (probe_exit): Ditto.
-
-2005-07-28 Martin Hunt <hunt@redhat.com>
-
- * bench/ALL: Chnage to probe sys_getuid() and sys_getgid()
- because those aren't used by stpd, unlike sys_read() and sys_write().
-
-2005-07-11 Martin Hunt <hunt@redhat.com>
-
- * build_probe: Set RELAYFS correctly.
-
- * Makefile.template: Fix for RELAYFS.
-
- * stp: Moved here. All probes now use this copy.
-
- * ALL/stp: source the master copy of stp.
-
-2005-07-08 Martin Hunt <hunt@redhat.com>
-
- * ALL: Use new runtime.h. Change init_module()
- to probe_start() and don't do transport calls.
- Remove MODULE_LICENSE and cleanup_module().
-
-2005-07-01 Martin Hunt <hunt@redhat.com>
-
- * Makefile.template (debug): New target.
-
- * build: Support "debug" target.
-
- * build_probe: Ditto.
-
-2005-06-28 Martin Hunt <hunt@redhat.com>
-
- * bench/bench_ret.c (inst_sys_write_ret): Fix prototype.
-
- * bench: New probe to do benchmarks.
-
-2005-06-23 Martin Hunt <hunt@redhat.com>
-
- * all probes: Modified to use latest changes to transport.h.
-
-2005-06-21 Martin Hunt <hunt@redhat.com>
-
- * build_probe (build): Add relay_flush and relay_switch_subbuf to the
- list of undefines to ignore.
-
-2005-06-20 Tom Zanussi <zanussi@us.ibm.com>
-
- * added transport_mode, subbuf_size, n_subbufs to all
- probes and changed _stp_transport_open() calls.
-
- * removed all obsolete params from stp scripts.
-
-2005-06-18 Martin Hunt <hunt@redhat.com>
-
- * build: Modified to use build_probe.
-
- * build_probe: New file. This does the work of building
- a single probe or set of probes in a directory.
-
- * Makefile.template: New file. Template used by
- build_probe to create Makefiles.
-
- * agg: New set of probes to test/demonstrate
- Counter and Stat aggregations.
-
- * all probes modified for latest changes and new build
- process.
-
diff --git a/runtime/probes/Makefile.template b/runtime/probes/Makefile.template
deleted file mode 100644
index 5d770e95..00000000
--- a/runtime/probes/Makefile.template
+++ /dev/null
@@ -1,21 +0,0 @@
-# Makefile
-PWD := $(shell pwd)
-RT := $(PWD)/../..
-KVERSION := $(shell uname -r)
-KDIR := /lib/modules/$(KVERSION)/build include
-
-FLAGS := -I $(RT) RELAYFS
-
-DFLAGS := $(FLAGS) -D DEBUG
-
-obj-m := XXX.o
-
-default:
- $(MAKE) V=1 -C $(KDIR) M=$(PWD) RT=$(RT) EXTRA_CFLAGS="$(FLAGS)" modules
-
-debug:
- $(MAKE) V=1 -C $(KDIR) M=$(PWD) RT=$(RT) EXTRA_CFLAGS="$(DFLAGS)" modules
-
-
-clean:
- /bin/rm -rf *.o *.o.d *.ko *~ *.mod.c .*.cmd .tmp_versions
diff --git a/runtime/probes/README b/runtime/probes/README
deleted file mode 100644
index f3cd9fb2..00000000
--- a/runtime/probes/README
+++ /dev/null
@@ -1,10 +0,0 @@
-/** @dir probes
-This directory contains working example probes that demonstrate and test
-the runtime library. They are tested on i386 and x86_64.
-*/
-
-To build all probes, just type "./build"
-To clean up, "./build clean"
-To see a verbose build "./build -v"
-
-The same commands work in any probe subdirectory.
diff --git a/runtime/probes/agg/README b/runtime/probes/agg/README
deleted file mode 100644
index b48db1b8..00000000
--- a/runtime/probes/agg/README
+++ /dev/null
@@ -1,3 +0,0 @@
-/** @dir agg
-Test probes to use the Counter and Stat aggregations.
-*/
diff --git a/runtime/probes/agg/build b/runtime/probes/agg/build
deleted file mode 100755
index f3e83244..00000000
--- a/runtime/probes/agg/build
+++ /dev/null
@@ -1,2 +0,0 @@
-#!/bin/bash
-../build_probe $*
diff --git a/runtime/probes/agg/count1.c b/runtime/probes/agg/count1.c
deleted file mode 100644
index 731b236b..00000000
--- a/runtime/probes/agg/count1.c
+++ /dev/null
@@ -1,102 +0,0 @@
-#define STP_NETLINK_ONLY
-#define STP_NUM_STRINGS 1
-
-#include "runtime.h"
-
-#include "counter.c"
-#include "probes.c"
-
-MODULE_DESCRIPTION("SystemTap probe: count1");
-MODULE_AUTHOR("Martin Hunt <hunt@redhat.com>");
-
-Counter opens;
-Counter reads;
-Counter writes;
-Counter sched;
-Counter idle;
-
-static int inst_sys_open (struct kprobe *p, struct pt_regs *regs)
-{
- _stp_counter_add (opens, 1);
- return 0;
-}
-
-static int inst_sys_read (struct kprobe *p, struct pt_regs *regs)
-{
- _stp_counter_add (reads, 1);
- return 0;
-}
-
-static int inst_sys_write (struct kprobe *p, struct pt_regs *regs)
-{
- _stp_counter_add (writes, 1);
- return 0;
-}
-
-static int inst_schedule(struct kprobe *p, struct pt_regs *regs)
-{
- _stp_counter_add (sched, 1);
- return 0;
-}
-
-static int inst_idle_cpu(struct kprobe *p, struct pt_regs *regs)
-{
- _stp_counter_add (idle, 1);
- return 0;
-}
-
-static struct kprobe stp_probes[] = {
- {
- .addr = "sys_open",
- .pre_handler = inst_sys_open
- },
- {
- .addr = "sys_read",
- .pre_handler = inst_sys_read
- },
- {
- .addr = "sys_write",
- .pre_handler = inst_sys_write
- },
- {
- .addr = "schedule",
- .pre_handler = inst_schedule
- },
- {
- .addr = "idle_cpu",
- .pre_handler = inst_idle_cpu
- },
-};
-
-#define MAX_STP_ROUTINE (sizeof(stp_probes)/sizeof(struct kprobe))
-
-int probe_start(void)
-{
- opens = _stp_counter_init();
- reads = _stp_counter_init();
- writes = _stp_counter_init();
- sched = _stp_counter_init();
- idle = _stp_counter_init();
-
- return _stp_register_kprobes (stp_probes, MAX_STP_ROUTINE);
-}
-
-void probe_exit (void)
-{
- int i;
-
- _stp_unregister_kprobes (stp_probes, MAX_STP_ROUTINE);
-
- for_each_cpu(i)
- _stp_printf ("sched calls for cpu %d = %lld\n", i, _stp_counter_get_cpu(sched, i, 0));
-
- _stp_print ("\n\n");
-
- _stp_printf ("open calls: %lld\n", _stp_counter_get(opens, 0));
- _stp_printf ("read calls: %lld\n", _stp_counter_get(reads, 0));
- _stp_printf ("write calls: %lld\n", _stp_counter_get(writes, 0));
- _stp_printf ("sched calls: %lld\n", _stp_counter_get(sched, 0));
- _stp_printf ("idle calls: %lld\n", _stp_counter_get(idle, 0));
- _stp_print_flush();
-}
-
diff --git a/runtime/probes/agg/count2.c b/runtime/probes/agg/count2.c
deleted file mode 100644
index 23987759..00000000
--- a/runtime/probes/agg/count2.c
+++ /dev/null
@@ -1,81 +0,0 @@
-#define STP_NETLINK_ONLY
-#define STP_NUM_STRINGS 1
-#include "runtime.h"
-
-#include "counter.c"
-#include "probes.c"
-
-MODULE_DESCRIPTION("SystemTap probe: count2");
-MODULE_AUTHOR("Martin Hunt <hunt@redhat.com>");
-
-Counter opens;
-Counter reads;
-Counter writes;
-Counter read_bytes;
-Counter write_bytes;
-
-asmlinkage long inst_sys_open (const char __user * filename, int flags, int mode)
-{
- _stp_counter_add (opens, 1);
- jprobe_return();
- return 0;
-}
-
-asmlinkage ssize_t inst_sys_read (unsigned int fd, char __user * buf, size_t count)
-{
- _stp_counter_add (reads, 1);
- _stp_counter_add (read_bytes, count);
- jprobe_return();
- return 0;
-}
-
-asmlinkage ssize_t inst_sys_write (unsigned int fd, const char __user * buf, size_t count)
-{
- _stp_counter_add (writes, 1);
- _stp_counter_add (write_bytes, count);
- jprobe_return();
- return 0;
-}
-
-static struct jprobe stp_probes[] = {
- {
- .kp.addr = (kprobe_opcode_t *)"sys_open",
- .entry = (kprobe_opcode_t *) inst_sys_open
- },
- {
- .kp.addr = (kprobe_opcode_t *)"sys_read",
- .entry = (kprobe_opcode_t *) inst_sys_read
- },
- {
- .kp.addr = (kprobe_opcode_t *)"sys_write",
- .entry = (kprobe_opcode_t *) inst_sys_write
- },
-};
-
-#define MAX_STP_ROUTINE (sizeof(stp_probes)/sizeof(struct jprobe))
-
-int probe_start(void)
-{
- opens = _stp_counter_init();
- reads = _stp_counter_init();
- writes = _stp_counter_init();
- read_bytes = _stp_counter_init();
- write_bytes = _stp_counter_init();
-
- return _stp_register_jprobes (stp_probes, MAX_STP_ROUTINE);
-}
-
-void probe_exit (void)
-{
- int i;
-
- _stp_unregister_jprobes (stp_probes, MAX_STP_ROUTINE);
-
- _stp_printf ("open calls: %lld\n", _stp_counter_get(opens, 0));
- _stp_printf ("read calls: %lld\n", _stp_counter_get(reads, 0));
- _stp_printf ("read bytes: %lld\n", _stp_counter_get(read_bytes, 0));
- _stp_printf ("write calls: %lld\n", _stp_counter_get(writes, 0));
- _stp_printf ("write bytes: %lld\n", _stp_counter_get(write_bytes, 0));
-
- _stp_print_flush();
-}
diff --git a/runtime/probes/agg/stat1.c b/runtime/probes/agg/stat1.c
deleted file mode 100644
index 4e0cf961..00000000
--- a/runtime/probes/agg/stat1.c
+++ /dev/null
@@ -1,72 +0,0 @@
-#define STP_NETLINK_ONLY
-#define STP_NUM_STRINGS 1
-#include "runtime.h"
-#include "stat.c"
-#include "counter.c"
-#include "probes.c"
-
-MODULE_DESCRIPTION("SystemTap probe: stat1");
-MODULE_AUTHOR("Martin Hunt <hunt@redhat.com>");
-
-
-Counter opens;
-Stat reads;
-Stat writes;
-
-asmlinkage long inst_sys_open (const char __user * filename, int flags, int mode)
-{
- _stp_counter_add (opens, 1);
- jprobe_return();
- return 0;
-}
-
-asmlinkage ssize_t inst_sys_read (unsigned int fd, char __user * buf, size_t count)
-{
- _stp_stat_add (reads, count);
- jprobe_return();
- return 0;
-}
-
-asmlinkage ssize_t inst_sys_write (unsigned int fd, const char __user * buf, size_t count)
-{
- _stp_stat_add (writes, count);
- jprobe_return();
- return 0;
-}
-
-static struct jprobe stp_probes[] = {
- {
- .kp.addr = (kprobe_opcode_t *)"sys_open",
- .entry = (kprobe_opcode_t *) inst_sys_open
- },
- {
- .kp.addr = (kprobe_opcode_t *)"sys_read",
- .entry = (kprobe_opcode_t *) inst_sys_read
- },
- {
- .kp.addr = (kprobe_opcode_t *)"sys_write",
- .entry = (kprobe_opcode_t *) inst_sys_write
- },
-};
-
-#define MAX_STP_ROUTINE (sizeof(stp_probes)/sizeof(struct jprobe))
-
-int probe_start(void)
-{
- opens = _stp_counter_init();
- reads = _stp_stat_init(HIST_LOG,24);
- writes = _stp_stat_init(HIST_LINEAR,0,1000,50);
-
- return _stp_register_jprobes (stp_probes, MAX_STP_ROUTINE);
-}
-
-void probe_exit (void)
-{
- _stp_unregister_jprobes (stp_probes, MAX_STP_ROUTINE);
-
- _stp_printf ("OPENS: %lld\n", _stp_counter_get(opens, 0));
- _stp_stat_print (reads, "READS: count:%C sum:%S avg:%A min:%m max:%M\n%H", 0);
- _stp_stat_print (writes, "WRITES: count:%C sum:%S avg:%A min:%m max:%M\n%H", 0);
-
- _stp_print_flush();
-}
diff --git a/runtime/probes/agg/targets b/runtime/probes/agg/targets
deleted file mode 100644
index 614a00d2..00000000
--- a/runtime/probes/agg/targets
+++ /dev/null
@@ -1,3 +0,0 @@
-count1
-count2
-stat1
diff --git a/runtime/probes/bench/Makefile b/runtime/probes/bench/Makefile
deleted file mode 100644
index 9154e3dc..00000000
--- a/runtime/probes/bench/Makefile
+++ /dev/null
@@ -1,10 +0,0 @@
-all: ttest itest
-
-ttest: ttest.c
- gcc -Wall -O3 -o ttest ttest.c
-
-itest: itest.c
- gcc -Wall -O3 -o itest itest.c
-
-clean:
- /bin/rm -f itest ttest stpd_cpu* xxx*
diff --git a/runtime/probes/bench/README b/runtime/probes/bench/README
deleted file mode 100644
index 04801a74..00000000
--- a/runtime/probes/bench/README
+++ /dev/null
@@ -1,18 +0,0 @@
-This is a benchmark program for the SystemTap Runtime.
-
-It works by instrumenting sys_uid() and sys_gid(). It calls each a million
-times and measures how long it takes. Then it puts an empty kprobe on one and jprobe on the
-other and measures that. Subtracting the difference between the two runs gives
-the kprobe and jprobe overhead. The process is then repeated for more
-complicated probes.
-
-To Start:
-
-1. Build the test program.
-> gcc -O3 -o time time.c
-
-2. Run the benchmarks
-> ./run_bench
-
-
-
diff --git a/runtime/probes/bench/bench.c b/runtime/probes/bench/bench.c
deleted file mode 100644
index a00efa05..00000000
--- a/runtime/probes/bench/bench.c
+++ /dev/null
@@ -1,51 +0,0 @@
-#define STP_NETLINK_ONLY
-#define STP_NUM_STRINGS 1
-
-#include "runtime.h"
-#include "probes.c"
-
-MODULE_DESCRIPTION("SystemTap probe: bench");
-MODULE_AUTHOR("Martin Hunt");
-
-asmlinkage ssize_t inst_sys_getgid (unsigned int fd, const char __user * buf, size_t count)
-{
- jprobe_return();
- return 0;
-}
-
-static int inst_sys_getuid (struct kprobe *p, struct pt_regs *regs)
-{
- return 0;
-}
-
-static struct jprobe jp[] = {
- {
- .kp.addr = (kprobe_opcode_t *)"sys_getgid",
- .entry = (kprobe_opcode_t *) inst_sys_getgid
- },
-};
-
-static struct kprobe kp[] = {
- {
- .addr = "sys_getuid",
- .pre_handler = inst_sys_getuid
- }
-};
-
-#define NUM_JPROBES (sizeof(jp)/sizeof(struct jprobe))
-#define NUM_KPROBES (sizeof(kp)/sizeof(struct kprobe))
-
-int probe_start(void)
-{
- int ret = _stp_register_jprobes (jp, NUM_JPROBES);
- if (ret >= 0)
- if ((ret = _stp_register_kprobes (kp, NUM_KPROBES)) < 0)
- _stp_unregister_jprobes (jp, NUM_JPROBES);
- return ret;
-}
-
-void probe_exit (void)
-{
- _stp_unregister_jprobes (jp, NUM_JPROBES);
- _stp_unregister_kprobes (kp, NUM_KPROBES);
-}
diff --git a/runtime/probes/bench/bench_io1.c b/runtime/probes/bench/bench_io1.c
deleted file mode 100644
index 8bdc4018..00000000
--- a/runtime/probes/bench/bench_io1.c
+++ /dev/null
@@ -1,46 +0,0 @@
-#define STP_NUM_STRINGS 1
-
-#include "runtime.h"
-#include "probes.c"
-
-MODULE_DESCRIPTION("SystemTap probe: bench_io1");
-MODULE_AUTHOR("Martin Hunt");
-
-static int inst_sys_getuid (struct kprobe *p, struct pt_regs *regs)
-{
- /* print 100 chars */
- _stp_printf ("123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789\n");
- _stp_print_flush();
- return 0;
-}
-
-static int inst_sys_getgid (struct kprobe *p, struct pt_regs *regs)
-{
- /* print 100 chars */
- _stp_print_cstr ("123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789\n");
- _stp_print_flush();
- return 0;
-}
-
-static struct kprobe kp[] = {
- {
- .addr = "sys_getuid",
- .pre_handler = inst_sys_getuid
- },
- {
- .addr = "sys_getgid",
- .pre_handler = inst_sys_getgid
- }
-};
-
-#define NUM_KPROBES (sizeof(kp)/sizeof(struct kprobe))
-
-int probe_start(void)
-{
- return _stp_register_kprobes (kp, NUM_KPROBES);
-}
-
-void probe_exit (void)
-{
- _stp_unregister_kprobes (kp, NUM_KPROBES);
-}
diff --git a/runtime/probes/bench/bench_io2.c b/runtime/probes/bench/bench_io2.c
deleted file mode 100644
index 14216913..00000000
--- a/runtime/probes/bench/bench_io2.c
+++ /dev/null
@@ -1,47 +0,0 @@
-#define STP_RELAYFS
-#define STP_NUM_STRINGS 1
-
-#include "runtime.h"
-#include "probes.c"
-
-MODULE_DESCRIPTION("SystemTap probe: bench_io2");
-MODULE_AUTHOR("Martin Hunt");
-
-static int inst_sys_getuid (struct kprobe *p, struct pt_regs *regs)
-{
- /* print 100 chars */
- _stp_printf ("123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789\n");
- _stp_print_flush();
- return 0;
-}
-
-static int inst_sys_getgid (struct kprobe *p, struct pt_regs *regs)
-{
- /* print 100 chars */
- _stp_print_cstr ("123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789\n");
- _stp_print_flush();
- return 0;
-}
-
-static struct kprobe kp[] = {
- {
- .addr = "sys_getuid",
- .pre_handler = inst_sys_getuid
- },
- {
- .addr = "sys_getgid",
- .pre_handler = inst_sys_getgid
- }
-};
-
-#define NUM_KPROBES (sizeof(kp)/sizeof(struct kprobe))
-
-int probe_start(void)
-{
- return _stp_register_kprobes (kp, NUM_KPROBES);
-}
-
-void probe_exit (void)
-{
- _stp_unregister_kprobes (kp, NUM_KPROBES);
-}
diff --git a/runtime/probes/bench/bench_io3.c b/runtime/probes/bench/bench_io3.c
deleted file mode 100644
index a491edd9..00000000
--- a/runtime/probes/bench/bench_io3.c
+++ /dev/null
@@ -1,44 +0,0 @@
-#define STP_NUM_STRINGS 1
-
-#include "runtime.h"
-#include "probes.c"
-
-MODULE_DESCRIPTION("SystemTap probe: bench_io3");
-MODULE_AUTHOR("Martin Hunt");
-
-static int inst_sys_getuid (struct kprobe *p, struct pt_regs *regs)
-{
- /* print 1000 chars */
- _stp_printf ("123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789\n");
- _stp_printf ("123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789\n");
- _stp_printf ("123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789\n");
- _stp_printf ("123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789\n");
- _stp_printf ("123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789\n");
- _stp_printf ("123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789\n");
- _stp_printf ("123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789\n");
- _stp_printf ("123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789\n");
- _stp_printf ("123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789\n");
- _stp_printf ("123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789\n");
- _stp_print_flush();
- return 0;
-}
-
-
-static struct kprobe kp[] = {
- {
- .addr = "sys_getuid",
- .pre_handler = inst_sys_getuid
- },
-};
-
-#define NUM_KPROBES (sizeof(kp)/sizeof(struct kprobe))
-
-int probe_start(void)
-{
- return _stp_register_kprobes (kp, NUM_KPROBES);
-}
-
-void probe_exit (void)
-{
- _stp_unregister_kprobes (kp, NUM_KPROBES);
-}
diff --git a/runtime/probes/bench/bench_io4.c b/runtime/probes/bench/bench_io4.c
deleted file mode 100644
index a6b19ab5..00000000
--- a/runtime/probes/bench/bench_io4.c
+++ /dev/null
@@ -1,45 +0,0 @@
-#define STP_RELAYFS
-#define STP_NUM_STRINGS 1
-
-#include "runtime.h"
-#include "probes.c"
-
-MODULE_DESCRIPTION("SystemTap probe: bench_io3");
-MODULE_AUTHOR("Martin Hunt");
-
-static int inst_sys_getuid (struct kprobe *p, struct pt_regs *regs)
-{
- /* print 1000 chars */
- _stp_printf ("123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789\n");
- _stp_printf ("123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789\n");
- _stp_printf ("123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789\n");
- _stp_printf ("123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789\n");
- _stp_printf ("123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789\n");
- _stp_printf ("123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789\n");
- _stp_printf ("123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789\n");
- _stp_printf ("123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789\n");
- _stp_printf ("123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789\n");
- _stp_printf ("123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789\n");
- _stp_print_flush();
- return 0;
-}
-
-
-static struct kprobe kp[] = {
- {
- .addr = "sys_getuid",
- .pre_handler = inst_sys_getuid
- },
-};
-
-#define NUM_KPROBES (sizeof(kp)/sizeof(struct kprobe))
-
-int probe_start(void)
-{
- return _stp_register_kprobes (kp, NUM_KPROBES);
-}
-
-void probe_exit (void)
-{
- _stp_unregister_kprobes (kp, NUM_KPROBES);
-}
diff --git a/runtime/probes/bench/bench_multi.c b/runtime/probes/bench/bench_multi.c
deleted file mode 100644
index a6dc38a4..00000000
--- a/runtime/probes/bench/bench_multi.c
+++ /dev/null
@@ -1,73 +0,0 @@
-#define STP_NETLINK_ONLY
-#define STP_NUM_STRINGS 1
-
-#include "runtime.h"
-#include "probes.c"
-
-MODULE_DESCRIPTION("SystemTap probe: bench_multi");
-MODULE_AUTHOR("Martin Hunt");
-
-static int inst_sys_getuid1 (struct kprobe *p, struct pt_regs *regs)
-{
- return 0;
-}
-static int inst_sys_getuid2 (struct kprobe *p, struct pt_regs *regs)
-{
- return 0;
-}
-
-static int inst_sys_getgid1 (struct kprobe *p, struct pt_regs *regs)
-{
- return 0;
-}
-static int inst_sys_getgid2 (struct kprobe *p, struct pt_regs *regs)
-{
- return 0;
-}
-static int inst_sys_getgid3 (struct kprobe *p, struct pt_regs *regs)
-{
- return 0;
-}
-static int inst_sys_getgid4 (struct kprobe *p, struct pt_regs *regs)
-{
- return 0;
-}
-
-static struct kprobe kp[] = {
- {
- .addr = "sys_getuid",
- .pre_handler = inst_sys_getuid1
- },
- {
- .addr = "sys_getuid",
- .pre_handler = inst_sys_getuid2
- },
- {
- .addr = "sys_getgid",
- .pre_handler = inst_sys_getgid1
- },
- {
- .addr = "sys_getgid",
- .pre_handler = inst_sys_getgid2
- },
- {
- .addr = "sys_getgid",
- .pre_handler = inst_sys_getgid3
- },
- {
- .addr = "sys_getgid",
- .pre_handler = inst_sys_getgid4
- }
-};
-
-#define NUM_KPROBES (sizeof(kp)/sizeof(struct kprobe))
-
-int probe_start(void)
-{
- return _stp_register_kprobes (kp, NUM_KPROBES);
-}
-
-void probe_exit (void)
-{
- _stp_unregister_kprobes (kp, NUM_KPROBES);
-}
diff --git a/runtime/probes/bench/bench_ret.c b/runtime/probes/bench/bench_ret.c
deleted file mode 100644
index 40f2ddad..00000000
--- a/runtime/probes/bench/bench_ret.c
+++ /dev/null
@@ -1,61 +0,0 @@
-#define STP_NETLINK_ONLY
-#define STP_NUM_STRINGS 1
-#define USE_RET_PROBES
-
-#include "runtime.h"
-#include "probes.c"
-
-MODULE_DESCRIPTION("SystemTap probe: bench_ret");
-MODULE_AUTHOR("Martin Hunt");
-
-static int inst_sys_getuid (struct kprobe *p, struct pt_regs *regs)
-{
- return 0;
-}
-
-static int inst_sys_getgid_ret (struct kretprobe_instance *ri, struct pt_regs *regs)
-{
- return 0;
-}
-
-static int inst_sys_getgid (struct kprobe *p, struct pt_regs *regs)
-{
- return 0;
-}
-
-static struct kretprobe kpr[] = {
- {
- .kp.addr = "sys_getuid",
- .handler = inst_sys_getuid
- },
- {
- .kp.addr = "sys_getgid",
- .handler = inst_sys_getgid_ret
- }
-};
-
-static struct kprobe kp[] = {
- {
- .addr = "sys_getgid",
- .pre_handler = inst_sys_getgid
- }
-};
-
-
-#define NUM_KPROBES (sizeof(kpr)/sizeof(struct kretprobe))
-
-int probe_start(void)
-{
- int ret = _stp_register_kretprobes (kpr, NUM_KPROBES);
- if (ret >= 0) {
- if ((ret = _stp_register_kprobes (kp, 1)) < 0)
- _stp_unregister_kretprobes (kpr, NUM_KPROBES);
- }
- return ret;
-}
-
-void probe_exit (void)
-{
- _stp_unregister_kretprobes (kpr, NUM_KPROBES);
- _stp_unregister_kprobes (kp, 1);
-}
diff --git a/runtime/probes/bench/build b/runtime/probes/bench/build
deleted file mode 100755
index f3e83244..00000000
--- a/runtime/probes/bench/build
+++ /dev/null
@@ -1,2 +0,0 @@
-#!/bin/bash
-../build_probe $*
diff --git a/runtime/probes/bench/check_modules b/runtime/probes/bench/check_modules
deleted file mode 100755
index c3ab9ac3..00000000
--- a/runtime/probes/bench/check_modules
+++ /dev/null
@@ -1,28 +0,0 @@
-#!/bin/bash
-
-RELAYFS=`grep " relayfs_poll" /boot/System.map-\`uname -r\``
-if [ -z "$RELAYFS" ]
-then
- RELAYFS=`lsmod | grep relayfs`
- if [ -z "$RELAYFS" ]
- then
- /sbin/insmod ../../relayfs/relayfs.ko
- fi
-fi
-
-if [ ! -d "/mnt/relay" ]
-then
- mkdir /mnt/relay
-fi
-
-MOUNT=`mount | grep relayfs |awk '{print $1}'`
-if [ "$MOUNT" != "relayfs" ]
-then
- mount -t relayfs relayfs /mnt/relay
-fi
-
-STP_CONTROL=`lsmod | grep stp_control |awk '{print $1}'`
-if [ "$STP_CONTROL" != "stp_control" ]
-then
- /sbin/insmod ../../transport/stp-control.ko
-fi
diff --git a/runtime/probes/bench/itest.c b/runtime/probes/bench/itest.c
deleted file mode 100644
index 8ac11b8f..00000000
--- a/runtime/probes/bench/itest.c
+++ /dev/null
@@ -1,71 +0,0 @@
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <sys/time.h>
-#include <stdlib.h>
-#include <sys/resource.h>
-#include <unistd.h>
-
-typedef unsigned long long uint64;
-struct rusage rstart;
-struct timeval tstart, tstop;
-uint64 ttime = 0;
-
-void start()
-{
- gettimeofday (&tstart, NULL);
- getrusage (RUSAGE_SELF, &rstart);
-}
-
-uint64 usecs (struct timeval *tv)
-{
- return tv->tv_sec * 1000000 + tv->tv_usec;
-}
-
-uint64 stop()
-{
- struct rusage rend;
- getrusage (RUSAGE_SELF, &rend);
- gettimeofday (&tstop, NULL);
- uint64 utime = usecs(&rend.ru_utime) - usecs(&rstart.ru_utime);
- uint64 stime = usecs(&rend.ru_stime) - usecs(&rstart.ru_stime);
- ttime = usecs(&tstop) - usecs(&tstart);
- return utime + stime;
-}
-
-void usage(char *name)
-{
- printf ("Usage %s [time]\nWhere \"time\" is millions of times to loop.\n", name);
- exit(1);
-}
-
-int main(int argc, char *argv[])
-{
- int i, n = 1;
- uint64 nsecs;
-
- if (argc > 2)
- usage(argv[0]);
-
- if (argc == 2) {
- n = strtol(argv[1], NULL, 10);
- if (n == 0)
- usage(argv[0]);
- }
-
-
- start();
- for (i = 0; i < n * 1000000; i++)
- getuid();
-
- nsecs = stop() / (n * 1000);
-
- /* returns
- nanosecs per call (user + system time)
- elapsed usecs (real time)
- */
- printf("%lld %.2f\n", nsecs, ttime/1000000.0);
-
- return 0;
-}
diff --git a/runtime/probes/bench/run_bench b/runtime/probes/bench/run_bench
deleted file mode 100755
index a9442d3b..00000000
--- a/runtime/probes/bench/run_bench
+++ /dev/null
@@ -1,136 +0,0 @@
-#!/usr/bin/tclsh
-# -*- tcl -*-
-
-proc do_time {module n} {
- global Failures
-
- # start kprobes
- if {[catch {exec ../../stpd/staprun -rmq $module.ko > xxx &} pid]} {
- puts $pid
- exit -1
- }
-
- exec sleep 2
-
- # get the timings while kprobes running
- if {[catch {exec ./ttest $n} res2]} {
- puts $res2
- exit -1
- }
-
- # terminate kprobes
- if {[catch {exec kill -s SIGINT $pid} res]} {
- puts $res
- }
-
- exec sleep 2
-
- # look for warnings
- exec tail xxx >xxx.tail
- if {[catch {open xxx.tail r} fd]} {
- puts "Cannot open test output\n"
- exit -1
- }
-
- set Failures 0
- while {[gets $fd line] >= 0} {
- if {[regexp {^\033\[33mWARNING: \033\[0mThere were ([0-9]*) transport failures.} $line match var]} {
- set Failures $var
- break
- }
- }
- close $fd
- exec /bin/rm -f xxx xxx.out
- return $res2
-}
-
-######## START HERE ###########
-
-
-set nproc [exec grep ^processor /proc/cpuinfo | wc -l]
-if {![catch {exec grep "physical id" /proc/cpuinfo} phyid]} {
- foreach phy [split $phyid \n] {
- set cpu($phy) 1
- }
-}
-set model [exec grep "model name" /proc/cpuinfo]
-set model [lindex [split $model \n] 0]
-set model [string range $model [expr [string first : $model]+1] end]
-set model [string trimleft $model]
-
-puts "STP BENCH for [exec uname -r] on [exec uname -m]"
-if {[file exists /etc/redhat-release]} {
- puts [exec cat /etc/redhat-release]
-}
-puts "[exec uname -n]: [exec uptime]"
-if {$nproc > 1} {
- puts "processors: $nproc ([array size cpu] physical) $model"
-} else {
- puts "processors: $nproc $model"
-}
-set mem [split [exec cat /proc/meminfo] \n]
-puts "[lindex $mem 0] [lindex $mem 1]"
-puts "--------------------------------------"
-
-# get the timings without kprobes
-if {[catch {exec ./ttest 4} res1]} {
- puts $res1
- exit -1
-}
-
-set r_overhead [lindex $res1 0]
-set w_overhead [lindex $res1 1]
-
-puts "function call overhead = $r_overhead ns"
-puts "--------------------------------------"
-
-set res2 [do_time bench 4]
-set t_kprobe [expr [lindex $res2 0] - $r_overhead]
-set t_jprobe [expr [lindex $res2 1] - $w_overhead]
-
-puts "Jprobes overhead = $t_jprobe ns"
-puts "Kprobes overhead = $t_kprobe ns"
-puts "--------------------------------------"
-
-if {[file exists bench_ret.ko]} {
- set res2 [do_time bench_ret 4]
- set t_ret [expr [lindex $res2 0] - $r_overhead]
- set t_entret [expr [lindex $res2 1] - $w_overhead]
-
- puts "Return probe overhead = $t_ret ns"
- puts "Entry+Return probe overhead = $t_entret ns"
- puts "--------------------------------------"
-}
-
-set res2 [do_time bench_multi 4]
-set t_k2 [expr [lindex $res2 0] - $r_overhead]
-set t_k4 [expr [lindex $res2 1] - $w_overhead]
-
-puts "2 kprobes on same func = $t_k2 ns"
-puts "4 kprobes on same func = $t_k4 ns"
-puts "--------------------------------------"
-
-set res2 [do_time bench_io1 1]
-# subtract function call overhead and kprobe overhead
-set t_printf [expr [lindex $res2 0] - $r_overhead - $t_kprobe]
-set t_print [expr [lindex $res2 1] - $w_overhead - $t_kprobe]
-
-puts "PROCFS"
-puts "_stp_printf on 100 chars = $t_printf ns."
-puts "_stp_print on 100 chars = $t_print ns."
-puts "Transport failures: $Failures"
-puts "--------------------------------------"
-exec sleep 4
-
-set res2 [do_time bench_io2 1]
-# subtract function call overhead and kprobe overhead
-set t_printf [expr [lindex $res2 0] - $r_overhead - $t_kprobe]
-set t_print [expr [lindex $res2 1] - $w_overhead - $t_kprobe]
-
-puts "RELAYFS"
-puts "_stp_printf on 100 chars = $t_printf ns."
-puts "_stp_print on 100 chars = $t_print ns."
-puts "Transport failures: $Failures"
-puts "--------------------------------------"
-
-exec /bin/rm -f stpd_cpu*
diff --git a/runtime/probes/bench/targets b/runtime/probes/bench/targets
deleted file mode 100644
index 6c89c8d7..00000000
--- a/runtime/probes/bench/targets
+++ /dev/null
@@ -1,7 +0,0 @@
-bench
-bench_io1
-bench_io2
-bench_io3
-bench_io4
-bench_ret
-bench_multi
diff --git a/runtime/probes/bench/trans_bench b/runtime/probes/bench/trans_bench
deleted file mode 100755
index 12adbaff..00000000
--- a/runtime/probes/bench/trans_bench
+++ /dev/null
@@ -1,186 +0,0 @@
-#!/usr/bin/tclsh
-# -*- tcl -*-
-
-proc do_time {module n buf} {
- global Failures Filesize
-
- # start kprobes
- if {[catch {exec ../../stpd/staprun -b $buf $module.ko > xxx &} pid]} {
- puts $pid
- exit -1
- }
-
- exec sleep 2
-
- # get the timings while kprobes running
- if {[catch {exec ./itest $n} res2]} {
- puts "itest failed: $res2"
- exit -1
- }
-
- exec sleep 4
- # terminate kprobes
- if {[catch {exec kill -s SIGINT $pid} res]} {
- puts "Kill failed: $res"
- }
-
- exec sleep 4
-
- # look for warnings
- exec tail xxx >xxx.tail
- if {[catch {open xxx.tail r} fd]} {
- puts "Cannot open test output\n"
- exit -1
- }
-
- set Failures 0
- while {[gets $fd line] >= 0} {
- if {[regexp {^\033\[33mWARNING: \033\[0mThere were ([0-9]*) transport failures.} $line match var]} {
- set Failures $var
- break
- }
- }
- close $fd
-
- set Filesize [file size xxx]
- exec /bin/rm -f xxx xxx.out
- return $res2
-}
-
-######## START HERE ###########
-
-
-set nproc [exec grep ^processor /proc/cpuinfo | wc -l]
-if {![catch {exec grep "physical id" /proc/cpuinfo} phyid]} {
- foreach phy [split $phyid \n] {
- set cpu($phy) 1
- }
-}
-set model [exec grep "model name" /proc/cpuinfo]
-set model [lindex [split $model \n] 0]
-set model [string range $model [expr [string first : $model]+1] end]
-set model [string trimleft $model]
-
-puts "TRANS BENCH for [exec uname -r] on [exec uname -m]"
-if {[file exists /etc/redhat-release]} {
- puts [exec cat /etc/redhat-release]
-}
-puts "[exec uname -n]: [exec uptime]"
-if {$nproc > 1} {
- puts "processors: $nproc ([array size cpu] physical) $model"
-} else {
- puts "processors: $nproc $model"
-}
-set mem [split [exec cat /proc/meminfo] \n]
-puts "[lindex $mem 0] [lindex $mem 1]"
-puts "--------------------------------------"
-
-# load the modules
-if {[catch {exec stp_check} res]} {
- puts $res
- exit -1
-}
-
-# warmup
-exec ./itest 20 > /dev/null
-
-set res1 [do_time bench 1 1]
-set call_overhead [lindex $res1 0]
-
-puts "Function call plus kprobe overhead = $call_overhead ns per call"
-puts "--------------------------------------"
-
-
-set max 5
-set n 1
-set buf 1
-while {$buf <= 64 && $n < $max} {
- set Failures 0
- while {!$Failures && $n < $max} {
- set res2 [do_time bench_io1 $n $buf]
- set t_printf [expr [lindex $res2 0] - $call_overhead]
- set total_print [lindex $res2 1]
- puts "PROCFS with ${buf}MB buffers"
- puts "_stp_printf on 100 chars = $t_printf ns / call system + user time."
- if {$t_printf < 0} {
- puts "res2=$res2"
- exit
- }
- puts "_stp_printf of [expr $n * 100]MB in $total_print secs real time."
- puts "Transfer rate = [format "%6.2f" [expr ($n * 100)/$total_print]] MB/sec"
- puts "Transport failures: $Failures"
- if {$Filesize != [expr $n * 100000000]} {
- puts "WARNING: file size was $Filesize (expected [expr $n * 100000000])."
- }
- puts "--------------------------------------"
- if {$Failures == 0} {incr n}
- }
- set buf [expr $buf + $buf]
-}
-
-set max 5
-set n 1
-set buf 1
-while {$buf <= 64 && $n < $max} {
- set Failures 0
- while {!$Failures && $n < $max} {
- set res2 [do_time bench_io2 $n $buf]
- set t_printf [expr [lindex $res2 0] - $call_overhead]
- set total_print [lindex $res2 1]
- puts "RELAYFS with ${buf}MB buffers"
- puts "_stp_printf on 100 chars = $t_printf ns / call system + user time."
- if {$t_printf < 0} {
- puts "res2=$res2"
- exit
- }
- puts "_stp_printf of [expr $n * 100]MB in $total_print secs real time."
- puts "Transfer rate = [format "%6.2f" [expr ($n * 100)/$total_print]] MB/sec"
- puts "Transport failures: $Failures"
- if {$Filesize != [expr $n * 100000000]} {
- puts "WARNING: file size was $Filesize (expected [expr $n * 100000000])."
- }
- puts "--------------------------------------"
- if {$Failures == 0} {incr n}
- }
- set buf [expr $buf + $buf]
-}
-
-set Failures 0
-set buf 1
-set res2 [do_time bench_io3 1 $buf]
-set t_printf [expr [lindex $res2 0] - $call_overhead]
-set total_print [lindex $res2 1]
-puts "PROCFS with ${buf}MB buffers"
-puts "_stp_printf on 1000 chars = $t_printf ns / call system + user time."
-if {$t_printf < 0} {
- puts "res2=$res2"
- exit
-}
-puts "_stp_printf of 1GB in $total_print secs real time."
-puts "Transfer rate = [format "%6.2f" [expr 1000/$total_print]] MB/sec"
-puts "Transport failures: $Failures"
-if {$Filesize != 1000000000} {
- puts "WARNING: file size was $Filesize (expected 1000000000)."
-}
-puts "--------------------------------------"
-
-set Failures 0
-set buf 1
-set res2 [do_time bench_io4 1 $buf]
-set t_printf [expr [lindex $res2 0] - $call_overhead]
-set total_print [lindex $res2 1]
-puts "RELAYFS with ${buf}MB buffers"
-puts "_stp_printf on 1000 chars = $t_printf ns / call system + user time."
-if {$t_printf < 0} {
- puts "res2=$res2"
- exit
-}
-puts "_stp_printf of 1GB in $total_print secs real time."
-puts "Transfer rate = [format "%6.2f" [expr 1000/$total_print]] MB/sec"
-puts "Transport failures: $Failures"
-if {$Filesize != 1000000000} {
- puts "WARNING: file size was $Filesize (expected 1000000000)."
-}
-puts "--------------------------------------"
-
-exec /bin/rm -f stpd_cpu*
diff --git a/runtime/probes/bench/ttest.c b/runtime/probes/bench/ttest.c
deleted file mode 100644
index 93b37c84..00000000
--- a/runtime/probes/bench/ttest.c
+++ /dev/null
@@ -1,74 +0,0 @@
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <sys/time.h>
-#include <stdlib.h>
-#include <sys/resource.h>
-#include <unistd.h>
-
-typedef unsigned long long uint64;
-struct rusage rstart;
-
-void start()
-{
- getrusage (RUSAGE_SELF, &rstart);
-}
-
-uint64 usecs (struct timeval *tv)
-{
- return tv->tv_sec * 1000000 + tv->tv_usec;
-}
-
-uint64 stop()
-{
- struct rusage rend;
- getrusage (RUSAGE_SELF, &rend);
- uint64 utime = usecs(&rend.ru_utime) - usecs(&rstart.ru_utime);
- uint64 stime = usecs(&rend.ru_stime) - usecs(&rstart.ru_stime);
- return utime + stime;
-}
-
-void usage(char *name)
-{
- printf ("Usage %s [time]\nWhere \"time\" is millions of times to loop.\n", name);
- exit(1);
-}
-
-int main(int argc, char *argv[])
-{
- int i, n = 1;
- uint64 nsecs;
-
- if (argc > 2)
- usage(argv[0]);
-
- if (argc == 2) {
- n = strtol(argv[1], NULL, 10);
- if (n == 0)
- usage(argv[0]);
- }
-
- /* large warmup time */
- for (i = 0; i < n * 1000000; i++) {
- getuid();
- }
-
- start();
- for (i = 0; i < n * 1000000; i++)
- getuid();
-
- nsecs = stop() / (n * 1000);
-
- printf("%lld ", nsecs);
-
- start();
- for (i = 0; i < n * 1000000; i++)
- getgid();
-
- nsecs = stop() / (n * 1000);
-
- printf("%lld\n", nsecs);
-
- return 0;
-}
diff --git a/runtime/probes/build b/runtime/probes/build
deleted file mode 100755
index ad65b0dc..00000000
--- a/runtime/probes/build
+++ /dev/null
@@ -1,40 +0,0 @@
-#!/usr/bin/tclsh
-# -*- tcl -*-
-
-# simple script to build each probe directory
-
-proc usage {} {
- puts "Usage: build \[-v\] \[clean\] \[debug\]"
- exit
-}
-
-set clean ""
-set verbose ""
-set debug ""
-
-foreach arg $argv {
- if {$arg == "clean"} {
- set clean $arg
- } elseif {$arg == "-v"} {
- set verbose $arg
- } elseif {$arg == "debug"} {
- set debug $arg
- } else {
- usage
- }
-}
-
-set cmd "exec ../build_probe $verbose $clean"
-
-foreach filename [lsort [glob *]] {
- if {$filename != "CVS" && [file isdirectory $filename]} {
- cd $filename
- if {[catch {exec ../build_probe $verbose $clean $debug} res]} {
- puts $res
- exit
- }
- puts $res
- cd ..
- }
-}
-
diff --git a/runtime/probes/build_probe b/runtime/probes/build_probe
deleted file mode 100755
index 7e3207b1..00000000
--- a/runtime/probes/build_probe
+++ /dev/null
@@ -1,154 +0,0 @@
-#!/usr/bin/tclsh
-# -*- tcl -*-
-
-proc usage {} {
- puts "Usage: build \[-v\] \[clean\]"
- exit -1
-}
-
-# use Makefile.template to generate a Makefile
-proc create_makefile {target relayfs} {
- if {[catch {open ../Makefile.template r} fd]} {
- puts "ERROR opening ../Makefile.template"
- exit -1
- }
- if {[catch {open Makefile w} mfd]} {
- puts "ERROR creating Makefile"
- exit -1
- }
- while {[gets $fd line] >= 0} {
- if {[regsub XXX $line $target newline]} {
- set line $newline
- }
- if {[regsub RELAYFS $line $relayfs newline]} {
- set line $newline
- }
- puts $mfd $line
- }
- close $fd
- close $mfd
-}
-
-proc build {{target ""}} {
- global clean verbose debug
- if {$target == ""} {
- set target [file tail [pwd]]
- }
- if {$clean} {
- puts "Cleaning $target"
- if {[catch {exec make clean >& compile.errors} res]} {
- [exec cat compile.errors]
- exit -1
- }
- } else {
- puts "Building $target"
-
- if {$debug == ""} {
- if {[catch {exec make >& compile.errors} res]} {
- puts "\n------------ Compile error in $target -------------------\n"
- if {[catch {open compile.errors r} fd]} {
- puts "Compile failed for unknown reasons"
- exit -1
- }
- while {[gets $fd line] >= 0} {
- puts $line
- }
- close $fd
- exit -1
- }
- } else {
- if {[catch {exec make debug >& compile.errors} res]} {
- puts "\n------------ Compile error in $target -------------------\n"
- if {[catch {open compile.errors r} fd]} {
- puts "Compile failed for unknown reasons"
- exit -1
- }
- while {[gets $fd line] >= 0} {
- puts $line
- }
- close $fd
- exit -1
- }
- }
-
- if {![catch {open compile.errors r} fd]} {
- # search for warnings
- set bad 0
- while {[gets $fd line] >= 0} {
- if {$verbose} {
- puts $line
- } else {
- if {[regexp {[^W]*([A-Za-z][A-Za-z0-9_]*)[^\"]*\"([^\"]*)} $line match warn var]} {
- if {$warn == "Warning"} {
- switch $var {
- _stp_ctrl_unregister -
- _stp_ctrl_register -
- relay_subbufs_consumed -
- _stp_ctrl_send -
- relay_open -
- relayfs_create_dir -
- relayfs_remove_dir -
- relay_flush -
- relay_switch_subbuf -
- relay_close {}
- default {
- if {$bad == 0} {
- puts "\n------------ Unexpected Warnings in $target -------------------\n"
- }
- puts $line
- set bad 1
- }
- }
- }
- }
- }
- }
- close $fd
- }
- if {$bad} {
- exit -1
- }
- }
-}
-
-set clean 0
-set verbose 0
-set debug ""
-foreach arg $argv {
- if {$arg == "clean"} {
- set clean 1
- } elseif {$arg == "-v"} {
- set verbose 1
- } elseif {$arg == "debug"} {
- set debug $arg
- } elseif {$arg != ""} {
- usage
- }
-}
-
-set relayfs ""
-if {![file exists /lib/modules/[exec uname -r]/build/include/linux/relayfs_fs.h]} {
- set relayfs {-I $(RT)/relayfs}
-}
-
-if {![catch {open targets r} tfd]} {
- while {[gets $tfd line] >= 0} {
- set target [lindex $line 0]
- create_makefile $target $relayfs
- build $target
- catch {exec /bin/rm Makefile}
- }
- close $tfd
-} else {
- if {![file exists Makefile]} {
- puts "Now in [pwd]"
- puts "ERROR: No targets file found and no Makefile either"
- exit -1
- }
- build
-}
-
-puts "Done"
-catch {exec /bin/rm compile.errors}
-
-
diff --git a/runtime/probes/os_timer/build b/runtime/probes/os_timer/build
deleted file mode 100755
index f3e83244..00000000
--- a/runtime/probes/os_timer/build
+++ /dev/null
@@ -1,2 +0,0 @@
-#!/bin/bash
-../build_probe $*
diff --git a/runtime/probes/os_timer/os_timer.c b/runtime/probes/os_timer/os_timer.c
deleted file mode 100644
index 4a80d02b..00000000
--- a/runtime/probes/os_timer/os_timer.c
+++ /dev/null
@@ -1,126 +0,0 @@
-/* Use the os timer as a poor-man's time based profiler for a UP system */
-
-/* Demonstrates the beginnings of a generic framework for */
-/* asynchronous probes using the runtime */
-
-/* @todo NOTE: the statement: regs = task_pt_regs(current); */
-/* isn't working in the way I would expect. The timer callback */
-/* happens, but I don't get a reasonable value in regs->eip */
-/* Can this routine be called during the timer callback? */
-
-/* os includes */
-#include "linux/timer.h"
-
-/* How many strings to allocate. see strings.c. Default is 0. */
-#define STP_NUM_STRINGS 1
-
-/* maximum size for a string. default is 2048 */
-#define STP_STRING_SIZE 2048
-
-/* size of strings saved in maps */
-#define MAP_STRING_LENGTH 256
-
-/* width of histograms. Default 50 */
-#define HIST_WIDTH 50
-
-/* always include this. Put all non-map defines above it. */
-#include "runtime.h"
-
-/* @todo since we don't have aggregation maps yet, try regular maps */
-#define VALUE_TYPE INT64
-#define KEY1_TYPE STRING
-#define KEY2_TYPE INT64
-#include "map-gen.c"
-
-#include "map.c"
-
-#include "stat.c"
-#include "stack.c"
-
-MODULE_DESCRIPTION("SystemTap probe: os_timer");
-MODULE_AUTHOR("Charles Spirakis <charles.spirakis@intel.com>");
-
-Stat timing;
-MAP cur_addr;
-
-/* A generic asynchorous probe entry point */
-void inst_async(struct pt_regs *regs)
-{
- u64 start;
- u64 end;
- unsigned long ip;
-
- rdtscll(start);
- ip = REG_IP(regs);
-
- /* Create a map of interrupted addresses seen */
- /* really want a map of image name / address */
- _stp_map_add_sii(cur_addr, current->comm, ip, 1);
-
- /* Need _stp_stack() and _stp_ustack()? */
- /* _stp_image() and aggregation maps */
-
- rdtscll(end);
- _stp_stat_add(timing, end - start);
-}
-
-static struct timer_list timer;
-
-/* Helper function to convert from os timer callback into */
-/* generic asynchronous entry point form */
-static void os_timer_callback(unsigned long val)
-{
- struct pt_regs *regs;
-
- /* setup the next timeout now so it doesn't drift */
- /* due to processing the async probe code */
- mod_timer(&timer, jiffies + val);
-
- /* determine pt_regs from the kernel stack */
- /* @todo This doesn't seem to get a reasonable pt_regs pointer */
- /* based on the value of regs->eip. However, KSTK_EIP() in */
- /* include/asm/processor.h implies regs->eip is valid... */
- regs = task_pt_regs(current);
-
- /* Call the asynchronous probe with a ptregs struct */
- inst_async(regs);
-}
-
-/* called when the module loads. */
-int probe_start(void)
-{
- timing = _stp_stat_init(HIST_LINEAR, 0, 5000, 250);
-
- cur_addr = _stp_map_new_sii(1000);
-
- /* register the os_timer */
- init_timer(&timer);
-
- timer.expires = jiffies + 50;
- timer.function = os_timer_callback;
-
- /* data is usd for defining when the next timeout shoud occur */
- timer.data = 50;
-
- add_timer(&timer);
- return 0;
-}
-
-void probe_exit (void)
-{
- /* unregister the os_timer */
- del_timer_sync(&timer);
-
- /* print out any colledted data, etc */
- _stp_printf ("os timer done.\n");
- _stp_printf ("WARNING: Currently using task_pt_regs() to get the pt_regs struct\n");
- _stp_printf ("during the timer interrupt, but there seems to be issues with that...\n\n");
- _stp_stat_print (timing, "timing (cpu cycles): # calls:%C avg:%A min:%m max:%M\n%H", 0);
-
- _stp_print("Process\tIp\tCount\n");
- _stp_map_print (cur_addr, "%1s\t%2P\t%d");
- _stp_map_del(cur_addr);
-
- _stp_print_flush();
-}
-
diff --git a/runtime/probes/os_timer/stp b/runtime/probes/os_timer/stp
deleted file mode 100755
index f3feee70..00000000
--- a/runtime/probes/os_timer/stp
+++ /dev/null
@@ -1,2 +0,0 @@
-#!/bin/bash
-source ../stp
diff --git a/runtime/probes/os_timer/targets b/runtime/probes/os_timer/targets
deleted file mode 100644
index 879d3afc..00000000
--- a/runtime/probes/os_timer/targets
+++ /dev/null
@@ -1 +0,0 @@
-os_timer
diff --git a/runtime/probes/scf/README b/runtime/probes/scf/README
deleted file mode 100644
index 39fcfda8..00000000
--- a/runtime/probes/scf/README
+++ /dev/null
@@ -1,12 +0,0 @@
-/** @dir scf
-This example probe instruments smp_call_function().
-
-It demonstrates using stack backtraces as map keys to compute the most
-common path to a function.
-
-kernel.function("smp_call_function")
-{
- traces[stack()] += 1
-}
-
-*/
diff --git a/runtime/probes/scf/build b/runtime/probes/scf/build
deleted file mode 100755
index f3e83244..00000000
--- a/runtime/probes/scf/build
+++ /dev/null
@@ -1,2 +0,0 @@
-#!/bin/bash
-../build_probe $*
diff --git a/runtime/probes/scf/scf.c b/runtime/probes/scf/scf.c
deleted file mode 100644
index 0e29df43..00000000
--- a/runtime/probes/scf/scf.c
+++ /dev/null
@@ -1,50 +0,0 @@
-#define STP_NUM_STRINGS 1
-#include "runtime.h"
-
-#define MAP_STRING_LENGTH 512
-
-#define VALUE_TYPE INT64
-#define KEY1_TYPE STRING
-#include "map-gen.c"
-
-#include "map.c"
-#include "sym.c"
-#include "current.c"
-#include "stack.c"
-#include "probes.c"
-
-MODULE_DESCRIPTION("SystemTap probe: scf");
-MODULE_AUTHOR("Martin Hunt <hunt@redhat.com>");
-
-MAP map1;
-
-int inst_smp_call_function (struct kprobe *p, struct pt_regs *regs)
-{
- String str = _stp_string_init (0);
- _stp_stack_sprint (str, regs, 1);
- _stp_map_add_si (map1, _stp_string_ptr(str), 1);
- return 0;
-}
-
-static struct kprobe stp_probes[] = {
- {
- .addr = (kprobe_opcode_t *)"smp_call_function",
- .pre_handler = inst_smp_call_function
- },
-};
-
-#define MAX_STP_ROUTINE (sizeof(stp_probes)/sizeof(struct kprobe))
-
-int probe_start(void)
-{
- map1 = _stp_map_new_si (100);
- return _stp_register_kprobes (stp_probes, MAX_STP_ROUTINE);
-}
-
-void probe_exit (void)
-{
- _stp_unregister_kprobes (stp_probes, MAX_STP_ROUTINE);
- _stp_map_print (map1, "trace[%1s] = %d\n");
- _stp_map_del (map1);
-}
-
diff --git a/runtime/probes/scf/targets b/runtime/probes/scf/targets
deleted file mode 100644
index aafcca22..00000000
--- a/runtime/probes/scf/targets
+++ /dev/null
@@ -1 +0,0 @@
-scf
diff --git a/runtime/probes/shellsnoop/README b/runtime/probes/shellsnoop/README
deleted file mode 100644
index 70b5e614..00000000
--- a/runtime/probes/shellsnoop/README
+++ /dev/null
@@ -1,73 +0,0 @@
-/** @dir shellsnoop
-Snoops on what commands are being run by shells.
-
-This is a translation of on an old dtr probe. It demonstrates maps,
-lists, and how to use _stp_copy_argv_from_user() and _stp_strncpy_from_user().
-
-Original dtr source:
-
-\verbatim
-# shellsnoop.probe - snoop shell execution as it occurs.
-# clone of dtrace shellsnoop example
-
-global {
- long @pids[long];
-}
-
-probe do_execve:entry {
- char __user *vstr;
- char str[256];
- int len;
-
- /* watch shells only */
- /* FIXME: detect more shells, like csh, tcsh, zsh */
-
- if (!strcmp(current->comm,"bash") || !strcmp(current->comm,"sh") || !strcmp(current->comm, "zsh")
- || !strcmp(current->comm, "tcsh") || !strcmp(current->comm, "pdksh"))
- {
- dlog ("%d\t%d\t%d\t%s ", current->uid, current->pid, current->parent->pid, filename);
- @pids[current->pid] = 1;
-
- /* print out argv, ignoring argv[0] */
- if (argv) argv++;
- while (argv != NULL)
- {
- if (get_user (vstr, argv))
- break;
- if (!vstr)
- break;
- len = dtr_strncpy_from_user(str, vstr, 256);
- str[len] = 0;
- printk ("%s ", str);
- argv++;
- }
- printk ("\n");
- }
-}
-
-# use filp_open because copy_from_user not needed there
-probe filp_open:entry {
- if (@pids[current->pid])
- dlog ("%d\t%d\t%s\tO %s\n", current->pid, current->parent->pid, current->comm, filename);
-}
-
-probe sys_read:entry {
- if (@pids[current->pid])
- dlog ("%d\t%d\t%s\tR %d\n", current->pid, current->parent->pid, current->comm, fd);
-}
-
-probe sys_write:entry {
- size_t len;
- char str[256];
- if (@pids[current->pid])
- {
- if (count < 64) len = count;
- else len = 64;
- if (len = dtr_strncpy_from_user(str, buf, len)) {
- str[len] = 0;
- dlog ("%d\t%d\t%s\tW %s\n", current->pid, current->parent->pid, current->comm, str);
- }
- }
-}
-\endverbatim
-*/
diff --git a/runtime/probes/shellsnoop/build b/runtime/probes/shellsnoop/build
deleted file mode 100755
index f3e83244..00000000
--- a/runtime/probes/shellsnoop/build
+++ /dev/null
@@ -1,2 +0,0 @@
-#!/bin/bash
-../build_probe $*
diff --git a/runtime/probes/shellsnoop/shellsnoop.c b/runtime/probes/shellsnoop/shellsnoop.c
deleted file mode 100644
index dd0c81b9..00000000
--- a/runtime/probes/shellsnoop/shellsnoop.c
+++ /dev/null
@@ -1,161 +0,0 @@
-//#define STP_RELAYFS
-#define STP_NUM_STRINGS 1
-#define STP_STRING_SIZE 8192
-#include "runtime.h"
-
-#define VALUE_TYPE INT64
-#define KEY1_TYPE INT64
-#include "map-gen.c"
-
-#define VALUE_TYPE STRING
-#define KEY1_TYPE INT64
-#include "map-gen.c"
-
-#include "map.c"
-#include "copy.c"
-#include "probes.c"
-
-MODULE_DESCRIPTION("SystemTap probe: shellsnoop");
-MODULE_AUTHOR("Martin Hunt <hunt@redhat.com>");
-
-MAP pids, arglist ;
-
-void _stp_copy_argv_from_user (MAP list, char __user *__user *argv)
-{
- char str[128];
- char __user *vstr;
- int len, i = 0;
-
- if (argv)
- argv++;
-
- while (argv != NULL) {
- if (get_user (vstr, argv))
- break;
-
- if (vstr == NULL)
- break;
-
- len = _stp_strncpy_from_user(str, vstr, 128);
- str[len] = 0;
- _stp_map_set_is (list, i++, str);
- argv++;
- }
-}
-
-int inst_do_execve (char * filename, char __user *__user *argv, char __user *__user *envp, struct pt_regs * regs)
-{
- struct map_node *ptr;
-
- /* watch shells only */
- /* FIXME: detect more shells, like csh, tcsh, zsh */
-
- if (!strcmp(current->comm,"bash") || !strcmp(current->comm,"sh") || !strcmp(current->comm, "zsh")
- || !strcmp(current->comm, "tcsh") || !strcmp(current->comm, "pdksh"))
- {
- _stp_printf ("%d\t%d\t%d\t%s ", current->uid, current->pid, current->parent->pid, filename);
-
- _stp_map_set_ii (pids, current->pid, 1);
-
- _stp_map_clear (arglist);
- _stp_copy_argv_from_user (arglist, argv);
-
- foreach (arglist, ptr)
- _stp_printf ("%s ", _stp_get_str(ptr));
- _stp_print("\n");
-
- _stp_print_flush();
- }
- jprobe_return();
- return 0;
-}
-
-struct file * inst_filp_open (const char * filename, int flags, int mode)
-{
- if (_stp_map_get_ii (pids, current->pid)) {
- _stp_printf ("%d\t%d\t%s\tO %s\n", current->pid, current->parent->pid, current->comm, filename);
- _stp_print_flush();
- }
- jprobe_return();
- return 0;
-}
-
-asmlinkage ssize_t inst_sys_read (unsigned int fd, char __user * buf, size_t count)
-{
- if (_stp_map_get_ii (pids, current->pid)) {
- _stp_printf ("%d\t%d\t%s\tR %d\n", current->pid, current->parent->pid, current->comm, fd);
- _stp_print_flush();
- }
- jprobe_return();
- return 0;
-}
-
-asmlinkage ssize_t inst_sys_write (unsigned int fd, const char __user * buf, size_t count)
-{
- if (_stp_map_get_ii (pids, current->pid)) {
- String str = _stp_string_init (0);
- _stp_string_from_user(str, buf, count);
- _stp_printf ("%d\t%d\t%s\tW %s", current->pid, current->parent->pid,
- current->comm, _stp_string_ptr(str));
- _stp_print_flush();
- }
-
- jprobe_return();
- return 0;
-}
-
-static struct jprobe stp_probes[] = {
- {
- .kp.addr = (kprobe_opcode_t *)"do_execve",
- .entry = (kprobe_opcode_t *) inst_do_execve
- },
- {
- .kp.addr = (kprobe_opcode_t *)"filp_open",
- .entry = (kprobe_opcode_t *) inst_filp_open
- },
- {
- .kp.addr = (kprobe_opcode_t *)"sys_read",
- .entry = (kprobe_opcode_t *) inst_sys_read
- },
- {
- .kp.addr = (kprobe_opcode_t *)"sys_write",
- .entry = (kprobe_opcode_t *) inst_sys_write
- },
-};
-
-#define MAX_STP_ROUTINE (sizeof(stp_probes)/sizeof(struct jprobe))
-
-
-int probe_start(void)
-{
- int ret;
-
- /* now initialize any data or variables */
- pids = _stp_map_new_ii(10000);
- arglist = _stp_map_new_is (10);
-
- /* now we are ready to enable the probes */
- ret = _stp_register_jprobes (stp_probes, MAX_STP_ROUTINE);
-
- if (ret < 0) {
- _stp_map_del (pids);
- _stp_map_del (arglist);
- return ret;
- }
-
- _stp_printf("instrumentation is enabled... %s\n", __this_module.name);
- _stp_print_flush();
- return ret;
-}
-
-
-void probe_exit (void)
-{
- _stp_unregister_jprobes (stp_probes, MAX_STP_ROUTINE);
- _stp_map_del (pids);
- _stp_map_del (arglist);
- _stp_printf("\nDropped %d packets\n", atomic_read(&_stp_transport_failures));
- _stp_print_flush();
-}
-
-
diff --git a/runtime/probes/shellsnoop/targets b/runtime/probes/shellsnoop/targets
deleted file mode 100644
index fdd0d724..00000000
--- a/runtime/probes/shellsnoop/targets
+++ /dev/null
@@ -1 +0,0 @@
-shellsnoop
diff --git a/runtime/probes/tasklet/README b/runtime/probes/tasklet/README
deleted file mode 100644
index 8507ad9b..00000000
--- a/runtime/probes/tasklet/README
+++ /dev/null
@@ -1,9 +0,0 @@
-/** @dir tasklet
-Sample probe in a tasklet. Useful for interrupt context testing.
-
-\verbatim
-> make
-> ./stp stp_tasklet.ko
-\endverbatim
-
-*/
diff --git a/runtime/probes/tasklet/build b/runtime/probes/tasklet/build
deleted file mode 100755
index f3e83244..00000000
--- a/runtime/probes/tasklet/build
+++ /dev/null
@@ -1,2 +0,0 @@
-#!/bin/bash
-../build_probe $*
diff --git a/runtime/probes/tasklet/stp_tasklet.c b/runtime/probes/tasklet/stp_tasklet.c
deleted file mode 100644
index f47fea9e..00000000
--- a/runtime/probes/tasklet/stp_tasklet.c
+++ /dev/null
@@ -1,40 +0,0 @@
-/* Framework for putting a jprobe in a tasklet. */
-/* Useful for testing probes in interrupt context. */
-/* Doesn't do anything useful as is. Put test code in the inst func */
-
-#define STP_NETLINK_ONLY
-#define STP_NUM_STRINGS 1
-
-#include "runtime.h"
-#include "probes.c"
-
-MODULE_DESCRIPTION("test jprobes of tasklets");
-MODULE_AUTHOR("Martin Hunt <hunt@redhat.com>");
-
-void inst__rcu_process_callbacks(struct rcu_ctrlblk *rcp,
- struct rcu_state *rsp, struct rcu_data *rdp)
-{
- _stp_printf ("count=%d irqs_disabled=%d in_interrupt=%d in_irq=%d",
- preempt_count(), irqs_disabled(), in_interrupt(), in_irq());
- _stp_print_flush();
- jprobe_return();
-}
-
-static struct jprobe stp_probes[] = {
- {
- .kp.addr = (kprobe_opcode_t *)"__rcu_process_callbacks",
- .entry = (kprobe_opcode_t *) inst__rcu_process_callbacks
- },
-};
-#define MAX_STP_PROBES (sizeof(stp_probes)/sizeof(struct jprobe))
-
-int probe_start(void)
-{
- return _stp_register_jprobes (stp_probes, MAX_STP_PROBES);
-}
-
-void probe_exit (void)
-{
- _stp_unregister_jprobes (stp_probes, MAX_STP_PROBES);
-}
-
diff --git a/runtime/probes/tasklet/targets b/runtime/probes/tasklet/targets
deleted file mode 100644
index 236dbd95..00000000
--- a/runtime/probes/tasklet/targets
+++ /dev/null
@@ -1 +0,0 @@
-stp_tasklet
diff --git a/runtime/probes/test4/README b/runtime/probes/test4/README
deleted file mode 100644
index 75d4be10..00000000
--- a/runtime/probes/test4/README
+++ /dev/null
@@ -1,24 +0,0 @@
-/** @dir test4
-This example probe tracks file opens, reads and writes.
-It demonstrates maps, stats, and iterators.
-
-This is a translation of on an old dtr probe. Original source is
-\verbatim
-global {
- long @opens[string];
- sum @reads[string], @writes[string];
-}
-
-probe sys_open:entry {
- @opens[current->comm]++;
-}
-
-probe sys_read:entry {
- @reads[current->comm] << count;
-}
-
-probe sys_write:entry {
- @writes[current->comm] << count;
-}
-\endverbatim
-*/
diff --git a/runtime/probes/test4/build b/runtime/probes/test4/build
deleted file mode 100755
index f3e83244..00000000
--- a/runtime/probes/test4/build
+++ /dev/null
@@ -1,2 +0,0 @@
-#!/bin/bash
-../build_probe $*
diff --git a/runtime/probes/test4/targets b/runtime/probes/test4/targets
deleted file mode 100644
index d234c5e0..00000000
--- a/runtime/probes/test4/targets
+++ /dev/null
@@ -1 +0,0 @@
-test4
diff --git a/runtime/probes/test4/test4.c b/runtime/probes/test4/test4.c
deleted file mode 100644
index 56027186..00000000
--- a/runtime/probes/test4/test4.c
+++ /dev/null
@@ -1,79 +0,0 @@
-#define STP_NUM_STRINGS 1
-#include "runtime.h"
-
-#define VALUE_TYPE INT64
-#define KEY1_TYPE STRING
-#include "map-gen.c"
-
-#define VALUE_TYPE STAT
-#define KEY1_TYPE STRING
-#include "map-gen.c"
-
-#include "map.c"
-#include "probes.c"
-
-MODULE_DESCRIPTION("SystemTap probe: test4");
-MODULE_AUTHOR("Martin Hunt <hunt@redhat.com>");
-
-
-MAP opens, reads, writes;
-
-asmlinkage long inst_sys_open (const char __user * filename, int flags, int mode)
-{
- _stp_map_add_si (opens, current->comm, 1);
- jprobe_return();
- return 0;
-}
-
-asmlinkage ssize_t inst_sys_read (unsigned int fd, char __user * buf, size_t count)
-{
- _stp_map_add_sx (reads, current->comm, count);
- jprobe_return();
- return 0;
-}
-
-asmlinkage ssize_t inst_sys_write (unsigned int fd, const char __user * buf, size_t count)
-{
- _stp_map_add_sx (writes, current->comm, count);
- jprobe_return();
- return 0;
-}
-
-static struct jprobe stp_probes[] = {
- {
- .kp.addr = (kprobe_opcode_t *)"sys_open",
- .entry = (kprobe_opcode_t *) inst_sys_open
- },
- {
- .kp.addr = (kprobe_opcode_t *)"sys_read",
- .entry = (kprobe_opcode_t *) inst_sys_read
- },
- {
- .kp.addr = (kprobe_opcode_t *)"sys_write",
- .entry = (kprobe_opcode_t *) inst_sys_write
- },
-};
-
-#define MAX_STP_ROUTINE (sizeof(stp_probes)/sizeof(struct jprobe))
-
-int probe_start(void)
-{
- opens = _stp_map_new_si (1000);
- reads = _stp_map_new_sx (1000, HIST_LOG, 12);
- writes = _stp_map_new_sx (1000, HIST_LOG, 12);
- return _stp_register_jprobes (stp_probes, MAX_STP_ROUTINE);
-}
-
-void probe_exit (void)
-{
- _stp_unregister_jprobes (stp_probes, MAX_STP_ROUTINE);
-
- _stp_map_print (opens,"%d opens by process \"%1s\"");
- _stp_map_print (reads,"reads by process \"%1s\": %C. Total bytes=%S. Average: %A\n%H");
- _stp_map_print (writes,"writes by process \"%1s\": %C. Total bytes=%S. Average: %A\n%H");
- _stp_printf("\nDropped %d packets\n", atomic_read(&_stp_transport_failures));
- _stp_print_flush();
- _stp_map_del (opens);
- _stp_map_del (reads);
- _stp_map_del (writes);
-}
diff --git a/runtime/probes/where_func/README b/runtime/probes/where_func/README
deleted file mode 100644
index 78009566..00000000
--- a/runtime/probes/where_func/README
+++ /dev/null
@@ -1,29 +0,0 @@
-/** @dir where_func
-This is a silly little instrumentation routine to instrument functions
-entry by name. It makes use of the SystemTap runtime libraries to break
-down the number of times the function by caller.
-
-It demonstrates kprobes, passing a module parameter, using the print buffer,
-and using _stp_print_symbol() to map the addresses back to locations
-in functions.
-
-By default it instruments schedule().
-
-The instrumentation module is built by having the kernel that is going
-to be instrumented currently on the machine and doing
-\code
-./build
-\endcode
-The instrumentation is inserted as root with:
-\code
-/sbin/insmod kprobe_funct_where.ko funct_name=function_name
-\endcode
-The instrumentation is removed as root with:
-\code
-/sbin/rmmod kprobe_funct_where
-\endcode
--Will Cohen
-
-Note that this module is broken now because we don't pass the module parameter
-tp staprun. FIXME
-*/
diff --git a/runtime/probes/where_func/build b/runtime/probes/where_func/build
deleted file mode 100755
index f3e83244..00000000
--- a/runtime/probes/where_func/build
+++ /dev/null
@@ -1,2 +0,0 @@
-#!/bin/bash
-../build_probe $*
diff --git a/runtime/probes/where_func/kprobe_where_funct.c b/runtime/probes/where_func/kprobe_where_funct.c
deleted file mode 100644
index 680dabd8..00000000
--- a/runtime/probes/where_func/kprobe_where_funct.c
+++ /dev/null
@@ -1,62 +0,0 @@
-/* kprobe_where_funct.c
- this is a simple module to get information about calls to a function
- that is passed as a module option
- Will Cohen
-*/
-
-#define STP_NUM_STRINGS 1
-
-#include "runtime.h"
-
-#define VALUE_TYPE INT64
-#define KEY1_TYPE INT64
-#include "map-gen.c"
-
-#include "map.c"
-#include "probes.c"
-#include "sym.c"
-#include "current.c"
-
-MODULE_DESCRIPTION("SystemTap probe: where_func");
-MODULE_AUTHOR("Will Cohen and Martin Hunt");
-
-static char default_name[] = "schedule";
-static char *funct_name = default_name;
-module_param(funct_name, charp, 0);
-MODULE_PARM_DESC(funct_name, "function entry name.\n");
-
-MAP funct_locations;
-
-static int inst_funct(struct kprobe *p, struct pt_regs *regs)
-{
- long ret_addr = _stp_ret_addr(regs);
- _stp_map_add_ii(funct_locations, ret_addr, 1);
- return 0;
-}
-
-/*For each probe you need to allocate a kprobe structure*/
-static struct kprobe kp[] = {
- {
- .addr = default_name,
- .pre_handler = inst_funct,
- }
-};
-#define MAX_KPROBES (sizeof(kp)/sizeof(struct kprobe))
-
-int probe_start(void)
-{
- funct_locations = _stp_map_new_ii (1000);
-
- if (funct_name)
- kp[0].addr = funct_name;
-
- return _stp_register_kprobes (kp, MAX_KPROBES);
-}
-
-void probe_exit (void)
-{
- _stp_unregister_kprobes (kp, MAX_KPROBES);
-
- _stp_map_print (funct_locations, "Count: %d\tCaller: %1P");
- _stp_map_del(funct_locations);
-}
diff --git a/runtime/probes/where_func/targets b/runtime/probes/where_func/targets
deleted file mode 100644
index 7e8e4cf1..00000000
--- a/runtime/probes/where_func/targets
+++ /dev/null
@@ -1 +0,0 @@
-kprobe_where_funct
diff --git a/runtime/regs.c b/runtime/regs.c
index 5821f7e7..81b865b1 100644
--- a/runtime/regs.c
+++ b/runtime/regs.c
@@ -256,6 +256,13 @@ void _stp_print_regs(struct pt_regs * regs)
#elif defined (__powerpc64__)
+static int _stp_probing_32bit_app(struct pt_regs *regs)
+{
+ if (!regs)
+ return 0;
+ return (user_mode(regs) && test_tsk_thread_flag(current, TIF_32BIT));
+}
+
void _stp_print_regs(struct pt_regs * regs)
{
int i;
diff --git a/runtime/regs.h b/runtime/regs.h
index 4954020f..123d7601 100644
--- a/runtime/regs.h
+++ b/runtime/regs.h
@@ -14,7 +14,7 @@
#if defined (STAPCONF_X86_UNIREGS) && (defined (__x86_64__) || defined (__i386__))
#define REG_IP(regs) regs->ip
#define REG_SP(regs) regs->sp
-#define REG_FP(regs) regs->bp;
+#define REG_FP(regs) regs->bp
#elif defined (__x86_64__)
@@ -25,7 +25,7 @@
#define REG_IP(regs) regs->eip
#define REG_SP(regs) regs->esp
-#define REG_FP(regs) regs->ebp;
+#define REG_FP(regs) regs->ebp
#elif defined (__ia64__)
#define REG_IP(regs) ((regs)->cr_iip +ia64_psr(regs)->ri)
diff --git a/runtime/staprun/ChangeLog b/runtime/staprun/ChangeLog
index 969c299d..27f4d8c8 100644
--- a/runtime/staprun/ChangeLog
+++ b/runtime/staprun/ChangeLog
@@ -1,3 +1,8 @@
+2008-06-03 Frank Ch. Eigler <fche@elastic.org>
+
+ PR 6429.
+ * mainloop.c (stp_main_loop): Remove STP_UNWIND message support.
+
2008-05-05 Martin Hunt <hunt@redhat.com>
* mainloop.c (child_proc): Handle sig_chld
diff --git a/runtime/staprun/mainloop.c b/runtime/staprun/mainloop.c
index 61963743..2bbadbc9 100644
--- a/runtime/staprun/mainloop.c
+++ b/runtime/staprun/mainloop.c
@@ -387,18 +387,6 @@ int stp_main_loop(void)
cleanup_and_exit(1);
break;
}
- case STP_UNWIND:
- {
- int len;
- char *ptr = (char *)data;
- while (nb > 0) {
- send_unwind_data(ptr);
- len = strlen(ptr) + 1;
- ptr += len;
- nb -= len;
- }
- break;
- }
default:
err("WARNING: ignored message of type %d\n", (type));
}
diff --git a/runtime/staprun/unwind_data.c b/runtime/staprun/unwind_data.c
deleted file mode 100644
index ed27cc20..00000000
--- a/runtime/staprun/unwind_data.c
+++ /dev/null
@@ -1,97 +0,0 @@
-/* -*- linux-c -*-
- * Unwind data functions for staprun.
- *
- * Copyright (C) 2008 Red Hat Inc.
- *
- * This file is part of systemtap, and is free software. You can
- * redistribute it and/or modify it under the terms of the GNU General
- * Public License (GPL); either version 2, or (at your option) any
- * later version.
- */
-
-#include "staprun.h"
-#include <elfutils/libdwfl.h>
-#include <dwarf.h>
-
-static char debuginfo_path_arr[] = "-:.debug:/usr/lib/debug";
-static char *debuginfo_path = debuginfo_path_arr;
-static const Dwfl_Callbacks kernel_callbacks = {
- .find_debuginfo = dwfl_standard_find_debuginfo,
- .debuginfo_path = &debuginfo_path,
- .find_elf = dwfl_linux_kernel_find_elf,
- .section_address = dwfl_linux_kernel_module_section_address,
-};
-
-void *get_module_unwind_data(Dwfl * dwfl, const char *name, int *len)
-{
- Dwarf_Addr bias = 0;
- Dwarf *dw;
- GElf_Ehdr *ehdr, ehdr_mem;
- GElf_Shdr *shdr, shdr_mem;
- Elf_Scn *scn = NULL;
- Elf_Data *data = NULL;
-
- Dwfl_Module *mod = dwfl_report_module(dwfl, name, 0, 0);
- dwfl_report_end(dwfl, NULL, NULL);
- dw = dwfl_module_getdwarf(mod, &bias);
- Elf *elf = dwarf_getelf(dw);
- ehdr = gelf_getehdr(elf, &ehdr_mem);
- while ((scn = elf_nextscn(elf, scn))) {
- shdr = gelf_getshdr(scn, &shdr_mem);
- if (strcmp(elf_strptr(elf, ehdr->e_shstrndx, shdr->sh_name), ".debug_frame") == 0) {
- data = elf_rawdata(scn, NULL);
- break;
- }
- }
-
- if (data == NULL) {
- *len = 0;
- dbug(2, "module %s returns NULL\n", name);
- return NULL;
- }
- dbug(2, "module %s returns %d\n", name, (int)data->d_size);
- *len = data->d_size;
- return data->d_buf;
-}
-
-void send_unwind_data(const char *name)
-{
- struct _stp_msg_unwind *un;
- int unwind_data_len = 0;
- void *unwind_data = NULL;
- char *buf;
-
- dbug(2, "module %s\n", name);
- if (strcmp(name, "*")) {
- Dwfl *dwfl = dwfl_begin(&kernel_callbacks);
-
- if (name[0] == 0)
- unwind_data = get_module_unwind_data(dwfl, "kernel", &unwind_data_len);
- else
- unwind_data = get_module_unwind_data(dwfl, name, &unwind_data_len);
-
- /* yuck */
- buf = (char *)malloc(unwind_data_len + sizeof(*un) + sizeof(uint32_t));
- if (!buf) {
- err("malloc failed\n");
- return;
- }
- memcpy(buf + sizeof(*un) + sizeof(uint32_t), unwind_data, unwind_data_len);
- dwfl_end(dwfl);
- } else {
- buf = (char *)malloc(sizeof(*un) + sizeof(uint32_t));
- if (!buf) {
- err("malloc failed\n");
- return;
- }
- }
-
- un = (struct _stp_msg_unwind *)(buf + sizeof(uint32_t));
- strncpy(un->name, name, sizeof(un->name));
- un->unwind_len = unwind_data_len;
- *(uint32_t *) buf = STP_UNWIND;
-
- /* send unwind data */
- if (write(control_channel, buf, unwind_data_len + sizeof(*un) + sizeof(uint32_t)) <= 0)
- err("write failed\n");
-}
diff --git a/runtime/stat-common.c b/runtime/stat-common.c
index a62297bf..7dabe708 100644
--- a/runtime/stat-common.c
+++ b/runtime/stat-common.c
@@ -1,6 +1,6 @@
/* -*- linux-c -*-
* common stats functions for aggragations and maps
- * Copyright (C) 2005, 2006, 2007 Red Hat Inc.
+ * Copyright (C) 2005, 2006, 2007, 2008 Red Hat Inc.
*
* This file is part of systemtap, and is free software. You can
* redistribute it and/or modify it under the terms of the GNU General
@@ -299,39 +299,6 @@ static void _stp_stat_print_histogram (Hist st, stat *sd)
_stp_print_flush();
}
-static void _stp_stat_print_valtype (char *fmt, Hist st, stat *sd, int cpu)
-{
- switch (*fmt) {
- case 'C':
- _stp_printf("%lld", sd->count);
- break;
- case 'm':
- _stp_printf("%lld", sd->min);
- break;
- case 'M':
- _stp_printf("%lld", sd->max);
- break;
- case 'S':
- _stp_printf("%lld", sd->sum);
- break;
- case 'A':
- {
- int64_t avg = 0;
- if (sd->count)
- avg = _stp_div64 (NULL, sd->sum, sd->count);
- _stp_printf("%lld", avg);
- break;
- }
- case 'H':
- _stp_stat_print_histogram (st, sd);
- _stp_print_flush();
- break;
- case 'c':
- _stp_printf("%d", cpu);
- break;
- }
-}
-
static void __stp_stat_add (Hist st, stat *sd, int64_t val)
{
int n;
diff --git a/runtime/stat.c b/runtime/stat.c
index f8b5f018..8bd7bf12 100644
--- a/runtime/stat.c
+++ b/runtime/stat.c
@@ -237,56 +237,6 @@ stat *_stp_stat_get (Stat st, int clear)
}
-static void __stp_stat_print (char *fmt, Stat st, stat *sd, int cpu)
-{
- int num;
- char *f = (char *)fmt;
- while (*f) {
- f = next_fmt (f, &num);
- _stp_stat_print_valtype (f, &st->hist, sd, cpu);
- if (*f)
- f++;
- }
- _stp_print_char('\n');
- _stp_print_flush();
-}
-
-/** Print per-cpu Stats.
- * Prints the Stats for each CPU.
- *
- * @param st Stat
- * @param fmt @ref format_string
- * @param clear Set if you want the data cleared after the read. Useful
- * for polling.
- */
-void _stp_stat_print_cpu (Stat st, char *fmt, int clear)
-{
- int i;
- for_each_cpu(i) {
- stat *sd = per_cpu_ptr (st->sd, i);
- STAT_LOCK(sd);
- __stp_stat_print (fmt, st, sd, i);
- if (clear)
- _stp_stat_clear_data (st, sd);
- STAT_UNLOCK(sd);
- }
-}
-
-/** Print Stats.
- * Prints the Stats.
- *
- * @param st Stat
- * @param fmt @ref format_string
- * @param clear Set if you want the data cleared after the read. Useful
- * for polling.
- */
-void _stp_stat_print (Stat st, char *fmt, int clear)
-{
- stat *agg = _stp_stat_get(st, clear);
- __stp_stat_print (fmt, st, agg, 0);
- STAT_UNLOCK(agg);
-}
-
/** Clear Stats.
* Clears the Stats.
*
diff --git a/runtime/syscall.h b/runtime/syscall.h
new file mode 100644
index 00000000..36fed2ff
--- /dev/null
+++ b/runtime/syscall.h
@@ -0,0 +1,160 @@
+/* syscall defines and inlines
+ * Copyright (C) 2008 Red Hat Inc.
+ *
+ * This file is part of systemtap, and is free software. You can
+ * redistribute it and/or modify it under the terms of the GNU General
+ * Public License (GPL); either version 2, or (at your option) any
+ * later version.
+ */
+
+#ifndef _SYSCALL_H_ /* -*- linux-c -*- */
+#define _SYSCALL_H_
+
+#if defined(__i386__) || defined(CONFIG_IA32_EMULATION)
+#define __MMAP_SYSCALL_NO_IA32 192 /* mmap2 */
+#define __MPROTECT_SYSCALL_NO_IA32 125
+#define __MUNMAP_SYSCALL_NO_IA32 91
+#define __MREMAP_SYSCALL_NO_IA32 163
+# if !defined(CONFIG_IA32_EMULATION)
+#define MMAP_SYSCALL_NO(tsk) __MMAP_SYSCALL_NO_IA32
+#define MPROTECT_SYSCALL_NO(tsk) __MPROTECT_SYSCALL_NO_IA32
+#define MUNMAP_SYSCALL_NO(tsk) __MUNMAP_SYSCALL_NO_IA32
+#define MREMAP_SYSCALL_NO(tsk) __MREMAP_SYSCALL_NO_IA32
+# endif
+#endif
+
+#if defined(__x86_64__)
+#define __MMAP_SYSCALL_NO_X86_64 9
+#define __MPROTECT_SYSCALL_NO_X86_64 10
+#define __MUNMAP_SYSCALL_NO_X86_64 11
+#define __MREMAP_SYSCALL_NO_X86_64 25
+# if defined(CONFIG_IA32_EMULATION)
+#define MMAP_SYSCALL_NO(tsk) ((test_tsk_thread_flag((tsk), TIF_IA32)) \
+ ? __MMAP_SYSCALL_NO_IA32 \
+ : __MMAP_SYSCALL_NO_X86_64)
+#define MPROTECT_SYSCALL_NO(tsk) ((test_tsk_thread_flag((tsk), TIF_IA32)) \
+ ? __MPROTECT_SYSCALL_NO_IA32 \
+ : __MPROTECT_SYSCALL_NO_X86_64)
+#define MUNMAP_SYSCALL_NO(tsk) ((test_tsk_thread_flag((tsk), TIF_IA32)) \
+ ? __MUNMAP_SYSCALL_NO_IA32 \
+ : __MUNMAP_SYSCALL_NO_X86_64)
+#define MREMAP_SYSCALL_NO(tsk) ((test_tsk_thread_flag((tsk), TIF_IA32)) \
+ ? __MREMAP_SYSCALL_NO_IA32 \
+ : __MREMAP_SYSCALL_NO_X86_64)
+# else
+#define MMAP_SYSCALL_NO(tsk) __MMAP_SYSCALL_NO_X86_64
+#define MPROTECT_SYSCALL_NO(tsk) __MPROTECT_SYSCALL_NO_X86_64
+#define MUNMAP_SYSCALL_NO(tsk) __MUNMAP_SYSCALL_NO_X86_64
+#define MREMAP_SYSCALL_NO(tsk) __MREMAP_SYSCALL_NO_X86_64
+# endif
+#endif
+
+#if !defined(MMAP_SYSCALL_NO) || !defined(MPROTECT_SYSCALL_NO) \
+ || !defined(MUNMAP_SYSCALL_NO) || !defined(MREMAP_SYSCALL_NO)
+#error "Unimplemented architecture"
+#endif
+
+#if defined(__i386__) || defined(__x86_64__)
+static inline unsigned long
+__stp_user_syscall_nr(struct pt_regs *regs)
+{
+#if defined(STAPCONF_X86_UNIREGS)
+ return regs->orig_ax;
+#elif defined(__x86_64__)
+ return regs->orig_rax;
+#elif defined (__i386__)
+ return regs->orig_eax;
+#endif
+}
+#endif
+
+#if defined(__i386__) || defined(__x86_64__)
+static inline long *
+__stp_user_syscall_return_value(struct task_struct *task, struct pt_regs *regs)
+{
+#ifdef CONFIG_IA32_EMULATION
+// This code works, but isn't what we need. Since
+// __stp_user_syscall_arg() doesn't sign-extend, a value passed in as
+// an argument and then returned won't compare correctly anymore. So,
+// for now, disable this code.
+# if 0
+ if (test_tsk_thread_flag(task, TIF_IA32))
+ // Sign-extend the value so (int)-EFOO becomes (long)-EFOO
+ // and will match correctly in comparisons.
+ regs->ax = (long) (int) regs->ax;
+# endif
+#endif
+#if defined(STAPCONF_X86_UNIREGS)
+ return &regs->ax;
+#elif defined(__x86_64__)
+ return &regs->rax;
+#elif defined (__i386__)
+ return &regs->eax;
+#endif
+}
+#endif
+
+#if defined(__i386__) || defined(__x86_64__)
+static inline long *
+__stp_user_syscall_arg(struct task_struct *task, struct pt_regs *regs,
+ unsigned int n)
+{
+#if defined(__i386__)
+ if (n > 5) {
+ _stp_error("syscall arg > 5");
+ return NULL;
+ }
+#if defined(STAPCONF_X86_UNIREGS)
+ return &regs->bx + n;
+#else
+ return &regs->ebx + n;
+#endif
+#elif defined(__x86_64__)
+#ifdef CONFIG_IA32_EMULATION
+ if (test_tsk_thread_flag(task, TIF_IA32))
+ switch (n) {
+#if defined(STAPCONF_X86_UNIREGS)
+ case 0: return &regs->bx;
+ case 1: return &regs->cx;
+ case 2: return &regs->dx;
+ case 3: return &regs->si;
+ case 4: return &regs->di;
+ case 5: return &regs->bp;
+#else
+ case 0: return &regs->rbx;
+ case 1: return &regs->rcx;
+ case 2: return &regs->rdx;
+ case 3: return &regs->rsi;
+ case 4: return &regs->rdi;
+ case 5: return &regs->rbp;
+#endif
+ default:
+ _stp_error("syscall arg > 5");
+ return NULL;
+ }
+#endif /* CONFIG_IA32_EMULATION */
+ switch (n) {
+#if defined(STAPCONF_X86_UNIREGS)
+ case 0: return &regs->di;
+ case 1: return &regs->si;
+ case 2: return &regs->dx;
+ case 3: return &regs->r10;
+ case 4: return &regs->r8;
+ case 5: return &regs->r9;
+#else
+ case 0: return &regs->rdi;
+ case 1: return &regs->rsi;
+ case 2: return &regs->rdx;
+ case 3: return &regs->r10;
+ case 4: return &regs->r8;
+ case 5: return &regs->r9;
+#endif
+ default:
+ _stp_error("syscall arg > 5");
+ return NULL;
+ }
+#endif /* CONFIG_X86_32 */
+}
+#endif
+
+#endif /* _SYSCALL_H_ */
diff --git a/runtime/task_finder.c b/runtime/task_finder.c
index e78caab6..71b11569 100644
--- a/runtime/task_finder.c
+++ b/runtime/task_finder.c
@@ -1,5 +1,7 @@
#include <linux/list.h>
#include <linux/binfmts.h>
+#include "syscall.h"
+#include "task_finder_vma.c"
static LIST_HEAD(__stp_task_finder_list);
@@ -11,10 +13,44 @@ struct stap_task_finder_target;
#define __STP_TF_STOPPED 3
atomic_t __stp_task_finder_state = ATOMIC_INIT(__STP_TF_STARTING);
+#ifdef DEBUG_TASK_FINDER
+atomic_t __stp_attach_count = ATOMIC_INIT (0);
+
+#define debug_task_finder_attach() (atomic_inc(&__stp_attach_count))
+#define debug_task_finder_detach() (atomic_dec(&__stp_attach_count))
+#define debug_task_finder_report() (_stp_dbug(__FUNCTION__, __LINE__, \
+ "attach count: %d\n", atomic_read(&__stp_attach_count)))
+#else
+#define debug_task_finder_attach() /* empty */
+#define debug_task_finder_detach() /* empty */
+#define debug_task_finder_report() /* empty */
+#endif
+
typedef int (*stap_task_finder_callback)(struct task_struct *tsk,
int register_p,
+ int process_p,
struct stap_task_finder_target *tgt);
+typedef int (*stap_task_finder_vm_callback)(struct task_struct *tsk,
+ int map_p, char *vm_path,
+ unsigned long vm_start,
+ unsigned long vm_end,
+ unsigned long vm_pgoff);
+
+#ifdef DEBUG_TASK_FINDER_VMA
+int __stp_tf_vm_cb(struct task_struct *tsk,
+ int map_p, char *vm_path,
+ unsigned long vm_start,
+ unsigned long vm_end,
+ unsigned long vm_pgoff)
+{
+ _stp_dbug(__FUNCTION__, __LINE__,
+ "vm_cb: tsk %d:%d path %s, start 0x%08lx, end 0x%08lx, offset 0x%lx\n",
+ tsk->pid, map_p, vm_path, vm_start, vm_end, vm_pgoff);
+ return 0;
+}
+#endif
+
struct stap_task_finder_target {
/* private: */
struct list_head list; /* __stp_task_finder_list linkage */
@@ -28,12 +64,27 @@ struct stap_task_finder_target {
const char *pathname;
pid_t pid;
stap_task_finder_callback callback;
+ stap_task_finder_vm_callback vm_callback;
};
static u32
__stp_utrace_task_finder_target_death(struct utrace_attached_engine *engine,
struct task_struct *tsk);
+static u32
+__stp_utrace_task_finder_target_quiesce(struct utrace_attached_engine *engine,
+ struct task_struct *tsk);
+
+static u32
+__stp_utrace_task_finder_target_syscall_entry(struct utrace_attached_engine *engine,
+ struct task_struct *tsk,
+ struct pt_regs *regs);
+
+static u32
+__stp_utrace_task_finder_target_syscall_exit(struct utrace_attached_engine *engine,
+ struct task_struct *tsk,
+ struct pt_regs *regs);
+
static int
stap_register_task_finder_target(struct stap_task_finder_target *new_tgt)
{
@@ -56,6 +107,11 @@ stap_register_task_finder_target(struct stap_task_finder_target *new_tgt)
new_tgt->engine_attached = 0;
memset(&new_tgt->ops, 0, sizeof(new_tgt->ops));
new_tgt->ops.report_death = &__stp_utrace_task_finder_target_death;
+ new_tgt->ops.report_quiesce = &__stp_utrace_task_finder_target_quiesce;
+ new_tgt->ops.report_syscall_entry = \
+ &__stp_utrace_task_finder_target_syscall_entry;
+ new_tgt->ops.report_syscall_exit = \
+ &__stp_utrace_task_finder_target_syscall_exit;
// Search the list for an existing entry for pathname/pid.
list_for_each(node, &__stp_task_finder_list) {
@@ -115,6 +171,7 @@ stap_utrace_detach_ops(struct utrace_engine_ops *ops)
}
else if (engine != NULL) {
utrace_detach(tsk, engine);
+ debug_task_finder_detach();
}
}
} while_each_thread(grp, tsk);
@@ -125,6 +182,7 @@ udo_err:
_stp_error("utrace_attach returned error %d on pid %d",
error, pid);
}
+ debug_task_finder_report();
}
static void
@@ -190,16 +248,28 @@ __stp_get_mm_path(struct mm_struct *mm, char *buf, int buflen)
return rc;
}
-#define __STP_UTRACE_TASK_FINDER_EVENTS (UTRACE_EVENT(CLONE) \
- | UTRACE_EVENT(EXEC) \
- | UTRACE_EVENT(DEATH))
+#define __STP_TASK_FINDER_EVENTS (UTRACE_EVENT(CLONE) \
+ | UTRACE_EVENT(EXEC) \
+ | UTRACE_EVENT(DEATH))
+
+#define __STP_ATTACHED_TASK_BASE_EVENTS (UTRACE_EVENT(DEATH))
+
+#define __STP_ATTACHED_TASK_VM_BASE_EVENTS (__STP_ATTACHED_TASK_BASE_EVENTS \
+ | UTRACE_EVENT(SYSCALL_ENTRY) \
+ | UTRACE_EVENT(SYSCALL_EXIT))
+
+#define __STP_ATTACHED_TASK_VM_EVENTS (__STP_ATTACHED_TASK_VM_BASE_EVENTS \
+ | UTRACE_ACTION_QUIESCE \
+ | UTRACE_EVENT(QUIESCE))
-#define __STP_UTRACE_ATTACHED_TASK_EVENTS (UTRACE_EVENT(DEATH))
+#define __STP_ATTACHED_TASK_EVENTS(tgt) \
+ ((((tgt)->vm_callback) == NULL) ? __STP_ATTACHED_TASK_BASE_EVENTS \
+ : __STP_ATTACHED_TASK_VM_EVENTS)
static int
-__stp_utrace_attach(struct task_struct *tsk,
- const struct utrace_engine_ops *ops, void *data,
- unsigned long event_flags)
+stap_utrace_attach(struct task_struct *tsk,
+ const struct utrace_engine_ops *ops, void *data,
+ unsigned long event_flags)
{
struct utrace_attached_engine *engine;
struct mm_struct *mm;
@@ -231,13 +301,15 @@ __stp_utrace_attach(struct task_struct *tsk,
}
else {
utrace_set_flags(tsk, engine, event_flags);
+ debug_task_finder_attach();
}
return rc;
}
static inline void
__stp_utrace_attach_match_filename(struct task_struct *tsk,
- const char * const filename)
+ const char * const filename,
+ int register_p, int process_p)
{
size_t filelen;
struct list_head *tgt_node;
@@ -270,72 +342,114 @@ __stp_utrace_attach_match_filename(struct task_struct *tsk,
continue;
if (cb_tgt->callback != NULL) {
- int rc = cb_tgt->callback(tsk, 1, cb_tgt);
+ int rc = cb_tgt->callback(tsk, register_p,
+ process_p, cb_tgt);
if (rc != 0) {
- _stp_error("exec callback for %d failed: %d",
+ _stp_error("callback for %d failed: %d",
(int)tsk->pid, rc);
break;
}
}
- // Set up thread death notification.
- rc = __stp_utrace_attach(tsk, &cb_tgt->ops, cb_tgt,
- __STP_UTRACE_ATTACHED_TASK_EVENTS);
- if (rc != 0 && rc != EPERM)
- break;
- cb_tgt->engine_attached = 1;
+ // Set up events we need for attached tasks.
+ if (register_p) {
+ rc = stap_utrace_attach(tsk, &cb_tgt->ops,
+ cb_tgt,
+ __STP_ATTACHED_TASK_EVENTS(cb_tgt));
+ if (rc != 0 && rc != EPERM)
+ break;
+ cb_tgt->engine_attached = 1;
+ }
+ else {
+ struct utrace_attached_engine *engine;
+ engine = utrace_attach(tsk,
+ UTRACE_ATTACH_MATCH_OPS,
+ &cb_tgt->ops, 0);
+ if (! IS_ERR(engine) && engine != NULL) {
+ utrace_detach(tsk, engine);
+ debug_task_finder_detach();
+ }
+ }
}
}
}
-static u32
-__stp_utrace_task_finder_report_clone(struct utrace_attached_engine *engine,
- struct task_struct *parent,
- unsigned long clone_flags,
- struct task_struct *child)
+// This function handles the details of getting a task's associated
+// pathname, and calling __stp_utrace_attach_match_filename() to
+// attach to it if we find the pathname "interesting". So, what's the
+// difference between path_tsk and match_tsk? Normally they are the
+// same, except in one case. In an UTRACE_EVENT(EXEC), we need to
+// detach engines from the newly exec'ed process (since its path has
+// changed). In this case, we have to match the path of the parent
+// (path_tsk) against the child (match_tsk).
+
+static void
+__stp_utrace_attach_match_tsk(struct task_struct *path_tsk,
+ struct task_struct *match_tsk, int register_p,
+ int process_p)
{
- int rc;
struct mm_struct *mm;
char *mmpath_buf;
char *mmpath;
- if (atomic_read(&__stp_task_finder_state) != __STP_TF_RUNNING)
- return UTRACE_ACTION_RESUME;
-
- // On clone, attach to the child.
- rc = __stp_utrace_attach(child, engine->ops, 0,
- __STP_UTRACE_TASK_FINDER_EVENTS);
- if (rc != 0 && rc != EPERM)
- return UTRACE_ACTION_RESUME;
+ if (path_tsk->pid <= 1 || match_tsk->pid <= 1)
+ return;
- /* Grab the path associated with this task. */
- mm = get_task_mm(child);
+ /* Grab the path associated with the path_tsk. */
+ mm = get_task_mm(path_tsk);
if (! mm) {
/* If the thread doesn't have a mm_struct, it is
* a kernel thread which we need to skip. */
- return UTRACE_ACTION_RESUME;
+ return;
}
// Allocate space for a path
mmpath_buf = _stp_kmalloc(PATH_MAX);
if (mmpath_buf == NULL) {
+ mmput(mm);
_stp_error("Unable to allocate space for path");
- return UTRACE_ACTION_RESUME;
+ return;
}
// Grab the path associated with the new task
mmpath = __stp_get_mm_path(mm, mmpath_buf, PATH_MAX);
mmput(mm); /* We're done with mm */
if (mmpath == NULL || IS_ERR(mmpath)) {
- rc = -PTR_ERR(mmpath);
+ int rc = -PTR_ERR(mmpath);
_stp_error("Unable to get path (error %d) for pid %d",
- rc, (int)child->pid);
+ rc, (int)path_tsk->pid);
}
else {
- __stp_utrace_attach_match_filename(child, mmpath);
+ __stp_utrace_attach_match_filename(match_tsk, mmpath,
+ register_p, process_p);
}
_stp_kfree(mmpath_buf);
+ return;
+}
+
+static u32
+__stp_utrace_task_finder_report_clone(struct utrace_attached_engine *engine,
+ struct task_struct *parent,
+ unsigned long clone_flags,
+ struct task_struct *child)
+{
+ int rc;
+ struct mm_struct *mm;
+ char *mmpath_buf;
+ char *mmpath;
+
+ if (atomic_read(&__stp_task_finder_state) != __STP_TF_RUNNING)
+ return UTRACE_ACTION_RESUME;
+
+ // On clone, attach to the child.
+ rc = stap_utrace_attach(child, engine->ops, 0,
+ __STP_TASK_FINDER_EVENTS);
+ if (rc != 0 && rc != EPERM)
+ return UTRACE_ACTION_RESUME;
+
+ __stp_utrace_attach_match_tsk(parent, child, 1,
+ (clone_flags & CLONE_THREAD) == 0);
return UTRACE_ACTION_RESUME;
}
@@ -353,11 +467,25 @@ __stp_utrace_task_finder_report_exec(struct utrace_attached_engine *engine,
if (atomic_read(&__stp_task_finder_state) != __STP_TF_RUNNING)
return UTRACE_ACTION_RESUME;
- // On exec, check bprm
- if (bprm->filename == NULL)
- return UTRACE_ACTION_RESUME;
+ // When exec'ing, we need to let callers detach from the
+ // parent thread (if necessary). For instance, assume
+ // '/bin/bash' clones and then execs '/bin/ls'. If the user
+ // was probing '/bin/bash', the cloned thread is still
+ // '/bin/bash' up until the exec.
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,25)
+#define real_parent parent
+#endif
+ if (tsk != NULL && tsk->real_parent != NULL
+ && tsk->real_parent->pid > 1) {
+ // We'll hardcode this as a process end, but a thread
+ // *could* call exec (although they aren't supposed to).
+ __stp_utrace_attach_match_tsk(tsk->real_parent, tsk, 0, 1);
+ }
- __stp_utrace_attach_match_filename(tsk, bprm->filename);
+ // We assume that all exec's are exec'ing a new process. Note
+ // that we don't use bprm->filename, since that path can be
+ // relative.
+ __stp_utrace_attach_match_tsk(tsk, tsk, 1, 1);
return UTRACE_ACTION_RESUME;
}
@@ -366,6 +494,7 @@ static u32
stap_utrace_task_finder_report_death(struct utrace_attached_engine *engine,
struct task_struct *tsk)
{
+ debug_task_finder_detach();
return UTRACE_ACTION_DETACH;
}
@@ -376,6 +505,7 @@ __stp_utrace_task_finder_target_death(struct utrace_attached_engine *engine,
struct stap_task_finder_target *tgt = engine->data;
if (atomic_read(&__stp_task_finder_state) != __STP_TF_RUNNING) {
+ debug_task_finder_detach();
return UTRACE_ACTION_DETACH;
}
@@ -392,15 +522,368 @@ __stp_utrace_task_finder_target_death(struct utrace_attached_engine *engine,
int rc;
// Call the callback
- rc = tgt->callback(tsk, 0, tgt);
+ rc = tgt->callback(tsk, 0,
+ (atomic_read(&tsk->signal->live) == 0),
+ tgt);
if (rc != 0) {
_stp_error("death callback for %d failed: %d",
(int)tsk->pid, rc);
}
}
+ debug_task_finder_detach();
return UTRACE_ACTION_DETACH;
}
+static u32
+__stp_utrace_task_finder_target_quiesce(struct utrace_attached_engine *engine,
+ struct task_struct *tsk)
+{
+ struct stap_task_finder_target *tgt = engine->data;
+
+ // Turn off quiesce handling.
+ utrace_set_flags(tsk, engine, __STP_ATTACHED_TASK_VM_BASE_EVENTS);
+
+ if (atomic_read(&__stp_task_finder_state) != __STP_TF_RUNNING) {
+ debug_task_finder_detach();
+ return UTRACE_ACTION_DETACH;
+ }
+
+ if (tgt != NULL && tgt->vm_callback != NULL) {
+ struct mm_struct *mm;
+ char *mmpath_buf;
+ char *mmpath;
+ struct vm_area_struct *vma;
+ int rc;
+
+ /* Call the vm_callback for every vma associated with
+ * a file. */
+ mm = get_task_mm(tsk);
+ if (! mm)
+ goto utftq_out;
+
+ // Allocate space for a path
+ mmpath_buf = _stp_kmalloc(PATH_MAX);
+ if (mmpath_buf == NULL) {
+ mmput(mm);
+ _stp_error("Unable to allocate space for path");
+ goto utftq_out;
+ }
+
+ down_read(&mm->mmap_sem);
+ vma = mm->mmap;
+ while (vma) {
+ if (vma->vm_file) {
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,25)
+ mmpath = d_path(vma->vm_file->f_dentry,
+ vma->vm_file->f_vfsmnt,
+ mmpath_buf, PATH_MAX);
+#else
+ mmpath = d_path(&(vma->vm_file->f_path),
+ mmpath_buf, PATH_MAX);
+#endif
+ if (mmpath) {
+ // Call the callback
+ rc = tgt->vm_callback(tsk, 1, mmpath,
+ vma->vm_start,
+ vma->vm_end,
+ vma->vm_pgoff);
+ if (rc != 0) {
+ _stp_error("vm callback for %d failed: %d",
+ (int)tsk->pid, rc);
+ }
+
+ }
+ else {
+ _stp_dbug(__FUNCTION__, __LINE__,
+ "no mmpath?\n");
+ }
+ }
+ vma = vma->vm_next;
+ }
+ up_read(&mm->mmap_sem);
+ mmput(mm); /* We're done with mm */
+ _stp_kfree(mmpath_buf);
+ }
+
+utftq_out:
+ return (UTRACE_ACTION_NEWSTATE | UTRACE_ACTION_RESUME);
+}
+
+
+struct vm_area_struct *
+__stp_find_file_based_vma(struct mm_struct *mm, unsigned long addr)
+{
+ struct vm_area_struct *vma = find_vma(mm, addr);
+
+ // I'm not positive why the checking for vm_start > addr is
+ // necessary, but it seems to be (sometimes find_vma() returns
+ // a vma that addr doesn't belong to).
+ if (vma && (vma->vm_file == NULL || vma->vm_start > addr))
+ vma = NULL;
+ return vma;
+}
+
+static u32
+__stp_utrace_task_finder_target_syscall_entry(struct utrace_attached_engine *engine,
+ struct task_struct *tsk,
+ struct pt_regs *regs)
+{
+ struct stap_task_finder_target *tgt = engine->data;
+ unsigned long syscall_no;
+ struct mm_struct *mm;
+ struct vm_area_struct *vma;
+ unsigned long *arg0_addr, arg0;
+ int rc;
+
+ if (atomic_read(&__stp_task_finder_state) != __STP_TF_RUNNING) {
+ debug_task_finder_detach();
+ return UTRACE_ACTION_DETACH;
+ }
+
+ if (tgt == NULL || tgt->vm_callback == NULL)
+ return UTRACE_ACTION_RESUME;
+
+ // See if syscall is one we're interested in.
+ //
+ // FIXME: do we need to handle mremap()?
+ syscall_no = __stp_user_syscall_nr(regs);
+ if (syscall_no != MMAP_SYSCALL_NO(tsk)
+ && syscall_no != MPROTECT_SYSCALL_NO(tsk)
+ && syscall_no != MUNMAP_SYSCALL_NO(tsk))
+ return UTRACE_ACTION_RESUME;
+
+
+ // We need the first syscall argument to see what address
+ // we're operating on.
+ arg0_addr = __stp_user_syscall_arg(tsk, regs, 0);
+ if ((rc = __stp_get_user(arg0, arg0_addr)) != 0) {
+ _stp_error("couldn't read syscall arg 0 for pid %d: %d",
+ tsk->pid, rc);
+ }
+ else if (arg0 != (unsigned long)NULL) {
+ mm = get_task_mm(tsk);
+ if (mm) {
+ down_read(&mm->mmap_sem);
+
+ // If we can find a matching vma associated
+ // with a file, save off its details.
+ vma = __stp_find_file_based_vma(mm, arg0);
+ if (vma != NULL) {
+ __stp_tf_add_vma(tsk, arg0, vma);
+ }
+
+ up_read(&mm->mmap_sem);
+ mmput(mm);
+ }
+ }
+ return UTRACE_ACTION_RESUME;
+}
+
+static void
+__stp_target_call_vm_callback(struct stap_task_finder_target *tgt,
+ struct task_struct *tsk,
+ struct vm_area_struct *vma)
+{
+ char *mmpath_buf;
+ char *mmpath;
+ int rc;
+
+ // Allocate space for a path
+ mmpath_buf = _stp_kmalloc(PATH_MAX);
+ if (mmpath_buf == NULL) {
+ _stp_error("Unable to allocate space for path");
+ return;
+ }
+
+ // Grab the path associated with this vma.
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,25)
+ mmpath = d_path(vma->vm_file->f_dentry, vma->vm_file->f_vfsmnt,
+ mmpath_buf, PATH_MAX);
+#else
+ mmpath = d_path(&(vma->vm_file->f_path), mmpath_buf, PATH_MAX);
+#endif
+ if (mmpath == NULL || IS_ERR(mmpath)) {
+ rc = -PTR_ERR(mmpath);
+ _stp_error("Unable to get path (error %d) for pid %d",
+ rc, (int)tsk->pid);
+ }
+ else {
+ rc = tgt->vm_callback(tsk, 1, mmpath, vma->vm_start,
+ vma->vm_end, vma->vm_pgoff);
+ if (rc != 0) {
+ _stp_error("vm callback for %d failed: %d",
+ (int)tsk->pid, rc);
+ }
+ }
+ _stp_kfree(mmpath_buf);
+}
+
+static u32
+__stp_utrace_task_finder_target_syscall_exit(struct utrace_attached_engine *engine,
+ struct task_struct *tsk,
+ struct pt_regs *regs)
+{
+ struct stap_task_finder_target *tgt = engine->data;
+ unsigned long syscall_no;
+ unsigned long *rv_addr, rv;
+ unsigned long *arg0_addr, arg0;
+ int rc;
+ struct mm_struct *mm;
+ struct vm_area_struct *vma;
+ struct __stp_tf_vma_entry *entry = NULL;
+
+ if (atomic_read(&__stp_task_finder_state) != __STP_TF_RUNNING) {
+ debug_task_finder_detach();
+ return UTRACE_ACTION_DETACH;
+ }
+
+ if (tgt == NULL || tgt->vm_callback == NULL)
+ return UTRACE_ACTION_RESUME;
+
+ // See if syscall is one we're interested in.
+ //
+ // FIXME: do we need to handle mremap()?
+ syscall_no = __stp_user_syscall_nr(regs);
+ if (syscall_no != MMAP_SYSCALL_NO(tsk)
+ && syscall_no != MPROTECT_SYSCALL_NO(tsk)
+ && syscall_no != MUNMAP_SYSCALL_NO(tsk))
+ return UTRACE_ACTION_RESUME;
+
+ // Get return value
+ rv_addr = __stp_user_syscall_return_value(tsk, regs);
+ if ((rc = __stp_get_user(rv, rv_addr)) != 0) {
+ _stp_error("couldn't read syscall return value for pid %d: %d",
+ tsk->pid, rc);
+ return UTRACE_ACTION_RESUME;
+ }
+
+ // We need the first syscall argument to see what address we
+ // were operating on.
+ arg0_addr = __stp_user_syscall_arg(tsk, regs, 0);
+ if ((rc = __stp_get_user(arg0, arg0_addr)) != 0) {
+ _stp_error("couldn't read syscall arg 0 for pid %d: %d",
+ tsk->pid, rc);
+ return UTRACE_ACTION_RESUME;
+ }
+
+#ifdef DEBUG_TASK_FINDER_VMA
+ _stp_dbug(__FUNCTION__, __LINE__,
+ "tsk %d found %s(0x%lx), returned 0x%lx\n",
+ tsk->pid,
+ ((syscall_no == MMAP_SYSCALL_NO(tsk)) ? "mmap"
+ : ((syscall_no == MPROTECT_SYSCALL_NO(tsk)) ? "mprotect"
+ : ((syscall_no == MUNMAP_SYSCALL_NO(tsk)) ? "munmap"
+ : "UNKNOWN"))),
+ arg0, rv);
+#endif
+
+ // Try to find the vma info we might have saved.
+ if (arg0 != (unsigned long)NULL)
+ entry = __stp_tf_get_vma_entry(tsk, arg0);
+
+ // If entry is NULL, this means we didn't find a file based
+ // vma to store in the syscall_entry routine. This could mean
+ // we just created a new vma.
+ if (entry == NULL) {
+ mm = get_task_mm(tsk);
+ if (mm) {
+ down_read(&mm->mmap_sem);
+ vma = __stp_find_file_based_vma(mm, rv);
+ if (vma != NULL) {
+ __stp_target_call_vm_callback(tgt, tsk,
+ vma);
+ }
+ up_read(&mm->mmap_sem);
+ mmput(mm);
+ }
+ }
+ // If we found saved vma information, try to match it up with
+ // what currently exists.
+ else {
+#ifdef DEBUG_TASK_FINDER_VMA
+ _stp_dbug(__FUNCTION__, __LINE__,
+ "** found stored vma 0x%lx/0x%lx/0x%lx!\n",
+ entry->vm_start, entry->vm_end, entry->vm_pgoff);
+#endif
+ mm = get_task_mm(tsk);
+ if (mm) {
+ down_read(&mm->mmap_sem);
+ vma = __stp_find_file_based_vma(mm, entry->vm_start);
+
+ // We couldn't find the vma at all. The
+ // original vma was deleted.
+ if (vma == NULL) {
+ // FIXME: We'll need to figure out to
+ // retrieve the path of a deleted
+ // vma.
+ rc = tgt->vm_callback(tsk, 0, NULL,
+ entry->vm_start,
+ entry->vm_end,
+ entry->vm_pgoff);
+ if (rc != 0) {
+ _stp_error("vm callback for %d failed: %d",
+ (int)tsk->pid, rc);
+ }
+ }
+
+ // If nothing has changed, there is no
+ // need to call the callback.
+ else if (vma->vm_start == entry->vm_start
+ && vma->vm_end == entry->vm_end
+ && vma->vm_pgoff == entry->vm_pgoff) {
+ // do nothing
+ }
+
+ // The original vma has been changed. It is
+ // possible that calling mprotect (e.g.) split
+ // up an existing vma into 2 or 3 new vma's
+ // (assuming it protected a portion of the
+ // original vma at the beginning, middle, or
+ // end). Try to determine what happened.
+ else {
+ unsigned long tmp;
+
+ // First report that the original vma
+ // is gone.
+ //
+ // FIXME: We'll need to figure out to
+ // retrieve the path of a deleted
+ // vma.
+ rc = tgt->vm_callback(tsk, 0, NULL,
+ entry->vm_start,
+ entry->vm_end,
+ entry->vm_pgoff);
+ if (rc != 0) {
+ _stp_error("vm callback for %d failed: %d",
+ (int)tsk->pid, rc);
+ }
+
+ // Now find all the new vma's that
+ // made up the original vma's address
+ // space and call the callback on each
+ // new vma.
+ tmp = entry->vm_start;
+ while (((vma = __stp_find_file_based_vma(mm,
+ tmp))
+ != NULL)
+ && vma->vm_end <= entry->vm_end) {
+ __stp_target_call_vm_callback(tgt, tsk,
+ vma);
+ if (vma->vm_end >= entry->vm_end)
+ break;
+ tmp = vma->vm_end;
+ }
+ }
+ up_read(&mm->mmap_sem);
+ mmput(mm);
+ }
+
+ // Cleanup by deleting the saved vma info.
+ __stp_tf_remove_vma_entry(entry);
+ }
+ return UTRACE_ACTION_RESUME;
+}
+
struct utrace_engine_ops __stp_utrace_task_finder_ops = {
.report_clone = __stp_utrace_task_finder_report_clone,
.report_exec = __stp_utrace_task_finder_report_exec,
@@ -429,8 +912,8 @@ stap_start_task_finder(void)
size_t mmpathlen;
struct list_head *tgt_node;
- rc = __stp_utrace_attach(tsk, &__stp_utrace_task_finder_ops, 0,
- __STP_UTRACE_TASK_FINDER_EVENTS);
+ rc = stap_utrace_attach(tsk, &__stp_utrace_task_finder_ops, 0,
+ __STP_TASK_FINDER_EVENTS);
if (rc == EPERM) {
/* Ignore EPERM errors, which mean this wasn't
* a thread we can attach to. */
@@ -482,21 +965,27 @@ stap_start_task_finder(void)
cb_tgt = list_entry(cb_node,
struct stap_task_finder_target,
callback_list);
- if (cb_tgt == NULL || cb_tgt->callback == NULL)
+ if (cb_tgt == NULL)
continue;
- // Call the callback.
- rc = cb_tgt->callback(tsk, 1, cb_tgt);
- if (rc != 0) {
- _stp_error("attach callback for %d failed: %d",
- (int)tsk->pid, rc);
- goto stf_err;
+ // Call the callback. Assume that if
+ // the thread is a thread group
+ // leader, it is a process.
+ if (cb_tgt->callback != NULL) {
+ rc = cb_tgt->callback(tsk, 1,
+ (tsk->pid == tsk->tgid),
+ cb_tgt);
+ if (rc != 0) {
+ _stp_error("attach callback for %d failed: %d",
+ (int)tsk->pid, rc);
+ goto stf_err;
+ }
}
- // Set up thread death notification.
- rc = __stp_utrace_attach(tsk, &cb_tgt->ops,
- cb_tgt,
- __STP_UTRACE_ATTACHED_TASK_EVENTS);
+ // Set up events we need for attached tasks.
+ rc = stap_utrace_attach(tsk, &cb_tgt->ops,
+ cb_tgt,
+ __STP_ATTACHED_TASK_EVENTS(cb_tgt));
if (rc != 0 && rc != EPERM)
goto stf_err;
cb_tgt->engine_attached = 1;
@@ -514,7 +1003,9 @@ static void
stap_stop_task_finder(void)
{
atomic_set(&__stp_task_finder_state, __STP_TF_STOPPING);
+ debug_task_finder_report();
stap_utrace_detach_ops(&__stp_utrace_task_finder_ops);
__stp_task_finder_cleanup();
+ debug_task_finder_report();
atomic_set(&__stp_task_finder_state, __STP_TF_STOPPED);
}
diff --git a/runtime/task_finder_vma.c b/runtime/task_finder_vma.c
new file mode 100644
index 00000000..76b5c059
--- /dev/null
+++ b/runtime/task_finder_vma.c
@@ -0,0 +1,112 @@
+#include <linux/list.h>
+#include <linux/jhash.h>
+#include <linux/mutex.h>
+
+// __stp_tf_vma_mutex protects the hash table.
+static DEFINE_MUTEX(__stp_tf_vma_mutex);
+
+#define __STP_TF_HASH_BITS 4
+#define __STP_TF_TABLE_SIZE (1 << __STP_TF_HASH_BITS)
+
+struct __stp_tf_vma_entry {
+ struct hlist_node hlist;
+
+ pid_t pid;
+ unsigned long addr;
+ unsigned long vm_start;
+ unsigned long vm_end;
+ unsigned long vm_pgoff;
+ // Is that enough? Should we store a dcookie for vm_file?
+};
+
+static struct hlist_head __stp_tf_vma_table[__STP_TF_TABLE_SIZE];
+
+static inline u32
+__stp_tf_vma_hash(struct task_struct *tsk, unsigned long addr)
+{
+#ifdef CONFIG_64BIT
+ return (jhash_3words(tsk->pid, (u32)addr, (u32)(addr >> 32), 0)
+ & (__STP_TF_TABLE_SIZE - 1));
+#else
+ return (jhash_2words(tsk->pid, addr, 0) & (__STP_TF_TABLE_SIZE - 1));
+#endif
+}
+
+
+// Get vma_entry if the vma is present in the vma hash table.
+// Returns NULL if not present.
+static struct __stp_tf_vma_entry *
+__stp_tf_get_vma_entry(struct task_struct *tsk, unsigned long addr)
+{
+ struct hlist_head *head;
+ struct hlist_node *node;
+ struct __stp_tf_vma_entry *entry;
+
+ mutex_lock(&__stp_tf_vma_mutex);
+ head = &__stp_tf_vma_table[__stp_tf_vma_hash(tsk, addr)];
+ hlist_for_each_entry(entry, node, head, hlist) {
+ if (tsk->pid == entry->pid
+ && addr == entry->addr) {
+ mutex_unlock(&__stp_tf_vma_mutex);
+ return entry;
+ }
+ }
+ mutex_unlock(&__stp_tf_vma_mutex);
+ return NULL;
+}
+
+// Add the vma info to the vma hash table.
+static int
+__stp_tf_add_vma(struct task_struct *tsk, unsigned long addr,
+ struct vm_area_struct *vma)
+{
+ struct hlist_head *head;
+ struct hlist_node *node;
+ struct __stp_tf_vma_entry *entry;
+
+ mutex_lock(&__stp_tf_vma_mutex);
+ head = &__stp_tf_vma_table[__stp_tf_vma_hash(tsk, addr)];
+ hlist_for_each_entry(entry, node, head, hlist) {
+ if (tsk->pid == entry->pid
+ && addr == entry->addr) {
+ printk(KERN_NOTICE
+ "vma (pid: %d, vm_start: 0x%lx) present?\n",
+ tsk->pid, vma->vm_start);
+ mutex_unlock(&__stp_tf_vma_mutex);
+ return -EBUSY; /* Already there */
+ }
+ }
+
+ // Using kmalloc here to allocate an element. Could cause some
+ // memory fragmentation if overused.
+ entry = kmalloc(sizeof(struct __stp_tf_vma_entry), GFP_KERNEL);
+ if (!entry) {
+ mutex_unlock(&__stp_tf_vma_mutex);
+ return -ENOMEM;
+ }
+ entry->pid = tsk->pid;
+ entry->addr = addr;
+ entry->vm_start = vma->vm_start;
+ entry->vm_end = vma->vm_end;
+ entry->vm_pgoff = vma->vm_pgoff;
+ hlist_add_head(&entry->hlist, head);
+ mutex_unlock(&__stp_tf_vma_mutex);
+ return 0;
+}
+
+// Remove the vma entry from the vma hash table.
+static int
+__stp_tf_remove_vma_entry(struct __stp_tf_vma_entry *entry)
+{
+ struct hlist_head *head;
+ struct hlist_node *node;
+ int found = 0;
+
+ if (entry != NULL) {
+ mutex_lock(&__stp_tf_vma_mutex);
+ hlist_del(&entry->hlist);
+ kfree(entry);
+ mutex_unlock(&__stp_tf_vma_mutex);
+ }
+ return 0;
+}
diff --git a/runtime/tests/ChangeLog b/runtime/tests/ChangeLog
deleted file mode 100644
index 38634d0f..00000000
--- a/runtime/tests/ChangeLog
+++ /dev/null
@@ -1,112 +0,0 @@
-2006-01-25 Martin Hunt <hunt@redhat.com>
-
- * agg/stats.c (main): Delete Stats when done.
-
-2005-12-08 Martin Hunt <hunt@redhat.com>
-
- * maps/map.test: Add size test.
- * pmaps/pmap.test: Add size test.
-
-2005-12-07 Martin Hunt <hunt@redhat.com>
-
- * agg/agg.test: Adjust results to match
- the more compact histogram format.
-
- * pmaps/*.c: Change pmap type from MAP to PMAP.
-
- * pmaps/pmap.test: Adjust results to match
- the more compact histogram format.
-
- * maps/map.test: Adjust results to match
- the more compact histogram format.
-
-2005-11-28 Martin Hunt <hunt@redhat.com>
-
- * pmaps/pmap.test: Add ix_log and ix_none.
- * pmaps/ix_log.c: Test log histograms.
- * pmaps/ix_none.c: Test no histograms.
-
-2005-11-10 Martin Hunt <hunt@redhat.com>
- * pmaps/ix2.c: New test. Test _stp_pmap_get_*().
- * pmaps/iii3.c: New test. Test _stp_pmap_get_*().
- * pmaps/pmap.test: Update.
-
-2005-11-10 Martin Hunt <hunt@redhat.com>
- * pmaps/ii2.c: New test of maps and pmaps with the same keysym.
- * pmaps/pmap.test: Update.
-
-2005-11-09 Martin Hunt <hunt@redhat.com>
-
- * maps/sort2.c: New file.
- * maps/sort_stat.c: New file.
- * maps/map.test: Update
-
-2005-11-08 Martin Hunt <hunt@redhat.com>
-
- * maps/map.test: Remove old map API tests.
- * maps/ii2.c: Renamed ii.c.
- * maps/iiss2.c: Renamed iiss.c.
- * maps/is2.c: Renamed is.c.
- * maps/issii2.c: Renamed issii.c.
- * maps/isx2.c: Renamed isx.c.
- * maps/map_format2.c: Renamed map_format.c.
- * maps/si2.c: Renamed si.c.
- * maps/keys.c: Deleted
- * maps/test_list_int64.c: Deleted.
- * maps/test_list_string.c: Deleted.
- * maps/sort.c: Update to use new map API.
-
-2005-11-08 Martin Hunt <hunt@redhat.com>
-
- * pmaps/*: Add new pmaps tests.
-
-2005-10-28 Martin Hunt <hunt@redhat.com>
- * maps/keys.c: New file. Tests specific to _stp_key_get_*().
-
- * maps/iiss2.c (main): Add some comments to make clear expected
- results.
- * maps/is2.c (main): _stp_map_get_*s() now returns "" instead
- of NULL when lookup fails. _stp_map_set_*s() now deletes a node
- when setting to "" (as well as NULL).
- * maps/setadd.c (main): Ditto.
- * maps/map.test: update results.
-
-2005-10-26 Martin Hunt <hunt@redhat.com>
-
- * maps/map.test: Add results for iiiiii and ssssss.
- * maps/iiiiii.c: New file.
- * maps/ssssss.c: New file.
-
-2005-10-26 Martin Hunt <hunt@redhat.com>
-
- * maps/map.test: Add results for issii2.
-
-2005-10-26 Martin Hunt <hunt@redhat.com>
-
- * maps/map.test: Update with results for new tests.
- * maps/*2.c: Tests for the new API.
- * maps/ist.c: Renamed isx.c.
- * maps/setadd.c: New test of adding and setting.
-
-2005-09-23 Martin Hunt <hunt@redhat.com>
-
- * maps/map.test: Add sort results.
- * maps/sort.c: New test.
-
-2005-09-14 Martin Hunt <hunt@redhat.com>
-
- * maps/ii.c (main): Add test for _stp_map_clear().
- * maps/map.test: Update results.
-
-2005-09-12 Martin Hunt <hunt@redhat.com>
-
- * math/div64.c (main): Set the expected result for LLONG_MIN/-1 to
- be LLONG_MIN (overflow) instead of 0.
-
-2005-09-09 Martin Hunt <hunt@redhat.com>
-
- * math/div64.c (main): Fixes for running on 64-bit hardware.
-
- * README: Update.
- * math/div64.c: New file. 64-bit division tests.
-
diff --git a/runtime/tests/Makefile b/runtime/tests/Makefile
deleted file mode 100644
index 4e744d25..00000000
--- a/runtime/tests/Makefile
+++ /dev/null
@@ -1,3 +0,0 @@
-tests:
- tclsh all.tcl
-
diff --git a/runtime/tests/README b/runtime/tests/README
deleted file mode 100644
index 000f1017..00000000
--- a/runtime/tests/README
+++ /dev/null
@@ -1,7 +0,0 @@
-This directory contains the user-levels tests.
-
-Before running these for the first time,
-> cd ../user
-> ./recreate_links
-
-To run the test here, just type "make".
diff --git a/runtime/tests/agg/Makefile b/runtime/tests/agg/Makefile
deleted file mode 100644
index c396c132..00000000
--- a/runtime/tests/agg/Makefile
+++ /dev/null
@@ -1,5 +0,0 @@
-default: tests
-
-tests:
- tclsh all.tcl
-
diff --git a/runtime/tests/agg/agg.test b/runtime/tests/agg/agg.test
deleted file mode 100644
index 2d56f031..00000000
--- a/runtime/tests/agg/agg.test
+++ /dev/null
@@ -1,169 +0,0 @@
-package require tcltest
-namespace import -force tcltest::*
-
-cd $tcltest::testsDirectory
-
-set CFLAGS "-Os"
-set KPATH "/lib/modules/[exec uname -r]/build/include"
-set MPATH "/lib/modules/[exec uname -r]/build/include/asm/mach-default"
-set PATH "../../user"
-
-test Counter {Counter Test} -setup {
- exec gcc $CFLAGS -I $KPATH -I $PATH -I $MPATH -o test count.c
-} -body {
- exec ./test
-} -result {cnt1[0] = 1
-cnt2[0] = 10
-cnt1[1] = 2
-cnt2[1] = 11
-cnt1[2] = 3
-cnt2[2] = 12
-cnt1[3] = 4
-cnt2[3] = 13
-cnt1[4] = 5
-cnt2[4] = 14
-cnt1[5] = 6
-cnt2[5] = 15
-cnt1[6] = 7
-cnt2[6] = 16
-cnt1[7] = 8
-cnt2[7] = 17
-cnt1 = 36
-cnt2 = 108
---------------------
-cnt1[0] = 2
-cnt2[0] = 20
-cnt1[1] = 4
-cnt2[1] = 22
-cnt1[2] = 6
-cnt2[2] = 24
-cnt1[3] = 8
-cnt2[3] = 26
-cnt1[4] = 10
-cnt2[4] = 28
-cnt1[5] = 12
-cnt2[5] = 30
-cnt1[6] = 14
-cnt2[6] = 32
-cnt1[7] = 16
-cnt2[7] = 34
-cnt1 = 72
-cnt2 = 216
---------------------
-cnt1 = 140
-cnt2 = 784
-cnt1 = 0
-cnt2 = 0
---------------------
-cnt1[0] = 0
-cnt2[0] = 0
-cnt1[1] = 1
-cnt2[1] = 1
-cnt1[2] = 4
-cnt2[2] = 8
-cnt1[3] = 9
-cnt2[3] = 27
-cnt1[4] = 16
-cnt2[4] = 64
-cnt1[5] = 25
-cnt2[5] = 125
-cnt1[6] = 36
-cnt2[6] = 216
-cnt1[7] = 49
-cnt2[7] = 343
-cnt1 = 140
-cnt2 = 784}
-
-test Stats {Stats Test} -setup {
- exec gcc $CFLAGS -I $KPATH -I $PATH -I $MPATH -o test stats.c
-} -body {
- exec ./test
-} -result {st1[0] = count: 1 sum:1
-st2[0] = count: 1 sum:10
-st3[0] = count: 1 sum:100
-st1[1] = count: 1 sum:2
-st2[1] = count: 1 sum:11
-st3[1] = count: 1 sum:101
-st1[2] = count: 1 sum:3
-st2[2] = count: 1 sum:12
-st3[2] = count: 1 sum:102
-st1[3] = count: 1 sum:4
-st2[3] = count: 1 sum:13
-st3[3] = count: 1 sum:103
-st1[4] = count: 1 sum:5
-st2[4] = count: 1 sum:14
-st3[4] = count: 1 sum:104
-st1[5] = count: 1 sum:6
-st2[5] = count: 1 sum:15
-st3[5] = count: 1 sum:105
-st1[6] = count: 1 sum:7
-st2[6] = count: 1 sum:16
-st3[6] = count: 1 sum:106
-st1[7] = count: 1 sum:8
-st2[7] = count: 1 sum:17
-st3[7] = count: 1 sum:107
---------------------
-CPU: 0 Count: 1 Sum: 1
-CPU: 1 Count: 1 Sum: 2
-CPU: 2 Count: 1 Sum: 3
-CPU: 3 Count: 1 Sum: 4
-CPU: 4 Count: 1 Sum: 5
-CPU: 5 Count: 1 Sum: 6
-CPU: 6 Count: 1 Sum: 7
-CPU: 7 Count: 1 Sum: 8
-CPU: 0 Count: 1 Sum: 10
-CPU: 1 Count: 1 Sum: 11
-CPU: 2 Count: 1 Sum: 12
-CPU: 3 Count: 1 Sum: 13
-CPU: 4 Count: 1 Sum: 14
-CPU: 5 Count: 1 Sum: 15
-CPU: 6 Count: 1 Sum: 16
-CPU: 7 Count: 1 Sum: 17
-CPU: 0 Count: 1 Sum: 100
-CPU: 1 Count: 1 Sum: 101
-CPU: 2 Count: 1 Sum: 102
-CPU: 3 Count: 1 Sum: 103
-CPU: 4 Count: 1 Sum: 104
-CPU: 5 Count: 1 Sum: 105
-CPU: 6 Count: 1 Sum: 106
-CPU: 7 Count: 1 Sum: 107
---------------------
-Count: 8 Sum: 36
-Count: 8 Sum: 108
-Count: 8 Sum: 828
---------------------
-count:8 sum:36 avg:4 min:1 max:8
-
-count:8 sum:108 avg:13 min:10 max:17
-value |-------------------------------------------------- count
- 2 | 0
- 4 | 0
- 8 |@@@@@@ 6
- 16 |@@ 2
- 32 | 0
-
-count:8 sum:828 avg:103 min:100 max:107
-value |-------------------------------------------------- count
- 85 | 0
- 90 | 0
- 95 |@@@@@@@@ 8
-
-count:0 sum:0 avg:0 min:0 max:0
-
-count:0 sum:0 avg:0 min:0 max:0
-value |-------------------------------------------------- count
- 0 | 0
- 1 | 0
- 2 | 0
-
-count:0 sum:0 avg:0 min:0 max:0
-value |-------------------------------------------------- count
- 0 | 0
- 5 | 0
- 10 | 0
-}
-
-
-exec rm test
-
-cleanupTests
diff --git a/runtime/tests/agg/all.tcl b/runtime/tests/agg/all.tcl
deleted file mode 100644
index 23757202..00000000
--- a/runtime/tests/agg/all.tcl
+++ /dev/null
@@ -1,4 +0,0 @@
-package require tcltest
-namespace import -force tcltest::*
-tcltest::testsDirectory [file dir [info script]]
-tcltest::runAllTests
diff --git a/runtime/tests/agg/count.c b/runtime/tests/agg/count.c
deleted file mode 100644
index 8e674d1e..00000000
--- a/runtime/tests/agg/count.c
+++ /dev/null
@@ -1,72 +0,0 @@
-#include "runtime.h"
-
-/* test of Counters */
-#include "counter.c"
-
-int main ()
-{
- int i;
- Counter cnt1 = _stp_counter_init();
- Counter cnt2 = _stp_counter_init();
-
- /* testing _stp_counter_add(). These will only be correct if _stp_counter_init() */
- /* set all values to 0 and add works properly. */
- for (_processor_number = 0; _processor_number < NR_CPUS; _processor_number++) {
- _stp_counter_add (cnt1, _processor_number + 1);
- _stp_counter_add (cnt2, _processor_number + 10);
- }
-
- /* testing _stp_counter_get_cpu() */
- for (i = 0; i < NR_CPUS; i++) {
- printf ("cnt1[%d] = %lld\n", i, _stp_counter_get_cpu(cnt1, i, 0));
- printf ("cnt2[%d] = %lld\n", i, _stp_counter_get_cpu(cnt2, i, 0));
- }
-
- /* testing _stp_counter_get() */
- printf ("cnt1 = %d\n", _stp_counter_get(cnt1, 0));
- printf ("cnt2 = %d\n", _stp_counter_get(cnt2, 0));
- printf ("--------------------\n");
-
- /* testing _stp_counter_add() */
- for (_processor_number = 0; _processor_number < NR_CPUS; _processor_number++) {
- _stp_counter_add (cnt1, _processor_number + 1);
- _stp_counter_add (cnt2, _processor_number + 10);
- }
-
- for (i = 0; i < NR_CPUS; i++) {
- printf ("cnt1[%d] = %lld\n", i, _stp_counter_get_cpu(cnt1, i, 0));
- printf ("cnt2[%d] = %lld\n", i, _stp_counter_get_cpu(cnt2, i, 0));
- }
- printf ("cnt1 = %d\n", _stp_counter_get(cnt1, 1));
- printf ("cnt2 = %d\n", _stp_counter_get(cnt2, 1));
-
- printf ("--------------------\n");
-
- for (_processor_number = 0; _processor_number < NR_CPUS; _processor_number++) {
- _stp_counter_add (cnt1, _processor_number * _processor_number);
- _stp_counter_add (cnt2, _processor_number * _processor_number * _processor_number);
- }
-
- printf ("cnt1 = %d\n", _stp_counter_get(cnt1, 1));
- printf ("cnt2 = %d\n", _stp_counter_get(cnt2, 1));
- printf ("cnt1 = %d\n", _stp_counter_get(cnt1, 0));
- printf ("cnt2 = %d\n", _stp_counter_get(cnt2, 0));
- printf ("--------------------\n");
-
-
- for (_processor_number = 0; _processor_number < NR_CPUS; _processor_number++) {
- _stp_counter_add (cnt1, _processor_number * _processor_number);
- _stp_counter_add (cnt2, _processor_number * _processor_number * _processor_number);
- }
-
- for (i = 0; i < NR_CPUS; i++) {
- printf ("cnt1[%d] = %lld\n", i, _stp_counter_get_cpu(cnt1, i, 0));
- printf ("cnt2[%d] = %lld\n", i, _stp_counter_get_cpu(cnt2, i, 0));
- }
- printf ("cnt1 = %d\n", _stp_counter_get(cnt1, 0));
- printf ("cnt2 = %d\n", _stp_counter_get(cnt2, 0));
-
- _stp_counter_free (cnt1);
- _stp_counter_free (cnt2);
- return 0;
-}
diff --git a/runtime/tests/agg/stats.c b/runtime/tests/agg/stats.c
deleted file mode 100644
index 58fb9d41..00000000
--- a/runtime/tests/agg/stats.c
+++ /dev/null
@@ -1,62 +0,0 @@
-#include "runtime.h"
-
-/* test of Stats */
-#include "stat.c"
-
-int main ()
-{
- int i;
- struct stat_data *st;
- Stat st1 = _stp_stat_init(HIST_NONE);
- Stat st2 = _stp_stat_init(HIST_LOG, 7);
- Stat st3 = _stp_stat_init(HIST_LINEAR, 0, 100, 5);
-
- for (_processor_number = 0; _processor_number < NR_CPUS; _processor_number++) {
- _stp_stat_add (st1, _processor_number + 1);
- _stp_stat_add (st2, _processor_number + 10);
- _stp_stat_add (st3, _processor_number + 100);
- }
- _processor_number = 0;
-
- /* this is for internal testing only. Not recommended */
- for (i = 0; i < NR_CPUS; i++) {
- st = _stp_stat_get_cpu(st1, i);
- printf ("st1[%d] = count: %lld sum:%lld\n", i, st->count, st->sum);
- STAT_UNLOCK(st1);
- st = _stp_stat_get_cpu(st2, i);
- printf ("st2[%d] = count: %lld sum:%lld\n", i, st->count, st->sum);
- STAT_UNLOCK(st2);
- st = _stp_stat_get_cpu(st3, i);
- printf ("st3[%d] = count: %lld sum:%lld\n", i, st->count, st->sum);
- STAT_UNLOCK(st3);
- }
- _stp_printf ("--------------------\n");
-
- /* normal way to print per-cpu stats */
- _stp_stat_print_cpu (st1, "CPU: %c\tCount: %C\tSum: %S", 0);
- _stp_stat_print_cpu (st2, "CPU: %c\tCount: %C\tSum: %S", 0);
- _stp_stat_print_cpu (st3, "CPU: %c\tCount: %C\tSum: %S", 0);
- printf ("--------------------\n");
-
- /* basic aggregated stats */
- _stp_stat_print (st1, "Count: %C\tSum: %S", 0);
- _stp_stat_print (st2, "Count: %C\tSum: %S", 0);
- _stp_stat_print (st3, "Count: %C\tSum: %S", 0);
- printf ("--------------------\n");
-
- /* now print full stats */
- _stp_stat_print (st1, "count:%C sum:%S avg:%A min:%m max:%M\n%H", 1);
- _stp_stat_print (st2, "count:%C sum:%S avg:%A min:%m max:%M\n%H", 1);
- _stp_stat_print (st3, "count:%C sum:%S avg:%A min:%m max:%M\n%H", 1);
-
- /* and print again, after they were cleared */
- _stp_stat_print (st1, "count:%C sum:%S avg:%A min:%m max:%M\n%H", 1);
- _stp_stat_print (st2, "count:%C sum:%S avg:%A min:%m max:%M\n%H", 1);
- _stp_stat_print (st3, "count:%C sum:%S avg:%A min:%m max:%M\n%H", 1);
-
- _stp_print_flush();
- _stp_stat_del(st1);
- _stp_stat_del(st2);
- _stp_stat_del(st3);
- return 0;
-}
diff --git a/runtime/tests/all.tcl b/runtime/tests/all.tcl
deleted file mode 100644
index f820c588..00000000
--- a/runtime/tests/all.tcl
+++ /dev/null
@@ -1,12 +0,0 @@
-package require tcltest
-namespace import -force tcltest::*
-
-puts "Running all SystemTap tests"
-
-#puts [tcltest::configure]
-#puts [tcltest::configure -file]
-
-
-tcltest::runAllTests
-
-puts "All tests completed"
diff --git a/runtime/tests/maps/Makefile b/runtime/tests/maps/Makefile
deleted file mode 100644
index c396c132..00000000
--- a/runtime/tests/maps/Makefile
+++ /dev/null
@@ -1,5 +0,0 @@
-default: tests
-
-tests:
- tclsh all.tcl
-
diff --git a/runtime/tests/maps/README b/runtime/tests/maps/README
deleted file mode 100644
index 3ff31703..00000000
--- a/runtime/tests/maps/README
+++ /dev/null
@@ -1,4 +0,0 @@
-Read ../README first!
-
-The *.c files test associative arrays (maps). "make tests" to run.
-
diff --git a/runtime/tests/maps/all.tcl b/runtime/tests/maps/all.tcl
deleted file mode 100644
index c0b38a0e..00000000
--- a/runtime/tests/maps/all.tcl
+++ /dev/null
@@ -1,5 +0,0 @@
-package require tcltest
-namespace import -force tcltest::*
-tcltest::testsDirectory [file dir [info script]]
-tcltest::runAllTests
-
diff --git a/runtime/tests/maps/ii.c b/runtime/tests/maps/ii.c
deleted file mode 100644
index 51b0d766..00000000
--- a/runtime/tests/maps/ii.c
+++ /dev/null
@@ -1,96 +0,0 @@
-#include "runtime.h"
-
-/* test of maps with keys of int64 and value of int64 */
-#define VALUE_TYPE INT64
-#define KEY1_TYPE INT64
-#include "map-gen.c"
-
-#include "map.c"
-
-int main ()
-{
- MAP map = _stp_map_new_ii(4);
- int64_t x;
-
- dbug("Hello World\n");
-
- /* map[1] = 2 */
- _stp_map_set_ii(map, 1, 2);
- x = _stp_map_get_ii(map, 1);
- printf ("map[1]=%lld\n", x);
-
- /* map[3] = 4 */
- _stp_map_set_ii(map, 3, 4);
- _stp_map_print(map,"map[%1d] = %d");
-
- /* now try to confuse things */
- /* These won't do anything useful, but shouldn't crash */
- _stp_map_set_ii(0,1,100);
- _stp_map_set_ii(map,0,0);
- _stp_map_set_ii(map,100,0);
- _stp_map_print(map,"map[%1d] = %d");
-
- /* check that unset values are 0 */
- printf ("%lld (should be 0)\n", _stp_map_get_ii(map, 5));
-
- /* map[5] = 6 */
- _stp_map_set_ii(map, 5, 6);
- _stp_map_print(map,"map[%1d] = %d");
-
- /* set wrap */
- map->wrap = 1;
- /* add 4 new entries, pushing the others out */
- int i, res;
- for (i = 6; i < 10; i++) {
- res = _stp_map_set_ii (map, i, 100 + i);
- if (res)
- printf("WARNING: During wrap test, got result of %d when expected 0\n", res);
- }
- _stp_map_print(map,"map[%1d] = %d");
-
- /* turn off wrap and repeat */
- map->wrap = 0;
- for (i = 16; i < 20; i++) {
- res = _stp_map_set_ii (map, i, 100 + i);
- if (res != -1)
- printf("WARNING: During wrap test, got result of %d when expected -1\n", res);
- }
-
- map->wrap = 1;
-
- /* 5, 382, 526, and 903 all hash to the same value (23) */
- /* use them to test the hash chain */
- _stp_map_set_ii (map, 5, 1005);
- _stp_map_set_ii (map, 382, 1382);
- _stp_map_set_ii (map, 526, 1526);
- _stp_map_set_ii (map, 903, 1903);
- _stp_map_print(map,"map[%1d] = %d");
-
-
- /* now delete all 4 nodes, one by one */
- _stp_map_set_ii (map, 382, 0);
- _stp_map_print(map,"map[%1d] = %d");
-
- _stp_map_set_ii (map, 5, 0);
- _stp_map_print(map,"map[%1d] = %d");
-
- _stp_map_set_ii (map, 903, 0);
- _stp_map_print(map,"map[%1d] = %d");
-
- _stp_map_set_ii (map, 526, 0);
- _stp_map_print(map,"map[%1d] = %d");
-
- /* finally check clearing the map */
- for (i = 33; i < 77; i+=11)
- _stp_map_set_ii (map, i, 100*i+i);
-
- _stp_map_print(map,"map[%1d] = %d");
-
- _stp_map_clear(map);
- _stp_map_print(map,"map[%1d] = %d");
- _stp_map_set_ii (map, 1970, 1799);
- _stp_map_print(map,"map[%1d] = %d");
-
- _stp_map_del (map);
- return 0;
-}
diff --git a/runtime/tests/maps/iiiiii.c b/runtime/tests/maps/iiiiii.c
deleted file mode 100644
index a5eeef70..00000000
--- a/runtime/tests/maps/iiiiii.c
+++ /dev/null
@@ -1,36 +0,0 @@
-#include "runtime.h"
-
-/* test of maps with 5 keys of int64 and value of int64 */
-#define VALUE_TYPE INT64
-#define KEY1_TYPE INT64
-#define KEY2_TYPE INT64
-#define KEY3_TYPE INT64
-#define KEY4_TYPE INT64
-#define KEY5_TYPE INT64
-#include "map-gen.c"
-
-#include "map.c"
-
-int main ()
-{
- struct map_node *ptr;
- MAP map = _stp_map_new_iiiiii(4);
-
- _stp_map_set_iiiiii (map,1,2,3,4,5, 10);
- _stp_map_set_iiiiii (map,10,20,30,40,50, 100);
- _stp_map_set_iiiiii (map,-1,-2,-3,-4,-5, -10);
- _stp_map_set_iiiiii (map,100,200,300,400,500, 1000);
-
- foreach (map, ptr)
- printf ("map[%lld, %lld, %lld, %lld, %lld] = %lld\n",
- _stp_key_get_int64(ptr,1),
- _stp_key_get_int64(ptr,2),
- _stp_key_get_int64(ptr,3),
- _stp_key_get_int64(ptr,4),
- _stp_key_get_int64(ptr,5),
- _stp_get_int64(ptr));
-
- _stp_map_print(map,"%1d - %2d - %3d - %4d - %5d *** %d");
- _stp_map_del (map);
- return 0;
-}
diff --git a/runtime/tests/maps/iiss.c b/runtime/tests/maps/iiss.c
deleted file mode 100644
index 96369d56..00000000
--- a/runtime/tests/maps/iiss.c
+++ /dev/null
@@ -1,45 +0,0 @@
-#include "runtime.h"
-
-/* test of maps with keys of int64,int64,string and value of string */
-#define VALUE_TYPE STRING
-#define KEY1_TYPE INT64
-#define KEY2_TYPE INT64
-#define KEY3_TYPE STRING
-#include "map-gen.c"
-
-#include "map.c"
-
-int main ()
-{
- MAP map = _stp_map_new_iiss(4);
- map->wrap = 1;
-
- _stp_map_set_iiss (map, 1,2,"Ohio", "Columbus" );
- _stp_map_set_iiss (map, 3,4,"California", "Sacramento" );
- _stp_map_set_iiss (map, 5,6,"Washington", "Seattle" );
- _stp_map_set_iiss (map, 7,8,"Oregon", "Salem" );
- _stp_map_print (map, "map[%1d, %2d, %3s] = %s");
-
- _stp_map_set_iiss (map, -9,-10,"Nevada", "Carson City" );
- _stp_map_print (map, "map[%1d, %2d, %3s] = %s");
-
- _stp_map_set_iiss (map, 5,6,"Washington", "Olymp" );
- _stp_map_print (map, "map[%1d, %2d, %3s] = %s");
-
- _stp_map_add_iiss (map, 5,6,"Washington", "is" );
- _stp_map_print (map, "map[%1d, %2d, %3s] = %s");
-
- _stp_map_set_iiss (map, 5,6,"Washington", "Olympia" );
- _stp_map_print (map, "map[%1d, %2d, %3s] = %s");
-
- /* delete */
- _stp_map_set_iiss (map, -9,-10,"Nevada", 0);
- _stp_map_print (map, "map[%1d, %2d, %3s] = %s");
-
- /* should add nothing */
- _stp_map_set_iiss(map, 0,0,"", "");
- _stp_map_print (map, "map[%1d, %2d, %3s] = %s");
-
- _stp_map_del (map);
- return 0;
-}
diff --git a/runtime/tests/maps/is.c b/runtime/tests/maps/is.c
deleted file mode 100644
index 3008f702..00000000
--- a/runtime/tests/maps/is.c
+++ /dev/null
@@ -1,119 +0,0 @@
-#include "runtime.h"
-
-/* test of maps with keys of int64 and value of string */
-#define KEY1_TYPE INT64
-#define VALUE_TYPE STRING
-#include "map-gen.c"
-
-#include "map.c"
-
-int main ()
-{
- MAP map = _stp_map_new_is(4);
- map->wrap = 1;
-
- /* map[1] = one */
- _stp_map_set_is (map, 1, "one");
-
- printf ("map[1]=%s\n", _stp_map_get_is(map,1));
- _stp_map_print(map,"map[%1d] = %s");
-
- /* map[3] = "three" */
- _stp_map_set_is (map, 3, "three");
- _stp_map_print(map,"map[%1d] = %s");
-
- /* now try to confuse things */
- /* These won't do anything useful, but shouldn't crash */
- _stp_map_set_is(0,1,"foobar");
- _stp_map_set_is(map,0,0);
- _stp_map_set_is(map,100,0);
- _stp_map_print(map,"map[%1d] = %s");
-
- /* create and delete a key */
- _stp_map_set_is (map, 1024, "2048");
- _stp_map_set_is (map, 1024, 0);
- _stp_map_print(map,"map[%1d] = %s");
-
- /* create and delete a key again*/
- _stp_map_set_is (map, 1024, "2048");
- _stp_map_print(map,"map[%1d] = %s");
- _stp_map_set_is (map, 1024, 0);
- _stp_map_print(map,"map[%1d] = %s");
-
-
- /* check that unset values are "" */
- if (*_stp_map_get_is(map, 5))
- printf("ERROR: unset key has nonempty value\n");
-
- /* map[5] = "five" */
- _stp_map_set_is (map, 5, "five");
- _stp_map_print(map,"map[%1d] = %s");
-
- /* test empty string (should delete)*/
- _stp_map_set_is (map, 5, "");
- _stp_map_print(map,"map[%1d] = %s");
-
-
- /* add 4 new entries, pushing the others out */
- int i;
- for (i = 6; i < 10; i++)
- {
- char buf[32];
- sprintf(buf, "value of %d", i);
- _stp_map_set_is (map, i, buf);
- }
- _stp_map_print(map,"map[%1d] = %s");
-
- /* 5, 382, 526, and 903 all hash to the same value (23) */
- /* use them to test the hash chain */
- _stp_map_set_is (map, 5, "1005");
- _stp_map_set_is (map, 382, "1382");
- _stp_map_set_is (map, 526, "1526");
- _stp_map_set_is (map, 903, "1903");
-
- _stp_map_print(map,"map[%1d] = %s");
-
- /* now delete all 4 nodes, one by one */
- _stp_map_set_is (map, 382, 0);
- _stp_map_print(map,"map[%1d] = %s");
-
- _stp_map_set_is (map, 5, 0);
- _stp_map_print(map,"map[%1d] = %s");
-
- _stp_map_set_is (map, 903, 0);
- _stp_map_print(map,"map[%1d] = %s");
-
- _stp_map_set_is (map, 526, 0);
- _stp_map_print(map,"map[%1d] = %s");
-
- /* test overflow errors */
- map->wrap = 0;
- for (i = 6; i < 10; i++)
- {
- char buf[32];
- sprintf(buf, "value of %d", i);
- _stp_map_set_is (map, i, buf);
- }
-
- for (i = 6; i < 10; i++)
- {
- char buf[32];
- int res;
- sprintf(buf, "new value of %d", i);
- res = _stp_map_set_is (map, i, buf);
- if (res)
- printf("WARNING: During wrap test, got result of %d when expected 0\n", res);
- }
- for (i = 16; i < 20; i++)
- {
- char buf[32];
- int res;
- sprintf(buf, "BAD value of %d", i);
- res = _stp_map_set_is (map, i, buf);
- if (res != -1)
- printf("WARNING: During wrap test, got result of %d when expected -1\n", res);
- }
- _stp_map_print(map,"map[%1d] = %s");
- _stp_map_del (map);
- return 0;
-}
diff --git a/runtime/tests/maps/issii.c b/runtime/tests/maps/issii.c
deleted file mode 100644
index 4861428a..00000000
--- a/runtime/tests/maps/issii.c
+++ /dev/null
@@ -1,34 +0,0 @@
-#include "runtime.h"
-
-/* test of maps with keys of int64,string.string.int64 and value of int64 */
-#define VALUE_TYPE INT64
-#define KEY1_TYPE INT64
-#define KEY2_TYPE STRING
-#define KEY3_TYPE STRING
-#define KEY4_TYPE INT64
-#include "map-gen.c"
-
-#include "map.c"
-
-int main ()
-{
- struct map_node *ptr;
- MAP map = _stp_map_new_issii(4);
-
- _stp_map_set_issii (map, 1, "Boston", "MA", 1970, 5224303 );
- _stp_map_set_issii (map, 2, "Boston", "MA", 2000, 6057826 );
- _stp_map_set_issii (map, 3, "Chicago", "IL", 2000, 8272768 );
-
- foreach (map, ptr)
- printf ("map[%lld, %s, %s, %lld] = %lld\n",
- key1int(ptr),
- key2str(ptr),
- _stp_key_get_str(ptr,3),
- _stp_key_get_int64(ptr,4),
- _stp_get_int64(ptr));
-
-
- _stp_map_print(map,"%1d. The population of %2s, %3s in %4d was %d");
- _stp_map_del (map);
- return 0;
-}
diff --git a/runtime/tests/maps/isx.c b/runtime/tests/maps/isx.c
deleted file mode 100644
index 9003f522..00000000
--- a/runtime/tests/maps/isx.c
+++ /dev/null
@@ -1,41 +0,0 @@
-#include "runtime.h"
-
-/* test of maps with keys of int64 and value of stat */
-#define VALUE_TYPE STAT
-#define KEY1_TYPE INT64
-#include "map-gen.c"
-#include "map.c"
-
-int main ()
-{
- int i, j;
- MAP map = _stp_map_new_ix (4, HIST_LINEAR, 0, 100, 10 );
- MAP map2 = _stp_map_new_ix(4, HIST_LOG, 11);
-
- for (i = 0; i < 100; i++)
- for (j = 0; j <= i*10 ; j++ )
- _stp_map_add_ix (map, 3, i);
-
- for (i = 0; i < 10; i++)
- for (j = 0; j < 10 ; j++ )
- _stp_map_add_ix (map, 2, j * i );
-
- for (i = 0; i < 100; i += 10)
- for (j = 0; j < i/10 ; j++ )
- _stp_map_add_ix (map, 1, i);
-
- for (i = 0; i < 128; i++)
- for (j = 0; j < 128 ; j++ )
- _stp_map_add_ix (map2, 1, i);
-
- for (i = 0; i < 1024; i++)
- for (j = 0; j < 1024 ; j++ )
- _stp_map_add_ix (map2, 2, i);
-
- _stp_map_print (map, "map[%1d] = count:%C sum:%S avg:%A min:%m max:%M\n%H");
- _stp_map_print (map2, "map2[%1d] = count:%C sum:%S avg:%A min:%m max:%M\n%H");
-
- _stp_map_del (map);
- _stp_map_del (map2);
- return 0;
-}
diff --git a/runtime/tests/maps/map.test b/runtime/tests/maps/map.test
deleted file mode 100644
index 51feca41..00000000
--- a/runtime/tests/maps/map.test
+++ /dev/null
@@ -1,999 +0,0 @@
-package require tcltest
-namespace import -force tcltest::*
-
-cd $tcltest::testsDirectory
-
-set CFLAGS "-Os"
-set KPATH "/lib/modules/[exec uname -r]/build/include"
-set MPATH "/lib/modules/[exec uname -r]/build/include/asm/mach-default"
-set PATH "../../user"
-
-test isx {Test of int64 keys and stat values} -setup {
- exec gcc $CFLAGS -I $KPATH -I $PATH -I $MPATH -o test isx.c
-} -body {
- exec ./test
-} -result {map[3] = count:49600 sum:3288450 avg:66 min:0 max:99
-value |-------------------------------------------------- count
- 0 |@@ 460
- 10 |@@@@@@@ 1460
- 20 |@@@@@@@@@@@@ 2460
- 30 |@@@@@@@@@@@@@@@@@@ 3460
- 40 |@@@@@@@@@@@@@@@@@@@@@@@ 4460
- 50 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 5460
- 60 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 6460
- 70 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 7460
- 80 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 8460
- 90 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 9460
-
-map[2] = count:100 sum:2025 avg:20 min:0 max:81
-value |-------------------------------------------------- count
- 0 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 42
- 10 |@@@@@@@@@@@@@@@@@ 17
- 20 |@@@@@@@@@@@@@ 13
- 30 |@@@@@@@@@ 9
- 40 |@@@@@@@@@ 9
- 50 |@@@@ 4
- 60 |@@@ 3
- 70 |@@ 2
- 80 |@ 1
- 90 | 0
-
-map[1] = count:45 sum:2850 avg:63 min:10 max:90
-value |-------------------------------------------------- count
- 0 | 0
- 10 |@ 1
- 20 |@@ 2
- 30 |@@@ 3
- 40 |@@@@ 4
- 50 |@@@@@ 5
- 60 |@@@@@@ 6
- 70 |@@@@@@@ 7
- 80 |@@@@@@@@ 8
- 90 |@@@@@@@@@ 9
-
-
-map2[1] = count:16384 sum:1040384 avg:63 min:0 max:127
-value |-------------------------------------------------- count
- 0 | 128
- 1 | 128
- 2 |@ 256
- 4 |@@@ 512
- 8 |@@@@@@ 1024
- 16 |@@@@@@@@@@@@ 2048
- 32 |@@@@@@@@@@@@@@@@@@@@@@@@ 4096
- 64 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 8192
- 128 | 0
- 256 | 0
-
-map2[2] = count:1048576 sum:536346624 avg:511 min:0 max:1023
-value |-------------------------------------------------- count
- 0 | 1024
- 1 | 1024
- 2 | 2048
- 4 | 4096
- 8 | 8192
- 16 |@ 16384
- 32 |@@@ 32768
- 64 |@@@@@@ 65536
- 128 |@@@@@@@@@@@@ 131072
- 256 |@@@@@@@@@@@@@@@@@@@@@@@@ 262144
- 512 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 524288
-
-}
-
-
-test map_format {Torture test of map formatting} -setup {
- exec gcc $CFLAGS -I $KPATH -I $PATH -I $MPATH -o test map_format.c
-} -body {
- exec ./test
-} -result {Columbus -> mapiis 1 2 Ohio
-Sacramento -> mapiis 3 4 California
-Olympia -> mapiis 5 6 Washington
-Salem -> mapiis 7 8 Oregon
-
-Columbus % Ohio
-Sacramento % California
-Olympia % Washington
-Salem % Oregon
-
-Columbus -> mapiis
-Sacramento -> mapiis
-Olympia -> mapiis
-Salem -> mapiis
-
-The capitol of Riga is Latvia and the nerd population is 212063400820736
-The capitol of Sofia is Bulgaria and the nerd population is -2400999087387945352
-The capitol of Valletta is Malta and the nerd population is 1
-The capitol of Nicosia is Cyprus and the nerd population is -1
-
-The capitol of Riga is Latvia and the nerd population is c0dedbad0000
-The capitol of Sofia is Bulgaria and the nerd population is deadf00d12345678
-The capitol of Valletta is Malta and the nerd population is 1
-The capitol of Nicosia is Cyprus and the nerd population is ffffffffffffffff
-
-The capitol of Riga is Latvia and the nerd population is C0DEDBAD0000
-The capitol of Sofia is Bulgaria and the nerd population is DEADF00D12345678
-The capitol of Valletta is Malta and the nerd population is 1
-The capitol of Nicosia is Cyprus and the nerd population is FFFFFFFFFFFFFFFF
-
-Bogons per packet for Riga
-count:49600 sum:3288450 avg:66 min:0 max:99
-value |-------------------------------------------------- count
- 0 |@@ 460
- 10 |@@@@@@@ 1460
- 20 |@@@@@@@@@@@@ 2460
- 30 |@@@@@@@@@@@@@@@@@@ 3460
- 40 |@@@@@@@@@@@@@@@@@@@@@@@ 4460
- 50 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 5460
- 60 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 6460
- 70 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 7460
- 80 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 8460
- 90 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 9460
-
-Bogons per packet for Sofia
-count:100 sum:2025 avg:20 min:0 max:81
-value |-------------------------------------------------- count
- 0 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 42
- 10 |@@@@@@@@@@@@@@@@@ 17
- 20 |@@@@@@@@@@@@@ 13
- 30 |@@@@@@@@@ 9
- 40 |@@@@@@@@@ 9
- 50 |@@@@ 4
- 60 |@@@ 3
- 70 |@@ 2
- 80 |@ 1
- 90 | 0
-
-Bogons per packet for Valletta
-count:45 sum:2850 avg:63 min:10 max:90
-value |-------------------------------------------------- count
- 0 | 0
- 10 |@ 1
- 20 |@@ 2
- 30 |@@@ 3
- 40 |@@@@ 4
- 50 |@@@@@ 5
- 60 |@@@@@@ 6
- 70 |@@@@@@@ 7
- 80 |@@@@@@@@ 8
- 90 |@@@@@@@@@ 9
-
-
-49600 was the count for Riga, Latvia
-100 was the count for Sofia, Bulgaria
-45 was the count for Valletta, Malta
-
-mapsst[ Riga, Latvia] = 322D82
-mapsst[ Sofia, Bulgaria] = 7E9
-mapsst[ Valletta, Malta] = B22}
-
-test map_issii {Test of int64,string,string,int64 keys and int64 values} -setup {
- exec gcc $CFLAGS -I $KPATH -I $PATH -I $MPATH -o test issii.c
-} -body {
- exec ./test
-} -result {map[1, Boston, MA, 1970] = 5224303
-map[2, Boston, MA, 2000] = 6057826
-map[3, Chicago, IL, 2000] = 8272768
-1. The population of Boston, MA in 1970 was 5224303
-2. The population of Boston, MA in 2000 was 6057826
-3. The population of Chicago, IL in 2000 was 8272768
-}
-
-test map_sort {Test of sorting} -setup {
- puts "gcc $CFLAGS -I $KPATH -I $PATH -I $MPATH -o test sort.c"
- exec gcc $CFLAGS -I $KPATH -I $PATH -I $MPATH -o test sort.c
-} -body {
- exec ./test
-} -result {sorting from A-Z on value
-Boston -> 5 5 Massachusetts
-Carson City -> 7 8 Nevada
-Columbus -> 1 2 Ohio
-Des Moines -> 8 8 Iowa
-Montpelier -> 2 2 Vermont
-Olympia -> 5 6 Washington
-Raleigh -> -1 9 North Carolina
-Sacramento -> 3 4 California
-Salem -> 7 8 Oregon
-Santa Fe -> 1 4 New Mexico
-
-
-sorting from Z-A on value
-Santa Fe -> 1 4 New Mexico
-Salem -> 7 8 Oregon
-Sacramento -> 3 4 California
-Raleigh -> -1 9 North Carolina
-Olympia -> 5 6 Washington
-Montpelier -> 2 2 Vermont
-Des Moines -> 8 8 Iowa
-Columbus -> 1 2 Ohio
-Carson City -> 7 8 Nevada
-Boston -> 5 5 Massachusetts
-
-
-sorting from low to high on key 1
--1 9 North Carolina -> Raleigh
-1 4 New Mexico -> Santa Fe
-1 2 Ohio -> Columbus
-2 2 Vermont -> Montpelier
-3 4 California -> Sacramento
-5 6 Washington -> Olympia
-5 5 Massachusetts -> Boston
-7 8 Oregon -> Salem
-7 8 Nevada -> Carson City
-8 8 Iowa -> Des Moines
-
-
-sorting from high to low on key 1
-8 8 Iowa -> Des Moines
-7 8 Oregon -> Salem
-7 8 Nevada -> Carson City
-5 6 Washington -> Olympia
-5 5 Massachusetts -> Boston
-3 4 California -> Sacramento
-2 2 Vermont -> Montpelier
-1 4 New Mexico -> Santa Fe
-1 2 Ohio -> Columbus
--1 9 North Carolina -> Raleigh
-
-
-sorting from low to high on key 2
-2 2 Vermont -> Montpelier
-1 2 Ohio -> Columbus
-3 4 California -> Sacramento
-1 4 New Mexico -> Santa Fe
-5 5 Massachusetts -> Boston
-5 6 Washington -> Olympia
-8 8 Iowa -> Des Moines
-7 8 Oregon -> Salem
-7 8 Nevada -> Carson City
--1 9 North Carolina -> Raleigh
-
-
-sorting from high to low on key 2
--1 9 North Carolina -> Raleigh
-8 8 Iowa -> Des Moines
-7 8 Oregon -> Salem
-7 8 Nevada -> Carson City
-5 6 Washington -> Olympia
-5 5 Massachusetts -> Boston
-3 4 California -> Sacramento
-1 4 New Mexico -> Santa Fe
-2 2 Vermont -> Montpelier
-1 2 Ohio -> Columbus
-
-
-sorting from low to high on key 3
-California 3 4 -> Sacramento
-Iowa 8 8 -> Des Moines
-Massachusetts 5 5 -> Boston
-Nevada 7 8 -> Carson City
-New Mexico 1 4 -> Santa Fe
-North Carolina -1 9 -> Raleigh
-Ohio 1 2 -> Columbus
-Oregon 7 8 -> Salem
-Vermont 2 2 -> Montpelier
-Washington 5 6 -> Olympia
-
-
-sorting from high to low on key 3
-Washington 5 6 -> Olympia
-Vermont 2 2 -> Montpelier
-Oregon 7 8 -> Salem
-Ohio 1 2 -> Columbus
-North Carolina -1 9 -> Raleigh
-New Mexico 1 4 -> Santa Fe
-Nevada 7 8 -> Carson City
-Massachusetts 5 5 -> Boston
-Iowa 8 8 -> Des Moines
-California 3 4 -> Sacramento
-
-
-top 3 alphabetical by value
-Boston -> 5 5 Massachusetts
-Carson City -> 7 8 Nevada
-Columbus -> 1 2 Ohio
-
-
-bottom 2 alphabetical by value
-Santa Fe -> 1 4 New Mexico
-Salem -> 7 8 Oregon
-
-
-top 5 sorted by key 1
-8 8 Iowa -> Des Moines
-7 8 Oregon -> Salem
-7 8 Nevada -> Carson City
-5 6 Washington -> Olympia
-5 5 Massachusetts -> Boston
-
-
-bottom 5 sorted by key 1
--1 9 North Carolina -> Raleigh
-1 4 New Mexico -> Santa Fe
-1 2 Ohio -> Columbus
-2 2 Vermont -> Montpelier
-3 4 California -> Sacramento
-
-sorted by population from low to high
-Nicosia is the capitol of Cyprus and the nerd population is -1
-Valletta is the capitol of Malta and the nerd population is 1
-Riga is the capitol of Latvia and the nerd population is 135786
-Sofia is the capitol of Bulgaria and the nerd population is 138740
-
-sorted by population from high to low
-Sofia is the capitol of Bulgaria and the nerd population is 138740
-Riga is the capitol of Latvia and the nerd population is 135786
-Valletta is the capitol of Malta and the nerd population is 1
-Nicosia is the capitol of Cyprus and the nerd population is -1
-}
-
-test ii {Test of int64 keys and int64 values} -setup {
- exec gcc $CFLAGS -I $KPATH -I $PATH -I $MPATH -o test ii.c
-} -body {
- exec ./test
-} -result {map[1]=2
-map[1] = 2
-map[3] = 4
-
-map[1] = 2
-map[3] = 4
-
-0 (should be 0)
-map[1] = 2
-map[3] = 4
-map[5] = 6
-
-map[6] = 106
-map[7] = 107
-map[8] = 108
-map[9] = 109
-
-map[5] = 1005
-map[382] = 1382
-map[526] = 1526
-map[903] = 1903
-
-map[5] = 1005
-map[526] = 1526
-map[903] = 1903
-
-map[526] = 1526
-map[903] = 1903
-
-map[526] = 1526
-
-
-map[33] = 3333
-map[44] = 4444
-map[55] = 5555
-map[66] = 6666
-
-
-map[1970] = 1799
-}
-
-test is {Test of int64 keys and string values} -setup {
- exec gcc $CFLAGS -I $KPATH -I $PATH -I $MPATH -o test is.c
-} -body {
- exec ./test
-} -result {map[1]=one
-map[1] = one
-
-map[1] = one
-map[3] = three
-
-map[1] = one
-map[3] = three
-
-map[1] = one
-map[3] = three
-
-map[1] = one
-map[3] = three
-map[1024] = 2048
-
-map[1] = one
-map[3] = three
-
-map[1] = one
-map[3] = three
-map[5] = five
-
-map[1] = one
-map[3] = three
-
-map[6] = value of 6
-map[7] = value of 7
-map[8] = value of 8
-map[9] = value of 9
-
-map[5] = 1005
-map[382] = 1382
-map[526] = 1526
-map[903] = 1903
-
-map[5] = 1005
-map[526] = 1526
-map[903] = 1903
-
-map[526] = 1526
-map[903] = 1903
-
-map[526] = 1526
-
-
-map[6] = new value of 6
-map[7] = new value of 7
-map[8] = new value of 8
-map[9] = new value of 9
-}
-
-test si {Test of string keys and int64 values} -setup {
- exec gcc $CFLAGS -I $KPATH -I $PATH -I $MPATH -o test si.c
-} -body {
- exec ./test
-} -result {map[Ohio]=1
-map[Ohio] = 1
-
-map[Ohio] = 1
-map[Washington] = 2
-
-map[Ohio] = 1
-map[Washington] = 2
-
-map[Ohio] = 1
-map[Washington] = 2
-map[1024] = 2048
-
-map[Ohio] = 1
-map[Washington] = 2
-
-map[Ohio] = 1
-map[Washington] = 2
-map[1024] = 2048
-
-map[Ohio] = 1
-map[Washington] = 2
-
-map[Ohio] = 1
-map[Washington] = 2
-map[California] = 3
-
-map[Ohio] = 1
-map[Washington] = 2
-map[California] = 3
-map[] = 7777
-
-map[Ohio] = 1
-map[Washington] = 2
-map[California] = 3
-map[] = 8888
-
-map[Ohio] = 1
-map[Washington] = 2
-map[California] = 3
-
-map[String 6] = 106
-map[String 7] = 107
-map[String 8] = 108
-map[String 9] = 109
-
-map[String 6] = 106
-map[String 7] = 107
-map[String 8] = 108
-map[String 9] = 109
-
-map[String 6] = 6106
-map[String 7] = 7107
-map[String 8] = 8108
-map[String 9] = 9109
-
-map[String 6] = 6
-map[String 7] = 7
-map[String 8] = 8
-map[String 9] = 9
-
-}
-
-test iiss {Test of int64,int64,string keys and string values} -setup {
- exec gcc $CFLAGS -I $KPATH -I $PATH -I $MPATH -o test iiss.c
-} -body {
- exec ./test
-} -result {map[1, 2, Ohio] = Columbus
-map[3, 4, California] = Sacramento
-map[5, 6, Washington] = Seattle
-map[7, 8, Oregon] = Salem
-
-map[3, 4, California] = Sacramento
-map[5, 6, Washington] = Seattle
-map[7, 8, Oregon] = Salem
-map[-9, -10, Nevada] = Carson City
-
-map[3, 4, California] = Sacramento
-map[5, 6, Washington] = Olymp
-map[7, 8, Oregon] = Salem
-map[-9, -10, Nevada] = Carson City
-
-map[3, 4, California] = Sacramento
-map[5, 6, Washington] = Olympis
-map[7, 8, Oregon] = Salem
-map[-9, -10, Nevada] = Carson City
-
-map[3, 4, California] = Sacramento
-map[5, 6, Washington] = Olympia
-map[7, 8, Oregon] = Salem
-map[-9, -10, Nevada] = Carson City
-
-map[3, 4, California] = Sacramento
-map[5, 6, Washington] = Olympia
-map[7, 8, Oregon] = Salem
-
-map[3, 4, California] = Sacramento
-map[5, 6, Washington] = Olympia
-map[7, 8, Oregon] = Salem
-}
-
-test setadd {Test of setting and adding values} -setup {
- exec gcc $CFLAGS -I $KPATH -I $PATH -I $MPATH -o test setadd.c
-} -body {
- exec ./test
-} -result {mapi[1] = 1
-mapi[2] = 4
-mapi[3] = 9
-mapi[4] = 16
-
-maps[1] = value of 1
-maps[2] = value of 2
-maps[3] = value of 3
-maps[4] = value of 4
-
-mapx[1] = count:1 sum:1 avg:1 min:1 max:1
-mapx[2] = count:1 sum:2 avg:2 min:2 max:2
-mapx[3] = count:1 sum:3 avg:3 min:3 max:3
-mapx[4] = count:1 sum:4 avg:4 min:4 max:4
-
-mapi[1] = 2
-mapi[2] = 8
-mapi[3] = 18
-mapi[4] = 32
-
-maps[1] = value of 1*****
-maps[2] = value of 2*****
-maps[3] = value of 3*****
-maps[4] = value of 4*****
-
-mapx[1] = count:2 sum:3 avg:1 min:1 max:2
-mapx[2] = count:2 sum:6 avg:3 min:2 max:4
-mapx[3] = count:2 sum:9 avg:4 min:3 max:6
-mapx[4] = count:2 sum:12 avg:6 min:4 max:8
-
-Adding 0
-mapi[1] = 2
-mapi[2] = 8
-mapi[3] = 18
-mapi[4] = 32
-
-maps[1] = value of 1*****
-maps[2] = value of 2*****
-maps[3] = value of 3*****
-maps[4] = value of 4*****
-
-maps[1] = value of 1*****
-maps[2] = value of 2*****
-maps[3] = value of 3*****
-maps[4] = value of 4*****
-
-mapx[1] = count:3 sum:3 avg:1 min:0 max:2
-mapx[2] = count:3 sum:6 avg:2 min:0 max:4
-mapx[3] = count:3 sum:9 avg:3 min:0 max:6
-mapx[4] = count:3 sum:12 avg:4 min:0 max:8
-
-Add 'X' to strings
-maps[1] = value of 1*****X
-maps[2] = value of 2*****X
-maps[3] = value of 3*****X
-maps[4] = value of 4*****X
-
-setting everything to 0
-
-
-
-
-Adding 0
-
-
-
-mapx[1] = count:1 sum:0 avg:0 min:0 max:0
-mapx[2] = count:1 sum:0 avg:0 min:0 max:0
-mapx[3] = count:1 sum:0 avg:0 min:0 max:0
-mapx[4] = count:1 sum:0 avg:0 min:0 max:0
-
-setting everything to -1
-mapi[1] = -1
-mapi[2] = -1
-mapi[3] = -1
-mapi[4] = -1
-
-mapx[1] = count:1 sum:-1 avg:-1 min:-1 max:-1
-mapx[2] = count:1 sum:-1 avg:-1 min:-1 max:-1
-mapx[3] = count:1 sum:-1 avg:-1 min:-1 max:-1
-mapx[4] = count:1 sum:-1 avg:-1 min:-1 max:-1
-
-adding -1
-mapi[1] = -2
-mapi[2] = -2
-mapi[3] = -2
-mapi[4] = -2
-
-mapx[1] = count:2 sum:-2 avg:-1 min:-1 max:-1
-mapx[2] = count:2 sum:-2 avg:-1 min:-1 max:-1
-mapx[3] = count:2 sum:-2 avg:-1 min:-1 max:-1
-mapx[4] = count:2 sum:-2 avg:-1 min:-1 max:-1
-}
-
-test iiiiii {Test of 5 int keys and an int value} -setup {
- exec gcc $CFLAGS -I $KPATH -I $PATH -I $MPATH -o test iiiiii.c
-} -body {
- exec ./test
-} -result {map[1, 2, 3, 4, 5] = 10
-map[10, 20, 30, 40, 50] = 100
-map[-1, -2, -3, -4, -5] = -10
-map[100, 200, 300, 400, 500] = 1000
-1 - 2 - 3 - 4 - 5 *** 10
-10 - 20 - 30 - 40 - 50 *** 100
--1 - -2 - -3 - -4 - -5 *** -10
-100 - 200 - 300 - 400 - 500 *** 1000
-}
-
-test ssssss {Test of 5 string keys and a string value} -setup {
- exec gcc $CFLAGS -I $KPATH -I $PATH -I $MPATH -o test ssssss.c
-} -body {
- exec ./test
-} -result {map[1ABC, 2ABC, 3ABC, 4ABC, 5ABC] = 666
-map[1QRS, 2QRS, 3QRS, 4QRS, 5QRS] = 777
-map[1abc, 2abc, 3abc, 4abc, 5abc] = 888
-map[1XYZ, 2XYZ, 3XYZ, 4XYZ, 5XYZ] = 999
-1ABC and 2ABC and 3ABC and 4ABC and 5ABC ---> 666
-1QRS and 2QRS and 3QRS and 4QRS and 5QRS ---> 777
-1abc and 2abc and 3abc and 4abc and 5abc ---> 888
-1XYZ and 2XYZ and 3XYZ and 4XYZ and 5XYZ ---> 999
-}
-
-test sort_stat {Test of sorting stats} -setup {
- exec gcc $CFLAGS -I $KPATH -I $PATH -I $MPATH -o test sort_stat.c
-} -body {
- exec ./test
-} -result {Bogons per packet for California
-count:49600 sum:3288450 avg:66 min:0 max:99
-value |-------------------------------------------------- count
- 0 |@@ 460
- 10 |@@@@@@@ 1460
- 20 |@@@@@@@@@@@@ 2460
- 30 |@@@@@@@@@@@@@@@@@@ 3460
- 40 |@@@@@@@@@@@@@@@@@@@@@@@ 4460
- 50 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 5460
- 60 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 6460
- 70 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 7460
- 80 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 8460
- 90 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 9460
-
-Bogons per packet for Washington
-count:100 sum:2025 avg:20 min:0 max:81
-value |-------------------------------------------------- count
- 0 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 42
- 10 |@@@@@@@@@@@@@@@@@ 17
- 20 |@@@@@@@@@@@@@ 13
- 30 |@@@@@@@@@ 9
- 40 |@@@@@@@@@ 9
- 50 |@@@@ 4
- 60 |@@@ 3
- 70 |@@ 2
- 80 |@ 1
- 90 | 0
-
-Bogons per packet for Oregon
-count:90 sum:5700 avg:63 min:10 max:90
-value |-------------------------------------------------- count
- 0 | 0
- 10 |@@ 2
- 20 |@@@@ 4
- 30 |@@@@@@ 6
- 40 |@@@@@@@@ 8
- 50 |@@@@@@@@@@ 10
- 60 |@@@@@@@@@@@@ 12
- 70 |@@@@@@@@@@@@@@ 14
- 80 |@@@@@@@@@@@@@@@@ 16
- 90 |@@@@@@@@@@@@@@@@@@ 18
-
-Bogons per packet for Nevada
-count:45 sum:2970 avg:66 min:10 max:98
-value |-------------------------------------------------- count
- 0 | 0
- 10 |@ 1
- 20 |@@ 2
- 30 |@@@ 3
- 40 |@@@@ 4
- 50 |@@@@@ 5
- 60 |@@@@@@ 6
- 70 |@@@@@@@ 7
- 80 |@@@@@@@@ 8
- 90 |@@@@@@@@@ 9
-
-Bogons per packet for Ohio
-count:20 sum:1000 avg:50 min:50 max:50
-value |-------------------------------------------------- count
- 30 | 0
- 40 | 0
- 50 |@@@@@@@@@@@@@@@@@@@@ 20
- 60 | 0
- 70 | 0
-
-Bogons per packet for North Carolina
-count:45 sum:-4200 avg:-93 min:-620 max:100
-value |-------------------------------------------------- count
- 0 |@@@@@@@@@@@@@@@@@@@@@@@@@@ 26
- 10 |@ 1
- 20 |@@ 2
- 30 |@ 1
- 40 |@@ 2
- 50 |@ 1
- 60 |@ 1
- 70 |@ 1
- 80 |@ 1
- 90 |@@@@@@@@@ 9
-
-Bogons per packet for New Mexico
-count:450 sum:8475 avg:18 min:-39 max:50
-value |-------------------------------------------------- count
- 0 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 145
- 10 |@@@@@@@@@@@@@@@@@@@ 59
- 20 |@@@@@@@@@@@@@@@@@@@@@@@ 69
- 30 |@@@@@@@@@@@@@@@@@@@@@@@@@@ 79
- 40 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 89
- 50 |@@@ 9
- 60 | 0
- 70 | 0
-
-
-SORTED BY COUNT
-49600 California
-450 New Mexico
-100 Washington
-90 Oregon
-45 Nevada
-45 North Carolina
-20 Ohio
-
-SORTED BY COUNT (low to high)
-20 Ohio
-45 Nevada
-45 North Carolina
-90 Oregon
-100 Washington
-450 New Mexico
-49600 California
-
-SORTED BY SUM
-3288450 California
-8475 New Mexico
-5700 Oregon
-2970 Nevada
-2025 Washington
-1000 Ohio
--4200 North Carolina
-
-SORTED BY SUM (low to high)
--4200 North Carolina
-1000 Ohio
-2025 Washington
-2970 Nevada
-5700 Oregon
-8475 New Mexico
-3288450 California
-
-SORTED BY MIN
-50 Ohio
-10 Nevada
-10 Oregon
-0 Washington
-0 California
--39 New Mexico
--620 North Carolina
-
-SORTED BY MIN (low to high)
--620 North Carolina
--39 New Mexico
-0 Washington
-0 California
-10 Nevada
-10 Oregon
-50 Ohio
-
-SORTED BY MAX
-100 North Carolina
-99 California
-98 Nevada
-90 Oregon
-81 Washington
-50 New Mexico
-50 Ohio
-
-SORTED BY MAX (low to high)
-50 New Mexico
-50 Ohio
-81 Washington
-90 Oregon
-98 Nevada
-99 California
-100 North Carolina
-
-SORTED BY AVG
-66 Nevada
-66 California
-63 Oregon
-50 Ohio
-20 Washington
-18 New Mexico
--93 North Carolina
-
-SORTED BY AVG (low to high)
--93 North Carolina
-18 New Mexico
-20 Washington
-50 Ohio
-63 Oregon
-66 Nevada
-66 California
-}
-
-test sort2 {Test of sorting (odd number of elements)} -setup {
- exec gcc $CFLAGS -I $KPATH -I $PATH -I $MPATH -o test sort2.c
-} -body {
- exec ./test
-} -result {sorting from A-Z on value
-Boston -> 5 5 Massachusetts
-Carson City -> 7 8 Nevada
-Columbus -> 1 2 Ohio
-Des Moines -> 8 8 Iowa
-Olympia -> 5 6 Washington
-Raleigh -> -1 9 North Carolina
-Sacramento -> 3 4 California
-Salem -> 7 8 Oregon
-Santa Fe -> 1 4 New Mexico
-
-
-sorting from Z-A on value
-Santa Fe -> 1 4 New Mexico
-Salem -> 7 8 Oregon
-Sacramento -> 3 4 California
-Raleigh -> -1 9 North Carolina
-Olympia -> 5 6 Washington
-Des Moines -> 8 8 Iowa
-Columbus -> 1 2 Ohio
-Carson City -> 7 8 Nevada
-Boston -> 5 5 Massachusetts
-
-
-sorting from low to high on key 1
--1 9 North Carolina -> Raleigh
-1 4 New Mexico -> Santa Fe
-1 2 Ohio -> Columbus
-3 4 California -> Sacramento
-5 6 Washington -> Olympia
-5 5 Massachusetts -> Boston
-7 8 Oregon -> Salem
-7 8 Nevada -> Carson City
-8 8 Iowa -> Des Moines
-
-
-sorting from high to low on key 1
-8 8 Iowa -> Des Moines
-7 8 Oregon -> Salem
-7 8 Nevada -> Carson City
-5 6 Washington -> Olympia
-5 5 Massachusetts -> Boston
-3 4 California -> Sacramento
-1 4 New Mexico -> Santa Fe
-1 2 Ohio -> Columbus
--1 9 North Carolina -> Raleigh
-
-
-sorting from low to high on key 2
-1 2 Ohio -> Columbus
-3 4 California -> Sacramento
-1 4 New Mexico -> Santa Fe
-5 5 Massachusetts -> Boston
-5 6 Washington -> Olympia
-8 8 Iowa -> Des Moines
-7 8 Oregon -> Salem
-7 8 Nevada -> Carson City
--1 9 North Carolina -> Raleigh
-
-
-sorting from high to low on key 2
--1 9 North Carolina -> Raleigh
-8 8 Iowa -> Des Moines
-7 8 Oregon -> Salem
-7 8 Nevada -> Carson City
-5 6 Washington -> Olympia
-5 5 Massachusetts -> Boston
-3 4 California -> Sacramento
-1 4 New Mexico -> Santa Fe
-1 2 Ohio -> Columbus
-
-
-sorting from low to high on key 3
-California 3 4 -> Sacramento
-Iowa 8 8 -> Des Moines
-Massachusetts 5 5 -> Boston
-Nevada 7 8 -> Carson City
-New Mexico 1 4 -> Santa Fe
-North Carolina -1 9 -> Raleigh
-Ohio 1 2 -> Columbus
-Oregon 7 8 -> Salem
-Washington 5 6 -> Olympia
-
-
-sorting from high to low on key 3
-Washington 5 6 -> Olympia
-Oregon 7 8 -> Salem
-Ohio 1 2 -> Columbus
-North Carolina -1 9 -> Raleigh
-New Mexico 1 4 -> Santa Fe
-Nevada 7 8 -> Carson City
-Massachusetts 5 5 -> Boston
-Iowa 8 8 -> Des Moines
-California 3 4 -> Sacramento
-
-
-top 3 alphabetical by value
-Boston -> 5 5 Massachusetts
-Carson City -> 7 8 Nevada
-Columbus -> 1 2 Ohio
-
-
-bottom 2 alphabetical by value
-Santa Fe -> 1 4 New Mexico
-Salem -> 7 8 Oregon
-
-
-top 5 sorted by key 1
-8 8 Iowa -> Des Moines
-7 8 Oregon -> Salem
-7 8 Nevada -> Carson City
-5 6 Washington -> Olympia
-5 5 Massachusetts -> Boston
-
-
-bottom 5 sorted by key 1
--1 9 North Carolina -> Raleigh
-1 4 New Mexico -> Santa Fe
-1 2 Ohio -> Columbus
-3 4 California -> Sacramento
-5 6 Washington -> Olympia
-
-sorted by population from low to high
-Nicosia is the capitol of Cyprus and the nerd population is -1
-Valletta is the capitol of Malta and the nerd population is 1
-Chisinau is the capitol of Moldova and the nerd population is 1024
-Riga is the capitol of Latvia and the nerd population is 135786
-Sofia is the capitol of Bulgaria and the nerd population is 138740
-
-sorted by population from high to low
-Sofia is the capitol of Bulgaria and the nerd population is 138740
-Riga is the capitol of Latvia and the nerd population is 135786
-Chisinau is the capitol of Moldova and the nerd population is 1024
-Valletta is the capitol of Malta and the nerd population is 1
-Nicosia is the capitol of Cyprus and the nerd population is -1
-}
-
-
-test size {Test of _stp_map_size()} -setup {
- exec gcc $CFLAGS -I $KPATH -I $PATH -I $MPATH -o test size.c
-} -body {
- exec ./test
-} -result {}
-
-catch {exec rm test}
-
-cleanupTests
diff --git a/runtime/tests/maps/map_format.c b/runtime/tests/maps/map_format.c
deleted file mode 100644
index 184aa79a..00000000
--- a/runtime/tests/maps/map_format.c
+++ /dev/null
@@ -1,72 +0,0 @@
-#include "runtime.h"
-
-/* torture test of map formatting */
-#define VALUE_TYPE STRING
-#define KEY1_TYPE INT64
-#define KEY2_TYPE INT64
-#define KEY3_TYPE STRING
-#include "map-gen.c"
-
-#define VALUE_TYPE INT64
-#define KEY1_TYPE STRING
-#define KEY2_TYPE STRING
-#include "map-gen.c"
-
-#define VALUE_TYPE STAT
-#define KEY1_TYPE STRING
-#define KEY2_TYPE STRING
-#include "map-gen.c"
-
-#include "map.c"
-
-int main ()
-{
- MAP mapiis = _stp_map_new_iiss(4);
- _stp_map_set_iiss (mapiis, 1,2,"Ohio", "Columbus" );
- _stp_map_set_iiss (mapiis, 3,4,"California", "Sacramento" );
- _stp_map_set_iiss (mapiis, 5,6,"Washington", "Olympia" );
- _stp_map_set_iiss (mapiis, 7,8,"Oregon", "Salem" );
- _stp_map_print (mapiis, "%s -> mapiis %1d %2d %3s");
-
- /* test printing of '%' */
- _stp_map_print (mapiis, "%s %% %3s");
-
- /* very bad string. don't crash */
- _stp_map_print (mapiis, "%s -> mapiis %1s %2s %3d %4d");
-
- MAP mapss = _stp_map_new_ssi(4);
- _stp_map_set_ssi (mapss, "Riga", "Latvia", 0x0000c0dedbad0000LL);
- _stp_map_set_ssi (mapss, "Sofia", "Bulgaria", 0xdeadf00d12345678LL);
- _stp_map_set_ssi (mapss, "Valletta", "Malta", 1);
- _stp_map_set_ssi (mapss, "Nicosia", "Cyprus", -1);
- _stp_map_print (mapss, "The capitol of %1s is %2s and the nerd population is %d");
- _stp_map_print (mapss, "The capitol of %1s is %2s and the nerd population is %x");
- _stp_map_print (mapss, "The capitol of %1s is %2s and the nerd population is %X");
-
- MAP mapsst = _stp_map_new_ssx (4, HIST_LINEAR, 0, 100, 10 );
- int i,j;
-
- for (i = 0; i < 100; i++)
- for (j = 0; j <= i*10 ; j++ )
- _stp_map_add_ssx (mapsst, "Riga", "Latvia", i);
-
- for (i = 0; i < 10; i++)
- for (j = 0; j < 10 ; j++ )
- _stp_map_add_ssx (mapsst, "Sofia", "Bulgaria", j * i );
-
- for (i = 0; i < 100; i += 10)
- for (j = 0; j < i/10 ; j++ )
- _stp_map_add_ssx (mapsst, "Valletta", "Malta", i);
-
- _stp_map_print (mapsst, "Bogons per packet for %1s\ncount:%C sum:%S avg:%A min:%m max:%M\n%H");
-
- _stp_map_print (mapsst, "%C was the count for %1s, %2s");
-
- /* here's how to print a map without using _stp_map_print(). */
- struct map_node *ptr;
- foreach (mapsst, ptr)
- _stp_printf ("mapsst[%09s,%09s] = %llX\n", key1str(ptr), key2str(ptr), _stp_get_stat(ptr)->sum);
- _stp_print_flush();
-
- return 0;
-}
diff --git a/runtime/tests/maps/setadd.c b/runtime/tests/maps/setadd.c
deleted file mode 100644
index 8eedbaa9..00000000
--- a/runtime/tests/maps/setadd.c
+++ /dev/null
@@ -1,245 +0,0 @@
-#include "runtime.h"
-
-/* verify correct set and add behavior */
-#define VALUE_TYPE INT64
-#define KEY1_TYPE INT64
-#define STP_MAP_II
-#include "map-gen.c"
-
-#define VALUE_TYPE STRING
-#define KEY1_TYPE INT64
-#include "map-gen.c"
-
-#define VALUE_TYPE STAT
-#define KEY1_TYPE INT64
-#include "map-gen.c"
-
-#include "map.c"
-
-int main ()
-{
- int i, res;
- MAP mapi = _stp_map_new_ii(4);
- MAP maps = _stp_map_new_is(4);
- MAP mapx = _stp_map_new_ix(4, HIST_NONE);
-
- /* use add to set initial values */
- for (i = 1; i < 5; i++)
- {
- res = _stp_map_add_ii (mapi, i, i*i);
- if (res)
- printf("ERROR: got result of %d when expected 0\n", res);
- }
- _stp_map_print(mapi,"mapi[%1d] = %d");
-
- for (i = 1; i < 5; i++)
- {
- char buf[32];
- sprintf(buf, "value of %d", i);
- res = _stp_map_add_is (maps, i, buf);
- if (res)
- printf("ERROR: got result of %d when expected 0\n", res);
- }
- _stp_map_print(maps,"maps[%1d] = %s");
-
- for (i = 1; i < 5; i++)
- {
- res = _stp_map_add_ix (mapx, i, i);
- if (res)
- printf("ERROR: got result of %d when expected 0\n", res);
- }
- _stp_map_print (mapx, "mapx[%1d] = count:%C sum:%S avg:%A min:%m max:%M");
-
- /*************** now add some values *******************/
-
- for (i = 1; i < 5; i++)
- {
- res = _stp_map_add_ii (mapi, i, i*i);
- if (res)
- printf("ERROR: got result of %d when expected 0\n", res);
- }
- _stp_map_print(mapi,"mapi[%1d] = %d");
-
- for (i = 1; i < 5; i++)
- {
- res = _stp_map_add_is (maps, i, "*****");
- if (res)
- printf("ERROR: got result of %d when expected 0\n", res);
- }
- _stp_map_print(maps,"maps[%1d] = %s");
-
- for (i = 1; i < 5; i++)
- {
- res = _stp_map_add_ix (mapx, i, i+i);
- if (res)
- printf("ERROR: got result of %d when expected 0\n", res);
- }
- _stp_map_print (mapx, "mapx[%1d] = count:%C sum:%S avg:%A min:%m max:%M");
-
- /*************** now add 0 *******************/
- printf ("Adding 0\n");
- for (i = 1; i < 5; i++)
- {
- res = _stp_map_add_ii (mapi, i, 0);
- if (res)
- printf("ERROR: got result of %d when expected 0\n", res);
- }
- _stp_map_print(mapi,"mapi[%1d] = %d");
-
- for (i = 1; i < 5; i++)
- {
- res = _stp_map_add_is (maps, i, "");
- if (res)
- printf("ERROR: got result of %d when expected 0\n", res);
- }
- _stp_map_print(maps,"maps[%1d] = %s");
-
- /* adding NULL should be same as adding "" for string values */
- for (i = 1; i < 5; i++)
- {
- res = _stp_map_add_is (maps, i, 0);
- if (res)
- printf("ERROR: got result of %d when expected 0\n", res);
- }
- _stp_map_print(maps,"maps[%1d] = %s");
-
- for (i = 1; i < 5; i++)
- {
- res = _stp_map_add_ix (mapx, i, 0);
- if (res)
- printf("ERROR: got result of %d when expected 0\n", res);
- }
- _stp_map_print (mapx, "mapx[%1d] = count:%C sum:%S avg:%A min:%m max:%M");
-
- /*************** now add X to strings *******************/
- printf ("Add 'X' to strings\n");
- for (i = 1; i < 5; i++)
- {
- res = _stp_map_add_is (maps, i, "X");
- if (res)
- printf("ERROR: got result of %d when expected 0\n", res);
- }
- _stp_map_print(maps,"maps[%1d] = %s");
-
- /*************** now set to 0 (clear) *******************/
- printf ("setting everything to 0\n");
- for (i = 1; i < 5; i++)
- {
- res = _stp_map_set_ii (mapi, i, 0);
- if (res)
- printf("ERROR: got result of %d when expected 0\n", res);
- }
- _stp_map_print(mapi,"mapi[%1d] = %d");
-
- for (i = 1; i < 5; i++)
- {
- res = _stp_map_set_is (maps, i, "");
- if (res)
- printf("ERROR: got result of %d when expected 0\n", res);
- }
- _stp_map_print(maps,"maps[%1d] = %s");
-
- /* set it back to something */
- for (i = 1; i < 5; i++)
- {
- char buf[32];
- sprintf(buf, "%d", i);
- res = _stp_map_set_is (maps, i, buf);
- if (res)
- printf("ERROR: got result of %d when expected 0\n", res);
- }
-
- /* setting to NULL also deletes */
- for (i = 1; i < 5; i++)
- {
- res = _stp_map_set_is (maps, i, 0);
- if (res)
- printf("ERROR: got result of %d when expected 0\n", res);
- }
- _stp_map_print(maps,"maps[%1d] = %s");
-
- for (i = 1; i < 5; i++)
- {
- res = _stp_map_set_ix (mapx, i, 0);
- if (res)
- printf("ERROR: got result of %d when expected 0\n", res);
- }
- _stp_map_print (mapx, "mapx[%1d] = count:%C sum:%S avg:%A min:%m max:%M");
-
- /*************** now add 0 *******************/
- printf ("Adding 0\n");
- for (i = 1; i < 5; i++)
- {
- res = _stp_map_add_ii (mapi, i, 0);
- if (res)
- printf("ERROR: got result of %d when expected 0\n", res);
- }
- _stp_map_print(mapi,"mapi[%1d] = %d");
-
- for (i = 1; i < 5; i++)
- {
- res = _stp_map_add_is (maps, i, 0);
- if (res)
- printf("ERROR: got result of %d when expected 0\n", res);
- }
- _stp_map_print(maps,"maps[%1d] = %s");
-
- for (i = 1; i < 5; i++)
- {
- res = _stp_map_add_is (maps, i, "");
- if (res)
- printf("ERROR: got result of %d when expected 0\n", res);
- }
- _stp_map_print(maps,"maps[%1d] = %s");
-
- for (i = 1; i < 5; i++)
- {
- res = _stp_map_add_ix (mapx, i, 0);
- if (res)
- printf("ERROR: got result of %d when expected 0\n", res);
- }
- _stp_map_print (mapx, "mapx[%1d] = count:%C sum:%S avg:%A min:%m max:%M");
-
-
- /*************** now set to -1 *******************/
- printf ("setting everything to -1\n");
- for (i = 1; i < 5; i++)
- {
- res = _stp_map_set_ii (mapi, i, -1);
- if (res)
- printf("ERROR: got result of %d when expected 0\n", res);
- }
- _stp_map_print(mapi,"mapi[%1d] = %d");
-
- for (i = 1; i < 5; i++)
- {
- res = _stp_map_set_ix (mapx, i, -1);
- if (res)
- printf("ERROR: got result of %d when expected 0\n", res);
- }
- _stp_map_print (mapx, "mapx[%1d] = count:%C sum:%S avg:%A min:%m max:%M");
-
- /*************** now add -1 *******************/
- printf ("adding -1\n");
- for (i = 1; i < 5; i++)
- {
- res = _stp_map_add_ii (mapi, i, -1);
- if (res)
- printf("ERROR: got result of %d when expected 0\n", res);
- }
- _stp_map_print(mapi,"mapi[%1d] = %d");
-
- for (i = 1; i < 5; i++)
- {
- res = _stp_map_add_ix (mapx, i, -1);
- if (res)
- printf("ERROR: got result of %d when expected 0\n", res);
- }
- _stp_map_print (mapx, "mapx[%1d] = count:%C sum:%S avg:%A min:%m max:%M");
-
-
- _stp_map_del (mapi);
- _stp_map_del (maps);
- _stp_map_del (mapx);
- return 0;
-}
diff --git a/runtime/tests/maps/si.c b/runtime/tests/maps/si.c
deleted file mode 100644
index d9db65d7..00000000
--- a/runtime/tests/maps/si.c
+++ /dev/null
@@ -1,125 +0,0 @@
-#include "runtime.h"
-
-/* test of maps with keys of string and value of int64 */
-#define VALUE_TYPE INT64
-#define KEY1_TYPE STRING
-#include "map-gen.c"
-#include "map.c"
-
-int main ()
-{
- int res;
- MAP map = _stp_map_new_si(4);
- map->wrap = 1;
-
- /* map[Ohio] = 1 */
- _stp_map_set_si (map, "Ohio", 1);
- printf ("map[Ohio]=%lld\n", _stp_map_get_si(map,"Ohio"));
- _stp_map_print(map,"map[%1s] = %d");
-
- /* map[Washington] = 2 */
- _stp_map_set_si (map, "Washington", 2);
- _stp_map_print (map, "map[%1s] = %d");
-
- /* now try to confuse things */
- /* These won't do anything useful, but shouldn't crash */
-
- /* bad map */
- res = _stp_map_set_si(0,"foo",100);
- if (res != -2)
- printf("WARNING: got result of %d when expected -2\n", res);
-
- /* bad key */
- res = _stp_map_set_si(map,0,0);
- if (res != -2)
- printf("WARNING: got result of %d when expected -2\n", res);
-
- /* bad key */
- res = _stp_map_set_si(map,0,42);
- if (res != -2)
- printf("WARNING: got result of %d when expected -2\n", res);
-
- res = _stp_map_set_si(map,"",0);
- if (res)
- printf("WARNING: got result of %d when expected 0\n", res);
- _stp_map_print (map, "map[%1s] = %d");
-
- /* create and delete a key */
- _stp_map_set_si (map, "1024", 2048);
- _stp_map_print (map, "map[%1s] = %d");
- _stp_map_set_si (map, "1024", 0);
- _stp_map_print (map, "map[%1s] = %d");
- _stp_map_set_si (map, "1024", 2048);
- _stp_map_print (map, "map[%1s] = %d");
- _stp_map_set_si (map, "1024", 0);
- _stp_map_print (map, "map[%1s] = %d");
-
- /* check that unset values are 0 */
- res = _stp_map_get_si (map, "California");
- if (res)
- printf("ERROR: map[California] = %d (should be 0)\n", res);
-
- /* map[California] = 3 */
- _stp_map_set_si (map, "California", 3);
- _stp_map_print (map, "map[%1s] = %d");
-
- /* test an empty string as key */
- _stp_map_set_si (map, "", 7777);
- _stp_map_print (map, "map[%1s] = %d");
- _stp_map_set_si (map, "", 8888);
- _stp_map_print (map, "map[%1s] = %d");
- _stp_map_set_si (map, "", 0);
- _stp_map_print (map, "map[%1s] = %d");
-
-
- /* add 4 new entries, pushing the others out */
- int i;
- for (i = 6; i < 10; i++)
- {
- char buf[32];
- sprintf (buf, "String %d", i);
- res = _stp_map_set_si (map, buf, 100 + i);
- if (res)
- printf("WARNING: During wrap test, got result of %d when expected 0\n", res);
- }
- _stp_map_print (map, "map[%1s] = %d");
-
- /* turn off wrap and repeat */
- map->wrap = 0;
- for (i = 16; i < 20; i++) {
- char buf[32];
- sprintf (buf, "BAD String %d", i);
- res = _stp_map_set_si (map, buf, 100 + i);
- if (res != -1)
- printf("WARNING: During wrap test, got result of %d when expected -1\n", res);
- }
- _stp_map_print (map, "map[%1s] = %d");
-
- /* test addition */
- for (i = 6; i < 10; i++)
- {
- char buf[32];
- sprintf (buf, "String %d", i);
- res = _stp_map_add_si (map, buf, 1000 * i);
- if (res)
- printf("WARNING: During wrap test, got result of %d when expected 0\n", res);
- }
- _stp_map_print (map, "map[%1s] = %d");
-
- /* reset all */
- for (i = 6; i < 10; i++)
- {
- char buf[32];
- sprintf (buf, "String %d", i);
- res = _stp_map_set_si (map, buf, i);
- if (res)
- printf("WARNING: During wrap test, got result of %d when expected 0\n", res);
- }
- _stp_map_print (map, "map[%1s] = %d");
-
- _stp_map_clear(map);
- _stp_map_print (map, "map[%1s] = %d");
-
- _stp_map_del (map);
- return 0;
-}
diff --git a/runtime/tests/maps/size.c b/runtime/tests/maps/size.c
deleted file mode 100644
index 2fb2575c..00000000
--- a/runtime/tests/maps/size.c
+++ /dev/null
@@ -1,103 +0,0 @@
-#include "runtime.h"
-
-/* test of _stp_map_size() */
-#define VALUE_TYPE INT64
-#define KEY1_TYPE INT64
-#include "map-gen.c"
-
-#include "map.c"
-
-#define check(map,num) \
- { \
- int size = _stp_map_size(map); \
- if (size != num) \
- printf("ERROR at line %d: expected size %d and got %d instead.\n", __LINE__, num, size); \
- }
-
-int main ()
-{
- MAP map = _stp_map_new_ii(4);
- int64_t x;
-
- check (map, 0);
-
- /* map[1] = 2 */
- _stp_map_set_ii(map, 1, 2);
- check (map, 1);
-
- /* map[3] = 4 */
- _stp_map_set_ii(map, 3, 4);
- check (map,2);
-
- /* now try to confuse things */
- /* These won't do anything useful, but shouldn't crash */
- _stp_map_set_ii(0,1,100);
- _stp_map_set_ii(map,0,0);
- _stp_map_set_ii(map,100,0);
- check (map,2);
-
- /* map[5] = 6 */
- _stp_map_set_ii(map, 5, 6);
- check (map,3);
-
- /* set wrap */
- map->wrap = 1;
- /* add 4 new entries, pushing the others out */
- int i, res;
- for (i = 6; i < 10; i++) {
- res = _stp_map_set_ii (map, i, 100 + i);
- if (res)
- printf("WARNING: During wrap test, got result of %d when expected 0\n", res);
- }
- check (map,4);
-
- /* turn off wrap and repeat */
- map->wrap = 0;
- for (i = 16; i < 20; i++) {
- res = _stp_map_set_ii (map, i, 100 + i);
- if (res != -1)
- printf("WARNING: During wrap test, got result of %d when expected -1\n", res);
- }
- check (map,4);
-
- map->wrap = 1;
-
- /* 5, 382, 526, and 903 all hash to the same value (23) */
- /* use them to test the hash chain */
- _stp_map_set_ii (map, 5, 1005);
- _stp_map_set_ii (map, 382, 1382);
- _stp_map_set_ii (map, 526, 1526);
- _stp_map_set_ii (map, 903, 1903);
- check (map,4);
-
- /* now delete all 4 nodes, one by one */
- _stp_map_set_ii (map, 382, 0);
- check (map,3);
-
- _stp_map_set_ii (map, 5, 0);
- check (map,2);
-
- _stp_map_set_ii (map, 903, 0);
- check (map,1);
-
- _stp_map_set_ii (map, 526, 0);
- check (map,0);
-
- /* finally check clearing the map */
- _stp_map_clear(map);
- check (map,0);
-
- map->wrap = 0;
- for (i = 33; i < 99; i+=11)
- _stp_map_set_ii (map, i, 100*i+i);
- check (map,4);
-
- _stp_map_clear(map);
- check (map,0);
-
- _stp_map_set_ii (map, 1970, 1799);
- check (map,1);
-
- _stp_map_del (map);
- return 0;
-}
diff --git a/runtime/tests/maps/sort.c b/runtime/tests/maps/sort.c
deleted file mode 100644
index 7ae22206..00000000
--- a/runtime/tests/maps/sort.c
+++ /dev/null
@@ -1,105 +0,0 @@
-#include "runtime.h"
-
-/* test of map sorting */
-#define VALUE_TYPE STRING
-#define KEY1_TYPE INT64
-#define KEY2_TYPE INT64
-#define KEY3_TYPE STRING
-#include "map-gen.c"
-
-#define VALUE_TYPE INT64
-#define KEY1_TYPE STRING
-#define KEY2_TYPE STRING
-#include "map-gen.c"
-
-#include "map.c"
-
-int main ()
-{
- MAP mapiis = _stp_map_new_iiss(10);
-
- /* try to crash the sorts with sorting an empty list */
- _stp_map_sort (mapiis, 0, -1);
- _stp_map_sort (mapiis, 0, 1);
- _stp_map_sortn (mapiis, 3, 0, -1);
- _stp_map_sortn (mapiis, 0, 0, -1);
-
- /* load some test data */
- _stp_map_add_iiss (mapiis, 3,4,"California","Sacramento" );
- _stp_map_set_iiss (mapiis, 5,6,"Washington","Olympia" );
- _stp_map_set_iiss (mapiis, 7,8,"Oregon","Salem" );
- _stp_map_set_iiss (mapiis, 7,8,"Nevada","Carson City" );
- _stp_map_set_iiss (mapiis, 1, 4,"New Mexico","Santa Fe" );
- _stp_map_set_iiss (mapiis, -1,9,"North Carolina","Raleigh" );
- _stp_map_set_iiss (mapiis, 5,5,"Massachusetts","Boston" );
- _stp_map_set_iiss (mapiis, 2,2,"Vermont","Montpelier" );
- _stp_map_set_iiss (mapiis, 8,8,"Iowa","Des Moines" );
- _stp_map_set_iiss (mapiis, 1,2,"Ohio","Columbus" );
-
- _stp_printf("sorting from A-Z on value\n");
- _stp_map_sort (mapiis, 0, -1);
- _stp_map_print (mapiis, "%s -> %1d %2d %3s");
-
- _stp_printf("\nsorting from Z-A on value\n");
- _stp_map_sort (mapiis, 0, 1);
- _stp_map_print (mapiis, "%s -> %1d %2d %3s");
-
- _stp_printf("\nsorting from low to high on key 1\n");
- _stp_map_sort (mapiis, 1, -1);
- _stp_map_print (mapiis, "%1d %2d %3s -> %s");
-
- _stp_printf("\nsorting from high to low on key 1\n");
- _stp_map_sort (mapiis, 1, 1);
- _stp_map_print (mapiis, "%1d %2d %3s -> %s");
-
- _stp_printf("\nsorting from low to high on key 2\n");
- _stp_map_sort (mapiis, 2, -1);
- _stp_map_print (mapiis, "%1d %2d %3s -> %s");
-
- _stp_printf("\nsorting from high to low on key 2\n");
- _stp_map_sort (mapiis, 2, 1);
- _stp_map_print (mapiis, "%1d %2d %3s -> %s");
-
-
- _stp_printf("\nsorting from low to high on key 3\n");
- _stp_map_sort (mapiis, 3, -1);
- _stp_map_print (mapiis, "%3s\t\t%1d %2d -> %s");
-
- _stp_printf("\nsorting from high to low on key 3\n");
- _stp_map_sort (mapiis, 3, 1);
- _stp_map_print (mapiis, "%3s\t\t%1d %2d -> %s");
-
- _stp_printf("\ntop 3 alphabetical by value\n");
- _stp_map_sortn (mapiis, 3, 0, -1);
- _stp_map_printn (mapiis, 3, "%s -> %1d %2d %3s");
-
- _stp_printf("\nbottom 2 alphabetical by value\n");
- _stp_map_sortn (mapiis, 2, 0, 1);
- _stp_map_printn (mapiis, 2, "%s -> %1d %2d %3s");
-
-
- _stp_printf("\ntop 5 sorted by key 1\n");
- _stp_map_sortn (mapiis, 5, 1, 1);
- _stp_map_printn (mapiis, 5, "%1d %2d %3s -> %s");
- _stp_printf("\nbottom 5 sorted by key 1\n");
- _stp_map_sortn (mapiis, 5, 1, -1);
- _stp_map_printn (mapiis, 5, "%1d %2d %3s -> %s");
-
- MAP mapss = _stp_map_new_ssi(4);
- _stp_map_set_ssi (mapss, "Riga", "Latvia", 135786);
- _stp_map_set_ssi (mapss, "Sofia", "Bulgaria", 138740);
- _stp_map_set_ssi (mapss, "Valletta", "Malta", 1);
- _stp_map_set_ssi (mapss, "Nicosia", "Cyprus", -1);
-
- _stp_printf("sorted by population from low to high\n");
- _stp_map_sort (mapss, 0, -1);
- _stp_map_print (mapss, "%1s is the capitol of %2s and the nerd population is %d");
- _stp_printf("sorted by population from high to low\n");
- _stp_map_sort (mapss, 0, 1);
- _stp_map_print (mapss, "%1s is the capitol of %2s and the nerd population is %d");
-
- _stp_map_del(mapss);
- _stp_map_del(mapiis);
-
- return 0;
-}
diff --git a/runtime/tests/maps/sort2.c b/runtime/tests/maps/sort2.c
deleted file mode 100644
index 0b3bc547..00000000
--- a/runtime/tests/maps/sort2.c
+++ /dev/null
@@ -1,105 +0,0 @@
-#include "runtime.h"
-
-/* test of map sorting. Just like sort.c, except test with an odd number of nodes */
-#define VALUE_TYPE STRING
-#define KEY1_TYPE INT64
-#define KEY2_TYPE INT64
-#define KEY3_TYPE STRING
-#include "map-gen.c"
-
-#define VALUE_TYPE INT64
-#define KEY1_TYPE STRING
-#define KEY2_TYPE STRING
-#include "map-gen.c"
-
-#include "map.c"
-
-int main ()
-{
- MAP mapiis = _stp_map_new_iiss(10);
-
- /* try to crash the sorts with sorting an empty list */
- _stp_map_sort (mapiis, 0, -1);
- _stp_map_sort (mapiis, 0, 1);
- _stp_map_sortn (mapiis, 3, 0, -1);
- _stp_map_sortn (mapiis, 0, 0, -1);
-
- /* load some test data */
- _stp_map_add_iiss (mapiis, 3,4,"California","Sacramento" );
- _stp_map_set_iiss (mapiis, 5,6,"Washington","Olympia" );
- _stp_map_set_iiss (mapiis, 7,8,"Oregon","Salem" );
- _stp_map_set_iiss (mapiis, 7,8,"Nevada","Carson City" );
- _stp_map_set_iiss (mapiis, 1, 4,"New Mexico","Santa Fe" );
- _stp_map_set_iiss (mapiis, -1,9,"North Carolina","Raleigh" );
- _stp_map_set_iiss (mapiis, 5,5,"Massachusetts","Boston" );
- _stp_map_set_iiss (mapiis, 8,8,"Iowa","Des Moines" );
- _stp_map_set_iiss (mapiis, 1,2,"Ohio","Columbus" );
-
- _stp_printf("sorting from A-Z on value\n");
- _stp_map_sort (mapiis, 0, -1);
- _stp_map_print (mapiis, "%s -> %1d %2d %3s");
-
- _stp_printf("\nsorting from Z-A on value\n");
- _stp_map_sort (mapiis, 0, 1);
- _stp_map_print (mapiis, "%s -> %1d %2d %3s");
-
- _stp_printf("\nsorting from low to high on key 1\n");
- _stp_map_sort (mapiis, 1, -1);
- _stp_map_print (mapiis, "%1d %2d %3s -> %s");
-
- _stp_printf("\nsorting from high to low on key 1\n");
- _stp_map_sort (mapiis, 1, 1);
- _stp_map_print (mapiis, "%1d %2d %3s -> %s");
-
- _stp_printf("\nsorting from low to high on key 2\n");
- _stp_map_sort (mapiis, 2, -1);
- _stp_map_print (mapiis, "%1d %2d %3s -> %s");
-
- _stp_printf("\nsorting from high to low on key 2\n");
- _stp_map_sort (mapiis, 2, 1);
- _stp_map_print (mapiis, "%1d %2d %3s -> %s");
-
-
- _stp_printf("\nsorting from low to high on key 3\n");
- _stp_map_sort (mapiis, 3, -1);
- _stp_map_print (mapiis, "%3s\t\t%1d %2d -> %s");
-
- _stp_printf("\nsorting from high to low on key 3\n");
- _stp_map_sort (mapiis, 3, 1);
- _stp_map_print (mapiis, "%3s\t\t%1d %2d -> %s");
-
- _stp_printf("\ntop 3 alphabetical by value\n");
- _stp_map_sortn (mapiis, 3, 0, -1);
- _stp_map_printn (mapiis, 3, "%s -> %1d %2d %3s");
-
- _stp_printf("\nbottom 2 alphabetical by value\n");
- _stp_map_sortn (mapiis, 2, 0, 1);
- _stp_map_printn (mapiis, 2, "%s -> %1d %2d %3s");
-
-
- _stp_printf("\ntop 5 sorted by key 1\n");
- _stp_map_sortn (mapiis, 5, 1, 1);
- _stp_map_printn (mapiis, 5, "%1d %2d %3s -> %s");
- _stp_printf("\nbottom 5 sorted by key 1\n");
- _stp_map_sortn (mapiis, 5, 1, -1);
- _stp_map_printn (mapiis, 5, "%1d %2d %3s -> %s");
-
- MAP mapss = _stp_map_new_ssi(5);
- _stp_map_set_ssi (mapss, "Riga", "Latvia", 135786);
- _stp_map_set_ssi (mapss, "Sofia", "Bulgaria", 138740);
- _stp_map_set_ssi (mapss, "Valletta", "Malta", 1);
- _stp_map_set_ssi (mapss, "Nicosia", "Cyprus", -1);
- _stp_map_set_ssi (mapss, "Chisinau", "Moldova", 1024);
-
- _stp_printf("sorted by population from low to high\n");
- _stp_map_sort (mapss, 0, -1);
- _stp_map_print (mapss, "%1s is the capitol of %2s and the nerd population is %d");
- _stp_printf("sorted by population from high to low\n");
- _stp_map_sort (mapss, 0, 1);
- _stp_map_print (mapss, "%1s is the capitol of %2s and the nerd population is %d");
-
- _stp_map_del(mapss);
- _stp_map_del(mapiis);
-
- return 0;
-}
diff --git a/runtime/tests/maps/sort_stat.c b/runtime/tests/maps/sort_stat.c
deleted file mode 100644
index f3f0435e..00000000
--- a/runtime/tests/maps/sort_stat.c
+++ /dev/null
@@ -1,90 +0,0 @@
-#include "runtime.h"
-
-/* test of map sorting */
-
-#define VALUE_TYPE STAT
-#define KEY1_TYPE STRING
-#define KEY2_TYPE STRING
-#include "map-gen.c"
-
-#include "map.c"
-
-int main ()
-{
- MAP mapssx = _stp_map_new_ssx (8, HIST_LINEAR, 0, 100, 10 );
- int i,j;
-
- for (i = 0; i < 100; i++)
- for (j = 0; j <= i*10 ; j++ )
- _stp_map_add_ssx (mapssx, "California", "Sacramento", i);
-
- for (i = 0; i < 10; i++)
- for (j = 0; j < 10 ; j++ )
- _stp_map_add_ssx (mapssx, "Washington", "Olympia", j * i );
-
- for (i = 0; i < 100; i += 10)
- for (j = 0; j < i/5 ; j++ )
- _stp_map_add_ssx (mapssx, "Oregon", "Salem", i);
-
- for (i = 0; i < 100; i += 10)
- for (j = 0; j < i/10 ; j++ )
- _stp_map_add_ssx (mapssx, "Nevada", "Carson City", i + j);
-
- for (i = 0; i < 100; i += 10)
- for (j = 0; j < i/20 ; j++ )
- _stp_map_add_ssx (mapssx, "Ohio", "Columbus", 50);
-
- for (i = 0; i < 100; i += 10)
- for (j = 0; j < i/10 ; j++ )
- _stp_map_add_ssx (mapssx, "North Carolina", "Raleigh", 100 - j * i);
-
- for (i = 0; i < 100; i += 10)
- for (j = 0; j < i ; j++ )
- _stp_map_add_ssx (mapssx, "New Mexico", "Santa Fe", 50 - j);
-
-
- _stp_map_print (mapssx, "Bogons per packet for %1s\ncount:%C sum:%S avg:%A min:%m max:%M\n%H");
-
- _stp_printf("SORTED BY COUNT\n");
- _stp_map_sort (mapssx, SORT_COUNT, 1);
- _stp_map_print (mapssx, "%C %1s");
-
- _stp_printf("SORTED BY COUNT (low to high)\n");
- _stp_map_sort (mapssx, SORT_COUNT, -1);
- _stp_map_print (mapssx, "%C %1s");
-
- _stp_printf("SORTED BY SUM\n");
- _stp_map_sort (mapssx, SORT_SUM, 1);
- _stp_map_print (mapssx, "%S %1s");
-
- _stp_printf("SORTED BY SUM (low to high)\n");
- _stp_map_sort (mapssx, SORT_SUM, -1);
- _stp_map_print (mapssx, "%S %1s");
-
- _stp_printf("SORTED BY MIN\n");
- _stp_map_sort (mapssx, SORT_MIN, 1);
- _stp_map_print (mapssx, "%m %1s");
-
- _stp_printf("SORTED BY MIN (low to high)\n");
- _stp_map_sort (mapssx, SORT_MIN, -1);
- _stp_map_print (mapssx, "%m %1s");
-
- _stp_printf("SORTED BY MAX\n");
- _stp_map_sort (mapssx, SORT_MAX, 1);
- _stp_map_print (mapssx, "%M %1s");
-
- _stp_printf("SORTED BY MAX (low to high)\n");
- _stp_map_sort (mapssx, SORT_MAX, -1);
- _stp_map_print (mapssx, "%M %1s");
-
- _stp_printf("SORTED BY AVG\n");
- _stp_map_sort (mapssx, SORT_AVG, 1);
- _stp_map_print (mapssx, "%A %1s");
-
- _stp_printf("SORTED BY AVG (low to high)\n");
- _stp_map_sort (mapssx, SORT_AVG, -1);
- _stp_map_print (mapssx, "%A %1s");
-
- _stp_map_del (mapssx);
- return 0;
-}
diff --git a/runtime/tests/maps/ssssss.c b/runtime/tests/maps/ssssss.c
deleted file mode 100644
index 1cc020b7..00000000
--- a/runtime/tests/maps/ssssss.c
+++ /dev/null
@@ -1,37 +0,0 @@
-#include "runtime.h"
-
-/* test of maps with keys 5 strings and values of string */
-#define VALUE_TYPE STRING
-#define KEY1_TYPE STRING
-#define KEY2_TYPE STRING
-#define KEY3_TYPE STRING
-#define KEY4_TYPE STRING
-#define KEY5_TYPE STRING
-#include "map-gen.c"
-
-#include "map.c"
-
-int main ()
-{
- struct map_node *ptr;
- MAP map = _stp_map_new_ssssss(4);
-
- _stp_map_set_ssssss (map, "1ABC", "2ABC", "3ABC", "4ABC", "5ABC", "666");
- _stp_map_set_ssssss (map, "1QRS", "2QRS", "3QRS", "4QRS", "5QRS", "777");
- _stp_map_set_ssssss (map, "1abc", "2abc", "3abc", "4abc", "5abc", "888");
- _stp_map_set_ssssss (map, "1XYZ", "2XYZ", "3XYZ", "4XYZ", "5XYZ", "999");
-
- foreach (map, ptr)
- printf ("map[%s, %s, %s, %s, %s] = %s\n",
- _stp_key_get_str(ptr,1),
- _stp_key_get_str(ptr,2),
- _stp_key_get_str(ptr,3),
- _stp_key_get_str(ptr,4),
- _stp_key_get_str(ptr,5),
- _stp_get_str(ptr));
-
-
- _stp_map_print(map,"%1s and %2s and %3s and %4s and %5s ---> %s");
- _stp_map_del (map);
- return 0;
-}
diff --git a/runtime/tests/math/Makefile b/runtime/tests/math/Makefile
deleted file mode 100644
index c396c132..00000000
--- a/runtime/tests/math/Makefile
+++ /dev/null
@@ -1,5 +0,0 @@
-default: tests
-
-tests:
- tclsh all.tcl
-
diff --git a/runtime/tests/math/all.tcl b/runtime/tests/math/all.tcl
deleted file mode 100644
index 23757202..00000000
--- a/runtime/tests/math/all.tcl
+++ /dev/null
@@ -1,4 +0,0 @@
-package require tcltest
-namespace import -force tcltest::*
-tcltest::testsDirectory [file dir [info script]]
-tcltest::runAllTests
diff --git a/runtime/tests/math/div64.c b/runtime/tests/math/div64.c
deleted file mode 100644
index ed033d5b..00000000
--- a/runtime/tests/math/div64.c
+++ /dev/null
@@ -1,182 +0,0 @@
-/* test of 64-bit division */
-#include "runtime.h"
-#define LLONG_MAX 0x7fffffffffffffffLL
-#ifndef LLONG_MIN
-#define LLONG_MIN 0x8000000000000000LL
-#endif
-
-/* This tests a lot of edge conditions.*/
-/* Then it does 10 million random divisions, comparing the result */
-/* with the results from glibc */
-
-int main()
-{
- int64_t x, y, div1, mod1, div2, mod2;
- const char *error;
- int i;
-
- x = 0;
- y = 0;
- div1 = _stp_div64(&error, x, y);
- if (div1 != 0 || *error != 'd') {
- printf("Failed 0/0 test\n");
- exit(-1);
- }
- error = "";
-
- mod1 = _stp_mod64(&error, x, y);
- if (mod1 != 0 || *error != 'd') {
- printf("Failed 0%0 test\n");
- exit(-1);
- }
- error = "";
-
- x = 1;
- y = 0;
- div1 = _stp_div64(&error, x, y);
- if (div1 != 0 || *error != 'd') {
- printf("Failed 1/0 test\n");
- exit(-1);
- }
- error = "";
-
- mod1 = _stp_mod64(&error, x, y);
- if (mod1 != 0 || *error != 'd') {
- printf("Failed 1%0 test\n");
- exit(-1);
- }
- error = "";
-
- x = 0;
- y = 1;
-
- div1 = _stp_div64(&error, x, y);
- if (*error || div1 != 0) {
- printf("Failed 0/1 test\n");
- exit(-1);
- }
-
- mod1 = _stp_mod64(&error, x, y);
- if (*error || mod1 != 0) {
- printf("Failed 0%1 test\n");
- exit(-1);
- }
-
- x = -1;
- y = -1;
-
- div1 = _stp_div64(&error, x, y);
- if (*error || div1 != 1) {
- printf("Failed -1/-1 test\n");
- exit(-1);
- }
-
- mod1 = _stp_mod64(&error, x, y);
- if (*error || mod1 != 0) {
- printf("Failed -1%-1 test\n");
- exit(-1);
- }
-
-
- for (y = -1; y < 2; y++) {
- if (y == 0)
- continue;
-
-#ifndef __LP64__
- for (x = LONG_MIN - 1LL; x < LONG_MIN + 2LL; x++ ) {
- div1 = _stp_div64(&error, x, y);
- mod1 = _stp_mod64(&error, x, y);
- div2 = x/y;
- mod2 = x%y;
- if (div1 != div2) {
- printf ("%lld/%lld (%llx/%llx) was %lld and should have been %lld\n", x,y,x,y,div1,div2);
- exit (-1);
- }
- if (mod1 != mod2) {
- printf ("%lld\%%%lld (%llx/%llx) was %lld and should have been %lld\n", x,y,x,y,mod1,mod2);
- exit (-1);
- }
- }
-
- for (x = LONG_MAX - 1LL; x < LONG_MAX + 2LL; x++ ) {
- div1 = _stp_div64(&error, x, y);
- mod1 = _stp_mod64(&error, x, y);
- div2 = x/y;
- mod2 = x%y;
- if (div1 != div2) {
- printf ("%lld/%lld (%llx/%llx) was %lld and should have been %lld\n", x,y,x,y,div1,div2);
- exit (-1);
- }
- if (mod1 != mod2) {
- printf ("%lld\%%%lld (%llx/%llx) was %lld and should have been %lld\n", x,y,x,y,mod1,mod2);
- exit (-1);
- }
- }
-#endif
-
- for (x = LLONG_MIN; x <= LLONG_MIN + 1LL; x++ ) {
- div1 = _stp_div64(&error, x, y);
- mod1 = _stp_mod64(&error, x, y);
-#ifdef __LP64__
- if (x == LLONG_MIN && y == -1) {
- if (div1 != LLONG_MIN) {
- printf ("%lld/%lld was %lld and should have been %lld (overflow)\n", x,y,div1,LLONG_MIN);
- exit(-1);
- }
- continue;
- }
-#endif
- div2 = x/y;
- mod2 = x%y;
- if (div1 != div2) {
- printf ("%lld/%lld was %lld and should have been %lld\n", x,y,div1,div2);
- exit (-1);
- }
- if (mod1 != mod2) {
- printf ("%lld\%%%lld was %lld and should have been %lld\n", x,y,mod1,mod2);
- exit (-1);
- }
- }
-
- for (x = LONG_MAX - 1; x > 0 && x <= LONG_MAX; x++ ) {
- div1 = _stp_div64(&error, x, y);
- mod1 = _stp_mod64(&error, x, y);
- div2 = x/y;
- mod2 = x%y;
- if (div1 != div2) {
- printf ("%lld/%lld was %lld and should have been %lld\n", x,y,div1,div2);
- exit (-1);
- }
- if (mod1 != mod2) {
- printf ("%lld\%%%lld was %lld and should have been %lld\n", x,y,mod1,mod2);
- exit (-1);
- }
- }
- }
-
- /* just for fun, do ten million random divisions and mods */
- for (i = 0; i < 10000000; i++) {
- x = mrand48();
- y = mrand48();
- if (y == 0) {
- i--;
- continue;
- }
-
- div1 = _stp_div64(NULL, x, y);
- mod1 = _stp_mod64(NULL, x, y);
- div2 = x/y;
- mod2 = x%y;
-
- if (div1 != div2) {
- printf ("%lld/%lld was %lld and should have been %lld\n", x,y,div1,div2);
- exit (-1);
- }
- if (mod1 != mod2) {
- printf ("%lld\%%%lld was %lld and should have been %lld\n", x,y,mod1,mod2);
- exit (-1);
- }
- }
- printf("OK\n");
- return 0;
-}
diff --git a/runtime/tests/math/math.test b/runtime/tests/math/math.test
deleted file mode 100644
index e7c58ba0..00000000
--- a/runtime/tests/math/math.test
+++ /dev/null
@@ -1,19 +0,0 @@
-package require tcltest
-namespace import -force tcltest::*
-
-cd $tcltest::testsDirectory
-
-set CFLAGS "-Os"
-set KPATH "/lib/modules/[exec uname -r]/build/include"
-set MPATH "/lib/modules/[exec uname -r]/build/include/asm/mach-default"
-set PATH "../../user"
-
-test printf_A {Basic printf test} -setup {
- exec gcc $CFLAGS -I $KPATH -I $PATH -I $MPATH -o test div64.c
-} -body {
- exec ./test
-} -result {OK}
-
-exec rm test
-
-cleanupTests
diff --git a/runtime/tests/pmaps/Makefile b/runtime/tests/pmaps/Makefile
deleted file mode 100644
index c396c132..00000000
--- a/runtime/tests/pmaps/Makefile
+++ /dev/null
@@ -1,5 +0,0 @@
-default: tests
-
-tests:
- tclsh all.tcl
-
diff --git a/runtime/tests/pmaps/all.tcl b/runtime/tests/pmaps/all.tcl
deleted file mode 100644
index c0b38a0e..00000000
--- a/runtime/tests/pmaps/all.tcl
+++ /dev/null
@@ -1,5 +0,0 @@
-package require tcltest
-namespace import -force tcltest::*
-tcltest::testsDirectory [file dir [info script]]
-tcltest::runAllTests
-
diff --git a/runtime/tests/pmaps/ii.c b/runtime/tests/pmaps/ii.c
deleted file mode 100644
index dfce0a07..00000000
--- a/runtime/tests/pmaps/ii.c
+++ /dev/null
@@ -1,59 +0,0 @@
-#include "runtime.h"
-
-/* test of pmaps with keys of int64 and value of int64 */
-
-/* It's not clear this would ever be used in the systemtap language.
- It would be useful as an array of counters. */
-
-#define VALUE_TYPE INT64
-#define KEY1_TYPE INT64
-#include "pmap-gen.c"
-
-#include "map.c"
-
-int main ()
-{
- PMAP map = _stp_pmap_new_ii(4);
- int64_t x;
-
- /* put some data in. _processor_number is a global hack that allows */
- /* us to set the current emulated cpu number for our userspace tests. */
- /* Note that we set values based on the cpu number just to show that */
- /* different values are stored in each cpu */
- for (_processor_number = 0; _processor_number < NR_CPUS; _processor_number++) {
- _stp_pmap_add_ii(map, 1, _processor_number);
- _stp_pmap_add_ii(map, 2, 10 *_processor_number + 1);
- _stp_pmap_add_ii(map, 3, _processor_number * _processor_number);
- _stp_pmap_add_ii(map, 4, 1);
- }
-
- /* read it back out and verify. Use the special get_cpu call to get non-aggregated data */
- for (_processor_number = 0; _processor_number < NR_CPUS; _processor_number++) {
- x = _stp_pmap_get_cpu_ii (map, 3);
- if (x != _processor_number * _processor_number)
- printf("ERROR: Got %lld when expected %lld\n", x, (long long)(_processor_number * _processor_number));
- x = _stp_pmap_get_cpu_ii (map, 1);
- if (x != _processor_number)
- printf("ERROR: Got %lld when expected %lld\n", x, (long long)_processor_number);
- x = _stp_pmap_get_cpu_ii (map, 2);
- if (x != 10 * _processor_number + 1)
- printf("ERROR: Got %lld when expected %lld\n", x, (long long)(10 * _processor_number + 1));
- x = _stp_pmap_get_cpu_ii (map, 4);
- if (x != 1LL)
- printf("ERROR: Got %lld when expected %lld\n", x, 1LL);
- }
-
- /* now print the per-cpu data */
- for (_processor_number = 0; _processor_number < NR_CPUS; _processor_number++) {
- printf("CPU #%d\n", _processor_number);
- _stp_pmap_printn_cpu (map,0, "map[%1d] = %d", _processor_number);
- }
- _processor_number = 0;
-
- /* print the aggregated data */
- _stp_pmap_print(map,"map[%1d] = %d");
-
- _stp_pmap_del (map);
- return 0;
-}
-
diff --git a/runtime/tests/pmaps/ii2.c b/runtime/tests/pmaps/ii2.c
deleted file mode 100644
index 0a28ad87..00000000
--- a/runtime/tests/pmaps/ii2.c
+++ /dev/null
@@ -1,48 +0,0 @@
-#include "runtime.h"
-
-/* test of maps and pmaps with keys of int64 and value of int64 */
-
-/* Make sure we can cleanly generate both */
-
-#define VALUE_TYPE INT64
-#define KEY1_TYPE INT64
-#include "pmap-gen.c"
-
-#define VALUE_TYPE INT64
-#define KEY1_TYPE INT64
-#include "map-gen.c"
-
-#include "map.c"
-
-int main ()
-{
- MAP map = _stp_map_new_ii(4);
- PMAP pmap = _stp_pmap_new_ii(4);
- int64_t x;
-
- /* put some data in. _processor_number is a global hack that allows */
- /* us to set the current emulated cpu number for our userspace tests. */
- /* Note that we set values based on the cpu number just to show that */
- /* different values are stored in each cpu */
- for (_processor_number = 0; _processor_number < NR_CPUS; _processor_number++) {
- _stp_pmap_add_ii(pmap, 1, _processor_number);
- _stp_pmap_add_ii(pmap, 2, 10 *_processor_number + 1);
- _stp_pmap_add_ii(pmap, 3, _processor_number * _processor_number);
- _stp_pmap_add_ii(pmap, 4, 1);
- _stp_map_add_ii(map, 1, _processor_number);
- _stp_map_add_ii(map, 2, 10 *_processor_number + 1);
- _stp_map_add_ii(map, 3, _processor_number * _processor_number);
- _stp_map_add_ii(map, 4, 1);
- }
-
- _processor_number = 0;
-
- /* print the aggregated data */
- _stp_map_print(map,"map[%1d] = %d");
- _stp_pmap_print(pmap,"pmap[%1d] = %d");
-
- _stp_map_del (map);
- _stp_pmap_del (pmap);
- return 0;
-}
-
diff --git a/runtime/tests/pmaps/ii3.c b/runtime/tests/pmaps/ii3.c
deleted file mode 100644
index e2dee7a6..00000000
--- a/runtime/tests/pmaps/ii3.c
+++ /dev/null
@@ -1,59 +0,0 @@
-#include "runtime.h"
-
-/* test of pmaps with keys of int64 and value of int64 */
-
-/* It's not clear this would ever be used in the systemtap language.
- It would be useful as an array of counters. */
-
-#define VALUE_TYPE INT64
-#define KEY1_TYPE INT64
-#include "pmap-gen.c"
-
-#include "map.c"
-
-int main ()
-{
- PMAP map = _stp_pmap_new_ii(4);
- int i;
-
- /* put some data in. _processor_number is a global hack that allows */
- /* us to set the current emulated cpu number for our userspace tests. */
- /* Note that we set values based on the cpu number just to show that */
- /* different values are stored in each cpu */
- for (_processor_number = 0; _processor_number < NR_CPUS; _processor_number++) {
- _stp_pmap_add_ii(map, 1, _processor_number);
- _stp_pmap_add_ii(map, 2, 10 *_processor_number + 1);
- _stp_pmap_add_ii(map, 3, _processor_number * _processor_number);
- _stp_pmap_add_ii(map, 4, 1);
- }
-
- _processor_number = 0;
-
- /* get the data with get calls. this is not very efficient */
- for (i = 1; i < 5; i++)
- printf("map[%d] = %lld\n", i, _stp_pmap_get_ii(map, i));
- printf("\n");
-
- /* do it again. test that the aggregation map got cleared */
- for (i = 1; i < 5; i++)
- printf("map[%d] = %lld\n", i, _stp_pmap_get_ii(map, i));
- printf("\n");
-
- /* print the aggregated data */
- _stp_pmap_print(map,"map[%1d] = %d");
-
- /* delete an entry and repeat */
- for (_processor_number = 0; _processor_number < NR_CPUS; _processor_number++)
- _stp_pmap_set_ii(map, 2, 0);
- _processor_number = 0;
-
- for (i = 1; i < 5; i++)
- printf("map[%d] = %lld\n", i, _stp_pmap_get_ii(map, i));
- printf("\n");
-
- _stp_pmap_print(map,"map[%1d] = %d");
-
- _stp_pmap_del (map);
- return 0;
-}
-
diff --git a/runtime/tests/pmaps/is.c b/runtime/tests/pmaps/is.c
deleted file mode 100644
index a97d8b0b..00000000
--- a/runtime/tests/pmaps/is.c
+++ /dev/null
@@ -1,67 +0,0 @@
-#include "runtime.h"
-
-/* test of pmaps with keys of int64 and value of string */
-
-/* It's not clear this would ever be used in the systemtap language.
- It is not clear this would be useful. */
-
-#define VALUE_TYPE STRING
-#define KEY1_TYPE INT64
-#include "pmap-gen.c"
-
-#include "map.c"
-
-int main ()
-{
- PMAP map = _stp_pmap_new_is(4);
- char *x;
- char buf[32];
-
- /* put some data in. _processor_number is a global hack that allows */
- /* us to set the current emulated cpu number for our userspace tests. */
- /* Note that we set values based on the cpu number just to show that */
- /* different values are stored in each cpu */
- for (_processor_number = 0; _processor_number < NR_CPUS; _processor_number++) {
- sprintf(buf, "%d,", _processor_number);
- _stp_pmap_add_is(map, 1, buf);
- sprintf(buf, "%d,", 10 *_processor_number + 1);
- _stp_pmap_add_is(map, 2, buf);
- sprintf(buf, "%d,", _processor_number * _processor_number);
- _stp_pmap_add_is(map, 3, buf);
- _stp_pmap_add_is(map, 4, "1,");
- }
-
- /* read it back out and verify. Use the special get_cpu call to get non-aggregated data */
- for (_processor_number = 0; _processor_number < NR_CPUS; _processor_number++) {
- x = _stp_pmap_get_cpu_is (map, 3);
- sprintf(buf, "%d,", _processor_number * _processor_number);
- if (strcmp(x, buf))
- printf("ERROR: Got %s when expected %s\n", x, buf);
- x = _stp_pmap_get_cpu_is (map, 1);
- sprintf(buf, "%d,", _processor_number);
- if (strcmp(x, buf))
- printf("ERROR: Got %s when expected %s\n", x, buf);
- x = _stp_pmap_get_cpu_is (map, 4);
- sprintf(buf, "%d,", 1);
- if (strcmp(x, buf))
- printf("ERROR: Got %s when expected %s\n", x, buf);
- x = _stp_pmap_get_cpu_is (map, 2);
- sprintf(buf, "%d,", 10 * _processor_number +1);
- if (strcmp(x, buf))
- printf("ERROR: Got %s when expected %s\n", x, buf);
- }
-
- /* now print the per-cpu data */
- for (_processor_number = 0; _processor_number < NR_CPUS; _processor_number++) {
- printf("CPU #%d\n", _processor_number);
- _stp_pmap_printn_cpu (map,0, "map[%1d] = %s", _processor_number);
- }
- _processor_number = 0;
-
- /* print the aggregated data */
- _stp_pmap_print(map,"map[%1d] = %s");
-
- _stp_pmap_del (map);
- return 0;
-}
-
diff --git a/runtime/tests/pmaps/ix.c b/runtime/tests/pmaps/ix.c
deleted file mode 100644
index 0eba2d54..00000000
--- a/runtime/tests/pmaps/ix.c
+++ /dev/null
@@ -1,61 +0,0 @@
-#include "runtime.h"
-
-/* test of pmaps with keys of int64 and value of stat */
-
-#define VALUE_TYPE STAT
-#define KEY1_TYPE INT64
-#include "pmap-gen.c"
-
-#include "map.c"
-
-int main ()
-{
- PMAP map = _stp_pmap_new_ix(4, HIST_LINEAR, 0, 100, 10);
- int64_t x;
-
- /* put some data in. _processor_number is a global hack that allows */
- /* us to set the current emulated cpu number for our userspace tests. */
- /* Note that we set values based on the cpu number just to show that */
- /* different values are stored in each cpu */
- for (_processor_number = 0; _processor_number < NR_CPUS; _processor_number++) {
- _stp_pmap_add_ix(map, 1, _processor_number);
- _stp_pmap_add_ix(map, 2, 10 *_processor_number + 1);
- _stp_pmap_add_ix(map, 3, _processor_number * _processor_number);
- _stp_pmap_add_ix(map, 4, 1);
- }
-
-#if 0
- /* read it back out and verify. Use the special get_cpu call to get non-aggregated data */
- for (_processor_number = 0; _processor_number < NR_CPUS; _processor_number++) {
- x = _stp_pmap_get_cpu_ix (map, 3);
- if (x != _processor_number * _processor_number)
- printf("ERROR: Got %lld when expected %lld\n", x, (long long)(_processor_number * _processor_number));
- x = _stp_pmap_get_cpu_ix (map, 1);
- if (x != _processor_number)
- printf("ERROR: Got %lld when expected %lld\n", x, (long long)_processor_number);
- x = _stp_pmap_get_cpu_ix (map, 2);
- if (x != 10 * _processor_number + 1)
- printf("ERROR: Got %lld when expected %lld\n", x, (long long)(10 * _processor_number + 1));
- x = _stp_pmap_get_cpu_ix (map, 4);
- if (x != 1LL)
- printf("ERROR: Got %lld when expected %lld\n", x, 1LL);
- }
-#endif
-
- /* now print the per-cpu data */
- for (_processor_number = 0; _processor_number < NR_CPUS; _processor_number++) {
- printf("CPU #%d\n", _processor_number);
- _stp_pmap_printn_cpu (map,
- 0,
- "map[%1d] = count:%C sum:%S avg:%A min:%m max:%M",
- _processor_number);
- }
- _processor_number = 0;
-
- /* print the aggregated data */
- _stp_pmap_print(map,"map[%1d] = count:%C sum:%S avg:%A min:%m max:%M\n%H");
-
- _stp_pmap_del (map);
- return 0;
-}
-
diff --git a/runtime/tests/pmaps/ix2.c b/runtime/tests/pmaps/ix2.c
deleted file mode 100644
index 638e5226..00000000
--- a/runtime/tests/pmaps/ix2.c
+++ /dev/null
@@ -1,64 +0,0 @@
-#include "runtime.h"
-
-/* test of pmaps with keys of int64 and value of stat */
-
-#define VALUE_TYPE STAT
-#define KEY1_TYPE INT64
-#include "pmap-gen.c"
-
-#include "map.c"
-
-int main ()
-{
- PMAP map = _stp_pmap_new_ix(4, HIST_LINEAR, 0, 100, 10);
- int i;
-
- /* put some data in. _processor_number is a global hack that allows */
- /* us to set the current emulated cpu number for our userspace tests. */
- /* Note that we set values based on the cpu number just to show that */
- /* different values are stored in each cpu */
- for (_processor_number = 0; _processor_number < NR_CPUS; _processor_number++) {
- _stp_pmap_add_ix(map, 1, _processor_number);
- _stp_pmap_add_ix(map, 2, 10 *_processor_number + 1);
- _stp_pmap_add_ix(map, 3, _processor_number * _processor_number);
- _stp_pmap_add_ix(map, 4, 1);
- }
-
- /* now print the per-cpu data */
- for (_processor_number = 0; _processor_number < NR_CPUS; _processor_number++) {
- printf("CPU #%d\n", _processor_number);
- _stp_pmap_printn_cpu (map,
- 0,
- "map[%1d] = count:%C sum:%S avg:%A min:%m max:%M",
- _processor_number);
- }
- _processor_number = 0;
-
- /* print the aggregated data */
- _stp_pmap_print(map,"map[%1d] = count:%C sum:%S avg:%A min:%m max:%M\n%H");
-
- /* now use GET */
- for (i = 1; i < 5; i++)
- printf("map[%d] Sum = %lld\n", i, _stp_pmap_get_ix(map, i)->sum);
- printf("\n");
-
- /* delete an entry and repeat */
- for (_processor_number = 0; _processor_number < NR_CPUS; _processor_number++)
- _stp_pmap_set_ix(map, 2, 0);
- _processor_number = 0;
-
- /* print the aggregated data */
- _stp_pmap_print(map,"map[%1d] = count:%C sum:%S avg:%A min:%m max:%M\n%H");
-
- /* now use GET */
- for (i = 1; i < 5; i++) {
- stat *sd = _stp_pmap_get_ix(map, i);
- if (sd)
- printf("map[%d] Sum = %lld\n", i, sd->sum);
- }
- printf("\n");
-
- _stp_pmap_del (map);
- return 0;
-}
-
diff --git a/runtime/tests/pmaps/ix_log.c b/runtime/tests/pmaps/ix_log.c
deleted file mode 100644
index 4f3c5503..00000000
--- a/runtime/tests/pmaps/ix_log.c
+++ /dev/null
@@ -1,62 +0,0 @@
-#include "runtime.h"
-
-/* like ix.c, except use HIST_LOG */
-/* test of pmaps with keys of int64 and value of stat */
-
-#define VALUE_TYPE STAT
-#define KEY1_TYPE INT64
-#include "pmap-gen.c"
-
-#include "map.c"
-
-int main ()
-{
- PMAP map = _stp_pmap_new_ix(4, HIST_LOG, 5);
- int64_t x;
-
- /* put some data in. _processor_number is a global hack that allows */
- /* us to set the current emulated cpu number for our userspace tests. */
- /* Note that we set values based on the cpu number just to show that */
- /* different values are stored in each cpu */
- for (_processor_number = 0; _processor_number < NR_CPUS; _processor_number++) {
- _stp_pmap_add_ix(map, 1, _processor_number);
- _stp_pmap_add_ix(map, 2, 10 *_processor_number + 1);
- _stp_pmap_add_ix(map, 3, _processor_number * _processor_number);
- _stp_pmap_add_ix(map, 4, 1);
- }
-
-#if 0
- /* read it back out and verify. Use the special get_cpu call to get non-aggregated data */
- for (_processor_number = 0; _processor_number < NR_CPUS; _processor_number++) {
- x = _stp_pmap_get_cpu_ix (map, 3);
- if (x != _processor_number * _processor_number)
- printf("ERROR: Got %lld when expected %lld\n", x, (long long)(_processor_number * _processor_number));
- x = _stp_pmap_get_cpu_ix (map, 1);
- if (x != _processor_number)
- printf("ERROR: Got %lld when expected %lld\n", x, (long long)_processor_number);
- x = _stp_pmap_get_cpu_ix (map, 2);
- if (x != 10 * _processor_number + 1)
- printf("ERROR: Got %lld when expected %lld\n", x, (long long)(10 * _processor_number + 1));
- x = _stp_pmap_get_cpu_ix (map, 4);
- if (x != 1LL)
- printf("ERROR: Got %lld when expected %lld\n", x, 1LL);
- }
-#endif
-
- /* now print the per-cpu data */
- for (_processor_number = 0; _processor_number < NR_CPUS; _processor_number++) {
- printf("CPU #%d\n", _processor_number);
- _stp_pmap_printn_cpu (map,
- 0,
- "map[%1d] = count:%C sum:%S avg:%A min:%m max:%M",
- _processor_number);
- }
- _processor_number = 0;
-
- /* print the aggregated data */
- _stp_pmap_print(map,"map[%1d] = count:%C sum:%S avg:%A min:%m max:%M\n%H");
-
- _stp_pmap_del (map);
- return 0;
-}
-
diff --git a/runtime/tests/pmaps/ix_none.c b/runtime/tests/pmaps/ix_none.c
deleted file mode 100644
index 440b0069..00000000
--- a/runtime/tests/pmaps/ix_none.c
+++ /dev/null
@@ -1,62 +0,0 @@
-#include "runtime.h"
-
-/* like ix.c, except with no histogram */
-/* test of pmaps with keys of int64 and value of stat */
-
-#define VALUE_TYPE STAT
-#define KEY1_TYPE INT64
-#include "pmap-gen.c"
-
-#include "map.c"
-
-int main ()
-{
- PMAP map = _stp_pmap_new_ix(4, HIST_NONE);
- int64_t x;
-
- /* put some data in. _processor_number is a global hack that allows */
- /* us to set the current emulated cpu number for our userspace tests. */
- /* Note that we set values based on the cpu number just to show that */
- /* different values are stored in each cpu */
- for (_processor_number = 0; _processor_number < NR_CPUS; _processor_number++) {
- _stp_pmap_add_ix(map, 1, _processor_number);
- _stp_pmap_add_ix(map, 2, 10 *_processor_number + 1);
- _stp_pmap_add_ix(map, 3, _processor_number * _processor_number);
- _stp_pmap_add_ix(map, 4, 1);
- }
-
-#if 0
- /* read it back out and verify. Use the special get_cpu call to get non-aggregated data */
- for (_processor_number = 0; _processor_number < NR_CPUS; _processor_number++) {
- x = _stp_pmap_get_cpu_ix (map, 3);
- if (x != _processor_number * _processor_number)
- printf("ERROR: Got %lld when expected %lld\n", x, (long long)(_processor_number * _processor_number));
- x = _stp_pmap_get_cpu_ix (map, 1);
- if (x != _processor_number)
- printf("ERROR: Got %lld when expected %lld\n", x, (long long)_processor_number);
- x = _stp_pmap_get_cpu_ix (map, 2);
- if (x != 10 * _processor_number + 1)
- printf("ERROR: Got %lld when expected %lld\n", x, (long long)(10 * _processor_number + 1));
- x = _stp_pmap_get_cpu_ix (map, 4);
- if (x != 1LL)
- printf("ERROR: Got %lld when expected %lld\n", x, 1LL);
- }
-#endif
-
- /* now print the per-cpu data */
- for (_processor_number = 0; _processor_number < NR_CPUS; _processor_number++) {
- printf("CPU #%d\n", _processor_number);
- _stp_pmap_printn_cpu (map,
- 0,
- "map[%1d] = count:%C sum:%S avg:%A min:%m max:%M",
- _processor_number);
- }
- _processor_number = 0;
-
- /* print the aggregated data */
- _stp_pmap_print(map,"map[%1d] = count:%C sum:%S avg:%A min:%m max:%M\n%H");
-
- _stp_pmap_del (map);
- return 0;
-}
-
diff --git a/runtime/tests/pmaps/map_format.c b/runtime/tests/pmaps/map_format.c
deleted file mode 100644
index b27506e0..00000000
--- a/runtime/tests/pmaps/map_format.c
+++ /dev/null
@@ -1,92 +0,0 @@
-#include "runtime.h"
-
-/* map formatting test. Same as the non-pmap version. Output should be identical */
-
-/* torture test of map formatting */
-#define VALUE_TYPE STRING
-#define KEY1_TYPE INT64
-#define KEY2_TYPE INT64
-#define KEY3_TYPE STRING
-#include "pmap-gen.c"
-
-#define VALUE_TYPE INT64
-#define KEY1_TYPE STRING
-#define KEY2_TYPE STRING
-#include "pmap-gen.c"
-
-#define VALUE_TYPE STAT
-#define KEY1_TYPE STRING
-#define KEY2_TYPE STRING
-#include "pmap-gen.c"
-
-#include "map.c"
-
-void inc_cpu(void)
-{
- _processor_number++;
- if (_processor_number == NR_CPUS)
- _processor_number = 0;
-}
-
-int main ()
-{
- PMAP mapiis = _stp_pmap_new_iiss(4);
- _processor_number = 0;
- _stp_pmap_set_iiss (mapiis, 1,2,"Ohio", "Columbus" );
- _stp_pmap_set_iiss (mapiis, 3,4,"California", "Sacramento" );
- _stp_pmap_set_iiss (mapiis, 5,6,"Washington", "Olympia" );
- _stp_pmap_set_iiss (mapiis, 7,8,"Oregon", "Salem" );
- _stp_pmap_print (mapiis, "%s -> mapiis %1d %2d %3s");
-
- /* test printing of '%' */
- _stp_pmap_print (mapiis, "%s %% %3s");
-
- /* very bad string. don't crash */
- _stp_pmap_print (mapiis, "%s -> mapiis %1s %2s %3d %4d");
-
- PMAP mapss = _stp_pmap_new_ssi(4);
- _stp_pmap_set_ssi (mapss, "Riga", "Latvia", 0x0000c0dedbad0000LL);
- _stp_pmap_set_ssi (mapss, "Sofia", "Bulgaria", 0xdeadf00d12345678LL);
- _stp_pmap_set_ssi (mapss, "Valletta", "Malta", 1);
- _stp_pmap_set_ssi (mapss, "Nicosia", "Cyprus", -1);
- _stp_pmap_print (mapss, "The capitol of %1s is %2s and the nerd population is %d");
- _stp_pmap_print (mapss, "The capitol of %1s is %2s and the nerd population is %x");
- _stp_pmap_print (mapss, "The capitol of %1s is %2s and the nerd population is %X");
-
- PMAP mapssx = _stp_pmap_new_ssx (4, HIST_LINEAR, 0, 100, 10 );
- int i,j;
-
- for (i = 0; i < 100; i++)
- for (j = 0; j <= i*10 ; j++ ) {
- inc_cpu();
- _stp_pmap_add_ssx (mapssx, "Riga", "Latvia", i);
- }
-
- for (i = 0; i < 10; i++)
- for (j = 0; j < 10 ; j++ ) {
- inc_cpu();
- _stp_pmap_add_ssx (mapssx, "Sofia", "Bulgaria", j * i );
- }
-
- for (i = 0; i < 100; i += 10)
- for (j = 0; j < i/10 ; j++ ) {
- inc_cpu();
- _stp_pmap_add_ssx (mapssx, "Valletta", "Malta", i);
- }
-
- _stp_pmap_print (mapssx, "Bogons per packet for %1s\ncount:%C sum:%S avg:%A min:%m max:%M\n%H");
-
- _stp_pmap_print (mapssx, "%C was the count for %1s, %2s");
-
- /* here's how to print a map without using _stp_pmap_print(). */
- _stp_pmap_agg (mapssx);
- struct map_node *ptr;
- foreach (_stp_pmap_get_agg(mapssx), ptr)
- _stp_printf ("mapssx[%09s,%09s] = %llX\n", key1str(ptr), key2str(ptr), _stp_get_stat(ptr)->sum);
- _stp_print_flush();
-
- _stp_pmap_del (mapssx);
- _stp_pmap_del (mapiis);
- _stp_pmap_del (mapss);
- return 0;
-}
diff --git a/runtime/tests/pmaps/pmap.test b/runtime/tests/pmaps/pmap.test
deleted file mode 100644
index fb5c3d0d..00000000
--- a/runtime/tests/pmaps/pmap.test
+++ /dev/null
@@ -1,678 +0,0 @@
-package require tcltest
-namespace import -force tcltest::*
-
-cd $tcltest::testsDirectory
-
-set CFLAGS "-Os"
-set KPATH "/lib/modules/[exec uname -r]/build/include"
-set MPATH "/lib/modules/[exec uname -r]/build/include/asm/mach-default"
-set PATH "../../user"
-
-test ii {Test of int64 keys and int64 values} -setup {
- puts "gcc $CFLAGS -I $KPATH -I $PATH -I $MPATH -o test ii.c"
- exec gcc $CFLAGS -I $KPATH -I $PATH -I $MPATH -o test ii.c
-} -body {
- exec ./test
-} -result {CPU #0
-map[2] = 1
-map[4] = 1
-
-CPU #1
-map[1] = 1
-map[2] = 11
-map[3] = 1
-map[4] = 1
-
-CPU #2
-map[1] = 2
-map[2] = 21
-map[3] = 4
-map[4] = 1
-
-CPU #3
-map[1] = 3
-map[2] = 31
-map[3] = 9
-map[4] = 1
-
-CPU #4
-map[1] = 4
-map[2] = 41
-map[3] = 16
-map[4] = 1
-
-CPU #5
-map[1] = 5
-map[2] = 51
-map[3] = 25
-map[4] = 1
-
-CPU #6
-map[1] = 6
-map[2] = 61
-map[3] = 36
-map[4] = 1
-
-CPU #7
-map[1] = 7
-map[2] = 71
-map[3] = 49
-map[4] = 1
-
-map[2] = 288
-map[4] = 8
-map[1] = 28
-map[3] = 140
-}
-
-test is {Test of int64 keys and string values} -setup {
- exec gcc $CFLAGS -I $KPATH -I $PATH -I $MPATH -o test is.c
-} -body {
- exec ./test
-} -result {CPU #0
-map[1] = 0,
-map[2] = 1,
-map[3] = 0,
-map[4] = 1,
-
-CPU #1
-map[1] = 1,
-map[2] = 11,
-map[3] = 1,
-map[4] = 1,
-
-CPU #2
-map[1] = 2,
-map[2] = 21,
-map[3] = 4,
-map[4] = 1,
-
-CPU #3
-map[1] = 3,
-map[2] = 31,
-map[3] = 9,
-map[4] = 1,
-
-CPU #4
-map[1] = 4,
-map[2] = 41,
-map[3] = 16,
-map[4] = 1,
-
-CPU #5
-map[1] = 5,
-map[2] = 51,
-map[3] = 25,
-map[4] = 1,
-
-CPU #6
-map[1] = 6,
-map[2] = 61,
-map[3] = 36,
-map[4] = 1,
-
-CPU #7
-map[1] = 7,
-map[2] = 71,
-map[3] = 49,
-map[4] = 1,
-
-map[2] = 1,11,21,31,41,51,61,71,
-map[4] = 1,1,1,1,1,1,1,1,
-map[1] = 0,1,2,3,4,5,6,7,
-map[3] = 0,1,4,9,16,25,36,49,
-}
-
-test si {Test of string keys and int64 values} -setup {
- exec gcc $CFLAGS -I $KPATH -I $PATH -I $MPATH -o test si.c
-} -body {
- exec ./test
-} -result {CPU #0
-map[TWO] = 1
-map[FOUR] = 1
-
-CPU #1
-map[ONE] = 1
-map[TWO] = 11
-map[THREE] = 1
-map[FOUR] = 1
-
-CPU #2
-map[ONE] = 2
-map[TWO] = 21
-map[THREE] = 4
-map[FOUR] = 1
-
-CPU #3
-map[ONE] = 3
-map[TWO] = 31
-map[THREE] = 9
-map[FOUR] = 1
-
-CPU #4
-map[ONE] = 4
-map[TWO] = 41
-map[THREE] = 16
-map[FOUR] = 1
-
-CPU #5
-map[ONE] = 5
-map[TWO] = 51
-map[THREE] = 25
-map[FOUR] = 1
-
-CPU #6
-map[ONE] = 6
-map[TWO] = 61
-map[THREE] = 36
-map[FOUR] = 1
-
-CPU #7
-map[ONE] = 7
-map[TWO] = 71
-map[THREE] = 49
-map[FOUR] = 1
-
-map[FOUR] = 8
-map[TWO] = 288
-map[THREE] = 140
-map[ONE] = 28
-}
-
-test ix {Test of int64 keys and stat values} -setup {
- exec gcc $CFLAGS -I $KPATH -I $PATH -I $MPATH -o test ix.c
-} -body {
- exec ./test
-} -result {CPU #0
-map[1] = count:1 sum:0 avg:0 min:0 max:0
-map[2] = count:1 sum:1 avg:1 min:1 max:1
-map[3] = count:1 sum:0 avg:0 min:0 max:0
-map[4] = count:1 sum:1 avg:1 min:1 max:1
-
-CPU #1
-map[1] = count:1 sum:1 avg:1 min:1 max:1
-map[2] = count:1 sum:11 avg:11 min:11 max:11
-map[3] = count:1 sum:1 avg:1 min:1 max:1
-map[4] = count:1 sum:1 avg:1 min:1 max:1
-
-CPU #2
-map[1] = count:1 sum:2 avg:2 min:2 max:2
-map[2] = count:1 sum:21 avg:21 min:21 max:21
-map[3] = count:1 sum:4 avg:4 min:4 max:4
-map[4] = count:1 sum:1 avg:1 min:1 max:1
-
-CPU #3
-map[1] = count:1 sum:3 avg:3 min:3 max:3
-map[2] = count:1 sum:31 avg:31 min:31 max:31
-map[3] = count:1 sum:9 avg:9 min:9 max:9
-map[4] = count:1 sum:1 avg:1 min:1 max:1
-
-CPU #4
-map[1] = count:1 sum:4 avg:4 min:4 max:4
-map[2] = count:1 sum:41 avg:41 min:41 max:41
-map[3] = count:1 sum:16 avg:16 min:16 max:16
-map[4] = count:1 sum:1 avg:1 min:1 max:1
-
-CPU #5
-map[1] = count:1 sum:5 avg:5 min:5 max:5
-map[2] = count:1 sum:51 avg:51 min:51 max:51
-map[3] = count:1 sum:25 avg:25 min:25 max:25
-map[4] = count:1 sum:1 avg:1 min:1 max:1
-
-CPU #6
-map[1] = count:1 sum:6 avg:6 min:6 max:6
-map[2] = count:1 sum:61 avg:61 min:61 max:61
-map[3] = count:1 sum:36 avg:36 min:36 max:36
-map[4] = count:1 sum:1 avg:1 min:1 max:1
-
-CPU #7
-map[1] = count:1 sum:7 avg:7 min:7 max:7
-map[2] = count:1 sum:71 avg:71 min:71 max:71
-map[3] = count:1 sum:49 avg:49 min:49 max:49
-map[4] = count:1 sum:1 avg:1 min:1 max:1
-
-map[2] = count:8 sum:288 avg:36 min:1 max:71
-value |-------------------------------------------------- count
- 0 |@ 1
- 10 |@ 1
- 20 |@ 1
- 30 |@ 1
- 40 |@ 1
- 50 |@ 1
- 60 |@ 1
- 70 |@ 1
- 80 | 0
- 90 | 0
-
-map[4] = count:8 sum:8 avg:1 min:1 max:1
-value |-------------------------------------------------- count
- 0 |@@@@@@@@ 8
- 10 | 0
- 20 | 0
-
-map[1] = count:8 sum:28 avg:3 min:0 max:7
-value |-------------------------------------------------- count
- 0 |@@@@@@@@ 8
- 10 | 0
- 20 | 0
-
-map[3] = count:8 sum:140 avg:17 min:0 max:49
-value |-------------------------------------------------- count
- 0 |@@@@ 4
- 10 |@ 1
- 20 |@ 1
- 30 |@ 1
- 40 |@ 1
- 50 | 0
- 60 | 0
-
-}
-
-test ix_log {Test of int64 keys and stat values (log histogram)} -setup {
- exec gcc $CFLAGS -I $KPATH -I $PATH -I $MPATH -o test ix_log.c
-} -body {
- exec ./test
-} -result {CPU #0
-map[1] = count:1 sum:0 avg:0 min:0 max:0
-map[2] = count:1 sum:1 avg:1 min:1 max:1
-map[3] = count:1 sum:0 avg:0 min:0 max:0
-map[4] = count:1 sum:1 avg:1 min:1 max:1
-
-CPU #1
-map[1] = count:1 sum:1 avg:1 min:1 max:1
-map[2] = count:1 sum:11 avg:11 min:11 max:11
-map[3] = count:1 sum:1 avg:1 min:1 max:1
-map[4] = count:1 sum:1 avg:1 min:1 max:1
-
-CPU #2
-map[1] = count:1 sum:2 avg:2 min:2 max:2
-map[2] = count:1 sum:21 avg:21 min:21 max:21
-map[3] = count:1 sum:4 avg:4 min:4 max:4
-map[4] = count:1 sum:1 avg:1 min:1 max:1
-
-CPU #3
-map[1] = count:1 sum:3 avg:3 min:3 max:3
-map[2] = count:1 sum:31 avg:31 min:31 max:31
-map[3] = count:1 sum:9 avg:9 min:9 max:9
-map[4] = count:1 sum:1 avg:1 min:1 max:1
-
-CPU #4
-map[1] = count:1 sum:4 avg:4 min:4 max:4
-map[2] = count:1 sum:41 avg:41 min:41 max:41
-map[3] = count:1 sum:16 avg:16 min:16 max:16
-map[4] = count:1 sum:1 avg:1 min:1 max:1
-
-CPU #5
-map[1] = count:1 sum:5 avg:5 min:5 max:5
-map[2] = count:1 sum:51 avg:51 min:51 max:51
-map[3] = count:1 sum:25 avg:25 min:25 max:25
-map[4] = count:1 sum:1 avg:1 min:1 max:1
-
-CPU #6
-map[1] = count:1 sum:6 avg:6 min:6 max:6
-map[2] = count:1 sum:61 avg:61 min:61 max:61
-map[3] = count:1 sum:36 avg:36 min:36 max:36
-map[4] = count:1 sum:1 avg:1 min:1 max:1
-
-CPU #7
-map[1] = count:1 sum:7 avg:7 min:7 max:7
-map[2] = count:1 sum:71 avg:71 min:71 max:71
-map[3] = count:1 sum:49 avg:49 min:49 max:49
-map[4] = count:1 sum:1 avg:1 min:1 max:1
-
-map[2] = count:8 sum:288 avg:36 min:1 max:71
-value |-------------------------------------------------- count
- 0 | 0
- 1 |@ 1
- 2 | 0
- 4 | 0
- 8 |@@@@@@@ 7
-
-map[4] = count:8 sum:8 avg:1 min:1 max:1
-value |-------------------------------------------------- count
- 0 | 0
- 1 |@@@@@@@@ 8
- 2 | 0
- 4 | 0
-
-map[1] = count:8 sum:28 avg:3 min:0 max:7
-value |-------------------------------------------------- count
- 0 |@ 1
- 1 |@ 1
- 2 |@@ 2
- 4 |@@@@ 4
- 8 | 0
-
-map[3] = count:8 sum:140 avg:17 min:0 max:49
-value |-------------------------------------------------- count
- 0 |@ 1
- 1 |@ 1
- 2 | 0
- 4 |@ 1
- 8 |@@@@@ 5
-
-}
-
-test ix_none {Test of int64 keys and stat values (no histogram)} -setup {
- exec gcc $CFLAGS -I $KPATH -I $PATH -I $MPATH -o test ix_none.c
-} -body {
- exec ./test
-} -result {CPU #0
-map[1] = count:1 sum:0 avg:0 min:0 max:0
-map[2] = count:1 sum:1 avg:1 min:1 max:1
-map[3] = count:1 sum:0 avg:0 min:0 max:0
-map[4] = count:1 sum:1 avg:1 min:1 max:1
-
-CPU #1
-map[1] = count:1 sum:1 avg:1 min:1 max:1
-map[2] = count:1 sum:11 avg:11 min:11 max:11
-map[3] = count:1 sum:1 avg:1 min:1 max:1
-map[4] = count:1 sum:1 avg:1 min:1 max:1
-
-CPU #2
-map[1] = count:1 sum:2 avg:2 min:2 max:2
-map[2] = count:1 sum:21 avg:21 min:21 max:21
-map[3] = count:1 sum:4 avg:4 min:4 max:4
-map[4] = count:1 sum:1 avg:1 min:1 max:1
-
-CPU #3
-map[1] = count:1 sum:3 avg:3 min:3 max:3
-map[2] = count:1 sum:31 avg:31 min:31 max:31
-map[3] = count:1 sum:9 avg:9 min:9 max:9
-map[4] = count:1 sum:1 avg:1 min:1 max:1
-
-CPU #4
-map[1] = count:1 sum:4 avg:4 min:4 max:4
-map[2] = count:1 sum:41 avg:41 min:41 max:41
-map[3] = count:1 sum:16 avg:16 min:16 max:16
-map[4] = count:1 sum:1 avg:1 min:1 max:1
-
-CPU #5
-map[1] = count:1 sum:5 avg:5 min:5 max:5
-map[2] = count:1 sum:51 avg:51 min:51 max:51
-map[3] = count:1 sum:25 avg:25 min:25 max:25
-map[4] = count:1 sum:1 avg:1 min:1 max:1
-
-CPU #6
-map[1] = count:1 sum:6 avg:6 min:6 max:6
-map[2] = count:1 sum:61 avg:61 min:61 max:61
-map[3] = count:1 sum:36 avg:36 min:36 max:36
-map[4] = count:1 sum:1 avg:1 min:1 max:1
-
-CPU #7
-map[1] = count:1 sum:7 avg:7 min:7 max:7
-map[2] = count:1 sum:71 avg:71 min:71 max:71
-map[3] = count:1 sum:49 avg:49 min:49 max:49
-map[4] = count:1 sum:1 avg:1 min:1 max:1
-
-map[2] = count:8 sum:288 avg:36 min:1 max:71
-
-map[4] = count:8 sum:8 avg:1 min:1 max:1
-
-map[1] = count:8 sum:28 avg:3 min:0 max:7
-
-map[3] = count:8 sum:140 avg:17 min:0 max:49
-
-}
-
-test map_format {Test of map formatting and histograms} -setup {
- exec gcc $CFLAGS -I $KPATH -I $PATH -I $MPATH -o test map_format.c
-} -body {
- exec ./test
-} -result {Columbus -> mapiis 1 2 Ohio
-Salem -> mapiis 7 8 Oregon
-Olympia -> mapiis 5 6 Washington
-Sacramento -> mapiis 3 4 California
-
-Columbus % Ohio
-Salem % Oregon
-Olympia % Washington
-Sacramento % California
-
-Columbus -> mapiis
-Salem -> mapiis
-Olympia -> mapiis
-Sacramento -> mapiis
-
-The capitol of Riga is Latvia and the nerd population is 212063400820736
-The capitol of Sofia is Bulgaria and the nerd population is -2400999087387945352
-The capitol of Nicosia is Cyprus and the nerd population is -1
-The capitol of Valletta is Malta and the nerd population is 1
-
-The capitol of Riga is Latvia and the nerd population is c0dedbad0000
-The capitol of Sofia is Bulgaria and the nerd population is deadf00d12345678
-The capitol of Nicosia is Cyprus and the nerd population is ffffffffffffffff
-The capitol of Valletta is Malta and the nerd population is 1
-
-The capitol of Riga is Latvia and the nerd population is C0DEDBAD0000
-The capitol of Sofia is Bulgaria and the nerd population is DEADF00D12345678
-The capitol of Nicosia is Cyprus and the nerd population is FFFFFFFFFFFFFFFF
-The capitol of Valletta is Malta and the nerd population is 1
-
-Bogons per packet for Riga
-count:49600 sum:3288450 avg:66 min:0 max:99
-value |-------------------------------------------------- count
- 0 |@@ 460
- 10 |@@@@@@@ 1460
- 20 |@@@@@@@@@@@@ 2460
- 30 |@@@@@@@@@@@@@@@@@@ 3460
- 40 |@@@@@@@@@@@@@@@@@@@@@@@ 4460
- 50 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 5460
- 60 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 6460
- 70 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 7460
- 80 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 8460
- 90 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 9460
-
-Bogons per packet for Sofia
-count:100 sum:2025 avg:20 min:0 max:81
-value |-------------------------------------------------- count
- 0 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 42
- 10 |@@@@@@@@@@@@@@@@@ 17
- 20 |@@@@@@@@@@@@@ 13
- 30 |@@@@@@@@@ 9
- 40 |@@@@@@@@@ 9
- 50 |@@@@ 4
- 60 |@@@ 3
- 70 |@@ 2
- 80 |@ 1
- 90 | 0
-
-Bogons per packet for Valletta
-count:45 sum:2850 avg:63 min:10 max:90
-value |-------------------------------------------------- count
- 0 | 0
- 10 |@ 1
- 20 |@@ 2
- 30 |@@@ 3
- 40 |@@@@ 4
- 50 |@@@@@ 5
- 60 |@@@@@@ 6
- 70 |@@@@@@@ 7
- 80 |@@@@@@@@ 8
- 90 |@@@@@@@@@ 9
-
-
-49600 was the count for Riga, Latvia
-100 was the count for Sofia, Bulgaria
-45 was the count for Valletta, Malta
-
-mapssx[ Riga, Latvia] = 322D82
-mapssx[ Sofia, Bulgaria] = 7E9
-mapssx[ Valletta, Malta] = B22}
-
-
-test ii2 {Test of maps and pmaps with int64 keys and int64 values} -setup {
- exec gcc $CFLAGS -I $KPATH -I $PATH -I $MPATH -o test ii2.c
-} -body {
- exec ./test
-} -result {map[2] = 288
-map[4] = 8
-map[1] = 28
-map[3] = 140
-
-pmap[2] = 288
-pmap[4] = 8
-pmap[1] = 28
-pmap[3] = 140
-}
-
-test ii3 {Test of int64 keys and int64 values with GET} -setup {
- exec gcc $CFLAGS -I $KPATH -I $PATH -I $MPATH -o test ii3.c
-} -body {
- exec ./test
-} -result {map[1] = 28
-map[2] = 288
-map[3] = 140
-map[4] = 8
-
-map[1] = 28
-map[2] = 288
-map[3] = 140
-map[4] = 8
-
-map[2] = 288
-map[4] = 8
-map[1] = 28
-map[3] = 140
-
-map[1] = 28
-map[2] = 0
-map[3] = 140
-map[4] = 8
-
-map[4] = 8
-map[1] = 28
-map[3] = 140
-}
-
-test ix2 {Test of int64 keys and sttat values with GET} -setup {
- exec gcc $CFLAGS -I $KPATH -I $PATH -I $MPATH -o test ix2.c
-} -body {
- exec ./test
-} -result {CPU #0
-map[1] = count:1 sum:0 avg:0 min:0 max:0
-map[2] = count:1 sum:1 avg:1 min:1 max:1
-map[3] = count:1 sum:0 avg:0 min:0 max:0
-map[4] = count:1 sum:1 avg:1 min:1 max:1
-
-CPU #1
-map[1] = count:1 sum:1 avg:1 min:1 max:1
-map[2] = count:1 sum:11 avg:11 min:11 max:11
-map[3] = count:1 sum:1 avg:1 min:1 max:1
-map[4] = count:1 sum:1 avg:1 min:1 max:1
-
-CPU #2
-map[1] = count:1 sum:2 avg:2 min:2 max:2
-map[2] = count:1 sum:21 avg:21 min:21 max:21
-map[3] = count:1 sum:4 avg:4 min:4 max:4
-map[4] = count:1 sum:1 avg:1 min:1 max:1
-
-CPU #3
-map[1] = count:1 sum:3 avg:3 min:3 max:3
-map[2] = count:1 sum:31 avg:31 min:31 max:31
-map[3] = count:1 sum:9 avg:9 min:9 max:9
-map[4] = count:1 sum:1 avg:1 min:1 max:1
-
-CPU #4
-map[1] = count:1 sum:4 avg:4 min:4 max:4
-map[2] = count:1 sum:41 avg:41 min:41 max:41
-map[3] = count:1 sum:16 avg:16 min:16 max:16
-map[4] = count:1 sum:1 avg:1 min:1 max:1
-
-CPU #5
-map[1] = count:1 sum:5 avg:5 min:5 max:5
-map[2] = count:1 sum:51 avg:51 min:51 max:51
-map[3] = count:1 sum:25 avg:25 min:25 max:25
-map[4] = count:1 sum:1 avg:1 min:1 max:1
-
-CPU #6
-map[1] = count:1 sum:6 avg:6 min:6 max:6
-map[2] = count:1 sum:61 avg:61 min:61 max:61
-map[3] = count:1 sum:36 avg:36 min:36 max:36
-map[4] = count:1 sum:1 avg:1 min:1 max:1
-
-CPU #7
-map[1] = count:1 sum:7 avg:7 min:7 max:7
-map[2] = count:1 sum:71 avg:71 min:71 max:71
-map[3] = count:1 sum:49 avg:49 min:49 max:49
-map[4] = count:1 sum:1 avg:1 min:1 max:1
-
-map[2] = count:8 sum:288 avg:36 min:1 max:71
-value |-------------------------------------------------- count
- 0 |@ 1
- 10 |@ 1
- 20 |@ 1
- 30 |@ 1
- 40 |@ 1
- 50 |@ 1
- 60 |@ 1
- 70 |@ 1
- 80 | 0
- 90 | 0
-
-map[4] = count:8 sum:8 avg:1 min:1 max:1
-value |-------------------------------------------------- count
- 0 |@@@@@@@@ 8
- 10 | 0
- 20 | 0
-
-map[1] = count:8 sum:28 avg:3 min:0 max:7
-value |-------------------------------------------------- count
- 0 |@@@@@@@@ 8
- 10 | 0
- 20 | 0
-
-map[3] = count:8 sum:140 avg:17 min:0 max:49
-value |-------------------------------------------------- count
- 0 |@@@@ 4
- 10 |@ 1
- 20 |@ 1
- 30 |@ 1
- 40 |@ 1
- 50 | 0
- 60 | 0
-
-
-map[1] Sum = 28
-map[2] Sum = 288
-map[3] Sum = 140
-map[4] Sum = 8
-
-map[4] = count:8 sum:8 avg:1 min:1 max:1
-value |-------------------------------------------------- count
- 0 |@@@@@@@@ 8
- 10 | 0
- 20 | 0
-
-map[1] = count:8 sum:28 avg:3 min:0 max:7
-value |-------------------------------------------------- count
- 0 |@@@@@@@@ 8
- 10 | 0
- 20 | 0
-
-map[3] = count:8 sum:140 avg:17 min:0 max:49
-value |-------------------------------------------------- count
- 0 |@@@@ 4
- 10 |@ 1
- 20 |@ 1
- 30 |@ 1
- 40 |@ 1
- 50 | 0
- 60 | 0
-
-
-map[1] Sum = 28
-map[3] Sum = 140
-map[4] Sum = 8
-}
-
-
-test size {Test _stp_pmap_size()} -setup {
- exec gcc $CFLAGS -I $KPATH -I $PATH -I $MPATH -o test size.c
-} -body {
- exec ./test
-} -result {}
-
-catch {exec rm test}
-
-cleanupTests
diff --git a/runtime/tests/pmaps/si.c b/runtime/tests/pmaps/si.c
deleted file mode 100644
index 8b05da74..00000000
--- a/runtime/tests/pmaps/si.c
+++ /dev/null
@@ -1,62 +0,0 @@
-#include "runtime.h"
-
-/* test of pmaps with keys of string and value of int64 */
-
-/* It's not clear this would ever be used in the systemtap language.
- It would be useful as an array of counters. */
-
-#define VALUE_TYPE INT64
-#define KEY1_TYPE STRING
-#include "pmap-gen.c"
-
-#include "map.c"
-
-int main ()
-{
- PMAP map = _stp_pmap_new_si(4);
- int64_t x;
-
- if (!map)
- return -1;
-
- /* put some data in. _processor_number is a global hack that allows */
- /* us to set the current emulated cpu number for our userspace tests. */
- /* Note that we set values based on the cpu number just to show that */
- /* different values are stored in each cpu */
- for (_processor_number = 0; _processor_number < NR_CPUS; _processor_number++) {
- _stp_pmap_add_si(map, "ONE", _processor_number);
- _stp_pmap_add_si(map, "TWO", 10 *_processor_number + 1);
- _stp_pmap_add_si(map, "THREE", _processor_number * _processor_number);
- _stp_pmap_add_si(map, "FOUR", 1);
- }
-
- /* read it back out and verify. Use the special get_cpu call to get non-aggregated data */
- for (_processor_number = 0; _processor_number < NR_CPUS; _processor_number++) {
- x = _stp_pmap_get_cpu_si (map, "THREE");
- if (x != _processor_number * _processor_number)
- printf("ERROR: Got %lld when expected %lld\n", x, (long long)(_processor_number * _processor_number));
- x = _stp_pmap_get_cpu_si (map, "ONE");
- if (x != _processor_number)
- printf("ERROR: Got %lld when expected %lld\n", x, (long long)_processor_number);
- x = _stp_pmap_get_cpu_si (map, "TWO");
- if (x != 10 * _processor_number + 1)
- printf("ERROR: Got %lld when expected %lld\n", x, (long long)(10 * _processor_number + 1));
- x = _stp_pmap_get_cpu_si (map, "FOUR");
- if (x != 1LL)
- printf("ERROR: Got %lld when expected %lld\n", x, 1LL);
- }
-
- /* now print the per-cpu data */
- for (_processor_number = 0; _processor_number < NR_CPUS; _processor_number++) {
- printf("CPU #%d\n", _processor_number);
- _stp_pmap_printn_cpu (map,0, "map[%1s] = %d", _processor_number);
- }
- _processor_number = 0;
-
- /* print the aggregated data */
- _stp_pmap_print(map,"map[%1s] = %d");
-
- _stp_pmap_del (map);
- return 0;
-}
-
diff --git a/runtime/tests/pmaps/size.c b/runtime/tests/pmaps/size.c
deleted file mode 100644
index be8b4590..00000000
--- a/runtime/tests/pmaps/size.c
+++ /dev/null
@@ -1,72 +0,0 @@
-#include "runtime.h"
-
-/* test of _stp_pmap_size() */
-
-/* It's not clear this would ever be used in the systemtap language.
- It would be useful as an array of counters. */
-
-#define VALUE_TYPE INT64
-#define KEY1_TYPE INT64
-#include "pmap-gen.c"
-
-#include "map.c"
-
-#define check(map,num) \
- { \
- int size = _stp_pmap_size(map); \
- if (size != num) \
- printf("ERROR at line %d: expected size %d and got %d instead.\n", __LINE__, num, size); \
- }
-
-int main ()
-{
- PMAP map = _stp_pmap_new_ii(8);
- int64_t x;
-
- check(map,0);
-
- /* put some data in. _processor_number is a global hack that allows */
- /* us to set the current emulated cpu number for our userspace tests. */
- /* Note that we set values based on the cpu number just to show that */
- /* different values are stored in each cpu */
- for (_processor_number = 0; _processor_number < NR_CPUS; _processor_number++) {
- _stp_pmap_add_ii(map, 1, _processor_number);
- _stp_pmap_add_ii(map, 2, 10 *_processor_number + 1);
- _stp_pmap_add_ii(map, 3, _processor_number * _processor_number);
- _stp_pmap_add_ii(map, 4, 1);
- }
- _processor_number = 0;
-
- check(map,4*NR_CPUS-2);
-
- _stp_pmap_add_ii(map, 1, 1);
- _stp_pmap_add_ii(map, 3, 1);
- check(map,4*NR_CPUS);
-
- _stp_pmap_add_ii(map, 5, 100);
- check(map,4*NR_CPUS+1);
-
- _processor_number = 1;
- _stp_pmap_add_ii(map, 5, 100);
- check(map,4*NR_CPUS+2);
-
- _stp_pmap_set_ii(map, 5, 0);
- check(map,4*NR_CPUS+1);
-
- _processor_number = 0;
- _stp_pmap_set_ii(map, 5, 0);
- check(map,4*NR_CPUS);
-
- for (_processor_number = 0; _processor_number < NR_CPUS; _processor_number++) {
- _stp_pmap_set_ii(map, 1, 0);
- _stp_pmap_set_ii(map, 2, 0);
- _stp_pmap_set_ii(map, 3, 0);
- _stp_pmap_set_ii(map, 4, 0);
- }
- _processor_number = 0;
- check(map,0);
-
- _stp_pmap_del (map);
- return 0;
-}
-
diff --git a/runtime/tests/string/Makefile b/runtime/tests/string/Makefile
deleted file mode 100644
index c396c132..00000000
--- a/runtime/tests/string/Makefile
+++ /dev/null
@@ -1,5 +0,0 @@
-default: tests
-
-tests:
- tclsh all.tcl
-
diff --git a/runtime/tests/string/all.tcl b/runtime/tests/string/all.tcl
deleted file mode 100644
index 23757202..00000000
--- a/runtime/tests/string/all.tcl
+++ /dev/null
@@ -1,4 +0,0 @@
-package require tcltest
-namespace import -force tcltest::*
-tcltest::testsDirectory [file dir [info script]]
-tcltest::runAllTests
diff --git a/runtime/tests/string/print_cstr.c b/runtime/tests/string/print_cstr.c
deleted file mode 100644
index 2de0f592..00000000
--- a/runtime/tests/string/print_cstr.c
+++ /dev/null
@@ -1,56 +0,0 @@
-/* test of _stp_print_cstr() */
-
-/* use very small buffer size for testing */
-#define STP_PRINT_BUF_LEN 20
-#include "runtime.h"
-
-int main ()
-{
- /* can we see output? */
- _stp_print_cstr("ABCDE\n");
- _stp_print_flush();
-
-
- /* overflow */
- _stp_print_cstr("1234567890123456789012345\n");
- _stp_print_cstr("XYZZY\n");
- _stp_print_flush();
-
- /* small string then overflow string */
- _stp_print_cstr("XYZZY\n");
- _stp_print_cstr("1234567890123456789012345");
- _stp_print_cstr("\n");
- _stp_print_flush();
-
- /* two small string that overflow */
- _stp_print_cstr("abcdefghij");
- _stp_print_cstr("1234567890");
- _stp_print_cstr("\n");
- _stp_print_flush();
-
- /* two small string that overflow */
- _stp_print_cstr("abcdefghij");
- _stp_print_cstr("1234567890X");
- _stp_print_cstr("\n");
- _stp_print_flush();
-
- _stp_print_cstr("12345\n");
- _stp_print_cstr("67890\n");
- _stp_print_cstr("abcde\n");
- _stp_print_flush();
- _stp_print_flush();
- _stp_print_cstr("12345");
- _stp_print_cstr("67890");
- _stp_print_cstr("abcde");
- _stp_print_cstr("fghij");
- _stp_print_cstr("\n");
- _stp_print_flush();
-
- /* null string */
- _stp_print_cstr("");
- _stp_print_flush();
- _stp_print_cstr("");
- _stp_print_cstr("Q\n");
- _stp_print_flush();
- return 0;
-}
diff --git a/runtime/tests/string/printf_A.c b/runtime/tests/string/printf_A.c
deleted file mode 100644
index e6c1a93f..00000000
--- a/runtime/tests/string/printf_A.c
+++ /dev/null
@@ -1,56 +0,0 @@
-/* basic printf tests */
-
-/* use very small buffer size for testing */
-#define STP_PRINT_BUF_LEN 20
-#include "runtime.h"
-
-int main ()
-{
- /* can we see output? */
- _stp_printf("ABCDE\n");
- _stp_print_flush();
-
-
- /* overflow */
- _stp_printf("1234567890123456789012345\n");
- _stp_printf("XYZZY\n");
- _stp_print_flush();
-
- /* small string then overflow string */
- _stp_printf("XYZZY\n");
- _stp_printf("1234567890123456789012345");
- _stp_printf("\n");
- _stp_print_flush();
-
- /* two small string that overflow */
- _stp_printf("abcdefghij");
- _stp_printf("1234567890");
- _stp_printf("\n");
- _stp_print_flush();
-
- /* two small string that overflow */
- _stp_printf("abcdefghij");
- _stp_printf("1234567890X");
- _stp_printf("\n");
- _stp_print_flush();
-
- _stp_printf("12345\n");
- _stp_printf("67890\n");
- _stp_printf("abcde\n");
- _stp_print_flush();
- _stp_print_flush();
- _stp_printf("12345");
- _stp_printf("67890");
- _stp_printf("abcde");
- _stp_printf("fghij");
- _stp_printf("\n");
- _stp_print_flush();
-
- /* null string */
- _stp_printf("");
- _stp_print_flush();
- _stp_printf("");
- _stp_printf("Q\n");
- _stp_print_flush();
- return 0;
-}
diff --git a/runtime/tests/string/printf_B.c b/runtime/tests/string/printf_B.c
deleted file mode 100644
index b9bbe170..00000000
--- a/runtime/tests/string/printf_B.c
+++ /dev/null
@@ -1,37 +0,0 @@
-/* more printf tests */
-
-/* use very small buffer size for testing */
-#define STP_PRINT_BUF_LEN 20
-#include "runtime.h"
-
-#define LLONG_MAX 9223372036854775807LL
-#define LLONG_MIN (-LLONG_MAX - 1LL)
-
-
-int main ()
-{
- int i;
-
- /* a couple of loops showing continuous output */
- for (i = 0; i < 20; i++)
- _stp_sprintf(_stp_stdout, "i=%d ", i);
- _stp_printf("\n");
- _stp_print_flush();
-
- for (i = 0; i < 5; i++)
- _stp_printf("[%d %d %d] ", i, i*i, i*i*i);
- _stp_printf("\n");
- _stp_print_flush();
-
- int64_t x,y;
- x = LLONG_MAX;
- y = LLONG_MIN;
-
- _stp_printf("%lld ",x);
- _stp_printf("(%llx) ", x);
- _stp_printf("%lld ",y);
- _stp_printf("(%llx) ", y);
- _stp_printf("\n");
- _stp_print_flush();
- return 0;
-}
diff --git a/runtime/tests/string/string.test b/runtime/tests/string/string.test
deleted file mode 100644
index 348b6b1f..00000000
--- a/runtime/tests/string/string.test
+++ /dev/null
@@ -1,89 +0,0 @@
-package require tcltest
-namespace import -force tcltest::*
-
-cd $tcltest::testsDirectory
-
-set CFLAGS "-Os"
-set KPATH "/lib/modules/[exec uname -r]/build/include"
-set MPATH "/lib/modules/[exec uname -r]/build/include/asm/mach-default"
-set PATH "../../user"
-
-test printf_A {Basic printf test} -setup {
- exec gcc $CFLAGS -I $KPATH -I $PATH -I $MPATH -o test printf_A.c
-} -body {
- exec ./test
-} -result {ABCDE
-12345678901234567890XYZZY
-XYZZY
-12345678901234567890
-abcdefghij1234567890
-abcdefghij1234567890X
-12345
-67890
-abcde
-1234567890abcdefghij
-Q}
-
-test printf_B {More printf test} -setup {
- exec gcc $CFLAGS -I $KPATH -I $PATH -I $MPATH -o test printf_B.c
-} -body {
- exec ./test
-} -result {i=0 i=1 i=2 i=3 i=4 i=5 i=6 i=7 i=8 i=9 i=10 i=11 i=12 i=13 i=14 i=15 i=16 i=17 i=18 i=19
-[0 0 0] [1 1 1] [2 4 8] [3 9 27] [4 16 64]
-9223372036854775807 (7fffffffffffffff) -9223372036854775808(8000000000000000) }
-
-test print_cstr {Test of _stp_print_cstr()} -setup {
- exec gcc $CFLAGS -I $KPATH -I $PATH -I $MPATH -o test print_cstr.c
-} -body {
- exec ./test
-} -result {ABCDE
-12345678901234567890XYZZY
-XYZZY
-12345678901234567890
-abcdefghij1234567890
-abcdefghij1234567890X
-12345
-67890
-abcde
-1234567890abcdefghij
-Q}
-
-test string1 {Basic String test} -setup {
- exec gcc $CFLAGS -I $KPATH -I $PATH -I $MPATH -o test string1.c
-} -body {
- exec ./test
-} -result {Hello worldRed HatIntelIBM
-Hello world / Red Hat / Intel / IBM /
-Red Hat Inc.
-Hello world Red Hat
-IntelIBM}
-
-test string2 {More String tests} -setup {
- exec gcc $CFLAGS -I $KPATH -I $PATH -I $MPATH -o test string2.c
-} -body {
- exec ./test
-} -result {ABCDE
-1234567890123456789
-XYZZY
-1234567890123
-abcdefghij123456789
-abcdefghij123456789
-12345
-67890
-abcde
-1234567890abcdefghi
-Q}
-test string3 {Even More String tests} -setup {
- exec gcc $CFLAGS -I $KPATH -I $PATH -I $MPATH -o test string3.c
-} -body {
- exec ./test
-} -result {1234567890abcABCDEvwxyz
-abcde
-1234567890abcde
-1234567890abcdeABCD
-1234567890abcdeABCD
-ABCDEvwxyz}
-
-exec rm test
-
-cleanupTests
diff --git a/runtime/tests/string/string1.c b/runtime/tests/string/string1.c
deleted file mode 100644
index 48773e5f..00000000
--- a/runtime/tests/string/string1.c
+++ /dev/null
@@ -1,44 +0,0 @@
-/* test of Strings */
-
-/* use very small buffer size for testing */
-#define STP_PRINT_BUF_LEN 20
-#define STP_NUM_STRINGS 4
-#include "runtime.h"
-
-int main ()
-{
- String str[4];
- int i;
-
- for (i = 0; i < 4; i++)
- str[i] = _stp_string_init (i);
-
- _stp_sprintf(str[0], "Hello world");
- _stp_sprintf(str[1], "Red Hat");
- _stp_sprintf(str[2], "Intel");
- _stp_sprintf(str[3], "IBM");
-
- for (i = 0; i < 4; i++)
- _stp_print(str[i]);
- _stp_print_cstr("\n");
-
- for (i = 0; i < 4; i++) {
- _stp_print(str[i]);
- _stp_print(" / ");
- }
- _stp_print_cstr("\n");
-
- _stp_string_cat_cstr (str[1], " Inc.");
- _stp_print(str[1]);
- _stp_print("\n");
-
- _stp_string_cat_cstr (str[0], " ");
- _stp_string_cat_string (str[0], str[1]);
- _stp_print(str[0]);
- _stp_print("\n");
-
- _stp_sprintf(str[2], "%s\n", _stp_string_ptr(str[3]));
- _stp_print(str[2]);
- _stp_print_flush();
- return 0;
-}
diff --git a/runtime/tests/string/string2.c b/runtime/tests/string/string2.c
deleted file mode 100644
index ccf3997a..00000000
--- a/runtime/tests/string/string2.c
+++ /dev/null
@@ -1,68 +0,0 @@
-/* test of Strings */
-
-/* use very small buffer size for testing */
-#define STP_STRING_SIZE 20
-#define STP_NUM_STRINGS 1
-#include "runtime.h"
-
-int main ()
-{
- String str = _stp_string_init (0);
-
- /* can we see output? */
- _stp_sprintf(str, "ABCDE\n");
- _stp_print(str);
-
-
- /* overflow */
- str = _stp_string_init (0);
- _stp_sprintf(str, "1234567890123456789012345\n");
- _stp_sprintf(str, "XYZZY\n");
- _stp_print(str);
- _stp_printf("\n");
-
- /* small string then overflow string */
- str = _stp_string_init (0);
- _stp_sprintf(str,"XYZZY\n");
- _stp_sprintf(str,"1234567890123456789012345");
- _stp_print(str);
- _stp_printf("\n");
-
- /* two small string that overflow */
- str = _stp_string_init (0);
- _stp_sprintf(str,"abcdefghij");
- _stp_sprintf(str,"123456789");
- _stp_print(str);
- _stp_printf("\n");
-
- /* two small string that overflow */
- str = _stp_string_init (0);
- _stp_sprintf(str,"abcdefghij");
- _stp_sprintf(str,"1234567890X");
- _stp_print(str);
- _stp_printf("\n");
-
- str = _stp_string_init (0);
- _stp_sprintf(str,"12345\n");
- _stp_sprintf(str,"67890\n");
- _stp_sprintf(str,"abcde\n");
- _stp_print(str);
-
- str = _stp_string_init (0);
- _stp_sprintf(str,"12345");
- _stp_sprintf(str,"67890");
- _stp_sprintf(str,"abcde");
- _stp_sprintf(str,"fghij");
- _stp_print(str);
- _stp_printf("\n");
-
- /* null string */
- str = _stp_string_init (0);
- _stp_sprintf(str,"");
- _stp_sprintf(str,"");
- _stp_sprintf(str,"Q\n");
- _stp_print(str);
-
- _stp_print_flush();
- return 0;
-}
diff --git a/runtime/tests/string/string3.c b/runtime/tests/string/string3.c
deleted file mode 100644
index 3982a8e1..00000000
--- a/runtime/tests/string/string3.c
+++ /dev/null
@@ -1,45 +0,0 @@
-/* test of Strings */
-
-/* use very small buffer size for testing */
-#define STP_STRING_SIZE 20
-#define STP_NUM_STRINGS 4
-#include "runtime.h"
-
-int main ()
-{
- String str[4];
- int i;
-
- for (i = 0; i < 4; i++)
- str[i] = _stp_string_init (i);
-
- _stp_string_cat(str[0], "1234567890");
- _stp_string_cat(str[1], "abc");
- _stp_string_cat(str[2], "ABCDE");
- _stp_string_cat(str[3], "vwxyz");
-
- for (i = 0; i < 4; i++)
- _stp_print(str[i]);
- _stp_print("\n");
-
- _stp_string_cat (str[1], "de");
- _stp_print(str[1]);
- _stp_print("\n");
-
- _stp_string_cat(str[0], str[1]);
- _stp_print(str[0]);
- _stp_print("\n");
-
- _stp_string_cat(str[0], str[2]);
- _stp_print(str[0]);
- _stp_print("\n");
-
- _stp_string_cat(str[0], str[2]);
- _stp_print(str[0]);
- _stp_print("\n");
-
- _stp_sprintf(str[2], "%s\n", _stp_string_ptr(str[3]));
- _stp_print(str[2]);
- _stp_print_flush();
- return 0;
-}
diff --git a/runtime/transport/ChangeLog b/runtime/transport/ChangeLog
index 9d0ba162..2e59ff90 100644
--- a/runtime/transport/ChangeLog
+++ b/runtime/transport/ChangeLog
@@ -1,3 +1,14 @@
+2008-06-13 Wenji Huang <wenji.huang@oracle.com>
+
+ * control.c (_stp_ctl_write_dbug): Remove STP_UNWIND support.
+
+2008-06-03 Frank Ch. Eigler <fche@elastic.org>
+
+ PR 6429
+ * symbols.c (_stp_init_modules): Don't ask stapio for unwind data.
+ * control.c (_stp_ctl_write_cmd): Remove STP_UNWIND support.
+ * transport_msgs.h (STP_UNWIND): Remove declaration.
+
2008-04-30 Masami Hiramatsu <mhiramat@redhat.com>
PR 5645
diff --git a/runtime/transport/control.c b/runtime/transport/control.c
index ca7edf79..9319b9ca 100644
--- a/runtime/transport/control.c
+++ b/runtime/transport/control.c
@@ -36,9 +36,6 @@ static ssize_t _stp_ctl_write_cmd(struct file *file, const char __user *buf, siz
#endif
switch (type) {
- case STP_UNWIND:
- _stp_do_unwind_data(buf, count);
- break;
case STP_START:
if (started == 0) {
struct _stp_msg_start st;
@@ -103,10 +100,6 @@ static void _stp_ctl_write_dbug(int type, void *data, int len)
case STP_TRANSPORT:
_dbug("sending STP_TRANSPORT\n");
break;
- case STP_UNWIND:
- snprintf(buf, sizeof(buf), "%s", (char *)data);
- _dbug("sending STP_UNWIND %s [len=%d]\n", buf, len);
- break;
default:
_dbug("ERROR: unknown message type: %d\n", type);
break;
diff --git a/runtime/transport/symbols.c b/runtime/transport/symbols.c
index 087bf893..4a3c4e17 100644
--- a/runtime/transport/symbols.c
+++ b/runtime/transport/symbols.c
@@ -196,7 +196,11 @@ static int _stp_init_kernel_symbols(void)
_stp_num_modules = 1;
/* Note: this mapping is used by kernel/_stext pseudo-relocations. */
+ #ifdef __powerpc__
+ _stp_modules[0]->text = _stp_kallsyms_lookup_name(".__start");
+ #else
_stp_modules[0]->text = _stp_kallsyms_lookup_name("_stext");
+ #endif
if (_stp_modules[0]->text == 0) {
_dbug("Lookup of _stext failed. Exiting.\n");
return -1;
@@ -399,6 +403,22 @@ static int _stp_section_is_interesting(const char *name)
return ret;
}
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,25)
+struct module_sect_attr
+{
+ struct module_attribute mattr;
+ char *name;
+ unsigned long address;
+};
+
+struct module_sect_attrs
+{
+ struct attribute_group grp;
+ unsigned int nsections;
+ struct module_sect_attr attrs[0];
+};
+#endif
+
/* Create a new _stp_module and load the symbols */
static struct _stp_module *_stp_load_module_symbols(struct module *mod)
{
@@ -609,7 +629,7 @@ static int _stp_init_modules(void)
/* unlocks the list */
modules_op->stop(NULL, NULL);
-#ifdef STP_USE_DWARF_UNWINDER
+#if 0 /* def STP_USE_DWARF_UNWINDER */
/* now that we have all the modules, ask for their unwind info */
{
unsigned long flags;
diff --git a/runtime/transport/transport_msgs.h b/runtime/transport/transport_msgs.h
index 5f385565..27476e76 100644
--- a/runtime/transport/transport_msgs.h
+++ b/runtime/transport/transport_msgs.h
@@ -23,7 +23,6 @@ enum
STP_EXIT,
STP_OOB_DATA,
STP_SYSTEM,
- STP_UNWIND,
STP_TRANSPORT,
STP_CONNECT,
STP_DISCONNECT,
@@ -44,7 +43,6 @@ static const char *_stp_command_name[] = {
"STP_EXIT",
"STP_OOB_DATA",
"STP_SYSTEM",
- "STP_UNWIND",
"STP_TRANSPORT",
"STP_CONNECT",
"STP_DISCONNECT",
diff --git a/session.h b/session.h
index 4122d0ac..734c8d7d 100644
--- a/session.h
+++ b/session.h
@@ -25,6 +25,7 @@ extern "C" {
struct match_node;
struct stapfile;
struct vardecl;
+struct token;
struct functiondecl;
struct derived_probe;
struct be_derived_probe_group;
@@ -42,6 +43,7 @@ struct embeddedcode;
struct translator_output;
struct unparser;
struct semantic_error;
+struct module_cache;
// XXX: a generalized form of this descriptor could be associated with
@@ -164,11 +166,17 @@ struct systemtap_session
// List of libdwfl module names to extract symbol/unwind data for.
std::set<std::string> unwindsym_modules;
+ struct module_cache* module_cache;
std::set<std::string> seen_errors;
+ std::set<std::string> seen_warnings;
unsigned num_errors () { return seen_errors.size(); }
+
// void print_error (const parse_error& e);
+ const token* last_token;
+ void print_token (std::ostream& o, const token* tok);
void print_error (const semantic_error& e);
+ void print_warning (const std::string& w, const token* tok = 0);
// reNB: new POD members likely need to be explicitly cleared in the ctor.
};
diff --git a/stap-client b/stap-client
new file mode 100755
index 00000000..42402a27
--- /dev/null
+++ b/stap-client
@@ -0,0 +1,606 @@
+#!/bin/bash
+
+# Compile server client for systemtap
+#
+# Copyright (C) 2008 Red Hat Inc.
+#
+# This file is part of systemtap, and is free software. You can
+# redistribute it and/or modify it under the terms of the GNU General
+# Public License (GPL); either version 2, or (at your option) any
+# later version.
+
+# This script examines the systemtap command line and packages the files and
+# information needed to execute the command. This is then sent to a trusted
+# systemtap server which will process the request and return the resulting
+# kernel module (if requested) and any other information generated by the
+# request. If a kernel module is generated, this script will load the module
+# and execute it using 'staprun', if requested.
+
+#-----------------------------------------------------------------------------
+# Helper functions.
+#-----------------------------------------------------------------------------
+# function: configuration
+function configuration {
+ tmpdir_prefix_client=stap.client
+ tmpdir_prefix_server=stap.server
+ avahi_service_tag=_stap._tcp
+}
+
+# function: initialization
+function initialization {
+ wd=`pwd`
+ umask 0
+
+ # Default options settings
+ p_phase=5
+ v_level=0
+ keep_temps=0
+
+ # Create a temporary directory to package things in
+ # Do this before parsing the command line so that there is a place
+ # to put -I and -R directories.
+ tmpdir_client=`mktemp -dt $tmpdir_prefix_client.XXXXXX` || \
+ fatal "ERROR: cannot create temporary directory " $tmpdir_client
+ tmpdir_env=`dirname $tmpdir_client`
+}
+
+# function: parse_options [ STAP-OPTIONS ]
+#
+# Examine the command line. We need not do much checking, but we do need to
+# parse all options in order to discover the ones we're interested in.
+# The server will take care of most situations and return the appropriate
+# output.
+#
+function parse_options {
+ cmdline=
+ while test $# != 0
+ do
+ advance_p=0
+ dash_seen=0
+
+ # Start of a new token.
+ first_token=$1
+ until test $advance_p != 0
+ do
+ # Identify the next option
+ first_char=`expr "$first_token" : '\(.\).*'`
+ if test $dash_seen = 0; then
+ if test "$first_char" = "-"; then
+ if test "$first_token" != "-"; then
+ # It's not a lone dash, so it's an option. Remove the dash.
+ first_token=`expr "$first_token" : '-\(.*\)'`
+ dash_seen=1
+ first_char=`expr "$first_token" : '\(.\).*'`
+ cmdline="$cmdline -"
+ fi
+ fi
+ if test $dash_seen = 0; then
+ # The dash has not been seen. This is either the script file
+ # name or an arument to be passed to the probe module.
+ # If this is the first time, and -e has not been specified,
+ # then it could be the name of the script file.
+ if test "X$e_script" = "X" -a "X$script_file" = "X"; then
+ script_file=$first_token
+ fi
+ advance_p=$(($advance_p + 1))
+ cmdline="$cmdline $first_token"
+ break
+ fi
+ fi
+
+ # We are at the start of an option. Look at the first character.
+ case $first_char in
+ c)
+ get_arg $first_token "$2"
+ process_c "$stap_arg"
+ ;;
+ D)
+ get_arg $first_token $2
+ cmdline="${cmdline}D '$stap_arg'"
+ ;;
+ e)
+ get_arg $first_token "$2"
+ process_e "$stap_arg"
+ ;;
+ I)
+ get_arg $first_token $2
+ process_I $stap_arg
+ ;;
+ k)
+ keep_temps=1
+ ;;
+ l)
+ get_arg $first_token $2
+ cmdline="${cmdline}l '$stap_arg'"
+ ;;
+ m)
+ get_arg $first_token $2
+ cmdline="${cmdline}m $stap_arg"
+ ;;
+ o)
+ get_arg $first_token $2
+ process_o $stap_arg
+ ;;
+ p)
+ get_arg $first_token $2
+ process_p $stap_arg
+ ;;
+ r)
+ get_arg $first_token $2
+ cmdline="${cmdline}r $stap_arg"
+ ;;
+ R)
+ get_arg $first_token $2
+ process_R $stap_arg
+ ;;
+ s)
+ get_arg $first_token $2
+ cmdline="${cmdline}s $stap_arg"
+ ;;
+ v)
+ v_level=$(($v_level + 1))
+ ;;
+ x)
+ get_arg $first_token $2
+ cmdline="${cmdline}x $stap_arg"
+ ;;
+ *)
+ # An unknown or unimportant flag. Ignore it, but pass it on to the server.
+ ;;
+ esac
+
+ if test $advance_p = 0; then
+ # Just another flag character. Consume it.
+ cmdline="$cmdline$first_char"
+ first_token=`expr "$first_token" : '.\(.*\)'`
+ if test "X$first_token" = "X"; then
+ advance_p=$(($advance_p + 1))
+ fi
+ fi
+ done
+
+ # Consume the arguments we just processed.
+ while test $advance_p != 0
+ do
+ shift
+ advance_p=$(($advance_p - 1))
+ done
+ done
+
+ # If the script file was given and it's not '-', then replace it with its
+ # client-temp-name in the command string.
+ if test "X$script_file" != "X" -a "$script_file" != "-"; then
+ local local_name=`generate_client_temp_name $script_file`
+ cmdline=`echo $cmdline | sed s,$script_file,script/$local_name,`
+ fi
+}
+
+# function: get_arg FIRSTWORD SECONDWORD
+#
+# Collect an argument to the given option
+function get_arg {
+ # Remove first character.
+ local opt=`expr "$1" : '\(.\).*'`
+ local first=`expr "$1" : '.\(.*\)'`
+
+ # Advance to the next token, if the first one is exhausted.
+ if test "X$first" = "X"; then
+ shift
+ advance_p=$(($advance_p + 1))
+ first=$1
+ fi
+
+ test "X$first" != "X" || \
+ fatal "Missing argument to -$opt"
+
+ stap_arg="$first"
+ advance_p=$(($advance_p + 1))
+}
+
+# function: process_c ARGUMENT
+#
+# Process the -c flag.
+function process_c {
+ c_cmd="$1"
+ cmdline="${cmdline}c '$1'"
+}
+
+# function: process_e ARGUMENT
+#
+# Process the -e flag.
+function process_e {
+ # Only the first -e option is recognized and it overrides any script file name
+ # which may have already been identified.
+ if test "X$e_script" = "X"; then
+ e_script="$1"
+ script_file=
+ fi
+ cmdline="${cmdline}e '$1'"
+}
+
+# function: process_I ARGUMENT
+#
+# Process the -I flag.
+function process_I {
+ local local_name=`include_file_or_directory tapsets $1`
+ test "X$local_name" != "X" || return
+ cmdline="${cmdline}I $local_name"
+}
+
+# function: process_o ARGUMENT
+#
+# Process the -o flag.
+function process_o {
+ stdout_redirection="> $1"
+ cmdline="${cmdline}o $1"
+}
+
+# function: process_p ARGUMENT
+#
+# Process the -p flag.
+function process_p {
+ p_phase=$1
+ cmdline="${cmdline}p '$1'"
+}
+
+# function: process_R ARGUMENT
+#
+# Process the -R flag.
+function process_R {
+ local local_name=`include_file_or_directory runtime $1`
+ test "X$local_name" != "X" || return
+ cmdline="${cmdline}R $local_name"
+}
+
+# function: include_file_or_directory PREFIX NAME
+#
+# Include the given file or directory in the client's temporary
+# tree to be sent to the server.
+function include_file_or_directory {
+ # Add a symbolic link of the named directory to our temporary directory
+ local local_name=`generate_client_temp_name $2`
+ mkdir -p $tmpdir_client/$1/`dirname $local_name` || \
+ fatal "ERROR: could not create $tmpdir_client/$1/`dirname $local_name`"
+ ln -s /$local_name $tmpdir_client/$1/$local_name || \
+ fatal "ERROR: could not link $tmpdir_client/$1/$local_name to /$local_name"
+ echo $local_name
+}
+
+# function: generate_client_temp_name NAME
+#
+# Generate the name to be used for the given file/directory relative to the
+# client's temporary directory.
+function generate_client_temp_name {
+ # Transform the name into a fully qualified path name
+ local full_name=`echo $1 | sed "s,^\\\([^/]\\\),$wd/\\\\1,"`
+
+ # The same name without the initial / or trailing /
+ local local_name=`echo $full_name | sed 's,^/\(.*\),\1,'`
+ local_name=`echo $local_name | sed 's,\(.*\)/$,\1,'`
+ echo $local_name
+}
+
+# function: create_request
+#
+# Add information to the client's temp directory representing the request
+# to the server.
+function create_request {
+ # Work in our temporary directory
+ cd $tmpdir_client
+
+ if test "X$script_file" != "X"; then
+ if test "$script_file" = "-"; then
+ mkdir -p $tmpdir_client/script || \
+ fatal "ERROR: cannot create temporary diectory " $tmpdir_client/script
+ cat > $tmpdir_client/script/-
+ else
+ include_file_or_directory script $script_file > /dev/null
+ fi
+ fi
+
+ # Add the necessary info to special files in our temporary directory. Do this
+ # after linking in -I and -R directories in order to guarantee no name clashes.
+ tmpfile=`mktemp cmdline.XXXXXX` || \
+ fatal "ERROR: cannot create temporary file "
+ echo "cmdline: $cmdline" > $tmpfile
+
+ tmpfile=`mktemp sysinfo.XXXXXX` || \
+ fatal "ERROR: cannot create temporary file " $tmpfile
+ echo "sysinfo: `client_sysinfo`" > $tmpfile
+}
+
+# function client_sysinfo
+#
+# Generate the client's sysinfo and echo it to stdout
+function client_sysinfo {
+ if test "X$sysinfo_client" = "X"; then
+ # Get the stap version
+ stap_version=`stap -V 2>&1 | grep version`
+ # Remove the number before the first slash
+ stap_version=`expr "$stap_version" : '.*version [^/]*/\([0-9./]*\).*'`
+ # Add some info from uname
+ sysinfo_client="stap $stap_version `uname -sr`"
+ fi
+ echo $sysinfo_client
+}
+
+# function: package_request
+#
+# Package the client's temp directory into a form suitable for sending to the
+# server.
+function package_request {
+ # Package up the temporary directory into a tar file
+ cd $tmpdir_env
+
+ local tmpdir_client_base=`basename $tmpdir_client`
+ tar_client=$tmpdir_env/`mktemp $tmpdir_client_base.tgz.XXXXXX` || \
+ fatal "ERROR: cannot create temporary file " $tar_client
+
+ tar -czhf $tar_client $tmpdir_client_base || \
+ fatal "ERROR: tar of request tree, $tmpdir_client, failed"
+
+ tar_server=$tmpdir_env/`mktemp $tmpdir_prefix_server.tgz.XXXXXX` || \
+ fatal "ERROR: cannot create temporary file " $tar_server
+}
+
+# function: send_request
+#
+# Notify the server and then send $tar_client to the server as $tar_server
+# The protocol is:
+# client -> "request: $tmpdir_client"
+# server -> "send: $tar_server"
+# client: rsync local:$tar_client server:$tar_server
+# client -> "waiting:"
+#
+# $tmpdir_client is provided on the request so that the server knows what
+# the tar file will expand to.
+function send_request {
+ echo "request: `basename $tmpdir_client`" >&3
+
+ read <&3
+ local line=$REPLY
+ check_server_error $line
+
+ local tar_dest=`expr "$line" : 'send: \([^ ]*\)$'`
+ test "X$tar_dest" == "X" && \
+ fatal "ERROR: destination tar file not provided"
+
+ rsync -essh -a --delete $tar_client root@$server:$tar_dest || \
+ fatal "ERROR: rsync of client request, $tar_client to $server:$tar_dest, failed"
+
+ echo "waiting:" >&3
+}
+
+# function: receive_response
+#
+# Wait for a response from the server indicating the results of our request.
+# The protocol is:
+# server -> "sending: remote-tar-name server-tempdir-name stap-tempdir-name"
+# client -> "OK"
+function receive_response {
+ read <&3
+ local line=$REPLY
+ check_server_error $line
+
+ tar_dest=`expr "$line" : 'sending: \([^ ]*\) [^ ]* [^ ]*$'`
+ test "X$tar_dest" == "X" && \
+ fatal "ERROR: server response remote file is missing"
+
+ tmpdir_server=`expr "$line" : 'sending: [^ ]* \([^ ]*\) [^ ]*$'`
+ test "X$tmpdir_server" == "X" && \
+ fatal "ERROR: server response temp dir is missing"
+
+ tmpdir_stap=`expr "$line" : 'sending: [^ ]* [^ ]* \([^ ]*\)$'`
+ test "X$tmpdir_stap" == "X" && \
+ fatal "ERROR: server response stap temp dir is missing"
+
+
+ # Retrieve the file
+ rsync -essh -a --delete root@$server:$tar_dest $tar_server || \
+ fatal "ERROR: rsync of server response, $server:$tar_dest to $tar_server, failed"
+ echo "OK" >&3
+}
+
+# function: unpack_response
+#
+# Unpack the tar file received from the server and make the contents available
+# for printing the results and/or running 'staprun'.
+function unpack_response {
+ # Unpack the server output directory
+ cd $tmpdir_client
+ tar -xzf $tar_server || \
+ fatal "ERROR: Unpacking of server response, $tar_server, failed"
+
+ # Create a local location for the server response.
+ local local_tmpdir_server_base=`basename $tar_server | sed 's,\.tgz,,'`
+ local local_tmpdir_server=`mktemp -dt $local_tmpdir_server_base.XXXXXX` || \
+ fatal "ERROR: cannot create temporary directory " $local_tmpdir_server
+
+ # Move the systemtap temp directory to our a local temp location, if -k
+ # was specified.
+ if test $keep_temps = 1; then
+ local local_tmpdir_stap=`mktemp -dt stapXXXXXX` || \
+ fatal "ERROR: cannot create temporary directory " $local_tmpdir_stap
+ mv $tmpdir_server/$tmpdir_stap/* $local_tmpdir_stap 2>/dev/null
+ rm -fr $tmpdir_server/$tmpdir_stap
+
+ # Correct the name of the temp directory in the server's stderr output
+ sed -i "s,^Keeping temporary directory.*,Keeping temporary directory \"$local_tmpdir_stap\"," $tmpdir_server/stderr
+ tmpdir_stap=$local_tmpdir_stap
+ else
+ tmpdir_stap=$local_tmpdir_server/$tmpdir_stap
+ fi
+
+ # Move the extracted tree to our local location
+ mv $tmpdir_server/* $local_tmpdir_server
+ rm -fr $tmpdir_server
+ tmpdir_server=$local_tmpdir_server
+}
+
+# function: find_and_connect_to_server
+#
+# Find and establish connection with a compatibale stap server.
+function find_and_connect_to_server {
+ # Find a server
+ server=`avahi-browse $avahi_service_tag --terminate -r 2>/dev/null | match_server`
+ test "X$server" != "X" || \
+ fatal "ERROR: cannot find a server"
+
+ port=`expr "$server" : '[^/]*/\(.*\)'`
+ server=`expr "$server" : '\([^/]*\)/.*'`
+
+ # Open a connection to the server
+ if ! exec 3<> /dev/tcp/$server/$port; then
+ fatal "ERROR: cannot connect to server at /dev/tcp/$server/$port"
+ fi
+}
+
+# function: match_server
+#
+# Find a suitable server using the avahi-browse output provided on stdin.
+function match_server {
+ local server_ip
+
+ # Loop over the avahi service descriptors.
+ while read
+ do
+ # Examine the next service descriptor
+ # Is it a stap server?
+ (echo $REPLY | grep -q "^=.*_stap") || continue
+
+ # Get the details of the service
+ local service_tag equal data
+ while read service_tag equal service_data
+ do
+ case $service_tag in
+ '=' )
+ break ;;
+ hostname )
+ server_name=`expr "$service_data" : '\[\([^]]*\)\]'`
+ ;;
+ address )
+ # Sometimes (seems random), avahi-resolve-host-name resolves a local server to its
+ # hardware address rather its ip address. Keep trying until we get
+ # an ip address.
+ server_ip=`expr "$service_data" : '\[\([^]]*\)\]'`
+ local attempt
+ for ((attempt=0; $attempt < 5; ++attempt))
+ do
+ server_ip=`expr "$server_ip" : '^\([0-9]*\.[0-9]*\.[0-9]*\.[0-9]*\)$'`
+ if test "X$server_ip" != "X"; then
+ break
+ fi
+ # Resolve the server.domain to an ip address.
+ server_ip=`avahi-resolve-host-name $hostname`
+ server_ip=`expr "$server_ip" : '.* \(.*\)$'`
+ done
+ ;;
+ port )
+ port=`expr "$service_data" : '\[\([^]]*\)\]'`
+ ;;
+ txt )
+ sysinfo_server=`expr "$service_data" : '\[\"\([^]]*\)\"\]'`
+ sysinfo_server=`expr "$sysinfo_server" : '[^/]*/\(.*\)'`
+ ;;
+ * )
+ break ;;
+ esac
+ done
+
+ # It is a stap server, but is it compatible?
+ sysinfo_server="stap $sysinfo_server"
+ if test "$sysinfo_server" != "`client_sysinfo`"; then
+ continue
+ fi
+
+ if test "X$server_ip" != "X"; then
+ break
+ fi
+ done
+
+ echo $server_ip/$port
+}
+
+# function: disconnect_from_server
+#
+# Disconnect from the server.
+function disconnect_from_server {
+ # Close the connection to the server.
+ exec 3<&-
+}
+
+# function: stream_output
+#
+# Write the stdout and stderr from the server to stdout and stderr respectively.
+function stream_output {
+ # Output stdout and stderr as directed
+ cd $local_tmpdir_server
+ cat ${tmpdir_server}/stderr >&2
+ eval cat ${tmpdir_server}/stdout $stdout_redirection
+}
+
+# function: maybe_call_staprun
+#
+# Call staprun using the module returned from the server, if requested.
+function maybe_call_staprun {
+ if test $p_phase = 5; then
+ for ((--v_level; $v_level > 0; --v_level))
+ do
+ staprun_opts="$staprun_opts -v"
+ done
+ staprun $staprun_opts \
+ $tmpdir_stap/`ls $tmpdir_stap | grep '.ko$'`
+ fi
+}
+
+# function: check_server_error SERVER_RESPONSE
+#
+# Check the given server response for an error message.
+function check_server_error {
+ echo $1 | grep -q "^ERROR:" && \
+ fatal "Server:" "$@"
+}
+
+# function: fatal [ MESSAGE ]
+#
+# Fatal error
+# Prints its arguments to stderr and exits
+function fatal {
+ echo $0: "$@" >&2
+ cat <&3 >&2
+ cleanup
+ exit 1
+}
+
+# function cleanup
+#
+# Cleanup work files unless asked to keep them.
+function cleanup {
+ # Clean up.
+ cd $tmpdir_env
+ if test $keep_temps != 1; then
+ rm -fr $tmpdir_client
+ rm -f $tar_client
+ rm -f $tar_server
+ rm -fr $tmpdir_server
+ fi
+}
+
+#-----------------------------------------------------------------------------
+# Beginning of main line execution.
+#-----------------------------------------------------------------------------
+configuration
+initialization
+parse_options "$@"
+create_request
+package_request
+find_and_connect_to_server
+send_request
+receive_response
+unpack_response
+disconnect_from_server
+stream_output
+maybe_call_staprun
+cleanup
+
+exit 0
diff --git a/stap-server b/stap-server
new file mode 100755
index 00000000..1a2e7918
--- /dev/null
+++ b/stap-server
@@ -0,0 +1,436 @@
+#!/bin/bash
+
+# Compile server for systemtap
+#
+# Copyright (C) 2008 Red Hat Inc.
+#
+# This file is part of systemtap, and is free software. You can
+# redistribute it and/or modify it under the terms of the GNU General
+# Public License (GPL); either version 2, or (at your option) any
+# later version.
+
+# This script unpacks the tar file provided on stdin and uses the information
+# contained in the unpacked tree to build the requested systemtap kernel module.
+# This module is then written to stdout.
+
+#-----------------------------------------------------------------------------
+# Helper functions.
+#-----------------------------------------------------------------------------
+# function: configuration
+function configuration {
+ # Configuration
+ tmpdir_prefix_client=stap.client
+ tmpdir_prefix_server=stap.server
+}
+
+# function: initialization
+function initialization {
+ # Initialization
+ wd=`pwd`
+
+ # Default options settings
+ p_phase=5
+ keep_temps=0
+
+ # Make a temp directory to work in.
+ tmpdir_server=`mktemp -dt $tmpdir_prefix_server.XXXXXX` || \
+ fatal "ERROR: cannot create temporary directory " $tmpdir_server
+ tmpdir_env=`dirname $tmpdir_server`
+}
+
+# function: receive_request
+#
+# Receive a tar file representing the request from the client:
+# The protocol is:
+# client -> "request: $tmpdir_client"
+# server -> "send: $tar_client"
+# client: copies file to server:$tar_client
+# client -> "waiting:"
+#
+# $tmpdir_client is provided on the request so that we know what
+# the tar file will expand to.
+function receive_request {
+ cd $tmpdir_server
+
+ # Request from the client is on stdin
+ read
+ line=$REPLY
+
+ # Extract the name of the client's temp directory.
+ tmpdir_client=`expr "$line" : 'request: \([^ ]*\)$'`
+ test "X$tmpdir_client" == "X" && \
+ fatal "ERROR: client request temp dir name is missing" $tmpdir_server
+ tmpdir_client=$tmpdir_server/$tmpdir_client
+
+ # Create the client's temp dir now to guarantee that it won't clash with
+ # any files we need to create later.
+ mkdir $tmpdir_client || \
+ fatal "ERROR: cannot create client temp dir" $tmpdir_client
+
+ # Create a place to receive the client's tar file
+ tar_client=`mktemp -t $tmpdir_prefix_client.tgz.XXXXXX` || \
+ fatal "ERROR: cannot create temporary tar file " $tar_client
+
+ # Request that the file be sent.
+ echo "send: $tar_client"
+
+ # Wait for confirmation that the tar file has arrived via rysnc
+ read
+ line=$REPLY
+ test "X$line" = "Xwaiting:" || \
+ fatal "ERROR: client send confirmation, '$line', is incorrect"
+}
+
+# function: unpack_request
+#
+# Unpack the tar file received from the client and make the contents
+# available for use when running 'stap'
+function unpack_request {
+ cd $tmpdir_server
+
+ # Unpack the tar file.
+ tar -xzf $tar_client || \
+ fatal "ERROR: cannot unpack tar archive $tar_client"
+
+ # Move the client's temp directory to a local temp location
+ local tmpdir_client_base=`basename $tar_client | sed 's,\.tgz,,'`
+ local local_tmpdir_client=`mktemp -dt $tmpdir_client_base.XXXXXX` || \
+ fatal "ERROR: cannot create temporary tar file " $local_tmpdir_client
+ mv $tmpdir_client/* $local_tmpdir_client
+ rm -fr $tmpdir_client
+ tmpdir_client=$local_tmpdir_client
+}
+
+# function: check_request
+#
+# Examine the contents of the request to make sure that they are valid.
+function check_request {
+ # Work in the temporary directory provided by the client
+ cd $tmpdir_client
+
+ # Add the necessary info from files in our temporary directory.
+ cmdline=`read_data_file cmdline`
+ test "X$cmdline" != "X" || exit 1
+ client_sysinfo=`read_data_file sysinfo`
+ test "X$client_sysinfo" != "X" || exit 1
+
+ # Extract the client's config info.
+ client_name=`expr "$client_sysinfo" : 'stap [^ ]* [^ ]* \([^ ]*\).*'`
+ client_sysinfo=`echo $client_sysinfo | sed s,$client_name,,`
+
+ # Extract the server's config info.
+ server_sysinfo=`uname -sr`
+ server_name=`expr "$server_sysinfo" : '[^ ]* \([^ ]*\).*'`
+ server_sysinfo=`echo $server_sysinfo | sed s,$server_name,,`
+ local stap_version=`stap -V 2>&1 | grep version`
+ stap_version=`expr "$stap_version" : '.*version \([0-9./]*\).*'`
+ server_sysinfo="stap $stap_version $server_sysinfo"
+
+ check_compatibility "$client_sysinfo" "$server_sysinfo"
+}
+
+# function check_compaibility SYSINFO1 SYSINFO2
+#
+# Make sure that systemtap as described by SYSINFO1 and SYSINFO2 are compaible
+function check_compatibility {
+ # TODO: This needs work
+ # - In stap version x/y, require that the y matches
+ # - Make sure the linux kernel matches exactly
+ local sysinfo1=`echo $1 | sed 's,stap [^/]*/,stap ,'`
+ local sysinfo2=`echo $2 | sed 's,stap [^/]*/,stap ,'`
+
+ if test "$sysinfo1" != "$sysinfo2"; then
+ error "ERROR: system configuration mismatch"
+ error " client: $sysinfo1"
+ fatal " server: $sysinfo2"
+ fi
+}
+
+# function: read_data_file PREFIX
+#
+# Find a file whose name matches '$1.??????' whose first line
+# contents are '$1: .*'. Read and echo the first line.
+function read_data_file {
+ for f in `ls $1.??????`
+ do
+ read < $f
+ line=$REPLY
+ data=`expr "$line" : "$1: \\\(.*\\\)"`
+ if test "X$data" != "X"; then
+ echo $data
+ return
+ fi
+ done
+ fatal "ERROR: Data file for $1 not found"
+}
+
+# function: parse_options [ STAP-OPTIONS ]
+#
+# Examine the command line. We need not do much checking, but we do need to
+# parse all options in order to discover the ones we're interested in.
+function parse_options {
+ while test $# != 0
+ do
+ advance_p=0
+ dash_seen=0
+
+ # Start of a new token.
+ first_token=$1
+ until test $advance_p != 0
+ do
+ # Identify the next option
+ first_char=`expr "$first_token" : '\(.\).*'`
+ if test $dash_seen = 0; then
+ if test "$first_char" = "-"; then
+ if test "$first_token" != "-"; then
+ # It's not a lone dash, so it's an option. Remove the dash.
+ first_token=`expr "$first_token" : '-\(.*\)'`
+ dash_seen=1
+ first_char=`expr "$first_token" : '\(.\).*'`
+ fi
+ fi
+ if test $dash_seen = 0; then
+ # The dash has not been seen. This is either the script file
+ # name or an arument to be passed to the probe module.
+ # If this is the first time, and -e has not been specified,
+ # then it could be the name of the script file.
+ if test "X$e_script" = "X" -a "X$script_file" = "X"; then
+ script_file=$first_token
+ fi
+ advance_p=$(($advance_p + 1))
+ break
+ fi
+ fi
+
+ # We are at the start of an option. Look at the first character.
+ case $first_char in
+ c)
+ get_arg $first_token "$2"
+ ;;
+ D)
+ get_arg $first_token $2
+ ;;
+ e)
+ get_arg $first_token "$2"
+ process_e "$stap_arg"
+ ;;
+ I)
+ get_arg $first_token $2
+ ;;
+ k)
+ keep_temps=1
+ ;;
+ l)
+ get_arg $first_token $2
+ ;;
+ m)
+ get_arg $first_token $2
+ ;;
+ o)
+ get_arg $first_token $2
+ ;;
+ p)
+ get_arg $first_token $2
+ process_p $stap_arg
+ ;;
+ r)
+ get_arg $first_token $2
+ ;;
+ R)
+ get_arg $first_token $2
+ ;;
+ s)
+ get_arg $first_token $2
+ ;;
+ x)
+ get_arg $first_token $2
+ ;;
+ *)
+ # An unknown flag. Ignore it.
+ ;;
+ esac
+
+ if test $advance_p = 0; then
+ # Just another flag character. Consume it.
+ first_token=`expr "$first_token" : '.\(.*\)'`
+ if test "X$first_token" = "X"; then
+ advance_p=$(($advance_p + 1))
+ fi
+ fi
+ done
+
+ # Consume the arguments we just processed.
+ while test $advance_p != 0
+ do
+ shift
+ advance_p=$(($advance_p - 1))
+ done
+ done
+}
+
+# function: get_arg FIRSTWORD SECONDWORD
+#
+# Collect an argument to the given option
+function get_arg {
+ # Remove first character. Advance to the next token, if the first one
+ # is exhausted.
+ local first=`expr "$1" : '.\(.*\)'`
+ if test "X$first" = "X"; then
+ shift
+ advance_p=$(($advance_p + 1))
+ first=$1
+ fi
+
+ stap_arg="$first"
+ advance_p=$(($advance_p + 1))
+}
+
+# function: process_e ARGUMENT
+#
+# Process the -e flag.
+function process_e {
+ if test "X$e_script" = "X"; then
+ e_script="$1"
+ script_file=
+ fi
+}
+
+# function: process_p ARGUMENT
+#
+# Process the -p flag.
+function process_p {
+ if test $1 -ge 1 -a $1 -le 5; then
+ p_phase=$1
+ fi
+}
+
+# function: call_stap
+#
+# Call 'stap' with the options provided. Don't run past phase 4.
+function call_stap {
+ # Invoke systemtap.
+ # Use -k so we can return results to the client
+ # Limit to -p4. i.e. don't run the module
+ cd $tmpdir_client
+ if test $p_phase -gt 4; then
+ server_p_phase=4
+ else
+ server_p_phase=$p_phase
+ fi
+ eval stap $cmdline -k -p $server_p_phase \
+ >> $tmpdir_server/stdout \
+ 2>> $tmpdir_server/stderr
+}
+
+# function: create_response
+#
+# Add information to the server's temp directory representing the response
+# to the client.
+function create_response {
+ cd $tmpdir_server
+
+ # Get the name of the stap temp directory, which was kept, from stderr.
+ tmpdir_line=`cat stderr | grep "Keeping temp"`
+ tmpdir_stap=`expr "$tmpdir_line" : '.*"\(.*\)".*'`
+
+ # Remove the message about keeping th<e stap temp directory from stderr, unless
+ # the user did request to keep it.
+ if test $keep_temps != 1; then
+ sed -i "/^Keeping temp/d" stderr
+ fi
+
+ # If the user specified -p5, remove the name of the kernel module from stdout.
+ if test $p_phase = 5; then
+ sed -i '/\.ko$/d' stdout
+ fi
+
+ # Add the contents of the stap temp directory to the server output directory
+ ln -s $tmpdir_stap `basename $tmpdir_stap`
+}
+
+# function: package_response
+#
+# Package the server's temp directory into a form suitable for sending to the
+# client.
+function package_response {
+ cd $tmpdir_env
+ # Create a place to generate our tar file of our temporary directory
+ local tmpdir_server_base=`basename $tmpdir_server`
+ tar_server=$tmpdir_env/`mktemp $tmpdir_server_base.tgz.XXXXXX` || \
+ fatal "ERROR: cannot create temporary tar file " $tar_server
+ chmod +r $tar_server
+
+ # Generate the tar file
+ tar -czphf $tar_server `basename $tmpdir_server` || \
+ fatal "ERROR: tar of $tmpdir_server failed"
+}
+
+# function: send_response
+#
+# Notify the client that $tar_server is ready and wait for the client to take
+# it.
+# The protocol is:
+# server -> "sending: $tar_server $tmpdir_server $tmpdir_stap"
+# client: copies file from server:$tar_server
+# client -> "OK"
+function send_response {
+ # TODO needed for rsync from client to work
+ chmod +r $tmpdir_server
+
+ # Tell the client where to get it.
+ echo "sending: $tar_server `basename $tmpdir_server` `basename $tmpdir_stap`"
+
+ # Wait for the confirmation
+ read
+ line=$REPLY
+ test $line = "OK" || \
+ fatal "ERROR: client final confirmation, '$line' is incorrect"
+}
+
+# function: fatal [ MESSAGE ]
+#
+# Fatal error
+# Prints its arguments to stderr and exits
+function fatal {
+ echo "$@" >&2
+ cleanup
+ exit 1
+}
+
+# Non fatal error
+# Prints its arguments to stderr but does not exit
+function error {
+ echo "$@" >&2
+}
+
+# function cleanup
+#
+# Cleanup work files unless asked to keep them.
+function cleanup {
+ # Clean up.
+ cd $tmpdir_env
+ if test $keep_temps != 1; then
+ rm -fr $tar_client
+ rm -fr $tmpdir_client
+ rm -fr $tar_server
+ rm -fr $tmpdir_server
+ rm -fr $tmpdir_stap
+ fi
+}
+
+#-----------------------------------------------------------------------------
+# Beginning of main line execution.
+#-----------------------------------------------------------------------------
+configuration
+initialization
+receive_request
+unpack_request
+check_request
+eval parse_options $cmdline
+call_stap
+create_response
+package_response
+send_response
+cleanup
+
+exit 0
diff --git a/stap.1.in b/stap.1.in
index d4458850..7a3686d1 100644
--- a/stap.1.in
+++ b/stap.1.in
@@ -1040,10 +1040,8 @@ RPM, unless overridden by the
.I SYSTEMTAP_DEBUGINFO_PATH
environment variable. The default value for this variable is
.IR \-:.debug:/usr/lib/debug .
-This path is interpreted by elfutils as a list of base directories of
-which various subdirectories will be searched. The \- at the front
-means to skip CRC matching for separated debug objects and is a small
-performance win if no possible corruption is suspected.
+Elfutils searches vmlinux in this path and it interprets the path as a base
+directory of which various subdirectories will be searched for finding modules.
.TP
@prefix@/bin/staprun
The auxiliary program supervising module loading, interaction, and
@@ -1052,6 +1050,7 @@ unloading.
.SH SEE ALSO
.IR stapprobes (5),
.IR stapfuncs (5),
+.IR stapvars (5),
.IR stapex (5),
.IR awk (1),
.IR gdb (1)
diff --git a/stapfuncs.5.in b/stapfuncs.5.in
index 04e5ea17..acfb42f9 100644
--- a/stapfuncs.5.in
+++ b/stapfuncs.5.in
@@ -252,6 +252,9 @@ Return the probe point's module name, if known.
target:long ()
Return the pid of the target process.
.TP
+user_mode:long ()
+Return 1 if the probe point occurred in user-mode.
+.TP
is_return:long ()
Return 1 if the probe point is a return probe. Deprecated.
@@ -345,6 +348,11 @@ Return the maximum number of file handles for the given task.
.SS CPU REGISTERS
.TP
+registers_valid:long ()
+Return 1 if register() and u_register() can be used
+in the current context, or 0 otherwise.
+For example, registers_valid() returns 0 when called from a begin or end probe.
+.TP
register:long (name:string)
Return the value of the named CPU register,
as it was saved when the current probe point was hit.
@@ -368,7 +376,7 @@ segment registers: xcs/cs, xss/ss.
For powerpc, the following names are recognized:
r1, r2... r31, nip, msr, orig_gpr3, ctr, link, xer, ccr, softe, trap,
-dar, dsisr, result;
+dar, dsisr, result.
.TP
u_register:long (name:string)
@@ -634,6 +642,20 @@ or SIG_ERR, it will return the address of the handler.
signal_str(num)
Returns the string representation of the given signal number.
+.SS DEVICE
+.TP
+MAJOR:long(dev:long)
+Extracts the major device number from a kernel device number (kdev_t).
+.TP
+MINOR:long(dev:long)
+Extracts the minor device number from a kernel device number (kdev_t).
+.TP
+MKDEV:long(major:long, minor:long)
+Creates a value that can be compared to a kernel device number (kdev_t).
+.TP
+usrdev2kerndev:long(dev:long)
+Converts a user-space device number into the format used in the kernel.
+
.SH FILES
.nh
.IR @prefix@/share/systemtap/tapset
diff --git a/stapprobes.5.in b/stapprobes.5.in
index 3633fd39..5d400cb6 100644
--- a/stapprobes.5.in
+++ b/stapprobes.5.in
@@ -256,7 +256,12 @@ linux source directory, although an absolute path may be necessary for some kern
If a relative pathname doesn't work, try absolute.
.IP \(bu 4
Finally, the third part is optional if the file name part was given,
-and identifies the line number in the source file, preceded by a ":".
+and identifies the line number in the source file preceded by a ":"
+or a "+". The line number is assumed to be an
+absolute line number if preceded by a ":", or relative to the entry of
+the function if preceded by a "+".
+All the lines in the function can be matched with ":*".
+A range of lines x through y can be matched with ":x-y".
.PP
As an alternative, PATTERN may be a numeric constant, indicating an
(module-relative or kernel-_stext-relative) address. In guru mode
@@ -309,12 +314,14 @@ All threads of that process will be probed.
.PP
Additional user-space probing is available in the following forms:
.SAMPLE
-process(PID).clone
-process("PATH").clone
-process(PID).exec
-process("PATH").exec
-process(PID).death
-process("PATH").death
+process(PID).begin
+process("PATH").begin
+process(PID).thread.begin
+process("PATH").thread.begin
+process(PID).end
+process("PATH").end
+process(PID).thread.end
+process("PATH").thread.end
process(PID).syscall
process("PATH").syscall
process(PID).syscall.return
@@ -322,15 +329,16 @@ process("PATH").syscall.return
.ESAMPLE
.PP
A
-.B .clone
-probe gets called when a thread described by PID or PATH creates a new
-thread.
+.B .begin
+probe gets called when new process described by PID or PATH gets created.
A
-.B .exec
-probe gets called when a thread described by PID or PATH returns from
-.IR exec() .
+.B .thread.begin
+probe gets called when a new thread described by PID or PATH gets created.
A
-.B .death
+.B .end
+probe gets called when process described by PID or PATH dies.
+A
+.B .thread.end
probe gets called when a thread described by PID or PATH dies.
A
.B .syscall
@@ -490,7 +498,10 @@ refers to the first byte of the statement whose compiled instructions
include the given address in the kernel.
.TP
kernel.statement("*@kernel/sched.c:2917")
-refers to the statement of line 2917 within the "kernel/sched.c".
+refers to the statement of line 2917 within "kernel/sched.c".
+.TP
+kernel.statement("bio_init@fs/bio.c+3")
+refers to the statement at line bio_init+3 within "fs/bio.c".
.TP
syscall.*.return
refers to the group of probe aliases with any name in the third position
diff --git a/stapvars.5.in b/stapvars.5.in
new file mode 100644
index 00000000..94e47667
--- /dev/null
+++ b/stapvars.5.in
@@ -0,0 +1,51 @@
+.\" -*- nroff -*-
+.TH STAPVARS 5 @DATE@ "Red Hat"
+.SH NAME
+stapvars \- systemtap variables
+
+.SH DESCRIPTION
+The following sections enumerate the public variables provided by
+standard tapsets installed under @prefix@/share/systemtap/tapset. Each
+variable is described with a type, and its behavior/restrictions.
+The syntax is the same as printed with the
+.IR stap " option " \-p2 .
+Examples:
+
+.TP
+example1:long
+Variable "example1" contains an integer.
+
+.TP
+example2:string [long]
+Variable "example2" is an array of strings, indexed by integers.
+
+.SS ARGV
+
+.TP
+argc:long
+Contains the value of the
+.BR
+$#
+value: the number of command line arguments passed to the systemtap script.
+It is initialized with an implicit begin(-1) probe.
+
+.TP
+argv:string [long]
+Contains each command line argument as a string. argv[1] will equal @1 if
+there was at least one command line argument. Arguments beyond #32 are not
+transcribed, and produce a warning message within the begin(-1) probe that
+initializes this array.
+
+.SS NULL
+
+.TP
+NULL:long
+Simply defined as the number 0.
+
+.SH FILES
+.nh
+.IR @prefix@/share/systemtap/tapset
+.hy
+
+.SH SEE ALSO
+.IR stap (1)
diff --git a/tapset/ChangeLog b/tapset/ChangeLog
index 4b37471c..7365d4c9 100644
--- a/tapset/ChangeLog
+++ b/tapset/ChangeLog
@@ -1,3 +1,90 @@
+2008-06-23 Zhaolei <zhaolei@cn.fujitsu.com>
+
+ * syscalls.stp: Add sys_mknodat.
+
+2008-06-20 wcohen <wcohen@redhat.com>
+
+ * dev.stp: New.
+
+2008-06-19 Zhaolei <zhaolei@cn.fujitsu.com>
+
+ * aux_syscalls.stp: Output unknown bits in _stp_lookup_or_str.
+
+2008-06-17 Zhaolei <zhaolei@cn.fujitsu.com>
+
+ * syscalls.stp: Add sys_linkat.
+
+2008-06-17 Zhaolei <zhaolei@cn.fujitsu.com>
+
+ * aux_syscalls.stp (__fork_flags): Add termination signal.
+
+2008-06-13 Josh Stone <joshua.i.stone@intel.com>
+
+ * aux_syscalls.stp, ctime.stp, inet.stp, memory.stp,
+ s390x/syscalls.stp, {i686,x86_64,ppc64}/registers.stp: Add
+ 'pure' to embedded-C functions that deserve it.
+
+2008-06-13 Zhaolei <zhaolei@cn.fujitsu.com>
+
+ * syscalls.stp: Add sys_fchownat.
+
+2008-06-12 Will Cohen <wcohen@redhat.com>
+
+ * tasks.stp: Add user_mode.
+
+2008-06-11 Zhaolei <zhaolei@cn.fujitsu.com>
+
+ * syscalls.stp: Add sys_fchmodat.
+
+2008-06-10 Zhaolei <zhaolei@cn.fujitsu.com>
+
+ * syscalls.stp: Add sys_faccessat.
+
+2008-06-10 Zhaolei <zhaolei@cn.fujitsu.com>
+
+ * syscalls.stp(syscall.mkdirat): Use _dfd_str() to add support
+ for AT_FDCWD.
+
+2008-06-10 Frank Ch. Eigler <fche@elastic.org>
+
+ PR 6470.
+ * argv.stp: New tapset.
+
+2008-06-09 David Smith <dsmith@redhat.com>
+
+ * x86_64/registers.stp (syscall_nr): Added syscall_nr function.
+ * i686/registers.stp (syscall_nr): Ditto.
+
+2008-06-04 Zhaolei <zhaolei@cn.fujitsu.com>
+
+ * syscalls2.stp: Add sys_unshare.
+
+2008-06-03 Zhaolei <zhaolei@cn.fujitsu.com>
+
+ * aux_syscalls.stp (__fork_flags): Support for new clone flags
+ before linux-2.6.25.
+
+2008-05-26 Mark Wielaard <mwielaard@redhat.com>
+
+ * task.stp : Only include fdtable.h for kernel versions > 2.6.25.
+
+2008-05-26 Wenji Huang <wenji.huang@oracle.com>
+
+ * task.stp : Include fdtable.h for 2.6.26.
+
+2008-05-26 Wenji Huang <wenji.huang@oracle.com>
+
+ * signal.stp (send.*): Correct for 2.6.26.
+
+2008-05-23 Frank Ch. Eigler <fche@elastic.org>
+
+ * nfs.stp (*): Similarly convert kernel?,module? -> kernel!,module.
+
+2008-05-23 Frank Ch. Eigler <fche@elastic.org>
+
+ * rpc.stp (*): Convert kernel?,module? -> kernel!,module probe points.
+ (rpc_create_task): Make conditional on kernel <= 2.6.18.
+
2008-05-21 Frank Ch. Eigler <fche@elastic.org>
PR 6538
diff --git a/tapset/argv.stp b/tapset/argv.stp
new file mode 100644
index 00000000..c941bfc5
--- /dev/null
+++ b/tapset/argv.stp
@@ -0,0 +1,48 @@
+// argument vector tapset
+// Copyright (C) 2008 Red Hat Inc.
+//
+// This file is part of systemtap, and is free software. You can
+// redistribute it and/or modify it under the terms of the GNU General
+// Public License (GPL); either version 2, or (at your option) any
+// later version.
+
+
+global argc = $#
+global argv %( $# >= 1 %? [$#] %: [1] %)
+
+probe begin(-1) {
+ %( $# == 0 %? argv[0] = "nothing"; delete argv[0] %) # ensure argv is set sometime
+ %( $# >= 1 %? argv[1]=@1 %)
+ %( $# >= 2 %? argv[2]=@2 %)
+ %( $# >= 3 %? argv[3]=@3 %)
+ %( $# >= 4 %? argv[4]=@4 %)
+ %( $# >= 5 %? argv[5]=@5 %)
+ %( $# >= 6 %? argv[6]=@6 %)
+ %( $# >= 7 %? argv[7]=@7 %)
+ %( $# >= 8 %? argv[8]=@8 %)
+ %( $# >= 9 %? argv[9]=@9 %)
+ %( $# >= 10 %? argv[10]=@10 %)
+ %( $# >= 11 %? argv[11]=@11 %)
+ %( $# >= 12 %? argv[12]=@12 %)
+ %( $# >= 13 %? argv[13]=@13 %)
+ %( $# >= 14 %? argv[14]=@14 %)
+ %( $# >= 15 %? argv[15]=@15 %)
+ %( $# >= 16 %? argv[16]=@16 %)
+ %( $# >= 17 %? argv[17]=@17 %)
+ %( $# >= 18 %? argv[18]=@18 %)
+ %( $# >= 19 %? argv[19]=@19 %)
+ %( $# >= 20 %? argv[20]=@20 %)
+ %( $# >= 21 %? argv[21]=@21 %)
+ %( $# >= 22 %? argv[22]=@22 %)
+ %( $# >= 23 %? argv[23]=@23 %)
+ %( $# >= 24 %? argv[24]=@24 %)
+ %( $# >= 25 %? argv[25]=@25 %)
+ %( $# >= 26 %? argv[26]=@26 %)
+ %( $# >= 27 %? argv[27]=@27 %)
+ %( $# >= 28 %? argv[28]=@28 %)
+ %( $# >= 29 %? argv[29]=@29 %)
+ %( $# >= 30 %? argv[30]=@30 %)
+ %( $# >= 31 %? argv[31]=@31 %)
+ %( $# >= 32 %? argv[32]=@32 %)
+ %( $# >= 33 %? warn(sprintf("argv is limited to 32 arguments")) %)
+}
diff --git a/tapset/aux_syscalls.stp b/tapset/aux_syscalls.stp
index ec7fdcb0..f79acaf0 100644
--- a/tapset/aux_syscalls.stp
+++ b/tapset/aux_syscalls.stp
@@ -1548,7 +1548,7 @@ void _stp_lookup_str(const _stp_val_array * const array, long val, char *ptr, in
}
void _stp_lookup_or_str(const _stp_val_array * const array, long val, char *ptr, int len)
{
- int i = 0, flag = 0;
+ int i = 0, flag = 0, slen;
if (val == 0) {
_stp_lookup_str(array, val, ptr, len);
@@ -1560,12 +1560,15 @@ void _stp_lookup_or_str(const _stp_val_array * const array, long val, char *ptr,
if (flag)
strlcat(ptr, "|", len);
strlcat(ptr, array[i].name, len);
+ val &= (~array[i].val);
flag = 1;
}
i++;
}
- if (flag == 0) {
- int slen = strlen(ptr);
+ if (val) {
+ if (flag)
+ strlcat(ptr, "|", len);
+ slen = strlen(ptr);
_stp_snprintf(ptr + slen, len - slen, "0x%lx", val);
}
}
@@ -1686,18 +1689,32 @@ const _stp_val_array const _stp_fork_list[] = {
V(CLONE_CHILD_SETTID),
V(CLONE_STOPPED),
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)
+ V(CLONE_NEWUTS),
V(CLONE_NEWIPC),
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23)
V(CLONE_NEWUSER),
#endif
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
+ V(CLONE_NEWPID),
+ V(CLONE_NEWNET),
+#endif
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,25)
+ V(CLONE_IO),
+#endif
{0, NULL}
};
%}
function __fork_flags:string(flags:long)
%{ /* pure */
- _stp_lookup_or_str(_stp_fork_list, THIS->flags, THIS->__retvalue, MAXSTRINGLEN);
+ _stp_lookup_or_str(_stp_fork_list, THIS->flags & ~0xff, THIS->__retvalue, MAXSTRINGLEN);
+ if ( THIS->flags & 0xff ) {
+ /* flags contains the termination signal */
+ if (*THIS->__retvalue)
+ strlcat(THIS->__retvalue, "|", MAXSTRINGLEN);
+ _stp_lookup_str(_stp_signal_list, THIS->flags & 0xff, THIS->__retvalue, MAXSTRINGLEN);
+ }
%}
%{
@@ -1779,7 +1796,7 @@ function _mmap_flags:string(flags:long)
# old mmap functions passed in a struct like this.
#
function get_mmap_args:string (args:long)
-%{
+%{ /* pure */
#if defined (__x86_64__) || defined (__ia64__)
struct mmap_arg_struct {
unsigned int addr;
diff --git a/tapset/context.stp b/tapset/context.stp
index dc560316..10c52226 100644
--- a/tapset/context.stp
+++ b/tapset/context.stp
@@ -136,6 +136,22 @@ function probemod:string () %{ /* pure */
}
%}
+function registers_valid:long () %{ /* pure */
+ THIS->__retvalue = (CONTEXT->regs != NULL);
+%}
+
+function user_mode:long () %{ /* pure */ /* currently a user-mode address? */
+ if (CONTEXT->regs) {
+#if defined(__i386__) || defined(__x86_64__)
+ THIS->__retvalue = (uint64_t) user_mode_vm (CONTEXT->regs);
+#else
+ THIS->__retvalue = (uint64_t) user_mode (CONTEXT->regs);
+#endif
+ } else {
+ THIS->__retvalue = 0;
+ }
+%}
+
function is_return:long () %{ /* pure */
if (CONTEXT->pi)
THIS->__retvalue = 1;
diff --git a/tapset/ctime.stp b/tapset/ctime.stp
index 96af4d47..d907c2db 100644
--- a/tapset/ctime.stp
+++ b/tapset/ctime.stp
@@ -41,7 +41,7 @@
*/
function ctime:string(epochsecs:long)
-%{
+%{ /* pure */
#define SECSPERMIN 60L
#define MINSPERHOUR 60L
diff --git a/tapset/dev.stp b/tapset/dev.stp
new file mode 100644
index 00000000..80449324
--- /dev/null
+++ b/tapset/dev.stp
@@ -0,0 +1,33 @@
+// Device numbering tapset
+// Copyright (C) 2008 Red Hat Corp.
+//
+// This file is part of systemtap, and is free software. You can
+// redistribute it and/or modify it under the terms of the GNU General
+// Public License (GPL); either version 2, or (at your option) any
+// later version.
+
+%{
+#include <linux/kdev_t.h>
+%}
+
+function MAJOR:long(dev:long)
+%{ /* pure */
+ THIS->__retvalue = MAJOR(THIS->dev);
+%}
+
+
+function MINOR:long(dev:long)
+%{ /* pure */
+ THIS->__retvalue = MINOR(THIS->dev);
+%}
+
+
+function MKDEV:long(major:long, minor:long)
+%{ /* pure */
+ THIS->__retvalue = MKDEV(THIS->major,THIS->minor);
+%}
+
+function usrdev2kerndev:long(dev:long)
+%{ /* pure */
+ THIS->__retvalue = new_decode_dev(THIS->dev);
+%}
diff --git a/tapset/i686/registers.stp b/tapset/i686/registers.stp
index db532f7a..c4c84814 100644
--- a/tapset/i686/registers.stp
+++ b/tapset/i686/registers.stp
@@ -1,4 +1,4 @@
-global _reg_offsets, _stp_regs_registered
+global _reg_offsets, _stp_regs_registered, _sp_offset, _ss_offset
function _stp_register_regs() {
/* Same order as pt_regs */
@@ -16,19 +16,21 @@ function _stp_register_regs() {
_reg_offsets["eip"] = 44 _reg_offsets["ip"] = 44
_reg_offsets["xcs"] = 48 _reg_offsets["cs"] = 48
_reg_offsets["eflags"] = 52 _reg_offsets["flags"] = 52
- _reg_offsets["esp"] = 56 _reg_offsets["sp"] = 56 sp_offset = 56
- _reg_offsets["xss"] = 60 _reg_offsets["ss"] = 60 ss_offset = 60
+ _reg_offsets["esp"] = 56 _reg_offsets["sp"] = 56
+ _reg_offsets["xss"] = 60 _reg_offsets["ss"] = 60
+ _sp_offset = 56
+ _ss_offset = 60
_stp_regs_registered = 1
}
-function _stp_get_register_by_offset:long (offset:long) %{
+function _stp_get_register_by_offset:long (offset:long) %{ /* pure */
long value;
memcpy(&value, ((char *)CONTEXT->regs) + THIS->offset, sizeof(value));
THIS->__retvalue = value;
%}
-function _stp_probing_kernel:long () %{
+function _stp_probing_kernel:long () %{ /* pure */
THIS->__retvalue = !user_mode(CONTEXT->regs);
%}
@@ -36,12 +38,12 @@ function _stp_probing_kernel:long () %{
* esp and ss aren't saved on a breakpoint in kernel mode, so
* the pre-trap stack pointer is &regs->sp.
*/
-function _stp_kernel_sp:long (sp_offset:long) %{
+function _stp_kernel_sp:long (sp_offset:long) %{ /* pure */
THIS->__retvalue = ((long) CONTEXT->regs) + THIS->sp_offset;
%}
/* Assume ss register hasn't changed since we took the trap. */
-function _stp_kernel_ss:long () %{
+function _stp_kernel_ss:long () %{ /* pure */
unsigned short ss;
asm volatile("movw %%ss, %0" : : "m" (ss));
THIS->__retvalue = ss;
@@ -49,6 +51,10 @@ function _stp_kernel_ss:long () %{
/* Return the named register value as a signed value. */
function register:long (name:string) {
+ if (!registers_valid()) {
+ error("cannot access CPU registers in this context")
+ return 0
+ }
if (!_stp_regs_registered)
_stp_register_regs()
offset = _reg_offsets[name]
@@ -57,9 +63,9 @@ function register:long (name:string) {
return 0
}
if (_stp_probing_kernel()) {
- if (offset == sp_offset)
- return _stp_kernel_sp(sp_offset)
- else if (offset == ss_offset)
+ if (offset == _sp_offset)
+ return _stp_kernel_sp(_sp_offset)
+ else if (offset == _ss_offset)
return _stp_kernel_ss()
}
return _stp_get_register_by_offset(offset)
@@ -74,7 +80,7 @@ function u_register:long (name:string) {
}
/* Return the value of function arg #argnum (1=first arg) as a signed value. */
-function _stp_arg:long (argnum:long) %{
+function _stp_arg:long (argnum:long) %{ /* pure */
long val;
int n, nr_regargs, result;
@@ -192,11 +198,15 @@ function fastcall() %{
CONTEXT->regparm = _STP_REGPARM | 3;
%}
-function regparm(n) %{
+function regparm(n:long) %{
if (THIS->n < 0 || THIS->n > 3) {
snprintf(CONTEXT->error_buffer, sizeof(CONTEXT->error_buffer),
"For i386, regparm value must be in the range 0-3.");
CONTEXT->last_error = CONTEXT->error_buffer;
} else
- CONTEXT->regparm = _STP_REGPARM | (int) n;
+ CONTEXT->regparm = _STP_REGPARM | (int) THIS->n;
%}
+
+function syscall_nr:long() {
+ return register("orig_ax")
+}
diff --git a/tapset/inet.stp b/tapset/inet.stp
index 0fdd4bab..8681fa2c 100644
--- a/tapset/inet.stp
+++ b/tapset/inet.stp
@@ -1,8 +1,8 @@
/* Some functions from libc <arpa/inet.h> */
-function htonll:long (x:long) %{ THIS->__retvalue = (int64_t) cpu_to_be64 ((u64) THIS->x); %}
-function htonl:long (x:long) %{ THIS->__retvalue = (int64_t) cpu_to_be32 ((u32) THIS->x); %}
-function htons:long (x:long) %{ THIS->__retvalue = (int64_t) cpu_to_be16 ((u16) THIS->x); %}
-function ntohll:long (x:long) %{ THIS->__retvalue = (int64_t) be64_to_cpu ((u64) THIS->x); %}
-function ntohl:long (x:long) %{ THIS->__retvalue = (int64_t) be32_to_cpu ((u32) THIS->x); %}
-function ntohs:long (x:long) %{ THIS->__retvalue = (int64_t) be16_to_cpu ((u16) THIS->x); %}
+function htonll:long (x:long) %{ /* pure */ THIS->__retvalue = (int64_t) cpu_to_be64 ((u64) THIS->x); %}
+function htonl:long (x:long) %{ /* pure */ THIS->__retvalue = (int64_t) cpu_to_be32 ((u32) THIS->x); %}
+function htons:long (x:long) %{ /* pure */ THIS->__retvalue = (int64_t) cpu_to_be16 ((u16) THIS->x); %}
+function ntohll:long (x:long) %{ /* pure */ THIS->__retvalue = (int64_t) be64_to_cpu ((u64) THIS->x); %}
+function ntohl:long (x:long) %{ /* pure */ THIS->__retvalue = (int64_t) be32_to_cpu ((u32) THIS->x); %}
+function ntohs:long (x:long) %{ /* pure */ THIS->__retvalue = (int64_t) be16_to_cpu ((u16) THIS->x); %}
diff --git a/tapset/memory.stp b/tapset/memory.stp
index 630e8984..a2d9cc19 100644
--- a/tapset/memory.stp
+++ b/tapset/memory.stp
@@ -46,8 +46,7 @@ probe vm.pagefault.return = kernel.function("__handle_mm_fault@mm/memory.c").ret
}
/* Return which node the given address belongs to in a NUMA system */
-function addr_to_node:long(addr:long) /* pure */
-%{
+function addr_to_node:long(addr:long) %{ /* pure */
int nid;
int pfn = __pa(THIS->addr) >> PAGE_SHIFT;
for_each_online_node(nid)
diff --git a/tapset/nd_syscalls.stp b/tapset/nd_syscalls.stp
index 5697cd21..5a258e75 100644
--- a/tapset/nd_syscalls.stp
+++ b/tapset/nd_syscalls.stp
@@ -46,7 +46,7 @@ probe nd_syscall.accept = kernel.function("sys_accept") ? {
asmlinkage()
sockfd = int_arg(1)
addr_uaddr = pointer_arg(2)
- addrlen_uaddr = int_arg(3)
+ addrlen_uaddr = pointer_arg(3)
argstr = sprintf("%d, %p, %p", sockfd, addr_uaddr, addrlen_uaddr)
}
probe nd_syscall.accept.return = kernel.function("sys_accept").return ? {
diff --git a/tapset/nfs.stp b/tapset/nfs.stp
index ba6bde5f..474b091f 100644
--- a/tapset/nfs.stp
+++ b/tapset/nfs.stp
@@ -305,9 +305,9 @@ probe nfs.fop.entries = nfs.fop.llseek,
nfs.fop.open,
nfs.fop.flush,
nfs.fop.release,
+ %( kernel_v <= "2.6.18" %? nfs.fop.sendfile, %)
nfs.fop.fsync,
- nfs.fop.lock,
- nfs.fop.sendfile
+ nfs.fop.lock
{
}
@@ -320,9 +320,9 @@ probe nfs.fop.return = nfs.fop.llseek.return,
nfs.fop.open.return,
nfs.fop.flush.return,
nfs.fop.release.return,
+ %( kernel_v <= "2.6.18" %? nfs.fop.sendfile.return, %)
nfs.fop.fsync.return,
- nfs.fop.lock.return,
- nfs.fop.sendfile.return
+ nfs.fop.lock.return
{
}
@@ -344,8 +344,8 @@ probe nfs.fop.return = nfs.fop.llseek.return,
* The offset is set to the size of the file plus offset bytes.
*
*/
-probe nfs.fop.llseek = kernel.function ("nfs_file_llseek") ?,
- module("nfs").function("nfs_file_llseek") ?
+probe nfs.fop.llseek = kernel.function ("nfs_file_llseek") !,
+ module("nfs").function("nfs_file_llseek")
{
dev = __file_dev($filp)
ino = __file_ino($filp)
@@ -360,8 +360,8 @@ probe nfs.fop.llseek = kernel.function ("nfs_file_llseek") ?,
argstr = sprintf("%d, %d", offset, origin)
}
-probe nfs.fop.llseek.return = kernel.function ("nfs_file_llseek").return ?,
- module("nfs").function("nfs_file_llseek").return ?
+probe nfs.fop.llseek.return = kernel.function ("nfs_file_llseek").return !,
+ module("nfs").function("nfs_file_llseek").return
{
name = "nfs.fop.llseek.return"
retstr = sprintf("%d", $return)
@@ -429,8 +429,8 @@ probe nfs.fop.write.return = vfs.do_sync_write.return
*
* jiffies - read_cache_jiffies > attrtimeo
*/
-probe nfs.fop.aio_read = kernel.function ("nfs_file_read") ?,
- module("nfs").function("nfs_file_read") ?
+probe nfs.fop.aio_read = kernel.function ("nfs_file_read") !,
+ module("nfs").function("nfs_file_read")
{
dev = __file_dev($iocb->ki_filp)
ino = __file_ino($iocb->ki_filp)
@@ -464,8 +464,8 @@ probe nfs.fop.aio_read = kernel.function ("nfs_file_read") ?,
}
-probe nfs.fop.aio_read.return = kernel.function ("nfs_file_read").return ?,
- module("nfs").function("nfs_file_read").return ?
+probe nfs.fop.aio_read.return = kernel.function ("nfs_file_read").return !,
+ module("nfs").function("nfs_file_read").return
{
name = "nfs.fop.aio_read.return"
retstr = sprintf("%d", $return)
@@ -490,8 +490,8 @@ probe nfs.fop.aio_read.return = kernel.function ("nfs_file_read").return ?,
* file_name : file name
*
*/
-probe nfs.fop.aio_write = kernel.function("nfs_file_write") ?,
- module("nfs").function("nfs_file_write") ?
+probe nfs.fop.aio_write = kernel.function("nfs_file_write") !,
+ module("nfs").function("nfs_file_write")
{
dev = __file_dev($iocb->ki_filp)
ino = __file_ino($iocb->ki_filp)
@@ -517,8 +517,8 @@ probe nfs.fop.aio_write = kernel.function("nfs_file_write") ?,
units = "bytes"
}
-probe nfs.fop.aio_write.return = kernel.function("nfs_file_write").return ?,
- module("nfs").function("nfs_file_write").return ?
+probe nfs.fop.aio_write.return = kernel.function("nfs_file_write").return !,
+ module("nfs").function("nfs_file_write").return
{
name = "nfs.fop.aio_write.return"
retstr = sprintf("%d", $return)
@@ -551,8 +551,8 @@ probe nfs.fop.aio_write.return = kernel.function("nfs_file_write").return ?,
*
* jiffies - read_cache_jiffies > attrtimeo
*/
-probe nfs.fop.mmap = kernel.function("nfs_file_mmap") ?,
- module("nfs").function("nfs_file_mmap") ?
+probe nfs.fop.mmap = kernel.function("nfs_file_mmap") !,
+ module("nfs").function("nfs_file_mmap")
{
dev = __file_dev($file)
ino = __file_ino($file)
@@ -574,8 +574,8 @@ probe nfs.fop.mmap = kernel.function("nfs_file_mmap") ?,
argstr = sprintf("0x%x, 0x%x, 0x%x", vm_start, vm_end, vm_flags)
}
-probe nfs.fop.mmap.return = kernel.function("nfs_file_mmap").return ?,
- module("nfs").function("nfs_file_mmap").return ?
+probe nfs.fop.mmap.return = kernel.function("nfs_file_mmap").return !,
+ module("nfs").function("nfs_file_mmap").return
{
name = "nfs.fop.mmap.return"
retstr = sprintf("%d", $return)
@@ -593,8 +593,8 @@ probe nfs.fop.mmap.return = kernel.function("nfs_file_mmap").return ?,
* flag : file flag
* i_size : file length in bytes
*/
-probe nfs.fop.open = kernel.function("nfs_file_open") ?,
- module("nfs").function("nfs_file_open") ?
+probe nfs.fop.open = kernel.function("nfs_file_open") !,
+ module("nfs").function("nfs_file_open")
{
dev = __file_dev($filp)
ino = $inode->i_ino
@@ -610,8 +610,8 @@ probe nfs.fop.open = kernel.function("nfs_file_open") ?,
argstr = sprintf("%d,%d, %s", flag, ino, filename)
}
-probe nfs.fop.open.return = kernel.function("nfs_file_open").return ?,
- module("nfs").function("nfs_file_open").return ?
+probe nfs.fop.open.return = kernel.function("nfs_file_open").return !,
+ module("nfs").function("nfs_file_open").return
{
name = "nfs.fop.open.return"
retstr = sprintf("%d", $return)
@@ -628,8 +628,8 @@ probe nfs.fop.open.return = kernel.function("nfs_file_open").return ?,
* mode : file mode
* ndirty : number of dirty page
*/
-probe nfs.fop.flush = kernel.function("nfs_file_flush") ?,
- module("nfs").function("nfs_file_flush") ?
+probe nfs.fop.flush = kernel.function("nfs_file_flush") !,
+ module("nfs").function("nfs_file_flush")
{
dev = __file_dev($file)
ino = __file_ino($file)
@@ -643,8 +643,8 @@ probe nfs.fop.flush = kernel.function("nfs_file_flush") ?,
argstr = sprintf("%d",ino)
}
-probe nfs.fop.flush.return = kernel.function("nfs_file_flush").return ?,
- module("nfs").function("nfs_file_flush").return ?
+probe nfs.fop.flush.return = kernel.function("nfs_file_flush").return !,
+ module("nfs").function("nfs_file_flush").return
{
name = "nfs.fop.flush.return"
retstr = sprintf("%d",$return)
@@ -660,8 +660,8 @@ probe nfs.fop.flush.return = kernel.function("nfs_file_flush").return ?,
* ino : inode number
* mode : file mode
*/
-probe nfs.fop.release = kernel.function("nfs_file_release") ?,
- module("nfs").function("nfs_file_release") ?
+probe nfs.fop.release = kernel.function("nfs_file_release") !,
+ module("nfs").function("nfs_file_release")
{
dev = __file_dev($filp)
ino = $inode->i_ino
@@ -674,8 +674,8 @@ probe nfs.fop.release = kernel.function("nfs_file_release") ?,
argstr = sprintf("%d" , ino)
}
-probe nfs.fop.release.return = kernel.function("nfs_file_release").return ?,
- module("nfs").function("nfs_file_release").return ?
+probe nfs.fop.release.return = kernel.function("nfs_file_release").return !,
+ module("nfs").function("nfs_file_release").return
{
name = "nfs.fop.release.return"
retstr = sprintf("%d", $return)
@@ -691,8 +691,8 @@ probe nfs.fop.release.return = kernel.function("nfs_file_release").return ?,
* ino : inode number
* ndirty : number of dirty pages
*/
-probe nfs.fop.fsync = kernel.function("nfs_fsync") ?,
- module("nfs").function("nfs_fsync") ?
+probe nfs.fop.fsync = kernel.function("nfs_fsync") !,
+ module("nfs").function("nfs_fsync")
{
dev = __file_dev($file)
ino = __file_ino($file)
@@ -705,8 +705,8 @@ probe nfs.fop.fsync = kernel.function("nfs_fsync") ?,
argstr = sprintf("%d",ino)
}
-probe nfs.fop.fsync.return = kernel.function("nfs_fsync").return ?,
- module("nfs").function("nfs_fsync").return ?
+probe nfs.fop.fsync.return = kernel.function("nfs_fsync").return !,
+ module("nfs").function("nfs_fsync").return
{
name = "nfs.fop.fsync.return"
retstr = sprintf("%d", $return)
@@ -727,8 +727,8 @@ probe nfs.fop.fsync.return = kernel.function("nfs_fsync").return ?,
* fl_start : starting offset of locked region
* fl_end : ending offset of locked region
*/
-probe nfs.fop.lock = kernel.function("nfs_lock") ?,
- module("nfs").function("nfs_lock") ?
+probe nfs.fop.lock = kernel.function("nfs_lock") !,
+ module("nfs").function("nfs_lock")
{
dev = __file_dev($filp)
ino = __file_ino($filp)
@@ -747,8 +747,8 @@ probe nfs.fop.lock = kernel.function("nfs_lock") ?,
argstr = sprintf("%d,%d",cmd,i_mode)
}
-probe nfs.fop.lock.return = kernel.function("nfs_lock").return ?,
- module("nfs").function("nfs_lock").return ?
+probe nfs.fop.lock.return = kernel.function("nfs_lock").return !,
+ module("nfs").function("nfs_lock").return
{
name = "nfs.fop.lock.return"
retstr = sprintf("%d",$return)
@@ -773,8 +773,9 @@ probe nfs.fop.lock.return = kernel.function("nfs_lock").return ?,
*
* jiffies - read_cache_jiffies > attrtimeo
*/
-probe nfs.fop.sendfile = kernel.function("nfs_file_sendfile") ?,
- module("nfs").function("nfs_file_sendfile") ?
+%( kernel_v <= "2.6.18" %?
+probe nfs.fop.sendfile = kernel.function("nfs_file_sendfile") !,
+ module("nfs").function("nfs_file_sendfile")
{
dev = __file_dev($filp)
@@ -796,8 +797,8 @@ probe nfs.fop.sendfile = kernel.function("nfs_file_sendfile") ?,
units = "bytes"
}
-probe nfs.fop.sendfile.return = kernel.function("nfs_file_sendfile").return ?,
- module("nfs").function("nfs_file_sendfile").return ?
+probe nfs.fop.sendfile.return = kernel.function("nfs_file_sendfile").return !,
+ module("nfs").function("nfs_file_sendfile").return
{
name = "nfs.fop.sendfile.return"
retstr = sprintf("%d", $return)
@@ -807,6 +808,7 @@ probe nfs.fop.sendfile.return = kernel.function("nfs_file_sendfile").return ?,
units = "bytes"
}
}
+%)
/*probe nfs.fop.check_flags
*
@@ -816,8 +818,8 @@ probe nfs.fop.sendfile.return = kernel.function("nfs_file_sendfile").return ?,
* Arguments:
* flag : file flag
*/
-probe nfs.fop.check_flags = kernel.function("nfs_check_flags") ?,
- module("nfs").function("nfs_check_flags") ?
+probe nfs.fop.check_flags = kernel.function("nfs_check_flags") !,
+ module("nfs").function("nfs_check_flags")
{
flag = $flags
@@ -825,8 +827,8 @@ probe nfs.fop.check_flags = kernel.function("nfs_check_flags") ?,
argstr = sprintf("%d",flag)
}
-probe nfs.fop.check_flags.return = kernel.function("nfs_check_flags").return ?,
- module("nfs").function("nfs_check_flags").return ?
+probe nfs.fop.check_flags.return = kernel.function("nfs_check_flags").return !,
+ module("nfs").function("nfs_check_flags").return
{
name = "nfs.fop.check_flags.return"
retstr = sprintf("%d",$return)
@@ -871,8 +873,8 @@ probe nfs.aop.return = nfs.aop.readpage.return,
* rsize : read size (in bytes)
* size : number of pages to be read in this execution
*/
-probe nfs.aop.readpage = kernel.function ("nfs_readpage") ?,
- module("nfs").function ("nfs_readpage") ?
+probe nfs.aop.readpage = kernel.function ("nfs_readpage") !,
+ module("nfs").function ("nfs_readpage")
{
__page = $page
dev = __page_dev(__page)
@@ -896,8 +898,8 @@ probe nfs.aop.readpage = kernel.function ("nfs_readpage") ?,
units = "pages"
}
-probe nfs.aop.readpage.return = kernel.function ("nfs_readpage").return ?,
- module("nfs").function ("nfs_readpage").return ?
+probe nfs.aop.readpage.return = kernel.function ("nfs_readpage").return !,
+ module("nfs").function ("nfs_readpage").return
{
name = "nfs.aop.readpage.return"
retstr = sprintf("%d", $return)
@@ -918,8 +920,8 @@ probe nfs.aop.readpage.return = kernel.function ("nfs_readpage").return ?,
* rsize : read size (in bytes)
* size : number of pages attempted to read in this execution
*/
-probe nfs.aop.readpages = kernel.function ("nfs_readpages") ?,
- module("nfs").function ("nfs_readpages") ?
+probe nfs.aop.readpages = kernel.function ("nfs_readpages") !,
+ module("nfs").function ("nfs_readpages")
{
dev = $mapping->host->i_sb->s_dev
ino = $mapping->host->i_ino
@@ -937,8 +939,8 @@ probe nfs.aop.readpages = kernel.function ("nfs_readpages") ?,
units = "pages"
}
-probe nfs.aop.readpages.return = kernel.function ("nfs_readpages").return ?,
- module("nfs").function ("nfs_readpages").return ?
+probe nfs.aop.readpages.return = kernel.function ("nfs_readpages").return !,
+ module("nfs").function ("nfs_readpages").return
{
name = "nfs.aop.readpages.return"
retstr = sprintf("%d", $return)
@@ -960,8 +962,8 @@ probe nfs.aop.readpages.return = kernel.function ("nfs_readpages").return ?,
* page_flag : page flags
*/
probe nfs.aop.set_page_dirty =
- kernel.function ("__set_page_dirty_nobuffers") ?,
- module("nfs").function ("__set_page_dirty_nobuffers") ?
+ kernel.function ("__set_page_dirty_nobuffers") !,
+ module("nfs").function ("__set_page_dirty_nobuffers")
{
/* dev = $mapping->host->i_sb->s_dev
devname = __find_bdevname(dev, $mapping->host->i_sb->s_bdev)
@@ -975,8 +977,8 @@ probe nfs.aop.set_page_dirty =
}
probe nfs.aop.set_page_dirty.return =
- kernel.function ("__set_page_dirty_nobuffers") .return?,
- module("nfs").function ("__set_page_dirty_nobuffers").return ?
+ kernel.function ("__set_page_dirty_nobuffers") .return !,
+ module("nfs").function ("__set_page_dirty_nobuffers").return
{
name = "nfs.aop.set_page_dirty.return"
retstr = sprintf("%d", $return)
@@ -1003,8 +1005,8 @@ probe nfs.aop.set_page_dirty.return =
* wsize : write size
* size : number of pages to be written in this execution
*/
-probe nfs.aop.writepage = kernel.function ("nfs_writepage") ?,
- module("nfs").function ("nfs_writepage") ?
+probe nfs.aop.writepage = kernel.function ("nfs_writepage") !,
+ module("nfs").function ("nfs_writepage")
{
__page = $page
dev = __page_dev(__page)
@@ -1033,8 +1035,8 @@ probe nfs.aop.writepage = kernel.function ("nfs_writepage") ?,
units = "pages"
}
-probe nfs.aop.writepage.return = kernel.function ("nfs_writepage").return ?,
- module("nfs").function ("nfs_writepage").return ?
+probe nfs.aop.writepage.return = kernel.function ("nfs_writepage").return !,
+ module("nfs").function ("nfs_writepage").return
{
name = "nfs.aop.writepage.return"
retstr = sprintf("%d", $return)
@@ -1053,8 +1055,8 @@ probe nfs.aop.writepage.return = kernel.function ("nfs_writepage").return ?,
* nr_to_write : number of pages attempted to be written in this execution
* size : number of pages attempted to be written in this execution
*/
-probe nfs.aop.writepages = kernel.function ("nfs_writepages") ?,
- module("nfs").function ("nfs_writepages") ?
+probe nfs.aop.writepages = kernel.function ("nfs_writepages") !,
+ module("nfs").function ("nfs_writepages")
{
dev = $mapping->host->i_sb->s_dev
ino = $mapping->host->i_ino
@@ -1073,8 +1075,8 @@ probe nfs.aop.writepages = kernel.function ("nfs_writepages") ?,
units = "pages"
}
-probe nfs.aop.writepages.return = kernel.function ("nfs_writepages").return ?,
- module("nfs").function ("nfs_writepages").return ?
+probe nfs.aop.writepages.return = kernel.function ("nfs_writepages").return !,
+ module("nfs").function ("nfs_writepages").return
{
name = "nfs.aop.writepages.return"
retstr = sprintf("%d", $return)
@@ -1099,8 +1101,8 @@ probe nfs.aop.writepages.return = kernel.function ("nfs_writepages").return ?,
in the page frame
* size : write bytes
*/
-probe nfs.aop.prepare_write= kernel.function ("nfs_prepare_write") ?,
- module("nfs").function ("nfs_prepare_write") ?
+probe nfs.aop.prepare_write= kernel.function ("nfs_prepare_write") !,
+ module("nfs").function ("nfs_prepare_write")
{
__page = $page
dev = __page_dev(__page)
@@ -1120,8 +1122,8 @@ probe nfs.aop.prepare_write= kernel.function ("nfs_prepare_write") ?,
}
probe nfs.aop.prepare_write.return =
- kernel.function ("nfs_prepare_write").return ?,
- module("nfs").function ("nfs_prepare_write").return ?
+ kernel.function ("nfs_prepare_write").return !,
+ module("nfs").function ("nfs_prepare_write").return
{
name = "nfs.aop.prepare_write.return"
retstr = sprintf("%d", $return)
@@ -1147,8 +1149,8 @@ probe nfs.aop.prepare_write.return =
in the page frame
* size : write bytes
*/
-probe nfs.aop.commit_write= kernel.function ("nfs_commit_write") ?,
- module("nfs").function ("nfs_commit_write") ?
+probe nfs.aop.commit_write= kernel.function ("nfs_commit_write") !,
+ module("nfs").function ("nfs_commit_write")
{
__page = $page
dev = __page_dev(__page)
@@ -1174,8 +1176,8 @@ probe nfs.aop.commit_write= kernel.function ("nfs_commit_write") ?,
probe nfs.aop.commit_write.return=
- kernel.function ("nfs_commit_write").return ?,
- module("nfs").function ("nfs_commit_write").return?
+ kernel.function ("nfs_commit_write").return !,
+ module("nfs").function ("nfs_commit_write").return
{
name = "nfs.aop.commit_write.return"
retstr = sprintf("%d", $return)
@@ -1194,8 +1196,8 @@ probe nfs.aop.commit_write.return=
in the page frame
* size : release pages
*/
-probe nfs.aop.release_page = kernel.function ("nfs_release_page") ?,
- module("nfs").function ("nfs_release_page")?
+probe nfs.aop.release_page = kernel.function ("nfs_release_page") !,
+ module("nfs").function ("nfs_release_page")
{
__page = $page
dev = __page_dev(__page)
@@ -1212,8 +1214,8 @@ probe nfs.aop.release_page = kernel.function ("nfs_release_page") ?,
}
-probe nfs.aop.release_page.return = kernel.function ("nfs_release_page").return ?,
- module("nfs").function ("nfs_release_page").return?
+probe nfs.aop.release_page.return = kernel.function ("nfs_release_page").return !,
+ module("nfs").function ("nfs_release_page").return
{
name = "nfs.aop.release_page.return"
retstr = sprintf("%d", $return)
diff --git a/tapset/nfs_proc.stp b/tapset/nfs_proc.stp
index 2dc7e659..6ffdf646 100644
--- a/tapset/nfs_proc.stp
+++ b/tapset/nfs_proc.stp
@@ -559,6 +559,9 @@ probe nfs.proc.commit.return = nfs.proc3.commit.return,
nfs.proc4.commit.return
{}
+// XXX: on kernels > 2.6.18 (?), module("nfs") -> module("nfsd") and
+// function("nfsN...") becomes function("nfsdN..."). PR3833.
+
probe nfs.proc3.commit = kernel.function ("nfs3_proc_commit")?,
module("nfs").function("nfs3_proc_commit")?
{
diff --git a/tapset/ppc64/registers.stp b/tapset/ppc64/registers.stp
index d3605c05..6a8ae279 100644
--- a/tapset/ppc64/registers.stp
+++ b/tapset/ppc64/registers.stp
@@ -58,7 +58,11 @@ function _stp_register_regs() {
_stp_regs_registered = 1
}
-function _stp_get_register_by_offset:long (offset:long) %{
+function probing_32bit_app() %{ /* pure */
+ THIS->__retvalue = _stp_probing_32bit_app(CONTEXT->regs);
+%}
+
+function _stp_get_register_by_offset:long (offset:long) %{ /* pure */
long value;
memcpy(&value, ((char *)CONTEXT->regs) + THIS->offset, sizeof(value));
THIS->__retvalue = value;
@@ -70,14 +74,11 @@ function _stp_sign_extend32:long (value:long) {
return value
}
-function _stp_probing_32bit_app() %{
- if (!(CONTEXT->regs))
- return 0;
- return (user_mode(CONTEXT->regs) &&
- test_tsk_thread_flag(current, TIF_32BIT));
-%}
-
function _stp_register:long (name:string, sign_extend:long) {
+ if (!registers_valid()) {
+ error("cannot access CPU registers in this context")
+ return 0
+ }
if (!_stp_regs_registered)
_stp_register_regs()
offset = _reg_offsets[name]
@@ -86,7 +87,7 @@ function _stp_register:long (name:string, sign_extend:long) {
return 0
}
value = _stp_get_register_by_offset(offset)
- if (_stp_probing_32bit_app()) {
+ if (probing_32bit_app()) {
if (sign_extend)
value = _stp_sign_extend32(value)
else
@@ -114,66 +115,39 @@ function u_register:long (name:string) {
* If sign_extend=1 and (truncate=1 or the probepoint we've hit is in a
* 32-bit app), sign-extend the 32-bit value.
*/
-function _stp_arg:long (argnum:long, sign_extend:long, truncate:long) %{
- long val;
- int n;
- size_t argsz = sizeof(long);
-
- THIS->__retvalue = 0;
- if (!CONTEXT->regs) {
- snprintf(CONTEXT->error_buffer, sizeof(CONTEXT->error_buffer),
- "cannot access function args in this context");
- CONTEXT->last_error = CONTEXT->error_buffer;
- return;
- }
- if (THIS->argnum < 1)
- goto bad_argnum;
- n = (int) THIS->argnum;
-
- switch (n) {
- case 1:
- val = u_register("r3");
- break;
- case 2:
- val = u_register("r4");
- break;
- case 3:
- val = u_register("r5");
- break;
- case 4:
- val = u_register("r6");
- break;
- case 5:
- val = u_register("r7");
- break;
- case 6:
- val = u_register("r8");
- break;
- case 7:
- val = u_register("r9");
- break;
- case 8:
- val = u_register("r10");
- break;
- default:
- goto bad_argnum;
+function _stp_arg:long (argnum:long, sign_extend:long, truncate:long) {
+ val = 0
+ if (argnum < 1 || argnum > 8) {
+ error(sprintf("Cannot access arg(%d)", argnum))
+ return 0
}
- if (THIS->truncate || argsz == sizeof(int)) {
- if (THIS->sign_extend)
- THIS->__retvalue = (int64_t) _stp_sign_extend32(val);
+
+ if (argnum == 1)
+ val = u_register("r3")
+ else if (argnum == 2)
+ val = u_register("r4")
+ else if (argnum == 3)
+ val = u_register("r5")
+ else if (argnum == 4)
+ val = u_register("r6")
+ else if (argnum == 5)
+ val = u_register("r7")
+ else if (argnum == 6)
+ val = u_register("r8")
+ else if (argnum == 7)
+ val = u_register("r9")
+ else (argnum == 8)
+ val = u_register("r10")
+
+ if (truncate) {
+ if (sign_extend)
+ val = _stp_sign_extend32(val)
else
/* High bits may be garbage. */
- THIS->__retvalue = (int64_t) (val & 0xffffffff);
- } else
- THIS->__retvalue = (int64_t) val;
- return;
-
-bad_argnum:
- snprintf(CONTEXT->error_buffer, sizeof(CONTEXT->error_buffer),
- "cannot access arg(%lld)", THIS->argnum);
- CONTEXT->last_error = CONTEXT->error_buffer;
- return;
-%}
+ val = (val & 0xffffffff);
+ }
+ return val;
+}
/* Return the value of function arg #argnum (1=first arg) as a signed int. */
function int_arg:long (argnum:long) {
@@ -194,7 +168,7 @@ function ulong_arg:long (argnum:long) {
}
function longlong_arg:long (argnum:long) {
- if (_stp_probing_32bit_app()) {
+ if (probing_32bit_app()) {
lowbits = _stp_arg(argnum, 0, 1)
highbits = _stp_arg(argnum+1, 0, 1)
return ((highbits << 32) | lowbits)
diff --git a/tapset/rpc.stp b/tapset/rpc.stp
index 537bf348..f97117b5 100644
--- a/tapset/rpc.stp
+++ b/tapset/rpc.stp
@@ -1,6 +1,7 @@
// rpc tapset
// Copyright (C) 2006 IBM Corp.
// Copyright (C) 2007 Bull S.A.S
+// Copyright (C) 2008 Red Hat
//
// This file is part of systemtap, and is free software. You can
// redistribute it and/or modify it under the terms of the GNU General
@@ -79,8 +80,9 @@ probe sunrpc.clnt.create_client = _sunrpc.clnt.create_client.*
prog, vers, prot, port, authflavor)
}
-probe _sunrpc.clnt.create_client.part1 = kernel.function("rpc_create_client") ?,
- module("sunrpc").function("rpc_create_client") ?
+%( kernel_v <= "2.6.18" %?
+probe _sunrpc.clnt.create_client.part1 = kernel.function("rpc_create_client") !,
+ module("sunrpc").function("rpc_create_client")
{
name = "sunrpc.clnt.create_client"
%( kernel_v >= "2.6.10" %?
@@ -95,9 +97,10 @@ probe _sunrpc.clnt.create_client.part1 = kernel.function("rpc_create_client") ?,
authflavor = $flavor
%)
}
+%)
-probe _sunrpc.clnt.create_client.part2 = kernel.function("rpc_new_client") ?,
- module("sunrpc").function("rpc_new_client") ?
+probe _sunrpc.clnt.create_client.part2 = kernel.function("rpc_new_client") !,
+ module("sunrpc").function("rpc_new_client")
{
name = "sunrpc.clnt.new_client"
progname = kernel_string($program->name)
@@ -106,21 +109,23 @@ probe _sunrpc.clnt.create_client.part2 = kernel.function("rpc_new_client") ?,
authflavor = $flavor
}
-probe sunrpc.clnt.create_client.return = _sunrpc.clnt.create_client.return.*
+probe sunrpc.clnt.create_client.return = _sunrpc.clnt.create_client.return.*
{
retstr = returnstr(2)
}
+%( kernel_v <= "2.6.18" %?
probe _sunrpc.clnt.create_client.return.part1 =
- kernel.function("rpc_create_client").return ?,
- module("sunrpc").function("rpc_create_client").return ?
+ kernel.function("rpc_create_client").return !,
+ module("sunrpc").function("rpc_create_client").return
{
name = "sunrpc.clnt.create_client.return"
}
+%)
probe _sunrpc.clnt.create_client.return.part2 =
- kernel.function("rpc_new_client").return ?,
- module("sunrpc").function("rpc_new_client").return ?
+ kernel.function("rpc_new_client").return !,
+ module("sunrpc").function("rpc_new_client").return
{
name = "sunrpc.clnt.new_client.return"
}
@@ -138,8 +143,8 @@ probe _sunrpc.clnt.create_client.return.part2 =
* @port: the port number
* @authflavor: the authentication flavor
*/
-probe sunrpc.clnt.clone_client = kernel.function("rpc_clone_client") ?,
- module("sunrpc").function("rpc_clone_client") ?
+probe sunrpc.clnt.clone_client = kernel.function("rpc_clone_client") !,
+ module("sunrpc").function("rpc_clone_client")
{
servername = kernel_string($clnt->cl_server)
progname = kernel_string($clnt->cl_protname)
@@ -155,8 +160,8 @@ probe sunrpc.clnt.clone_client = kernel.function("rpc_clone_client") ?,
}
probe sunrpc.clnt.clone_client.return =
- kernel.function("rpc_clone_client").return ?,
- module("sunrpc").function("rpc_clone_client").return ?
+ kernel.function("rpc_clone_client").return !,
+ module("sunrpc").function("rpc_clone_client").return
{
name = "sunrpc.clnt.clone_client.return"
retstr = returnstr(2)
@@ -188,8 +193,8 @@ probe sunrpc.clnt.clone_client.return =
* @om_rtt: the RPC RTT jiffies
* @om_execute: the RPC execution jiffies
*/
-probe sunrpc.clnt.shutdown_client = kernel.function("rpc_shutdown_client") ?,
- module("sunrpc").function("rpc_shutdown_client") ?
+probe sunrpc.clnt.shutdown_client = kernel.function("rpc_shutdown_client") !,
+ module("sunrpc").function("rpc_shutdown_client")
{
servername = kernel_string($clnt->cl_server)
progname = kernel_string($clnt->cl_protname)
@@ -220,8 +225,8 @@ probe sunrpc.clnt.shutdown_client = kernel.function("rpc_shutdown_client") ?,
}
probe sunrpc.clnt.shutdown_client.return =
- kernel.function("rpc_shutdown_client").return ?,
- module("sunrpc").function("rpc_shutdown_client").return ?
+ kernel.function("rpc_shutdown_client").return !,
+ module("sunrpc").function("rpc_shutdown_client").return
{
name = "sunrpc.clnt.shutdown_client.return"
retstr = returnstr(1)
@@ -242,8 +247,8 @@ probe sunrpc.clnt.shutdown_client.return =
* @vers: the version of new RPC program
*/
probe sunrpc.clnt.bind_new_program =
- kernel.function("rpc_bind_new_program") ?,
- module("sunrpc").function("rpc_bind_new_program") ?
+ kernel.function("rpc_bind_new_program") !,
+ module("sunrpc").function("rpc_bind_new_program")
{
servername = kernel_string($old->cl_server)
old_progname = kernel_string($old->cl_protname)
@@ -259,8 +264,8 @@ probe sunrpc.clnt.bind_new_program =
}
probe sunrpc.clnt.bind_new_program.return =
- kernel.function("rpc_bind_new_program").return ?,
- module("sunrpc").function("rpc_bind_new_program").return ?
+ kernel.function("rpc_bind_new_program").return !,
+ module("sunrpc").function("rpc_bind_new_program").return
{
name = "sunrpc.clnt.bind_new_program.return"
retstr = returnstr(2)
@@ -282,8 +287,8 @@ probe sunrpc.clnt.bind_new_program.return =
* @proc: the procedure number in this RPC call
* @flags: flags
*/
-probe sunrpc.clnt.call_sync = kernel.function("rpc_call_sync") ?,
- module("sunrpc").function("rpc_call_sync") ?
+probe sunrpc.clnt.call_sync = kernel.function("rpc_call_sync") !,
+ module("sunrpc").function("rpc_call_sync")
{
servername = kernel_string($clnt->cl_server)
progname = kernel_string($clnt->cl_protname)
@@ -306,8 +311,8 @@ probe sunrpc.clnt.call_sync = kernel.function("rpc_call_sync") ?,
vers, procname, flags)
}
-probe sunrpc.clnt.call_sync.return = kernel.function("rpc_call_sync").return ?,
- module("sunrpc").function("rpc_call_sync").return ?
+probe sunrpc.clnt.call_sync.return = kernel.function("rpc_call_sync").return !,
+ module("sunrpc").function("rpc_call_sync").return
{
name = "sunrpc.clnt.call_sync.return"
retstr = returnstr(1)
@@ -329,8 +334,8 @@ probe sunrpc.clnt.call_sync.return = kernel.function("rpc_call_sync").return ?,
* @proc: the procedure number in this RPC call
* @flags: flags
*/
-probe sunrpc.clnt.call_async = kernel.function("rpc_call_async") ?,
- module("sunrpc").function("rpc_call_async") ?
+probe sunrpc.clnt.call_async = kernel.function("rpc_call_async") !,
+ module("sunrpc").function("rpc_call_async")
{
servername = kernel_string($clnt->cl_server)
progname = kernel_string($clnt->cl_protname)
@@ -354,8 +359,8 @@ probe sunrpc.clnt.call_async = kernel.function("rpc_call_async") ?,
}
probe sunrpc.clnt.call_async.return =
- kernel.function("rpc_call_async").return ?,
- module("sunrpc").function("rpc_call_async").return ?
+ kernel.function("rpc_call_async").return !,
+ module("sunrpc").function("rpc_call_async").return
{
name = "sunrpc.clnt.call_async.return"
retstr = returnstr(1)
@@ -374,8 +379,8 @@ probe sunrpc.clnt.call_async.return =
* @tk_priority: the task priority
* @tk_runstate: the task run status
*/
-probe sunrpc.clnt.restart_call = kernel.function("rpc_restart_call") ?,
- module("sunrpc").function("rpc_restart_call") ?
+probe sunrpc.clnt.restart_call = kernel.function("rpc_restart_call") !,
+ module("sunrpc").function("rpc_restart_call")
{
servername = kernel_string($task->tk_client->cl_server)
prog = prog_from_clnt($task->tk_client)
@@ -391,8 +396,8 @@ probe sunrpc.clnt.restart_call = kernel.function("rpc_restart_call") ?,
}
probe sunrpc.clnt.restart_call.return =
- kernel.function("rpc_restart_call").return ?,
- module("sunrpc").function("rpc_restart_call").return ?
+ kernel.function("rpc_restart_call").return !,
+ module("sunrpc").function("rpc_restart_call").return
{
name = "sunrpc.clnt.restart_call.return"
}
@@ -434,8 +439,8 @@ probe sunrpc.svc.return =
* @prot: the IP protocol number
* @port: the port number
*/
-probe sunrpc.svc.register = kernel.function("svc_register") ?,
- module("sunrpc").function("svc_register") ?
+probe sunrpc.svc.register = kernel.function("svc_register") !,
+ module("sunrpc").function("svc_register")
{
sv_name = kernel_string($serv->sv_name)
progname = kernel_string($serv->sv_program->pg_name)
@@ -447,8 +452,8 @@ probe sunrpc.svc.register = kernel.function("svc_register") ?,
argstr = sprintf("%s %s %d %d", sv_name, progname, prot, port)
}
-probe sunrpc.svc.register.return = kernel.function("svc_register").return ?,
- module("sunrpc").function("svc_register").return ?
+probe sunrpc.svc.register.return = kernel.function("svc_register").return !,
+ module("sunrpc").function("svc_register").return
{
name = "sunrpc.svc.register.return"
retstr = returnstr(1)
@@ -465,8 +470,8 @@ probe sunrpc.svc.register.return = kernel.function("svc_register").return ?,
* @pg_nvers: the number of supported versions
* @bufsize: the buffer size
*/
-probe sunrpc.svc.create = kernel.function("svc_create") ?,
- module("sunrpc").function("svc_create") ?
+probe sunrpc.svc.create = kernel.function("svc_create") !,
+ module("sunrpc").function("svc_create")
{
progname = kernel_string($prog->pg_name)
prog = $prog->pg_prog
@@ -477,8 +482,8 @@ probe sunrpc.svc.create = kernel.function("svc_create") ?,
argstr = sprintf("%s %d %d %d", progname, prog, pg_nvers, bufsize)
}
-probe sunrpc.svc.create.return = kernel.function("svc_create").return ?,
- module("sunrpc").function("svc_create").return ?
+probe sunrpc.svc.create.return = kernel.function("svc_create").return !,
+ module("sunrpc").function("svc_create").return
{
name = "sunrpc.svc.create.return"
retstr = returnstr(2)
@@ -499,8 +504,8 @@ probe sunrpc.svc.create.return = kernel.function("svc_create").return ?,
* @rpcbadfmt: the count of requests dropped for bad formats
* @rpcbadauth: the count of requests drooped for authentication failure
*/
-probe sunrpc.svc.destroy = kernel.function("svc_destroy") ?,
- module("sunrpc").function("svc_destroy") ?
+probe sunrpc.svc.destroy = kernel.function("svc_destroy") !,
+ module("sunrpc").function("svc_destroy")
{
sv_name = kernel_string($serv->sv_name) /* service name */
sv_progname = kernel_string($serv->sv_program->pg_name)
@@ -518,8 +523,8 @@ probe sunrpc.svc.destroy = kernel.function("svc_destroy") ?,
argstr = sprintf("%s %d %d", sv_name, sv_prog, sv_nrthreads)
}
-probe sunrpc.svc.destroy.return = kernel.function("svc_destroy").return ?,
- module("sunrpc").function("svc_destroy").return ?
+probe sunrpc.svc.destroy.return = kernel.function("svc_destroy").return !,
+ module("sunrpc").function("svc_destroy").return
{
name = "sunrpc.svc.destroy.return"
}
@@ -539,8 +544,8 @@ probe sunrpc.svc.destroy.return = kernel.function("svc_destroy").return ?,
* @rq_proc: the procedure number in the request
* @rq_prot: the IP protocol of the reqeust
*/
-probe sunrpc.svc.process = kernel.function("svc_process") ?,
- module("sunrpc").function("svc_process") ?
+probe sunrpc.svc.process = kernel.function("svc_process") !,
+ module("sunrpc").function("svc_process")
{
%( kernel_v >= "2.6.19" %?
sv_name = kernel_string($rqstp->rq_server->sv_name) /* service name */
@@ -563,8 +568,8 @@ probe sunrpc.svc.process = kernel.function("svc_process") ?,
rq_xid, rq_prog, rq_vers, rq_proc)
}
-probe sunrpc.svc.process.return = kernel.function("svc_process").return ?,
- module("sunrpc").function("svc_process").return ?
+probe sunrpc.svc.process.return = kernel.function("svc_process").return !,
+ module("sunrpc").function("svc_process").return
{
name = "sunrpc.svc.process.return"
retstr = returnstr(1)
@@ -583,8 +588,8 @@ probe sunrpc.svc.process.return = kernel.function("svc_process").return ?,
* @rq_proc: the procedure number in the request
* @rq_prot: the IP protocol of the reqeust
*/
-probe sunrpc.svc.authorise = kernel.function("svc_authorise")?,
- module("sunrpc").function("svc_authorise")?
+probe sunrpc.svc.authorise = kernel.function("svc_authorise") !,
+ module("sunrpc").function("svc_authorise")
{
sv_name = kernel_string($rqstp->rq_server->sv_name)
peer_ip = addr_from_rqst($rqstp)
@@ -599,8 +604,8 @@ probe sunrpc.svc.authorise = kernel.function("svc_authorise")?,
rq_vers, rq_proc, rq_prot)
}
-probe sunrpc.svc.authorise.return = kernel.function("svc_authorise").return ?,
- module("sunrpc").function("svc_authorise").return ?
+probe sunrpc.svc.authorise.return = kernel.function("svc_authorise").return !,
+ module("sunrpc").function("svc_authorise").return
{
name = "sunrpc.svc.authorise.return"
retstr = returnstr(1)
@@ -616,8 +621,8 @@ probe sunrpc.svc.authorise.return = kernel.function("svc_authorise").return ?,
* @sv_nrthreads:the number of concurrent threads
* @timeout: the timeout of waiting for data
*/
-probe sunrpc.svc.recv = kernel.function("svc_recv")?,
- module("sunrpc").function("svc_recv")?
+probe sunrpc.svc.recv = kernel.function("svc_recv") !,
+ module("sunrpc").function("svc_recv")
{
%( kernel_v >= "2.6.19" %?
sv_name = kernel_string($rqstp->rq_server->sv_name)
@@ -634,8 +639,8 @@ probe sunrpc.svc.recv = kernel.function("svc_recv")?,
argstr = sprintf("%s %d", sv_name, timeout)
}
-probe sunrpc.svc.recv.return = kernel.function("svc_recv").return ?,
- module("sunrpc").function("svc_recv").return ?
+probe sunrpc.svc.recv.return = kernel.function("svc_recv").return !,
+ module("sunrpc").function("svc_recv").return
{
name = "sunrpc.svc.recv.return"
retstr = returnstr(1)
@@ -654,8 +659,8 @@ probe sunrpc.svc.recv.return = kernel.function("svc_recv").return ?,
* @rq_proc: the procedure number in the request
* @rq_prot: the IP protocol of the reqeust
*/
-probe sunrpc.svc.send = kernel.function("svc_send")?,
- module("sunrpc").function("svc_send")?
+probe sunrpc.svc.send = kernel.function("svc_send") !,
+ module("sunrpc").function("svc_send")
{
sv_name = kernel_string($rqstp->rq_server->sv_name)
peer_ip = addr_from_rqst($rqstp)
@@ -670,8 +675,8 @@ probe sunrpc.svc.send = kernel.function("svc_send")?,
rq_xid, rq_prog, rq_vers, rq_proc, rq_prot)
}
-probe sunrpc.svc.send.return = kernel.function("svc_send").return ?,
- module("sunrpc").function("svc_send").return ?
+probe sunrpc.svc.send.return = kernel.function("svc_send").return !,
+ module("sunrpc").function("svc_send").return
{
name = "sunrpc.svc.send.return"
retstr = returnstr(1)
@@ -690,8 +695,8 @@ probe sunrpc.svc.send.return = kernel.function("svc_send").return ?,
* @rq_proc: the procedure number in the request
* @rq_prot: the IP protocol of the reqeust
*/
-probe sunrpc.svc.drop = kernel.function("svc_drop")?,
- module("sunrpc").function("svc_drop")?
+probe sunrpc.svc.drop = kernel.function("svc_drop") !,
+ module("sunrpc").function("svc_drop")
{
sv_name = kernel_string($rqstp->rq_server->sv_name)
peer_ip = addr_from_rqst($rqstp)
@@ -706,8 +711,8 @@ probe sunrpc.svc.drop = kernel.function("svc_drop")?,
rq_xid, rq_prog, rq_vers, rq_proc, rq_prot)
}
-probe sunrpc.svc.drop.return = kernel.function("svc_drop").return ?,
- module("sunrpc").function("svc_drop").return ?
+probe sunrpc.svc.drop.return = kernel.function("svc_drop").return !,
+ module("sunrpc").function("svc_drop").return
{
name = "sunrpc.svc.drop.return"
}
@@ -741,8 +746,8 @@ probe sunrpc.sched.return =
* @prot: the IP protocol in the RPC call
* @tk_flags: the flags of the task
*/
-probe sunrpc.sched.new_task = kernel.function("rpc_new_task") ?,
- module("sunrpc").function("rpc_new_task") ?
+probe sunrpc.sched.new_task = kernel.function("rpc_new_task") !,
+ module("sunrpc").function("rpc_new_task")
{
xid = xid_from_clnt($clnt)
prog = prog_from_clnt($clnt)
@@ -754,8 +759,8 @@ probe sunrpc.sched.new_task = kernel.function("rpc_new_task") ?,
argstr = sprintf("%d %d %d %d %d", xid, prog, vers, prot, flags)
}
-probe sunrpc.sched.new_task.return = kernel.function("rpc_new_task").return ?,
- module("sunrpc").function("rpc_new_task").return ?
+probe sunrpc.sched.new_task.return = kernel.function("rpc_new_task").return !,
+ module("sunrpc").function("rpc_new_task").return
{
name = "sunrpc.sched.new_task.return"
retstr = returnstr(2)
@@ -772,8 +777,8 @@ probe sunrpc.sched.new_task.return = kernel.function("rpc_new_task").return ?,
* @prot: the IP protocol in the RPC call
* @tk_flags: the flags of the task
*/
-probe sunrpc.sched.release_task = kernel.function("rpc_release_task") ?,
- module("sunrpc").function("rpc_release_task") ?
+probe sunrpc.sched.release_task = kernel.function("rpc_release_task") !,
+ module("sunrpc").function("rpc_release_task")
{
xid = xid_from_clnt($task->tk_client)
prog = prog_from_clnt($task->tk_client)
@@ -786,8 +791,8 @@ probe sunrpc.sched.release_task = kernel.function("rpc_release_task") ?,
}
probe sunrpc.sched.release_task.return =
- kernel.function("rpc_release_task").return ?,
- module("sunrpc").function("rpc_release_task").return ?
+ kernel.function("rpc_release_task").return !,
+ module("sunrpc").function("rpc_release_task").return
{
name = "sunrpc.sched.release_task.return"
}
@@ -805,8 +810,8 @@ probe sunrpc.sched.release_task.return =
* @tk_pid: the debugging id of the task
* @tk_flags: the flags of the task
*/
-probe sunrpc.sched.execute = kernel.function("__rpc_execute") ?,
- module("sunrpc").function("__rpc_execute") ?
+probe sunrpc.sched.execute = kernel.function("__rpc_execute") !,
+ module("sunrpc").function("__rpc_execute")
{
xid = xid_from_clnt($task->tk_client)
prog = prog_from_clnt($task->tk_client)
@@ -820,8 +825,8 @@ probe sunrpc.sched.execute = kernel.function("__rpc_execute") ?,
tk_pid, tk_flags)
}
-probe sunrpc.sched.execute.return = kernel.function("__rpc_execute").return ?,
- module("sunrpc").function("__rpc_execute").return ?
+probe sunrpc.sched.execute.return = kernel.function("__rpc_execute").return !,
+ module("sunrpc").function("__rpc_execute").return
{
name = "sunrpc.sched.execute.return"
@@ -845,8 +850,8 @@ probe sunrpc.sched.execute.return = kernel.function("__rpc_execute").return ?,
* @tk_flags: the flags of the task
* @delay: the time delayed
*/
-probe sunrpc.sched.delay = kernel.function("rpc_delay") ?,
- module("sunrpc").function("rpc_delay") ?
+probe sunrpc.sched.delay = kernel.function("rpc_delay") !,
+ module("sunrpc").function("rpc_delay")
{
xid = xid_from_clnt($task->tk_client)
prog = prog_from_clnt($task->tk_client)
@@ -861,8 +866,8 @@ probe sunrpc.sched.delay = kernel.function("rpc_delay") ?,
prot, tk_pid, tk_flags, delay)
}
-probe sunrpc.sched.delay.return = kernel.function("rpc_delay").return ?,
- module("sunrpc").function("rpc_delay").return ?
+probe sunrpc.sched.delay.return = kernel.function("rpc_delay").return !,
+ module("sunrpc").function("rpc_delay").return
{
name = "sunrpc.sched.delay.return"
}
diff --git a/tapset/s390x/syscalls.stp b/tapset/s390x/syscalls.stp
index 39236d79..07cb0577 100644
--- a/tapset/s390x/syscalls.stp
+++ b/tapset/s390x/syscalls.stp
@@ -103,7 +103,7 @@ probe syscall.sysctl32.return = kernel.function("sys32_sysctl").return ? {
/* compat */
function get_32mmap_args:string (args:long)
-%{
+%{ /* pure */
struct mmap_arg_struct_emu31 {
u32 addr;
u32 len;
diff --git a/tapset/signal.stp b/tapset/signal.stp
index 72ba9520..4fec7c13 100644
--- a/tapset/signal.stp
+++ b/tapset/signal.stp
@@ -37,8 +37,7 @@
*/
probe signal.send = _signal.send.*
{
- sig=$sig
- sig_name = _signal_name($sig)
+ sig_name = _signal_name(sig)
sig_pid = task_pid(task)
pid_name = task_execname(task)
@@ -53,25 +52,35 @@ probe signal.send = _signal.send.*
probe _signal.send.part1 = kernel.function("__group_send_sig_info")
{
name = "__group_send_sig_info"
+ sig = $sig
task = $p
sinfo = $info
shared = 1
send2queue = 0
}
+%( kernel_v <= "2.6.25" %?
probe _signal.send.part2 = kernel.function("send_group_sigqueue")
{
name = "send_group_sigqueue"
+ sig = $sig
task = $p
sinfo = 0 # $q->info
shared = 1
send2queue = 1
}
+%)
probe _signal.send.part3 = kernel.function("send_sigqueue")
{
name = "send_sigqueue"
+%( kernel_v > "2.6.25" %?
+ task = $t
+ sig = $q->info->si_signo
+%:
task = $p
+ sig = $sig
+%)
sinfo = 0 # $q->info
shared = 0
send2queue = 1
@@ -80,6 +89,7 @@ probe _signal.send.part3 = kernel.function("send_sigqueue")
probe _signal.send.part4 = kernel.function("specific_send_sig_info")
{
name = "specific_send_sig_info"
+ sig = $sig
task = $t
sinfo = $info
shared = 0
@@ -121,6 +131,7 @@ probe _signal.send.part4.return = kernel.function("specific_send_sig_info").retu
send2queue = 0
}
+%( kernel_v <= "2.6.25" %?
/*
* - return 0 if the signal is either sucessfully added into the
* sigqueue of receiving process or a SI_TIMER entry is already
@@ -135,6 +146,7 @@ probe _signal.send.part2.return = kernel.function("send_group_sigqueue").return
shared = 1
send2queue = 1
}
+%)
/*
* - return 0 if the signal is either sucessfully added into the
@@ -224,7 +236,7 @@ probe signal.check_ignored = kernel.function("sig_ignored")
sig_name = _signal_name($sig)
}
-probe signal.check_ignored.return = kernel.function("sig_ignored").return
+probe signal.check_ignored.return = kernel.function("sig_ignored").return ?
{
name = "sig_ignored"
retstr = returnstr(1)
@@ -336,7 +348,7 @@ probe signal.systkill.return = syscall.tkill.return
*/
probe signal.send_sig_queue =
kernel.function("send_sigqueue"),
- kernel.function("send_group_sigqueue")
+ kernel.function("send_group_sigqueue") ?
{
sig = $sig
sig_name = _signal_name($sig)
@@ -347,7 +359,7 @@ probe signal.send_sig_queue =
probe signal.send_sig_queue.return =
kernel.function("send_sigqueue").return,
- kernel.function("send_group_sigqueue").return
+ kernel.function("send_group_sigqueue").return ?
{
retstr = returnstr(1)
}
diff --git a/tapset/syscalls.stp b/tapset/syscalls.stp
index d394208f..11c2bdf7 100644
--- a/tapset/syscalls.stp
+++ b/tapset/syscalls.stp
@@ -630,7 +630,8 @@ probe syscall.exit = kernel.function("do_exit") {
status = $code
argstr = sprint($code)
}
-probe syscall.exit.return = end {}
+# sys_exit() never returns, and is blacklisted for return probes,
+# so no alias here. See bz6588.
# exit_group _________________________________________________
# void sys_exit_group(int error_code)
@@ -640,8 +641,26 @@ probe syscall.exit_group = kernel.function("sys_exit_group") {
status = $error_code
argstr = sprint($error_code)
}
+# sys_exit_group() never returns, and is blacklisted for return probes,
+# so no alias here. See bz6588.
-probe syscall.exit_group.return = end {}
+# faccessat __________________________________________________
+# new function with 2.6.16
+# long sys_faccessat(int dfd, const char __user *filename, int mode)
+probe syscall.faccessat = kernel.function("sys_faccessat") ? {
+ name = "faccessat"
+ dfd = $dfd
+ dfd_str = _dfd_str($dfd)
+ filename = $filename
+ filename_str = user_string($filename)
+ mode = $mode
+ mode_str = _access_mode_str($mode)
+ argstr = sprintf("%s, %s, %s", dfd_str, user_string_quoted($filename), mode_str)
+}
+probe syscall.faccessat.return = kernel.function("sys_faccessat").return ? {
+ name = "faccessat"
+ retstr = returnstr(1)
+}
%(arch != "x86_64" %?
# fadvise64 __________________________________________________
@@ -736,6 +755,24 @@ probe syscall.fchmod.return = kernel.function("sys_fchmod").return {
retstr = returnstr(1)
}
+# fchmodat ___________________________________________________
+# new function with 2.6.16
+# long sys_fchmodat(int dfd, const char __user *filename,
+# mode_t mode)
+probe syscall.fchmodat = kernel.function("sys_fchmodat") ? {
+ name = "fchmodat"
+ dfd = $dfd
+ dfd_str = _dfd_str($dfd)
+ filename = $filename
+ filename_str = user_string($filename)
+ mode = $mode
+ argstr = sprintf("%s, %s, %#o", dfd_str, user_string_quoted($filename), $mode)
+}
+probe syscall.fchmodat.return = kernel.function("sys_fchmodat").return ? {
+ name = "fchmodat"
+ retstr = returnstr(1)
+}
+
# fchown _____________________________________________________
# long sys_fchown(unsigned int fd, uid_t user, gid_t group)
probe syscall.fchown = kernel.function("sys_fchown") {
@@ -764,6 +801,28 @@ probe syscall.fchown16.return = kernel.function("sys_fchown16").return ? {
retstr = returnstr(1)
}
+# fchownat ___________________________________________________
+# new function with 2.6.16
+# long sys_fchownat(int dfd, const char __user *filename,
+# uid_t user, gid_t group, int flag)
+probe syscall.fchownat = kernel.function("sys_fchownat") ? {
+ name = "fchownat"
+ dfd = $dfd
+ dfd_str = _dfd_str($dfd)
+ filename = $filename
+ filename_str = user_string($filename)
+ user = __int32($user)
+ group = __int32($group)
+ flag = $flag
+ flag_str = _at_flag_str($flag)
+ argstr = sprintf("%s, %s, %d, %d, %s",
+ dfd_str, user_string_quoted($filename), user, group, flag_str)
+}
+probe syscall.fchownat.return = kernel.function("sys_fchownat").return ? {
+ name = "fchownat"
+ retstr = returnstr(1)
+}
+
# fcntl ______________________________________________________
# long sys_fcntl(int fd, unsigned int cmd, unsigned long arg)
# long sys_fcntl64(unsigned int fd, unsigned int cmd, unsigned long arg)
@@ -2013,6 +2072,7 @@ probe syscall.lchown16.return = kernel.function("sys_lchown16").return ? {
name = "lchown16"
retstr = returnstr(1)
}
+
# lgetxattr __________________________________________________
# ssize_t sys_lgetxattr(char __user *path,
# char __user *name,
@@ -2035,6 +2095,7 @@ probe syscall.lgetxattr.return = kernel.function("sys_lgetxattr").return {
name = "lgetxattr"
retstr = returnstr(1)
}
+
# link _______________________________________________________
# long sys_link(const char __user * oldname,
# const char __user * newname)
@@ -2051,6 +2112,32 @@ probe syscall.link.return = kernel.function("sys_link").return {
retstr = returnstr(1)
}
+# linkat _____________________________________________________
+# new function with 2.6.16
+# long sys_linkat(int olddfd, const char __user *oldname,
+# int newdfd, const char __user *newname, int flags)
+probe syscall.linkat = kernel.function("sys_linkat") ? {
+ name = "linkat"
+ olddfd = $olddfd
+ olddfd_str = _dfd_str($olddfd)
+ oldname = $oldname
+ oldname_str = user_string($oldname)
+ newdfd = $newdfd
+ newdfd_str = _dfd_str($newdfd)
+ newname = $newname
+ newname_str = user_string($newname)
+ flags = $flags
+ flags_str = _at_flag_str($flags)
+ argstr = sprintf("%s, %s, %s, %s, %s",
+ olddfd_str, user_string_quoted($oldname),
+ newdfd_str, user_string_quoted($newname),
+ flags_str)
+}
+probe syscall.linkat.return = kernel.function("sys_linkat").return ? {
+ name = "linkat"
+ retstr = returnstr(1)
+}
+
# listen _____________________________________________________
# long sys_listen(int fd, int backlog)
probe syscall.listen = kernel.function("sys_listen") ? {
@@ -2328,7 +2415,7 @@ probe syscall.mkdirat = kernel.function("sys_mkdirat") ? {
dirfd = $dfd
pathname = user_string($pathname)
mode = $mode
- argstr = sprintf("%d, %s, %#o", $dfd, user_string_quoted($pathname), $mode)
+ argstr = sprintf("%s, %s, %#o", _dfd_str($dfd), user_string_quoted($pathname), $mode)
}
probe syscall.mkdirat.return = kernel.function("sys_mkdirat").return ? {
name = "mkdirat"
@@ -2350,6 +2437,27 @@ probe syscall.mknod.return = kernel.function("sys_mknod").return {
retstr = returnstr(1)
}
+# mknodat ____________________________________________________
+# new function with 2.6.16
+# long sys_mknodat(int dfd, const char __user *filename,
+# int mode, unsigned dev)
+probe syscall.mknodat = kernel.function("sys_mknodat") ? {
+ name = "mknodat"
+ dfd = $dfd
+ dfd_str = _dfd_str($dfd)
+ filename = $filename
+ filename_str = user_string($filename)
+ mode = $mode
+ mode_str = _mknod_mode_str($mode)
+ dev = $dev
+ argstr = sprintf("%s, %s, %s, %p",
+ dfd_str, user_string_quoted($filename), mode_str, $dev)
+}
+probe syscall.mknodat.return = kernel.function("sys_mknodat").return ? {
+ name = "mknodat"
+ retstr = returnstr(1)
+}
+
# mlock ______________________________________________________
#
# long sys_mlock(unsigned long start, size_t len)
diff --git a/tapset/syscalls2.stp b/tapset/syscalls2.stp
index 0db50347..98bdc95f 100644
--- a/tapset/syscalls2.stp
+++ b/tapset/syscalls2.stp
@@ -2853,6 +2853,20 @@ probe syscall.unlink.return = kernel.function("sys_unlink").return {
name = "unlink"
retstr = returnstr(1)
}
+
+# unshare ____________________________________________________
+# new function with 2.6.16
+# long sys_unshare(unsigned long unshare_flags)
+probe syscall.unshare = kernel.function("sys_unshare") ? {
+ name = "unshare"
+ unshare_flags = $unshare_flags
+ argstr = __fork_flags(unshare_flags)
+}
+probe syscall.unshare.return = kernel.function("sys_unshare").return ? {
+ name = "unshare"
+ retstr = returnstr(1)
+}
+
# uselib _____________________________________________________
#
# asmlinkage long
diff --git a/tapset/task.stp b/tapset/task.stp
index a15888f8..d89729e8 100644
--- a/tapset/task.stp
+++ b/tapset/task.stp
@@ -9,6 +9,9 @@
%{
#include <linux/version.h>
#include <linux/file.h>
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,25)
+#include <linux/fdtable.h>
+#endif
%}
// Return the task_struct representing the current process
diff --git a/tapset/x86_64/registers.stp b/tapset/x86_64/registers.stp
index a5aba55a..99c39e18 100644
--- a/tapset/x86_64/registers.stp
+++ b/tapset/x86_64/registers.stp
@@ -38,7 +38,7 @@ function _stp_register_regs() {
_stp_regs_registered = 1
}
-function _stp_get_register_by_offset:long (offset:long) %{
+function _stp_get_register_by_offset:long (offset:long) %{ /* pure */
long value;
memcpy(&value, ((char *)CONTEXT->regs) + THIS->offset, sizeof(value));
THIS->__retvalue = value;
@@ -48,12 +48,16 @@ function _stp_get_register_by_offset:long (offset:long) %{
* _stp_sign_extend32() is callable from a script function.
* __stp_sign_extend32() (in regs.c) is callable from a C function.
*/
-function _stp_sign_extend32:long (value:long) %{
+function _stp_sign_extend32:long (value:long) %{ /* pure */
THIS->__retvalue = __stp_sign_extend32(THIS->value);
%}
function _stp_register:long (name:string, sign_extend:long) {
reg32 = 0
+ if (!registers_valid()) {
+ error("cannot access CPU registers in this context")
+ return 0
+ }
if (!_stp_regs_registered)
_stp_register_regs()
offset = _reg_offsets[name]
@@ -94,7 +98,7 @@ function u_register:long (name:string) {
* If sign_extend=1 and (truncate=1 or the probepoint we've hit is in a
* 32-bit app), sign-extend the 32-bit value.
*/
-function _stp_arg:long (argnum:long, sign_extend:long, truncate:long) %{
+function _stp_arg:long (argnum:long, sign_extend:long, truncate:long) %{ /* pure */
long val;
int result, n, nr_regargs;
size_t argsz = sizeof(long);
@@ -166,7 +170,7 @@ deref_fault: /* branched to from deref() */
}
%}
-function probing_32bit_app() %{
+function probing_32bit_app() %{ /* pure */
THIS->__retvalue = _stp_probing_32bit_app(CONTEXT->regs);
%}
@@ -227,7 +231,7 @@ function asmlinkage() {
function fastcall() {
}
-function regparm(n) %{
+function regparm(n:long) %{
if (_stp_probing_32bit_app(CONTEXT->regs) &&
(THIS->n < 0 || THIS->n > 3)) {
snprintf(CONTEXT->error_buffer, sizeof(CONTEXT->error_buffer),
@@ -239,5 +243,9 @@ function regparm(n) %{
"For x86_64, regparm value must be in the range 0-6.");
CONTEXT->last_error = CONTEXT->error_buffer;
} else
- CONTEXT->regparm = _STP_REGPARM | (int) n;
+ CONTEXT->regparm = _STP_REGPARM | (int) THIS->n;
%}
+
+function syscall_nr:long() {
+ return _stp_register("orig_ax", 1)
+}
diff --git a/tapsets.cxx b/tapsets.cxx
index 54b951cd..a45233fc 100644
--- a/tapsets.cxx
+++ b/tapsets.cxx
@@ -14,6 +14,7 @@
#include "translate.h"
#include "session.h"
#include "util.h"
+#include "dwarf_wrappers.h"
#include <cstdlib>
#include <algorithm>
@@ -61,7 +62,6 @@ extern "C" {
using namespace std;
using namespace __gnu_cxx;
-
// ------------------------------------------------------------------------
// Generic derived_probe_group: contains an ordinary vector of the
// given type. It provides only the enrollment function.
@@ -81,6 +81,10 @@ public:
// begin/end/error probes are run right during registration / deregistration
// ------------------------------------------------------------------------
+static string TOK_BEGIN("begin");
+static string TOK_END("end");
+static string TOK_ERROR("error");
+
enum be_t { BEGIN, END, ERROR };
struct be_derived_probe: public derived_probe
@@ -116,7 +120,6 @@ public:
void emit_module_exit (systemtap_session& s);
};
-
struct be_builder: public derived_probe_builder
{
be_t type;
@@ -126,13 +129,13 @@ struct be_builder: public derived_probe_builder
virtual void build(systemtap_session &,
probe * base,
probe_point * location,
- std::map<std::string, literal *> const & parameters,
+ literal_map_t const & parameters,
vector<derived_probe *> & finished_results)
{
int64_t priority;
- if ((type == BEGIN && !get_param(parameters, "begin", priority)) ||
- (type == END && !get_param(parameters, "end", priority)) ||
- (type == ERROR && !get_param(parameters, "error", priority)))
+ if ((type == BEGIN && !get_param(parameters, TOK_BEGIN, priority)) ||
+ (type == END && !get_param(parameters, TOK_END, priority)) ||
+ (type == ERROR && !get_param(parameters, TOK_ERROR, priority)))
priority = 0;
finished_results.push_back(
new be_derived_probe(base, location, type, priority));
@@ -414,6 +417,8 @@ be_derived_probe_group::emit_module_exit (systemtap_session& s)
// never probes are never run
// ------------------------------------------------------------------------
+static string TOK_NEVER("never");
+
struct never_derived_probe: public derived_probe
{
never_derived_probe (probe* p): derived_probe (p) {}
@@ -428,7 +433,7 @@ struct never_builder: public derived_probe_builder
virtual void build(systemtap_session &,
probe * base,
probe_point * location,
- std::map<std::string, literal *> const &,
+ literal_map_t const &,
vector<derived_probe *> & finished_results)
{
finished_results.push_back(new never_derived_probe(base, location));
@@ -472,7 +477,7 @@ struct
func_info
{
func_info()
- : decl_file(NULL), decl_line(-1), addr(0), prologue_end(0)
+ : decl_file(NULL), decl_line(-1), addr(0), prologue_end(0), weak(false)
{
memset(&die, 0, sizeof(die));
}
@@ -482,6 +487,7 @@ func_info
Dwarf_Die die;
Dwarf_Addr addr;
Dwarf_Addr prologue_end;
+ bool weak;
};
struct
@@ -503,6 +509,7 @@ struct dwarf_query; // forward decls
struct dwflpp;
struct symbol_table;
+
struct
module_info
{
@@ -559,13 +566,20 @@ symbol_table
module_info *mod_info; // associated module
map<string, func_info*> map_by_name;
vector<func_info*> list_by_addr;
+#ifdef __powerpc__
+ GElf_Word opd_section;
+#endif
- void add_symbol(const char *name, Dwarf_Addr addr, Dwarf_Addr *high_addr);
+ void add_symbol(const char *name, bool weak, Dwarf_Addr addr,
+ Dwarf_Addr *high_addr);
enum info_status read_symbols(FILE *f, const string& path);
enum info_status read_from_elf_file(const string& path);
enum info_status read_from_text_file(const string& path);
enum info_status get_from_elf();
+ void prepare_section_rejection(Dwfl_Module *mod);
+ bool reject_section(GElf_Word section);
void mark_dwarf_redundancies(dwflpp *dw);
+ void purge_syscall_stubs();
func_info *lookup_symbol(const string& name);
Dwarf_Addr lookup_symbol_address(const string& name);
func_info *get_func_containing_address(Dwarf_Addr addr);
@@ -595,6 +609,8 @@ dwarf_diename_integrate (Dwarf_Die *die)
return dwarf_formstring (dwarf_attr_integrate (die, DW_AT_name, &attr_mem));
}
+enum line_t { ABSOLUTE, RELATIVE, RANGE, WILDCARD };
+
struct dwflpp
{
systemtap_session & sess;
@@ -816,35 +832,6 @@ struct dwflpp
return t;
}
-
- // NB: "rc == 0" means OK in this case
- static void dwfl_assert(string desc, int rc, string extra_msg = "")
- {
- string msg = "libdwfl failure (" + desc + "): ";
- if (rc < 0) msg += dwfl_errmsg (rc);
- else if (rc > 0) msg += strerror (rc);
- if (rc != 0)
- {
- if (extra_msg.length() > 0)
- msg += "\n" + extra_msg;
- throw semantic_error (msg);
- }
- }
-
- void dwarf_assert(string desc, int rc) // NB: "rc == 0" means OK in this case
- {
- string msg = "libdw failure (" + desc + "): ";
- if (rc < 0) msg += dwarf_errmsg (rc);
- else if (rc > 0) msg += strerror (rc);
- if (rc != 0)
- throw semantic_error (msg);
- }
-
- // static so pathname_caching_callback() can access them
- static module_cache_t module_cache;
- static bool ignore_vmlinux;
-
-
dwflpp(systemtap_session & session)
:
sess(session),
@@ -858,7 +845,6 @@ struct dwflpp
cu(NULL),
function(NULL)
{
- ignore_vmlinux = sess.ignore_vmlinux;
}
// Called by dwfl_linux_kernel_report_offline(). We may not have
@@ -867,12 +853,16 @@ struct dwflpp
// (Currently, we get all the elf info we need via elfutils -- if the
// elf file exists -- so remembering the pathname isn't strictly needed.
// But we still need to handle the case where there's no vmlinux.)
+
+ static systemtap_session* this_session; // XXX: used only due to elfutils shortcoming
+
static int pathname_caching_callback(const char *name, const char *path)
{
module_info *mi = new module_info(name);
- module_cache.cache[name] = mi;
+ assert (this_session);
+ this_session->module_cache->cache[name] = mi;
- if (ignore_vmlinux && path && name == TOK_KERNEL)
+ if (this_session->ignore_vmlinux && path && name == TOK_KERNEL)
{
// report_kernel() in elfutils found vmlinux, but pretend it didn't.
// Given a non-null path, returning 1 means keep reporting modules.
@@ -894,12 +884,17 @@ struct dwflpp
void setup(bool kernel, bool debuginfo_needed = true)
{
+ if (! sess.module_cache)
+ sess.module_cache = new module_cache ();
+
// XXX: this is where the session -R parameter could come in
static char debuginfo_path_arr[] = "-:.debug:/usr/lib/debug:build";
static char *debuginfo_env_arr = getenv("SYSTEMTAP_DEBUGINFO_PATH");
static char *debuginfo_path = (debuginfo_env_arr ?
debuginfo_env_arr : debuginfo_path_arr);
+ static const char *debug_path = (debuginfo_env_arr ?
+ debuginfo_env_arr : sess.kernel_release.c_str());
static const Dwfl_Callbacks proc_callbacks =
{
@@ -925,17 +920,24 @@ struct dwflpp
dwfl_report_begin (dwfl);
int (*callback)(const char *name, const char *path);
- if (sess.consult_symtab && !module_cache.paths_collected)
+ if (sess.consult_symtab && !sess.module_cache->paths_collected)
{
callback = pathname_caching_callback;
- module_cache.paths_collected = true;
+ sess.module_cache->paths_collected = true;
}
else
callback = NULL;
+
+ // XXX: we should not need to set this static variable just
+ // for the callback. The following elfutils routine should
+ // take some void* parameter to pass context to the callback.
+ this_session = & sess;
int rc = dwfl_linux_kernel_report_offline (dwfl,
- sess.kernel_release.c_str(),
+ debug_path,
/* selection predicate */
callback);
+ this_session = 0;
+
if (debuginfo_needed)
dwfl_assert (string("missing kernel ") +
sess.kernel_release +
@@ -983,10 +985,13 @@ struct dwflpp
Dwarf_Addr addr,
void *param)
{
- module_cache_t *cache = static_cast<module_cache_t*>(param);
+ systemtap_session *sess = static_cast<systemtap_session*>(param);
+ module_cache_t *cache = sess->module_cache;
module_info *mi = NULL;
- if (ignore_vmlinux && name == TOK_KERNEL)
+ assert (cache);
+
+ if (sess->ignore_vmlinux && name == TOK_KERNEL)
// This wouldn't be called for vmlinux if vmlinux weren't there.
return DWARF_CB_OK;
@@ -1004,18 +1009,18 @@ struct dwflpp
void cache_modules_dwarf()
{
- if (!module_cache.dwarf_collected)
+ if (!sess.module_cache->dwarf_collected)
{
ptrdiff_t off = 0;
do
{
if (pending_interrupts) return;
off = dwfl_getmodules (dwfl, module_caching_callback,
- & module_cache, off);
+ & sess, off);
}
while (off > 0);
- dwfl_assert("dwfl_getmodules", off);
- module_cache.dwarf_collected = true;
+ dwfl_assert("dwfl_getmodules", off == 0);
+ sess.module_cache->dwarf_collected = true;
}
}
@@ -1027,7 +1032,7 @@ struct dwflpp
cache_modules_dwarf();
map<string, module_info*>::iterator i;
- for (i = module_cache.cache.begin(); i != module_cache.cache.end(); i++)
+ for (i = sess.module_cache->cache.begin(); i != sess.module_cache->cache.end(); i++)
{
if (pending_interrupts) return;
module_info *mi = i->second;
@@ -1143,105 +1148,121 @@ struct dwflpp
bool has_single_line_record (dwarf_query * q, char const * srcfile, int lineno);
void iterate_over_srcfile_lines (char const * srcfile,
- int lineno,
+ int lines[2],
bool need_single_match,
- void (* callback) (Dwarf_Line * line, void * arg),
+ enum line_t line_type,
+ void (* callback) (const dwarf_line_t& line,
+ void * arg),
void *data)
{
Dwarf_Line **srcsp = NULL;
size_t nsrcs = 0;
dwarf_query * q = static_cast<dwarf_query *>(data);
+ int lineno = lines[0];
get_module_dwarf();
- dwarf_assert ("dwarf_getsrc_file",
- dwarf_getsrc_file (module_dwarf,
- srcfile, lineno, 0,
- &srcsp, &nsrcs));
+ if (line_type == RELATIVE)
+ {
+ Dwarf_Addr addr;
+ Dwarf_Line *line;
+ int line_number;
+
+ dwarf_assert ("dwarf_entrypc", dwarf_entrypc (this->function, &addr));
+ line = dwarf_getsrc_die (this->cu, addr);
+ dwarf_assert ("dwarf_getsrc_die", line == NULL);
+ dwarf_assert ("dwarf_lineno", dwarf_lineno (line, &line_number));
+ lineno += line_number;
+ }
+ else if (line_type == WILDCARD)
+ function_line (&lineno);
+
+ for (int l = lineno; ; l = l + 1)
+ {
+ dwarf_assert ("dwarf_getsrc_file",
+ dwarf_getsrc_file (module_dwarf,
+ srcfile, l, 0,
+ &srcsp, &nsrcs));
- // NB: Formerly, we used to filter, because:
+ if (line_type == WILDCARD || line_type == RANGE)
+ {
+ Dwarf_Addr line_addr;
+ dwarf_lineno (srcsp [0], &lineno);
+ if (lineno != l)
+ continue;
+ dwarf_lineaddr (srcsp [0], &line_addr);
+ if (dwarf_haspc (function, line_addr) != 1)
+ break;
+ }
- // dwarf_getsrc_file gets one *near hits* for line numbers, not
- // exact matches. For example, an existing file but a nonexistent
- // line number will be rounded up to the next definition in that
- // file. This may be similar to the GDB breakpoint algorithm, but
- // we don't want to be so fuzzy in systemtap land. So we filter.
+ // NB: Formerly, we used to filter, because:
- // But we now see the error of our ways, and skip this filtering.
+ // dwarf_getsrc_file gets one *near hits* for line numbers, not
+ // exact matches. For example, an existing file but a nonexistent
+ // line number will be rounded up to the next definition in that
+ // file. This may be similar to the GDB breakpoint algorithm, but
+ // we don't want to be so fuzzy in systemtap land. So we filter.
- // XXX: the code also fails to match e.g. inline function
- // definitions when the srcfile is a header file rather than the
- // CU name.
+ // But we now see the error of our ways, and skip this filtering.
- size_t remaining_nsrcs = nsrcs;
-#if 0
- for (size_t i = 0; i < nsrcs; ++i)
- {
- int l_no;
- Dwarf_Line* l = srcsp[i];
- dwarf_assert ("dwarf_lineno", dwarf_lineno (l, & l_no));
- if (l_no != lineno)
- {
- if (sess.verbose > 3)
- clog << "skipping line number mismatch "
- << "(" << l_no << " vs " << lineno << ")"
- << " in file '" << srcfile << "'"
- << "\n";
- srcsp[i] = 0;
- remaining_nsrcs --;
- }
- }
-#endif
+ // XXX: the code also fails to match e.g. inline function
+ // definitions when the srcfile is a header file rather than the
+ // CU name.
- if (need_single_match && remaining_nsrcs > 1)
- {
- // We wanted a single line record (a unique address for the
- // line) and we got a bunch of line records. We're going to
- // skip this probe (throw an exception) but before we throw
- // we're going to look around a bit to see if there's a low or
- // high line number nearby which *doesn't* have this problem,
- // so we can give the user some advice.
-
- int lo_try = -1;
- int hi_try = -1;
- for (size_t i = 1; i < 6; ++i)
+ size_t remaining_nsrcs = nsrcs;
+
+ if (need_single_match && remaining_nsrcs > 1)
{
- if (lo_try == -1 && has_single_line_record(q, srcfile, lineno - i))
- lo_try = lineno - i;
+ // We wanted a single line record (a unique address for the
+ // line) and we got a bunch of line records. We're going to
+ // skip this probe (throw an exception) but before we throw
+ // we're going to look around a bit to see if there's a low or
+ // high line number nearby which *doesn't* have this problem,
+ // so we can give the user some advice.
+
+ int lo_try = -1;
+ int hi_try = -1;
+ for (size_t i = 1; i < 6; ++i)
+ {
+ if (lo_try == -1 && has_single_line_record(q, srcfile, lineno - i))
+ lo_try = lineno - i;
- if (hi_try == -1 && has_single_line_record(q, srcfile, lineno + i))
- hi_try = lineno + i;
- }
+ if (hi_try == -1 && has_single_line_record(q, srcfile, lineno + i))
+ hi_try = lineno + i;
+ }
- stringstream advice;
- advice << "multiple addresses for " << srcfile << ":" << lineno;
- if (lo_try > 0 || hi_try > 0)
- {
- advice << " (try ";
- if (lo_try > 0)
- advice << srcfile << ":" << lo_try;
- if (lo_try > 0 && hi_try > 0)
- advice << " or ";
- if (hi_try > 0)
- advice << srcfile << ":" << hi_try;
- advice << ")";
- }
- throw semantic_error (advice.str());
- }
+ stringstream advice;
+ advice << "multiple addresses for " << srcfile << ":" << lineno;
+ if (lo_try > 0 || hi_try > 0)
+ {
+ advice << " (try ";
+ if (lo_try > 0)
+ advice << srcfile << ":" << lo_try;
+ if (lo_try > 0 && hi_try > 0)
+ advice << " or ";
+ if (hi_try > 0)
+ advice << srcfile << ":" << hi_try;
+ advice << ")";
+ }
+ throw semantic_error (advice.str());
+ }
- try
- {
- for (size_t i = 0; i < nsrcs; ++i)
+ try
{
- if (pending_interrupts) return;
- if (srcsp [i]) // skip over mismatched lines
- callback (srcsp[i], data);
+ for (size_t i = 0; i < nsrcs; ++i)
+ {
+ if (pending_interrupts) return;
+ if (srcsp [i]) // skip over mismatched lines
+ callback (dwarf_line_t(srcsp[i]), data);
+ }
}
- }
- catch (...)
- {
- free (srcsp);
- throw;
+ catch (...)
+ {
+ free (srcsp);
+ throw;
+ }
+ if (line_type != WILDCARD || l == lines[1])
+ break;
}
free (srcsp);
}
@@ -1316,23 +1337,23 @@ struct dwflpp
if (func->decl_file == 0) func->decl_file = "";
unsigned entrypc_srcline_idx = 0;
- Dwarf_Line* entrypc_srcline = 0;
+ dwarf_line_t entrypc_srcline;
// open-code binary search for exact match
{
unsigned l = 0, h = nlines;
while (l < h)
{
entrypc_srcline_idx = (l + h) / 2;
- Dwarf_Addr addr;
- Dwarf_Line *lr = dwarf_onesrcline(lines, entrypc_srcline_idx);
- dwarf_lineaddr (lr, &addr);
+ const dwarf_line_t lr(dwarf_onesrcline(lines,
+ entrypc_srcline_idx));
+ Dwarf_Addr addr = lr.addr();
if (addr == entrypc) { entrypc_srcline = lr; break; }
else if (l + 1 == h) { break; } // ran off bottom of tree
else if (addr < entrypc) { l = entrypc_srcline_idx; }
else { h = entrypc_srcline_idx; }
}
}
- if (entrypc_srcline == 0)
+ if (!entrypc_srcline)
throw semantic_error ("missing entrypc dwarf line record for function '"
+ func->name + "'");
@@ -1357,13 +1378,10 @@ struct dwflpp
bool ranoff_end = false;
while (postprologue_srcline_idx < nlines)
{
- Dwarf_Addr postprologue_addr;
- Dwarf_Line *lr = dwarf_onesrcline(lines, postprologue_srcline_idx);
- dwarf_lineaddr (lr, &postprologue_addr);
- const char* postprologue_file = dwarf_linesrc (lr, NULL, NULL);
- int postprologue_lineno;
- dwfl_assert ("dwarf_lineno",
- dwarf_lineno (lr, & postprologue_lineno));
+ dwarf_line_t lr(dwarf_onesrcline(lines, postprologue_srcline_idx));
+ Dwarf_Addr postprologue_addr = lr.addr();
+ const char* postprologue_file = lr.linesrc();
+ int postprologue_lineno = lr.lineno();
if (sess.verbose>2)
clog << "checking line record 0x" << hex << postprologue_addr << dec
@@ -1485,9 +1503,9 @@ struct dwflpp
dwarf_decl_line (function, linep);
}
- bool die_has_pc (Dwarf_Die * die, Dwarf_Addr pc)
+ bool die_has_pc (Dwarf_Die & die, Dwarf_Addr pc)
{
- int res = dwarf_haspc (die, pc);
+ int res = dwarf_haspc (&die, pc);
if (res == -1)
dwarf_assert ("dwarf_haspc", res);
return res == 1;
@@ -1524,19 +1542,19 @@ struct dwflpp
// We emit a comment approximating the variable+offset expression that
// relocatable module probing code will need to have.
Dwfl_Module *mod = dwfl_addrmodule (dwfl, address);
- dwfl_assert ("dwfl_addrmodule", mod == NULL);
+ dwfl_assert ("dwfl_addrmodule", mod);
int n = dwfl_module_relocations (mod);
- dwfl_assert ("dwfl_module_relocations", n < 0);
+ dwfl_assert ("dwfl_module_relocations", n >= 0);
int i = dwfl_module_relocate_address (mod, &address);
- dwfl_assert ("dwfl_module_relocate_address", i < 0);
+ dwfl_assert ("dwfl_module_relocate_address", i >= 0);
const char *modname = dwfl_module_info (mod, NULL, NULL, NULL,
NULL, NULL, NULL, NULL);
- dwfl_assert ("dwfl_module_info", modname == NULL);
+ dwfl_assert ("dwfl_module_info", modname);
const char *secname = dwfl_module_relocation_info (mod, i, NULL);
if (n > 0 && !(n == 1 && secname == NULL))
{
- dwfl_assert ("dwfl_module_relocation_info", secname == NULL);
+ dwfl_assert ("dwfl_module_relocation_info", secname);
if (n > 1 || secname[0] != '\0')
{
// This gives us the module name, and section name within the
@@ -1581,7 +1599,6 @@ struct dwflpp
void print_locals(Dwarf_Die *die, ostream &o)
{
// Try to get the first child of die.
- bool local_found = false;
Dwarf_Die child;
if (dwarf_child (die, &child) == 0)
{
@@ -1594,7 +1611,6 @@ struct dwflpp
case DW_TAG_variable:
case DW_TAG_formal_parameter:
o << " " << dwarf_diename (&child);
- local_found = true;
break;
default:
break;
@@ -1602,9 +1618,6 @@ struct dwflpp
}
while (dwarf_siblingof (&child, &child) == 0);
}
-
- if (! local_found)
- o << " (none found)";
}
Dwarf_Attribute *
@@ -1642,8 +1655,7 @@ struct dwflpp
print_locals (scopes, alternatives);
throw semantic_error ("unable to find local '" + local + "'"
+ " near pc " + lex_cast_hex<string>(pc)
- + " (alternatives:" + alternatives.str ()
- + ")");
+ + (alternatives.str() == "" ? "" : (" (alternatives:" + alternatives.str () + ")")));
}
for (int inner = 0; inner < nscopes; ++inner)
@@ -2177,8 +2189,10 @@ struct dwflpp
}
};
-module_cache_t dwflpp::module_cache;
-bool dwflpp::ignore_vmlinux = false;
+
+systemtap_session* dwflpp::this_session = 0; // XXX: used only due to elfutils shortcoming
+
+
enum
@@ -2252,7 +2266,7 @@ struct base_query
probe * base_probe,
probe_point * base_loc,
dwflpp & dw,
- map<string, literal *> const & params,
+ literal_map_t const & params,
vector<derived_probe *> & results);
virtual ~base_query() {}
@@ -2263,13 +2277,13 @@ struct base_query
vector<derived_probe *> & results;
// Parameter extractors.
- static bool has_null_param(map<string, literal *> const & params,
+ static bool has_null_param(literal_map_t const & params,
string const & k);
- static bool get_string_param(map<string, literal *> const & params,
+ static bool get_string_param(literal_map_t const & params,
string const & k, string & v);
- static bool get_number_param(map<string, literal *> const & params,
+ static bool get_number_param(literal_map_t const & params,
string const & k, long & v);
- static bool get_number_param(map<string, literal *> const & params,
+ static bool get_number_param(literal_map_t const & params,
string const & k, Dwarf_Addr & v);
// Extracted parameters.
@@ -2284,7 +2298,7 @@ base_query::base_query(systemtap_session & sess,
probe * base_probe,
probe_point * base_loc,
dwflpp & dw,
- map<string, literal *> const & params,
+ literal_map_t const & params,
vector<derived_probe *> & results)
: sess(sess), base_probe(base_probe), base_loc(base_loc), dw(dw),
results(results)
@@ -2301,7 +2315,7 @@ base_query::base_query(systemtap_session & sess,
}
bool
-base_query::has_null_param(map<string, literal *> const & params,
+base_query::has_null_param(literal_map_t const & params,
string const & k)
{
return derived_probe_builder::has_null_param(params, k);
@@ -2309,7 +2323,7 @@ base_query::has_null_param(map<string, literal *> const & params,
bool
-base_query::get_string_param(map<string, literal *> const & params,
+base_query::get_string_param(literal_map_t const & params,
string const & k, string & v)
{
return derived_probe_builder::get_param (params, k, v);
@@ -2317,7 +2331,7 @@ base_query::get_string_param(map<string, literal *> const & params,
bool
-base_query::get_number_param(map<string, literal *> const & params,
+base_query::get_number_param(literal_map_t const & params,
string const & k, long & v)
{
int64_t value;
@@ -2328,7 +2342,7 @@ base_query::get_number_param(map<string, literal *> const & params,
bool
-base_query::get_number_param(map<string, literal *> const & params,
+base_query::get_number_param(literal_map_t const & params,
string const & k, Dwarf_Addr & v)
{
int64_t value;
@@ -2337,6 +2351,8 @@ base_query::get_number_param(map<string, literal *> const & params,
return present;
}
+typedef map<Dwarf_Addr, inline_instance_info> inline_instance_map_t;
+typedef map<Dwarf_Addr, func_info> func_info_map_t;
struct dwarf_query : public base_query
{
@@ -2344,7 +2360,7 @@ struct dwarf_query : public base_query
probe * base_probe,
probe_point * base_loc,
dwflpp & dw,
- map<string, literal *> const & params,
+ literal_map_t const & params,
vector<derived_probe *> & results);
virtual void handle_query_module();
@@ -2404,14 +2420,15 @@ struct dwarf_query : public base_query
function_spec_type spec_type;
string function;
string file;
- int line;
+ line_t line_type;
+ int line[2];
bool query_done; // Found exact match
set<char const *> filtered_srcfiles;
// Map official entrypc -> func_info object
- map<Dwarf_Addr, inline_instance_info> filtered_inlines;
- map<Dwarf_Addr, func_info> filtered_functions;
+ inline_instance_map_t filtered_inlines;
+ func_info_map_t filtered_functions;
bool choose_next_line;
Dwarf_Addr entrypc_for_next_line;
};
@@ -2451,14 +2468,13 @@ dwflpp::has_single_line_record (dwarf_query * q, char const * srcfile, int linen
// We also try to filter out lines that leave the selected
// functions (if any).
- Dwarf_Line *line = srcsp[0];
- Dwarf_Addr addr;
- dwarf_lineaddr (line, &addr);
+ dwarf_line_t line(srcsp[0]);
+ Dwarf_Addr addr = line.addr();
- for (map<Dwarf_Addr, func_info>::iterator i = q->filtered_functions.begin();
+ for (func_info_map_t::iterator i = q->filtered_functions.begin();
i != q->filtered_functions.end(); ++i)
{
- if (q->dw.die_has_pc (&(i->second.die), addr))
+ if (q->dw.die_has_pc (i->second.die, addr))
{
if (q->sess.verbose>4)
clog << "alternative line " << lineno << " accepted: fn=" << i->second.name << endl;
@@ -2466,10 +2482,10 @@ dwflpp::has_single_line_record (dwarf_query * q, char const * srcfile, int linen
}
}
- for (map<Dwarf_Addr, inline_instance_info>::iterator i = q->filtered_inlines.begin();
+ for (inline_instance_map_t::iterator i = q->filtered_inlines.begin();
i != q->filtered_inlines.end(); ++i)
{
- if (q->dw.die_has_pc (&(i->second.die), addr))
+ if (q->dw.die_has_pc (i->second.die, addr))
{
if (sess.verbose>4)
clog << "alternative line " << lineno << " accepted: ifn=" << i->second.name << endl;
@@ -2570,7 +2586,7 @@ struct dwarf_builder: public derived_probe_builder
virtual void build(systemtap_session & sess,
probe * base,
probe_point * location,
- std::map<std::string, literal *> const & parameters,
+ literal_map_t const & parameters,
vector<derived_probe *> & finished_results);
};
@@ -2579,7 +2595,7 @@ dwarf_query::dwarf_query(systemtap_session & sess,
probe * base_probe,
probe_point * base_loc,
dwflpp & dw,
- map<string, literal *> const & params,
+ literal_map_t const & params,
vector<derived_probe *> & results)
: base_query(sess, base_probe, base_loc, dw, params, results)
{
@@ -2871,11 +2887,12 @@ dwarf_query::parse_function_spec(string & spec)
function.clear();
file.clear();
- line = 0;
+ line[0] = 0;
+ line[1] = 0;
while (i != e && *i != '@')
{
- if (*i == ':')
+ if (*i == ':' || *i == '+')
goto bad;
function += *i++;
}
@@ -2892,8 +2909,17 @@ dwarf_query::parse_function_spec(string & spec)
if (i++ == e)
goto bad;
- while (i != e && *i != ':')
+ while (i != e && *i != ':' && *i != '+')
file += *i++;
+ if (*i == ':')
+ {
+ if (*(i + 1) == '*')
+ line_type = WILDCARD;
+ else
+ line_type = ABSOLUTE;
+ }
+ else if (*i == '+')
+ line_type = RELATIVE;
if (i == e)
{
@@ -2910,7 +2936,22 @@ dwarf_query::parse_function_spec(string & spec)
try
{
- line = lex_cast<int>(string(i, e));
+ if (line_type != WILDCARD)
+ {
+ string::const_iterator dash = i;
+
+ while (dash != e && *dash != '-')
+ dash++;
+ if (dash == e)
+ line[0] = line[1] = lex_cast<int>(string(i, e));
+ else
+ {
+ line_type = RANGE;
+ line[0] = lex_cast<int>(string(i, dash));
+ line[1] = lex_cast<int>(string(dash + 1, e));
+ }
+ }
+
if (sess.verbose>2)
clog << "parsed '" << spec
<< "' -> func '"<< function
@@ -3016,7 +3057,7 @@ string dwarf_query::get_blacklist_section(Dwarf_Addr addr)
{
Elf_Scn* scn = 0;
size_t shstrndx;
- dw.dwfl_assert ("getshstrndx", elf_getshstrndx (elf, &shstrndx));
+ dwfl_assert ("getshstrndx", elf_getshstrndx (elf, &shstrndx));
while ((scn = elf_nextscn (elf, scn)) != NULL)
{
GElf_Shdr shdr_mem;
@@ -3268,20 +3309,18 @@ query_func_info (Dwarf_Addr entrypc,
static void
-query_srcfile_line (Dwarf_Line * line, void * arg)
+query_srcfile_line (const dwarf_line_t& line, void * arg)
{
dwarf_query * q = static_cast<dwarf_query *>(arg);
- Dwarf_Addr addr;
- dwarf_lineaddr(line, &addr);
+ Dwarf_Addr addr = line.addr();
- int lineno;
- dwarf_lineno (line, &lineno);
+ int lineno = line.lineno();
- for (map<Dwarf_Addr, func_info>::iterator i = q->filtered_functions.begin();
+ for (func_info_map_t::iterator i = q->filtered_functions.begin();
i != q->filtered_functions.end(); ++i)
{
- if (q->dw.die_has_pc (&(i->second.die), addr))
+ if (q->dw.die_has_pc (i->second.die, addr))
{
if (q->sess.verbose>3)
clog << "function DIE lands on srcfile\n";
@@ -3294,17 +3333,17 @@ query_srcfile_line (Dwarf_Line * line, void * arg)
}
}
- for (map<Dwarf_Addr, inline_instance_info>::iterator i
+ for (inline_instance_map_t::iterator i
= q->filtered_inlines.begin();
i != q->filtered_inlines.end(); ++i)
{
- if (q->dw.die_has_pc (&(i->second.die), addr))
+ if (q->dw.die_has_pc (i->second.die, addr))
{
if (q->sess.verbose>3)
clog << "inline instance DIE lands on srcfile\n";
if (q->has_statement_str)
query_statement (i->second.name, i->second.decl_file,
- q->line, &(i->second.die), addr, q);
+ q->line[0], &(i->second.die), addr, q);
else
query_inline_instance_info (i->first, i->second, q);
}
@@ -3390,7 +3429,7 @@ query_dwarf_func (Dwarf_Die * func, void * arg)
Dwarf_Die d;
q->dw.function_die (&d);
- if (q->dw.die_has_pc (&d, query_addr))
+ if (q->dw.die_has_pc (d, query_addr))
record_this_function = true;
}
@@ -3476,7 +3515,24 @@ query_cu (Dwarf_Die * cudie, void * arg)
if (q->filtered_srcfiles.empty())
return DWARF_CB_OK;
}
-
+ // Verify that a raw address matches the beginning of a
+ // statement. This is a somewhat lame check that the address
+ // is at the start of an assembly instruction.
+ if (q->has_statement_num)
+ {
+ Dwarf_Addr queryaddr = q->statement_num_val;
+ dwarf_line_t address_line(dwarf_getsrc_die(cudie, queryaddr));
+ Dwarf_Addr lineaddr = 0;
+ if (address_line)
+ lineaddr = address_line.addr();
+ if (!address_line || lineaddr != queryaddr)
+ {
+ stringstream msg;
+ msg << "address 0x" << hex << queryaddr
+ << "does not match the begining of a statement";
+ throw semantic_error(msg.str());
+ }
+ }
// Pick up [entrypc, name, DIE] tuples for all the functions
// matching the query, and fill in the prologue endings of them
// all in a single pass.
@@ -3497,18 +3553,18 @@ query_cu (Dwarf_Die * cudie, void * arg)
for (set<char const *>::const_iterator i = q->filtered_srcfiles.begin();
i != q->filtered_srcfiles.end(); ++i)
q->dw.iterate_over_srcfile_lines (*i, q->line, q->has_statement_str,
- query_srcfile_line, q);
+ q->line_type, query_srcfile_line, q);
}
else
{
// Otherwise, simply probe all resolved functions.
- for (map<Dwarf_Addr, func_info>::iterator i = q->filtered_functions.begin();
+ for (func_info_map_t::iterator i = q->filtered_functions.begin();
i != q->filtered_functions.end(); ++i)
query_func_info (i->first, i->second, q);
// And all inline instances (if we're not excluding inlines with ".call")
if (! q->has_call)
- for (map<Dwarf_Addr, inline_instance_info>::iterator i
+ for (inline_instance_map_t::iterator i
= q->filtered_inlines.begin(); i != q->filtered_inlines.end(); ++i)
query_inline_instance_info (i->first, i->second, q);
}
@@ -3576,7 +3632,7 @@ validate_module_elf (Dwfl_Module *mod, const char *name, base_query *q)
GElf_Ehdr ehdr_mem;
GElf_Ehdr* em = gelf_getehdr (elf, &ehdr_mem);
- if (em == 0) { q->dw.dwfl_assert ("dwfl_getehdr", dwfl_errno()); }
+ if (em == 0) { dwfl_assert ("dwfl_getehdr", dwfl_errno()); }
int elf_machine = em->e_machine;
const char* debug_filename = "";
const char* main_filename = "";
@@ -3681,8 +3737,8 @@ dwflpp::query_modules(dwarf_query *q)
{
cache_modules_dwarf();
- map<string, module_info*>::iterator i = module_cache.cache.find(name);
- if (i != module_cache.cache.end())
+ map<string, module_info*>::iterator i = sess.module_cache->cache.find(name);
+ if (i != sess.module_cache->cache.end())
{
module_info *mi = i->second;
query_module(mi->mod, mi, name.c_str(), mi->addr, q);
@@ -4621,7 +4677,7 @@ void
dwarf_builder::build(systemtap_session & sess,
probe * base,
probe_point * location,
- std::map<std::string, literal *> const & parameters,
+ literal_map_t const & parameters,
vector<derived_probe *> & finished_results)
{
// NB: the kernel/user dwlfpp objects are long-lived.
@@ -4697,12 +4753,18 @@ symbol_table::~symbol_table()
}
void
-symbol_table::add_symbol(const char *name, Dwarf_Addr addr,
- Dwarf_Addr *high_addr)
+symbol_table::add_symbol(const char *name, bool weak, Dwarf_Addr addr,
+ Dwarf_Addr *high_addr)
{
+#ifdef __powerpc__
+ // Map ".sys_foo" to "sys_foo".
+ if (name[0] == '.')
+ name++;
+#endif
func_info *fi = new func_info();
fi->addr = addr;
fi->name = name;
+ fi->weak = weak;
map_by_name[fi->name] = fi;
// TODO: Use a multimap in case there are multiple static
// functions with the same name?
@@ -4753,8 +4815,8 @@ symbol_table::read_symbols(FILE *f, const string& path)
free(mod);
goto done;
}
- if (type == 'T' || type == 't')
- add_symbol(name, (Dwarf_Addr) addr, &high_addr);
+ if (type == 'T' || type == 't' || type == 'W')
+ add_symbol(name, (type == 'W'), (Dwarf_Addr) addr, &high_addr);
free(name);
}
@@ -4809,6 +4871,55 @@ symbol_table::read_from_text_file(const string& path)
return status;
}
+void
+symbol_table::prepare_section_rejection(Dwfl_Module *mod)
+{
+#ifdef __powerpc__
+ /*
+ * The .opd section contains function descriptors that can look
+ * just like function entry points. For example, there's a function
+ * descriptor called "do_exit" that links to the entry point ".do_exit".
+ * Reject all symbols in .opd.
+ */
+ opd_section = SHN_UNDEF;
+ Dwarf_Addr bias;
+ Elf* elf = (dwarf_getelf (dwfl_module_getdwarf (mod, &bias))
+ ?: dwfl_module_getelf (mod, &bias));
+ Elf_Scn* scn = 0;
+ size_t shstrndx;
+
+ if (!elf)
+ return;
+ if (elf_getshstrndx(elf, &shstrndx) != 0)
+ return;
+ while ((scn = elf_nextscn(elf, scn)) != NULL)
+ {
+ GElf_Shdr shdr_mem;
+ GElf_Shdr *shdr = gelf_getshdr(scn, &shdr_mem);
+ if (!shdr)
+ continue;
+ const char *name = elf_strptr(elf, shstrndx, shdr->sh_name);
+ if (!strcmp(name, ".opd"))
+ {
+ opd_section = elf_ndxscn(scn);
+ return;
+ }
+ }
+#endif
+}
+
+bool
+symbol_table::reject_section(GElf_Word section)
+{
+ if (section == SHN_UNDEF)
+ return true;
+#ifdef __powerpc__
+ if (section == opd_section)
+ return true;
+#endif
+ return false;
+}
+
enum info_status
symbol_table::get_from_elf()
{
@@ -4816,12 +4927,16 @@ symbol_table::get_from_elf()
Dwfl_Module *mod = mod_info->mod;
int syments = dwfl_module_getsymtab(mod);
assert(syments);
+ prepare_section_rejection(mod);
for (int i = 1; i < syments; ++i)
{
GElf_Sym sym;
- const char *name = dwfl_module_getsym(mod, i, &sym, NULL);
- if (name && GELF_ST_TYPE(sym.st_info) == STT_FUNC)
- add_symbol(name, sym.st_value, &high_addr);
+ GElf_Word section;
+ const char *name = dwfl_module_getsym(mod, i, &sym, &section);
+ if (name && GELF_ST_TYPE(sym.st_info) == STT_FUNC &&
+ !reject_section(section))
+ add_symbol(name, (GELF_ST_BIND(sym.st_info) == STB_WEAK),
+ sym.st_value, &high_addr);
}
return info_present;
}
@@ -4913,6 +5028,33 @@ symbol_table::lookup_symbol_address(const string& name)
return 0;
}
+// This is the kernel symbol table. The kernel macro cond_syscall creates
+// a weak symbol for each system call and maps it to sys_ni_syscall.
+// For system calls not implemented elsewhere, this weak symbol shows up
+// in the kernel symbol table. Following the precedent of dwarfful stap,
+// we refuse to consider such symbols. Here we delete them from our
+// symbol table.
+// TODO: Consider generalizing this and/or making it part of blacklist
+// processing.
+void
+symbol_table::purge_syscall_stubs()
+{
+ Dwarf_Addr stub_addr = lookup_symbol_address("sys_ni_syscall");
+ if (stub_addr == 0)
+ return;
+ for (size_t i = 0; i < list_by_addr.size(); i++)
+ {
+ func_info *fi = list_by_addr.at(i);
+ if (fi->weak && fi->addr == stub_addr && fi->name != "sys_ni_syscall")
+ {
+ list_by_addr.erase(list_by_addr.begin()+i);
+ map_by_name.erase(fi->name);
+ delete fi;
+ i--;
+ }
+ }
+}
+
void
module_info::get_symtab(dwarf_query *q)
{
@@ -4968,6 +5110,9 @@ module_info::get_symtab(dwarf_query *q)
// precedes the call to query_module_symtab(). So we should never read
// a module's symbol table without first having tried to get its dwarf.
sym_table->mark_dwarf_redundancies(&q->dw);
+
+ if (name == TOK_KERNEL)
+ sym_table->purge_syscall_stubs();
}
module_info::~module_info()
@@ -5052,25 +5197,19 @@ task_finder_derived_probe_group::emit_module_exit (systemtap_session& s)
// utrace user-space probes
// ------------------------------------------------------------------------
-// Since we don't have access to <linux/utrace.h>, we'll have to
-// define our own version of the UTRACE_EVENT flags.
+static string TOK_THREAD("thread");
+static string TOK_SYSCALL("syscall");
+
+// Note that these flags don't match up exactly with UTRACE_EVENT
+// flags (and that's OK).
enum utrace_derived_probe_flags {
UDPF_NONE,
- UDPF_QUIESCE, // UTRACE_EVENT(QUIESCE)
- UDPF_REAP, // UTRACE_EVENT(REAP)
- UDPF_CLONE, // UTRACE_EVENT(CLONE)
- UDPF_VFORK_DONE, // UTRACE_EVENT(VFORK_DONE)
- UDPF_EXEC, // UTRACE_EVENT(EXEC)
- UDPF_EXIT, // UTRACE_EVENT(EXIT)
- UDPF_DEATH, // UTRACE_EVENT(DEATH)
- UDPF_SYSCALL_ENTRY, // UTRACE_EVENT(SYSCALL_ENTRY)
- UDPF_SYSCALL_EXIT, // UTRACE_EVENT(SYSCALL_EXIT)
- UDPF_SIGNAL, // UTRACE_EVENT(SIGNAL)
- UDPF_SIGNAL_IGN, // UTRACE_EVENT(SIGNAL_IGN)
- UDPF_SIGNAL_STOP, // UTRACE_EVENT(SIGNAL_STOP)
- UDPF_SIGNAL_TERM, // UTRACE_EVENT(SIGNAL_TERM)
- UDPF_SIGNAL_CORE, // UTRACE_EVENT(SIGNAL_CORE)
- UDPF_JCTL, // UTRACE_EVENT(JCTL)
+ UDPF_BEGIN, // process begin
+ UDPF_END, // process end
+ UDPF_THREAD_BEGIN, // thread begin
+ UDPF_THREAD_END, // thread end
+ UDPF_SYSCALL, // syscall entry
+ UDPF_SYSCALL_RETURN, // syscall exit
UDPF_NFLAGS
};
@@ -5100,6 +5239,9 @@ private:
bool flags_seen[UDPF_NFLAGS];
void emit_probe_decl (systemtap_session& s, utrace_derived_probe *p);
+ void emit_vm_callback_probe_decl (systemtap_session& s, bool has_path,
+ string path, int64_t pid,
+ string vm_callback);
public:
utrace_derived_probe_group(): num_probes(0), flags_seen() { }
@@ -5144,15 +5286,9 @@ void
utrace_derived_probe::join_group (systemtap_session& s)
{
if (! s.utrace_derived_probes)
- {
+ {
s.utrace_derived_probes = new utrace_derived_probe_group ();
-
- // Make sure <linux/tracehook.h> is included early.
- embeddedcode *ec = new embeddedcode;
- ec->tok = NULL;
- ec->code = string("#include <linux/tracehook.h>\n");
- s.embeds.push_back(ec);
- }
+ }
s.utrace_derived_probes->enroll (this);
task_finder_derived_probe_group::create_session_group (s);
@@ -5164,7 +5300,7 @@ utrace_var_expanding_copy_visitor::visit_target_symbol (target_symbol* e)
{
assert(e->base_name.size() > 0 && e->base_name[0] == '$');
- if (flags != UDPF_SYSCALL_ENTRY && flags != UDPF_SYSCALL_EXIT)
+ if (flags != UDPF_SYSCALL && flags != UDPF_SYSCALL_RETURN)
throw semantic_error ("only \"process(PATH_OR_PID).syscall\" and \"process(PATH_OR_PID).syscall.return\" probes support target symbols",
e->tok);
@@ -5198,28 +5334,11 @@ utrace_var_expanding_copy_visitor::visit_target_symbol (target_symbol* e)
// Remember that we've seen a target variable.
target_symbol_seen = true;
- // Synthesize a function.
- functiondecl *fdecl = new functiondecl;
- fdecl->tok = e->tok;
- embeddedcode *ec = new embeddedcode;
- ec->tok = e->tok;
-
- string fname = (string("_utrace_syscall_get") + "_"
- + lex_cast<string>(tick++));
- string locvalue = "CONTEXT->data";
-
- ec->code = string("THIS->__retvalue = *tracehook_syscall_callno(CONTEXT->regs); /* pure */");
-
- fdecl->name = fname;
- fdecl->body = ec;
- fdecl->type = pe_long;
-
- sess.functions.push_back(fdecl);
-
- // Synthesize a functioncall.
+ // We're going to substitute a synthesized 'syscall_nr' function
+ // call for the '$syscall' reference.
functioncall* n = new functioncall;
n->tok = e->tok;
- n->function = fname;
+ n->function = "syscall_nr";
n->referent = 0; // NB: must not resolve yet, to ensure inclusion in session
provide <functioncall*> (this, n);
@@ -5232,7 +5351,7 @@ struct utrace_builder: public derived_probe_builder
virtual void build(systemtap_session & sess,
probe * base,
probe_point * location,
- std::map<std::string, literal *> const & parameters,
+ literal_map_t const & parameters,
vector<derived_probe *> & finished_results)
{
string path;
@@ -5243,19 +5362,24 @@ struct utrace_builder: public derived_probe_builder
enum utrace_derived_probe_flags flags = UDPF_NONE;
assert (has_path || has_pid);
- if (has_null_param (parameters, "death"))
- flags = UDPF_DEATH;
- else if (has_null_param (parameters, "syscall"))
+ if (has_null_param (parameters, TOK_THREAD))
+ {
+ if (has_null_param (parameters, TOK_BEGIN))
+ flags = UDPF_THREAD_BEGIN;
+ else if (has_null_param (parameters, TOK_END))
+ flags = UDPF_THREAD_END;
+ }
+ else if (has_null_param (parameters, TOK_SYSCALL))
{
if (has_null_param (parameters, TOK_RETURN))
- flags = UDPF_SYSCALL_EXIT;
+ flags = UDPF_SYSCALL_RETURN;
else
- flags = UDPF_SYSCALL_ENTRY;
+ flags = UDPF_SYSCALL;
}
- else if (has_null_param (parameters, "clone"))
- flags = UDPF_CLONE;
- else if (has_null_param (parameters, "exec"))
- flags = UDPF_EXEC;
+ else if (has_null_param (parameters, TOK_BEGIN))
+ flags = UDPF_BEGIN;
+ else if (has_null_param (parameters, TOK_END))
+ flags = UDPF_END;
// If we have a path, we need to validate it.
if (has_path)
@@ -5338,6 +5462,7 @@ utrace_derived_probe_group::emit_probe_decl (systemtap_session& s,
}
s.op->line() << " .callback=&_stp_utrace_probe_cb,";
+ s.op->line() << " .vm_callback=NULL,";
s.op->line() << " },";
s.op->line() << " .pp=" << lex_cast_qstring (*p->sole_location()) << ",";
s.op->line() << " .ph=&" << p->name << ",";
@@ -5345,29 +5470,46 @@ utrace_derived_probe_group::emit_probe_decl (systemtap_session& s,
// Handle flags
switch (p->flags)
{
- case UDPF_CLONE:
- s.op->line() << " .ops={ .report_clone=stap_utrace_probe_clone, .report_death=stap_utrace_task_finder_report_death },";
- s.op->line() << " .flags=(UTRACE_EVENT(CLONE)|UTRACE_EVENT(DEATH)),";
+ // Look in _stp_utrace_probe_cb for description of why quiesce is
+ // used here.
+ case UDPF_BEGIN: // process begin
+ s.op->line() << " .flags=(UDPF_BEGIN),";
+ s.op->line() << " .ops={ .report_quiesce=stap_utrace_probe_quiesce },";
+ s.op->line() << " .events=(UTRACE_ACTION_QUIESCE|UTRACE_EVENT(QUIESCE)),";
break;
- case UDPF_EXEC:
- // Notice we're not setting up a .ops/.report_exec handler here.
- // Instead, we'll just call the probe directly when we get
- // notified the exec happened.
- s.op->line() << " .flags=(UTRACE_EVENT(EXEC)),";
+ case UDPF_THREAD_BEGIN: // thread begin
+ s.op->line() << " .flags=(UDPF_THREAD_BEGIN),";
+ s.op->line() << " .ops={ .report_quiesce=stap_utrace_probe_quiesce },";
+ s.op->line() << " .events=(UTRACE_ACTION_QUIESCE|UTRACE_EVENT(QUIESCE)),";
break;
- case UDPF_DEATH:
- // Notice we're not setting up a .ops/.report_death handler
- // here. Instead, we'll just call the probe directly when we
- // get notified the death happened.
- s.op->line() << " .flags=(UTRACE_EVENT(DEATH)),";
+
+ // Notice we're not setting up a .ops/.report_death handler for
+ // either UDPF_END or UDPF_THREAD_END. Instead, we'll just call
+ // the probe directly when we get notified.
+ case UDPF_END: // process end
+ s.op->line() << " .flags=(UDPF_END),";
break;
- case UDPF_SYSCALL_ENTRY:
+ case UDPF_THREAD_END: // thread end
+ s.op->line() << " .flags=(UDPF_THREAD_END),";
+ break;
+
+ // For UDPF_SYSCALL/UDPF_SYSCALL_RETURN probes, the .report_death
+ // handler isn't strictly necessary. However, it helps to keep
+ // our attaches/detaches symmetrical.
+ case UDPF_SYSCALL:
+ s.op->line() << " .flags=(UDPF_SYSCALL),";
s.op->line() << " .ops={ .report_syscall_entry=stap_utrace_probe_syscall, .report_death=stap_utrace_task_finder_report_death },";
- s.op->line() << " .flags=(UTRACE_EVENT(SYSCALL_ENTRY)|UTRACE_EVENT(DEATH)),";
+ s.op->line() << " .events=(UTRACE_EVENT(SYSCALL_ENTRY)|UTRACE_EVENT(DEATH)),";
break;
- case UDPF_SYSCALL_EXIT:
+ case UDPF_SYSCALL_RETURN:
+ s.op->line() << " .flags=(UDPF_SYSCALL_RETURN),";
s.op->line() << " .ops={ .report_syscall_exit=stap_utrace_probe_syscall, .report_death=stap_utrace_task_finder_report_death },";
- s.op->line() << " .flags=(UTRACE_EVENT(SYSCALL_EXIT)|UTRACE_EVENT(DEATH)),";
+ s.op->line() << " .events=(UTRACE_EVENT(SYSCALL_EXIT)|UTRACE_EVENT(DEATH)),";
+ break;
+ case UDPF_NONE:
+ s.op->line() << " .flags=(UDPF_NONE),";
+ s.op->line() << " .ops={ },";
+ s.op->line() << " .events=0,";
break;
default:
throw semantic_error ("bad utrace probe flag");
@@ -5379,6 +5521,40 @@ utrace_derived_probe_group::emit_probe_decl (systemtap_session& s,
void
+utrace_derived_probe_group::emit_vm_callback_probe_decl (systemtap_session& s,
+ bool has_path,
+ string path,
+ int64_t pid,
+ string vm_callback)
+{
+ s.op->newline() << "{";
+ s.op->line() << " .tgt={";
+
+ if (has_path)
+ {
+ s.op->line() << " .pathname=\"" << path << "\",";
+ s.op->line() << " .pid=0,";
+ }
+ else
+ {
+ s.op->line() << " .pathname=NULL,";
+ s.op->line() << " .pid=" << pid << ",";
+ }
+
+ s.op->line() << " .callback=NULL,";
+ s.op->line() << " .vm_callback=&" << vm_callback << ",";
+ s.op->line() << " },";
+ s.op->line() << " .pp=\"internal\",";
+ s.op->line() << " .ph=NULL,";
+ s.op->line() << " .flags=(UDPF_NONE),";
+ s.op->line() << " .ops={ NULL },";
+ s.op->line() << " .events=0,";
+ s.op->line() << " .engine_attached=0,";
+ s.op->line() << " },";
+}
+
+
+void
utrace_derived_probe_group::emit_module_decls (systemtap_session& s)
{
if (probes_by_path.empty() && probes_by_pid.empty())
@@ -5386,20 +5562,34 @@ utrace_derived_probe_group::emit_module_decls (systemtap_session& s)
s.op->newline();
s.op->newline() << "/* ---- utrace probes ---- */";
+ s.op->newline() << "enum utrace_derived_probe_flags {";
+ s.op->indent(1);
+ s.op->newline() << "UDPF_NONE,";
+ s.op->newline() << "UDPF_BEGIN,";
+ s.op->newline() << "UDPF_END,";
+ s.op->newline() << "UDPF_THREAD_BEGIN,";
+ s.op->newline() << "UDPF_THREAD_END,";
+ s.op->newline() << "UDPF_SYSCALL,";
+ s.op->newline() << "UDPF_SYSCALL_RETURN,";
+ s.op->newline() << "UDPF_NFLAGS";
+ s.op->newline(-1) << "};";
+
s.op->newline() << "struct stap_utrace_probe {";
s.op->indent(1);
s.op->newline() << "struct stap_task_finder_target tgt;";
s.op->newline() << "const char *pp;";
s.op->newline() << "void (*ph) (struct context*);";
+ s.op->newline() << "enum utrace_derived_probe_flags flags;";
s.op->newline() << "struct utrace_engine_ops ops;";
- s.op->newline() << "unsigned long flags;";
+ s.op->newline() << "unsigned long events;";
s.op->newline() << "int engine_attached;";
s.op->newline(-1) << "};";
- // Output handler function for CLONE events
- if (flags_seen[UDPF_CLONE])
+
+ // Output handler function for UDPF_BEGIN and UDPF_THREAD_BEGIN
+ if (flags_seen[UDPF_BEGIN] || flags_seen[UDPF_THREAD_BEGIN])
{
- s.op->newline() << "static u32 stap_utrace_probe_clone(struct utrace_attached_engine *engine, struct task_struct *parent, unsigned long clone_flags, struct task_struct *child) {";
+ s.op->newline() << "static u32 stap_utrace_probe_quiesce(struct utrace_attached_engine *engine, struct task_struct *tsk) {";
s.op->indent(1);
s.op->newline() << "struct stap_utrace_probe *p = (struct stap_utrace_probe *)engine->data;";
@@ -5410,12 +5600,15 @@ utrace_derived_probe_group::emit_module_decls (systemtap_session& s)
s.op->newline() << "(*p->ph) (c);";
common_probe_entryfn_epilogue (s.op);
- s.op->newline() << "return UTRACE_ACTION_RESUME;";
+ // UTRACE_ACTION_NEWSTATE not needed here to clear quiesce since
+ // we're detaching - utrace automatically restarts the thread.
+ s.op->newline() << "debug_task_finder_detach();";
+ s.op->newline() << "return UTRACE_ACTION_DETACH;";
s.op->newline(-1) << "}";
}
- // Output handler function for EXEC and DEATH events
- if (flags_seen[UDPF_EXEC] || flags_seen[UDPF_DEATH])
+ // Output handler function for UDPF_END and UDPF_THREAD_END
+ if (flags_seen[UDPF_END] || flags_seen[UDPF_THREAD_END])
{
s.op->newline() << "static void stap_utrace_probe_handler(struct task_struct *tsk, struct stap_utrace_probe *p) {";
s.op->indent(1);
@@ -5432,7 +5625,7 @@ utrace_derived_probe_group::emit_module_decls (systemtap_session& s)
}
// Output handler function for SYSCALL_ENTRY and SYSCALL_EXIT events
- if (flags_seen[UDPF_SYSCALL_ENTRY] || flags_seen[UDPF_SYSCALL_EXIT])
+ if (flags_seen[UDPF_SYSCALL] || flags_seen[UDPF_SYSCALL_RETURN])
{
s.op->newline() << "static u32 stap_utrace_probe_syscall(struct utrace_attached_engine *engine, struct task_struct *tsk, struct pt_regs *regs) {";
s.op->indent(1);
@@ -5450,9 +5643,9 @@ utrace_derived_probe_group::emit_module_decls (systemtap_session& s)
s.op->newline(-1) << "}";
}
- // Output task finder callback routine that gets called for all
+ // Output task_finder callback routine that gets called for all
// utrace probe types.
- s.op->newline() << "static int _stp_utrace_probe_cb(struct task_struct *tsk, int register_p, struct stap_task_finder_target *tgt) {";
+ s.op->newline() << "static int _stp_utrace_probe_cb(struct task_struct *tsk, int register_p, int process_p, struct stap_task_finder_target *tgt) {";
s.op->indent(1);
s.op->newline() << "int rc = 0;";
s.op->newline() << "struct stap_utrace_probe *p = container_of(tgt, struct stap_utrace_probe, tgt);";
@@ -5463,74 +5656,135 @@ utrace_derived_probe_group::emit_module_decls (systemtap_session& s)
s.op->newline() << "switch (p->flags) {";
s.op->indent(1);
- // When registering an exec probe, we can't install a utrace engine,
- // since we're already in a exec event. So, we just call the probe
- // directly. Note that for existing threads, this won't really work
- // since our state isn't STAP_SESSION_RUNNING yet. But that's OK,
- // since this isn't really a 'exec' event - it is a notification
- // that task_finder found an interesting process.
- if (flags_seen[UDPF_EXEC])
- {
- s.op->newline() << "case UTRACE_EVENT(EXEC):";
+
+ // When receiving a UTRACE_EVENT(CLONE) event, we can't call the
+ // begin/thread.begin probe directly. So, we'll just attach an
+ // engine that waits for the thread to quiesce. When the thread
+ // quiesces, then call the probe.
+ if (flags_seen[UDPF_BEGIN])
+ {
+ s.op->newline() << "case UDPF_BEGIN:";
s.op->indent(1);
- s.op->newline() << "stap_utrace_probe_handler(tsk, p);";
- s.op->newline() << "break;";
- s.op->indent(-1);
- }
- // For death probes, do nothing at registration time. We'll handle
- // these in the 'register_p == 0' case.
- if (flags_seen[UDPF_DEATH])
- {
- s.op->newline() << "case UTRACE_EVENT(DEATH):";
+ s.op->newline() << "if (process_p) {";
+ s.op->indent(1);
+ s.op->newline() << "rc = stap_utrace_attach(tsk, &p->ops, p, p->events);";
+ s.op->newline() << "if (rc == 0) {";
s.op->indent(1);
+ s.op->newline() << "p->engine_attached = 1;";
+ s.op->newline(-1) << "}";
+ s.op->newline(-1) << "}";
s.op->newline() << "break;";
s.op->indent(-1);
- }
- // Attach an engine for CLONE, SYSCALL_ENTRY, and SYSCALL_EXIT events.
- if (flags_seen[UDPF_CLONE] || flags_seen[UDPF_SYSCALL_ENTRY]
- || flags_seen[UDPF_SYSCALL_EXIT])
- {
- s.op->newline() << "case (UTRACE_EVENT(CLONE)|UTRACE_EVENT(DEATH)):";
- s.op->newline() << "case (UTRACE_EVENT(SYSCALL_ENTRY)|UTRACE_EVENT(DEATH)):";
- s.op->newline() << "case (UTRACE_EVENT(SYSCALL_EXIT)|UTRACE_EVENT(DEATH)):";
+ }
+ if (flags_seen[UDPF_THREAD_BEGIN])
+ {
+ s.op->newline() << "case UDPF_THREAD_BEGIN:";
s.op->indent(1);
- s.op->newline() << "engine = utrace_attach(tsk, UTRACE_ATTACH_CREATE, &p->ops, p);";
- s.op->newline() << "if (IS_ERR(engine)) {";
+ s.op->newline() << "if (! process_p) {";
s.op->indent(1);
- s.op->newline() << "int error = -PTR_ERR(engine);";
- s.op->newline() << "if (error != ENOENT) {";
+ s.op->newline() << "rc = stap_utrace_attach(tsk, &p->ops, p, p->events);";
+ s.op->newline() << "if (rc == 0) {";
s.op->indent(1);
- s.op->newline() << "_stp_error(\"utrace_attach returned error %d on pid %d\", error, (int)tsk->pid);";
- s.op->newline() << "rc = error;";
+ s.op->newline() << "p->engine_attached = 1;";
s.op->newline(-1) << "}";
s.op->newline(-1) << "}";
- s.op->newline() << "else if (unlikely(engine == NULL)) {";
+ s.op->newline() << "break;";
+ s.op->indent(-1);
+ }
+
+ // For end/thread_end probes, do nothing at registration time.
+ // We'll handle these in the 'register_p == 0' case.
+ if (flags_seen[UDPF_END] || flags_seen[UDPF_THREAD_END])
+ {
+ s.op->newline() << "case UDPF_END:";
+ s.op->newline() << "case UDPF_THREAD_END:";
s.op->indent(1);
- s.op->newline() << "_stp_error(\"utrace_attach returned NULL on pid %d!\", (int)tsk->pid);";
- s.op->newline() << "rc = ENOENT;";
- s.op->newline(-1) << "}";
- s.op->newline() << "else {";
+ s.op->newline() << "break;";
+ s.op->indent(-1);
+ }
+
+ // Attach an engine for SYSCALL_ENTRY and SYSCALL_EXIT events.
+ if (flags_seen[UDPF_SYSCALL] || flags_seen[UDPF_SYSCALL_RETURN])
+ {
+ s.op->newline() << "case UDPF_SYSCALL:";
+ s.op->newline() << "case UDPF_SYSCALL_RETURN:";
+ s.op->indent(1);
+ s.op->newline() << "rc = stap_utrace_attach(tsk, &p->ops, p, p->events);";
+ s.op->newline() << "if (rc == 0) {";
s.op->indent(1);
- s.op->newline() << "utrace_set_flags(tsk, engine, p->flags);";
s.op->newline() << "p->engine_attached = 1;";
s.op->newline(-1) << "}";
s.op->newline() << "break;";
s.op->indent(-1);
}
+
+ s.op->newline() << "default:";
+ s.op->indent(1);
+ s.op->newline() << "_stp_error(\"unhandled flag value %d at %s:%d\", p->flags, __FUNCTION__, __LINE__);";
+ s.op->newline() << "break;";
+ s.op->indent(-1);
s.op->newline(-1) << "}";
s.op->newline(-1) << "}";
+
// Since this engine could be attached to multiple threads, don't
- // cleanup here. We'll cleanup at module unload time.
+ // call stap_utrace_detach_ops() here.
s.op->newline() << "else {";
s.op->indent(1);
+ s.op->newline() << "switch (p->flags) {";
+ s.op->indent(1);
// For death probes, go ahead and call the probe directly.
- if (flags_seen[UDPF_DEATH])
+ if (flags_seen[UDPF_END])
+ {
+ s.op->newline() << "case UDPF_END:";
+ s.op->indent(1);
+ s.op->newline() << "if (process_p) {";
+ s.op->indent(1);
+ s.op->newline() << "stap_utrace_probe_handler(tsk, p);";
+ s.op->newline(-1) << "}";
+ s.op->newline() << "break;";
+ s.op->indent(-1);
+ }
+ if (flags_seen[UDPF_THREAD_END])
{
- s.op->newline() << "if (p->flags == UTRACE_EVENT(DEATH)) {";
+ s.op->newline() << "case UDPF_THREAD_END:";
+ s.op->indent(1);
+ s.op->newline() << "if (! process_p) {";
s.op->indent(1);
s.op->newline() << "stap_utrace_probe_handler(tsk, p);";
s.op->newline(-1) << "}";
+ s.op->newline() << "break;";
+ s.op->indent(-1);
}
+
+ // For begin/thread_begin probes, at deregistration time we'll try
+ // to detach. This will only be necessary if the new thread/process
+ // got killed before the probe got run in the UTRACE_EVENT(QUIESCE)
+ // handler.
+ if (flags_seen[UDPF_BEGIN] || flags_seen[UDPF_THREAD_BEGIN]
+ || flags_seen[UDPF_SYSCALL] || flags_seen[UDPF_SYSCALL_RETURN])
+ {
+ s.op->newline() << "case UDPF_BEGIN:";
+ s.op->newline() << "case UDPF_THREAD_BEGIN:";
+ s.op->newline() << "case UDPF_SYSCALL:";
+ s.op->newline() << "case UDPF_SYSCALL_RETURN:";
+ s.op->indent(1);
+ s.op->newline() << "engine = utrace_attach(tsk, UTRACE_ATTACH_MATCH_OPS, &p->ops, 0);";
+ s.op->newline() << "if (! IS_ERR(engine) && engine != NULL) {";
+ s.op->indent(1);
+ s.op->newline() << "utrace_detach(tsk, engine);";
+ s.op->newline() << "debug_task_finder_detach();";
+
+ s.op->newline(-1) << "}";
+ s.op->newline() << "break;";
+ s.op->indent(-1);
+ }
+
+ s.op->newline() << "default:";
+ s.op->indent(1);
+ s.op->newline() << "_stp_error(\"unhandled flag value %d at %s:%d\", p->flags, __FUNCTION__, __LINE__);";
+ s.op->newline() << "break;";
+ s.op->indent(-1);
+ s.op->newline(-1) << "}";
s.op->newline(-1) << "}";
s.op->newline() << "return rc;";
s.op->newline(-1) << "}";
@@ -5544,6 +5798,14 @@ utrace_derived_probe_group::emit_module_decls (systemtap_session& s)
for (p_b_path_iterator it = probes_by_path.begin();
it != probes_by_path.end(); it++)
{
+ // Emit a "fake" probe decl that is really a hook for to get
+ // our vm_callback called.
+ string path = it->first;
+ s.op->newline() << "#ifdef DEBUG_TASK_FINDER_VMA";
+ emit_vm_callback_probe_decl (s, true, path, (int64_t)0,
+ "__stp_tf_vm_cb");
+ s.op->newline() << "#endif";
+
for (unsigned i = 0; i < it->second.size(); i++)
{
utrace_derived_probe *p = it->second[i];
@@ -5558,6 +5820,13 @@ utrace_derived_probe_group::emit_module_decls (systemtap_session& s)
for (p_b_pid_iterator it = probes_by_pid.begin();
it != probes_by_pid.end(); it++)
{
+ // Emit a "fake" probe decl that is really a hook for to get
+ // our vm_callback called.
+ s.op->newline() << "#ifdef DEBUG_TASK_FINDER_VMA";
+ emit_vm_callback_probe_decl (s, false, NULL, it->first,
+ "__stp_tf_vm_cb");
+ s.op->newline() << "#endif";
+
for (unsigned i = 0; i < it->second.size(); i++)
{
utrace_derived_probe *p = it->second[i];
@@ -5667,7 +5936,7 @@ struct uprobe_builder: public derived_probe_builder
virtual void build(systemtap_session & sess,
probe * base,
probe_point * location,
- std::map<std::string, literal *> const & parameters,
+ literal_map_t const & parameters,
vector<derived_probe *> & finished_results)
{
int64_t process, address;
@@ -5802,6 +6071,8 @@ uprobe_derived_probe_group::emit_module_exit (systemtap_session& s)
// ------------------------------------------------------------------------
+static string TOK_TIMER("timer");
+
struct timer_derived_probe: public derived_probe
{
int64_t interval, randomize;
@@ -5983,7 +6254,7 @@ struct profile_builder: public derived_probe_builder
virtual void build(systemtap_session & sess,
probe * base,
probe_point * location,
- std::map<std::string, literal *> const &,
+ literal_map_t const &,
vector<derived_probe *> & finished_results)
{
finished_results.push_back(new profile_derived_probe(sess, base, location));
@@ -6090,6 +6361,10 @@ profile_derived_probe_group::emit_module_exit (systemtap_session& s)
// ------------------------------------------------------------------------
+static string TOK_PROCFS("procfs");
+static string TOK_READ("read");
+static string TOK_WRITE("write");
+
struct procfs_derived_probe: public derived_probe
{
string path;
@@ -6496,7 +6771,7 @@ struct procfs_builder: public derived_probe_builder
virtual void build(systemtap_session & sess,
probe * base,
probe_point * location,
- std::map<std::string, literal *> const & parameters,
+ literal_map_t const & parameters,
vector<derived_probe *> & finished_results);
};
@@ -6505,13 +6780,13 @@ void
procfs_builder::build(systemtap_session & sess,
probe * base,
probe_point * location,
- std::map<std::string, literal *> const & parameters,
+ literal_map_t const & parameters,
vector<derived_probe *> & finished_results)
{
string path;
- bool has_procfs = get_param(parameters, "procfs", path);
- bool has_read = (parameters.find("read") != parameters.end());
- bool has_write = (parameters.find("write") != parameters.end());
+ bool has_procfs = get_param(parameters, TOK_PROCFS, path);
+ bool has_read = (parameters.find(TOK_READ) != parameters.end());
+ bool has_write = (parameters.find(TOK_WRITE) != parameters.end());
// If no procfs path, default to "command". The runtime will do
// this for us, but if we don't do it here, we'll think the
@@ -6568,6 +6843,8 @@ procfs_builder::build(systemtap_session & sess,
// statically inserted macro-based derived probes
// ------------------------------------------------------------------------
+static string TOK_MARK("mark");
+static string TOK_FORMAT("format");
struct mark_arg
{
@@ -6802,9 +7079,9 @@ mark_derived_probe::mark_derived_probe (systemtap_session &s,
{
// create synthetic probe point name; preserve condition
vector<probe_point::component*> comps;
- comps.push_back (new probe_point::component ("kernel"));
- comps.push_back (new probe_point::component ("mark", new literal_string (probe_name)));
- comps.push_back (new probe_point::component ("format", new literal_string (probe_format)));
+ comps.push_back (new probe_point::component (TOK_KERNEL));
+ comps.push_back (new probe_point::component (TOK_MARK, new literal_string (probe_name)));
+ comps.push_back (new probe_point::component (TOK_FORMAT, new literal_string (probe_format)));
this->sole_location()->components = comps;
// expand the marker format
@@ -7161,7 +7438,7 @@ public:
void build(systemtap_session & sess,
probe * base,
probe_point * location,
- std::map<std::string, literal *> const & parameters,
+ literal_map_t const & parameters,
vector<derived_probe *> & finished_results);
};
@@ -7170,13 +7447,13 @@ void
mark_builder::build(systemtap_session & sess,
probe * base,
probe_point *loc,
- std::map<std::string, literal *> const & parameters,
+ literal_map_t const & parameters,
vector<derived_probe *> & finished_results)
{
string mark_str_val;
- bool has_mark_str = get_param (parameters, "mark", mark_str_val);
+ bool has_mark_str = get_param (parameters, TOK_MARK, mark_str_val);
string mark_format_val;
- bool has_mark_format = get_param (parameters, "format", mark_format_val);
+ bool has_mark_format = get_param (parameters, TOK_FORMAT, mark_format_val);
assert (has_mark_str);
(void) has_mark_str;
@@ -7460,7 +7737,7 @@ struct timer_builder: public derived_probe_builder
{
virtual void build(systemtap_session & sess,
probe * base, probe_point * location,
- std::map<std::string, literal *> const & parameters,
+ literal_map_t const & parameters,
vector<derived_probe *> & finished_results);
static void register_patterns(match_node *root);
@@ -7470,7 +7747,7 @@ void
timer_builder::build(systemtap_session & sess,
probe * base,
probe_point * location,
- std::map<std::string, literal *> const & parameters,
+ literal_map_t const & parameters,
vector<derived_probe *> & finished_results)
{
int64_t period, rand=0;
@@ -7538,7 +7815,7 @@ timer_builder::register_patterns(match_node *root)
{
derived_probe_builder *builder = new timer_builder();
- root = root->bind("timer");
+ root = root->bind(TOK_TIMER);
root->bind_num("s")->bind(builder);
root->bind_num("s")->bind_num("randomize")->bind(builder);
@@ -7682,7 +7959,7 @@ struct perfmon_builder: public derived_probe_builder
virtual void build(systemtap_session & sess,
probe * base,
probe_point * location,
- std::map<std::string, literal *> const & parameters,
+ literal_map_t const & parameters,
vector<derived_probe *> & finished_results)
{
string event;
@@ -7994,18 +8271,19 @@ perfmon_derived_probe_group::emit_module_init (translator_output* o)
void
register_standard_tapsets(systemtap_session & s)
{
- s.pattern_root->bind("begin")->bind(new be_builder(BEGIN));
- s.pattern_root->bind_num("begin")->bind(new be_builder(BEGIN));
- s.pattern_root->bind("end")->bind(new be_builder(END));
- s.pattern_root->bind_num("end")->bind(new be_builder(END));
- s.pattern_root->bind("error")->bind(new be_builder(ERROR));
- s.pattern_root->bind_num("error")->bind(new be_builder(ERROR));
+ s.pattern_root->bind(TOK_BEGIN)->bind(new be_builder(BEGIN));
+ s.pattern_root->bind_num(TOK_BEGIN)->bind(new be_builder(BEGIN));
+ s.pattern_root->bind(TOK_END)->bind(new be_builder(END));
+ s.pattern_root->bind_num(TOK_END)->bind(new be_builder(END));
+ s.pattern_root->bind(TOK_ERROR)->bind(new be_builder(ERROR));
+ s.pattern_root->bind_num(TOK_ERROR)->bind(new be_builder(ERROR));
- s.pattern_root->bind("never")->bind(new never_builder());
+ s.pattern_root->bind(TOK_NEVER)->bind(new never_builder());
timer_builder::register_patterns(s.pattern_root);
- s.pattern_root->bind("timer")->bind("profile")->bind(new profile_builder());
- s.pattern_root->bind("perfmon")->bind_str("counter")->bind(new perfmon_builder());
+ s.pattern_root->bind(TOK_TIMER)->bind("profile")->bind(new profile_builder());
+ s.pattern_root->bind("perfmon")->bind_str("counter")
+ ->bind(new perfmon_builder());
// dwarf-based kernel/module parts
dwarf_derived_probe::register_patterns(s.pattern_root);
@@ -8019,37 +8297,44 @@ register_standard_tapsets(systemtap_session & s)
->bind(new uprobe_builder ());
// utrace user-space probes
- s.pattern_root->bind_str(TOK_PROCESS)->bind("clone")
+ s.pattern_root->bind_str(TOK_PROCESS)->bind(TOK_BEGIN)
->bind(new utrace_builder ());
- s.pattern_root->bind_num(TOK_PROCESS)->bind("clone")
+ s.pattern_root->bind_num(TOK_PROCESS)->bind(TOK_BEGIN)
->bind(new utrace_builder ());
- s.pattern_root->bind_str(TOK_PROCESS)->bind("exec")
+ s.pattern_root->bind_str(TOK_PROCESS)->bind(TOK_END)
->bind(new utrace_builder ());
- s.pattern_root->bind_num(TOK_PROCESS)->bind("exec")
+ s.pattern_root->bind_num(TOK_PROCESS)->bind(TOK_END)
->bind(new utrace_builder ());
- s.pattern_root->bind_str(TOK_PROCESS)->bind("syscall")
+ s.pattern_root->bind_str(TOK_PROCESS)->bind(TOK_THREAD)->bind(TOK_BEGIN)
->bind(new utrace_builder ());
- s.pattern_root->bind_num(TOK_PROCESS)->bind("syscall")
+ s.pattern_root->bind_num(TOK_PROCESS)->bind(TOK_THREAD)->bind(TOK_BEGIN)
->bind(new utrace_builder ());
- s.pattern_root->bind_str(TOK_PROCESS)->bind("syscall")->bind(TOK_RETURN)
+ s.pattern_root->bind_str(TOK_PROCESS)->bind(TOK_THREAD)->bind(TOK_END)
->bind(new utrace_builder ());
- s.pattern_root->bind_num(TOK_PROCESS)->bind("syscall")->bind(TOK_RETURN)
+ s.pattern_root->bind_num(TOK_PROCESS)->bind(TOK_THREAD)->bind(TOK_END)
->bind(new utrace_builder ());
- s.pattern_root->bind_str(TOK_PROCESS)->bind("death")
+ s.pattern_root->bind_str(TOK_PROCESS)->bind(TOK_SYSCALL)
->bind(new utrace_builder ());
- s.pattern_root->bind_num(TOK_PROCESS)->bind("death")
+ s.pattern_root->bind_num(TOK_PROCESS)->bind(TOK_SYSCALL)
+ ->bind(new utrace_builder ());
+ s.pattern_root->bind_str(TOK_PROCESS)->bind(TOK_SYSCALL)->bind(TOK_RETURN)
+ ->bind(new utrace_builder ());
+ s.pattern_root->bind_num(TOK_PROCESS)->bind(TOK_SYSCALL)->bind(TOK_RETURN)
->bind(new utrace_builder ());
// marker-based parts
- s.pattern_root->bind("kernel")->bind_str("mark")->bind(new mark_builder());
- s.pattern_root->bind("kernel")->bind_str("mark")->bind_str("format")
+ s.pattern_root->bind(TOK_KERNEL)->bind_str(TOK_MARK)
+ ->bind(new mark_builder());
+ s.pattern_root->bind(TOK_KERNEL)->bind_str(TOK_MARK)->bind_str(TOK_FORMAT)
->bind(new mark_builder());
// procfs parts
- s.pattern_root->bind("procfs")->bind("read")->bind(new procfs_builder());
- s.pattern_root->bind_str("procfs")->bind("read")->bind(new procfs_builder());
- s.pattern_root->bind("procfs")->bind("write")->bind(new procfs_builder());
- s.pattern_root->bind_str("procfs")->bind("write")->bind(new procfs_builder());
+ s.pattern_root->bind(TOK_PROCFS)->bind(TOK_READ)->bind(new procfs_builder());
+ s.pattern_root->bind_str(TOK_PROCFS)->bind(TOK_READ)
+ ->bind(new procfs_builder());
+ s.pattern_root->bind(TOK_PROCFS)->bind(TOK_WRITE)->bind(new procfs_builder());
+ s.pattern_root->bind_str(TOK_PROCFS)->bind(TOK_WRITE)
+ ->bind(new procfs_builder());
}
diff --git a/testsuite/.gitignore b/testsuite/.gitignore
index 34a4e8d0..19b30bf1 100644
--- a/testsuite/.gitignore
+++ b/testsuite/.gitignore
@@ -1,4 +1,4 @@
-.systemtap
+.systemtap-*
site.exp
systemtap.log
systemtap.sum
diff --git a/testsuite/ChangeLog b/testsuite/ChangeLog
index fa6e4fad..4fda9c5f 100644
--- a/testsuite/ChangeLog
+++ b/testsuite/ChangeLog
@@ -1,3 +1,111 @@
+2008-06-23 Stan Cox <scox@redhat.com>
+
+ * systemtap.base/stmt_rel.stp: Added test for
+ kernel.statement("Func@File:*")
+
+2008-06-18 Josh Stone <joshua.i.stone@intel.com>
+
+ * systemtap.base/optim_voidstmt.stp: Add tests for various statement
+ optimizations that we should now be eliding.
+
+2008-06-16 Frank Ch. Eigler <fche@elastic.org>
+
+ * systemtap.base/warnings.exp: Adjust warning count again (me1 and
+ elide were formerly duplicated).
+
+2008-06-16 Stan Cox <scox@redhat.com>
+
+ * systemtap.base/warnings.stp: Added PR 6611 warning tests.
+ * systemtap.base/warnings.exp: Reset warning count.
+
+2008-06-13 Frank Ch. Eigler <fche@elastic.org>
+
+ * lib/stap_run.exp: Remove module/cache warning boilerplate.
+
+2008-06-11 Mark Wielaard <mwielaard@redhat.com>
+
+ * systemtap.base/warnings.exp: Expect 11 warning plus 1 .ko output
+ line.
+
+2008-06-11 David Smith <dsmith@redhat.com>
+
+ * systemtap.base/utrace_p5.exp: Made changes to work when not
+ configured in the src directory.
+ * systemtap.base/utrace_p5_multi.c: Made changes to work on x86_64
+ systems.
+
+ * systemtap.base/utrace_p5.exp: Added 'process().thread.begin' and
+ 'process().thread.end' tests.
+ * systemtap.base/utrace_p5_multi.c: Added multi-threaded test
+ program for utrace_p5.exp.
+ * .gitignore: Updated.
+
+2008-06-10 Stan Cox <scox@redhat.com>
+
+ * systemtap.base/warnings.exp: Adjust for duplicate warning elimination.
+
+2008-06-10 Frank Ch. Eigler <fche@elastic.org>
+
+ PR 6470.
+ * parseko/preprocess08.stp, ...08b.stp: Revised/new test.
+ * systemtap.base/cmd_parse.exp: Added some argv[] tests.
+
+2008-06-09 Stan Cox <scox@redhat.com>
+
+ * systemtap.base/stmt_rel.stp: New test.
+ * systemtap.base/stmt_rel.exp: Likewise.
+
+2008-06-06 David Smith <dsmith@redhat.com>
+
+ * systemtap.base/utrace_p4.exp: Updated for utrace probe changes.
+ * systemtap.base/utrace_p5.exp: Ditto.
+
+2008-06-03 Frank Ch. Eigler <fche@elastic.org>
+
+ * systemtap.context/backtrace.tcl: Tolerate "(inexact)" backtraces.
+
+2008-05-30 Wenji Huang <wenji.huang@oracle.com>
+
+ * systemtap.base/debugpath.exp: Add path for self-built kernel.
+
+2008-05-28 Josh Stone <joshua.i.stone@intel.com>
+
+ PR 6529
+ * systemtap.base/error_fn.*: New tests.
+
+2008-05-28 Mark Wielaard <mwielaard@redhat.com>
+
+ * testsuite/Makefile.am (clean-local): Correct redirect of stderr.
+ (installcheck): Don't depend on clean.
+
+2008-05-28 Mark Wielaard <mwielaard@redhat.com>
+
+ * lib/systemtap.exp (setup_systemtap_environment): Create user
+ based cache dir.
+ * systemtap.base/cache.exp: Likewise.
+ * Makefile.am (clean-local): Try to remove all .systemtap and
+ .cache_test dirs.
+
+2008-05-26 Frank Ch. Eigler <fche@elastic.org>
+
+ * testsuite/stmtvars.exp: Tweaked matching regexps, tested on
+ f7, rhel5.
+
+2008-05-24 Frank Ch. Eigler <fche@elastic.org>
+
+ * configure.ac (enable-dejazilla): Add option, default off.
+ * Makefile.am (*check): Send systemtap.sum to dejazilla if enabled$a
+ * execrc: New helper script for runtest rc overriding.
+ * configure, Makefile.in: Regenerated.
+
+2008-05-23 Frank Ch. Eigler <fche@elastic.org>
+
+ * buildok/{nfs,rpc}-all-probes.stp: Suppress warnings from empty probe
+ bodies.
+ * systemtap.pass1-4/buidok.exp: Mark above as kfail due to bug #4413.
+ While there, also mark the process_test kfail for #1155, though even
+ it fails only sporadically.
+
2008-05-21 Frank Ch. Eigler <fche@elastic.org>
PR 6538
diff --git a/testsuite/Makefile.am b/testsuite/Makefile.am
index edaaff3c..b66bb75f 100644
--- a/testsuite/Makefile.am
+++ b/testsuite/Makefile.am
@@ -3,20 +3,30 @@
AUTOMAKE_OPTIONS = dejagnu
-# The stap symlink is to enable "#! stap" test scripts.
all-local:
@echo Run \"make check\" or \"make installcheck\".
+ @if test -n "$(DEJAZILLA)"; then echo Test results will be emailed to $(DEJAZILLA); fi
clean-local:
-rm -f ./stap site.exp systemtap.sum systemtap.log
- -rm -rf .systemtap .cache_test 2>/dev/null
+ -rm -rf .systemtap* .cache_test* 2>/dev/null
-installcheck-local: clean site.exp
- $(MAKE) AM_RUNTESTFLAGS="--tool_opts install" check-DEJAGNU
+DEJAZILLA=@dejazilla@
+
+# automake's dejagnu library already runs check-DEJAGNU before check-local
+# That's why we need to add "execrc" to $(RUNTEST) - to ensure that this
+# subtarget gets run even if runtest per se exits with a failure.
+check-local:
+ if test -n "$(DEJAZILLA)"; then mail $(DEJAZILLA) < systemtap.sum; fi
+
+# but installcheck does not follow an implicit check-DEJAGNU, go figure
+installcheck: site.exp
+ -$(MAKE) $(AM_MAKEFLAGS) check-DEJAGNU RUNTESTFLAGS="$(RUNTESTFLAGS) --tool_opts install"
+ if test -n "$(DEJAZILLA)"; then mail $(DEJAZILLA) < systemtap.sum; fi
SRCDIR = $(shell cd $(srcdir); pwd)
-EXTRA_DIST = config lib systemtap \
+EXTRA_DIST = execrc config lib systemtap \
parseok parseko semok semko transok transko buildok buildok \
systemtap.syscall systemtap.stress systemtap.string \
systemtap.pass1-4 systemtap.samples systemtap.printf \
@@ -30,4 +40,6 @@ LD_LIBRARY_PATH=$(DESTDIR)$(libdir)/systemtap
CRASH_LIBDIR=$(DESTDIR)$(libdir)/systemtap
SYSTEMTAP_PATH=$(DESTDIR)$(bindir)
-RUNTEST="env SYSTEMTAP_RUNTIME=$(SYSTEMTAP_RUNTIME) SYSTEMTAP_TAPSET=$(SYSTEMTAP_TAPSET) LD_LIBRARY_PATH=$(LD_LIBRARY_PATH) CRASH_LIBDIR=$(CRASH_LIBDIR) PATH=$(SYSTEMTAP_PATH):$$PATH runtest"
+RUNTESTDEFAULTFLAGS = --tool $$tool --srcdir $$srcdir
+EXPECT = expect
+RUNTEST="env SYSTEMTAP_RUNTIME=$(SYSTEMTAP_RUNTIME) SYSTEMTAP_TAPSET=$(SYSTEMTAP_TAPSET) LD_LIBRARY_PATH=$(LD_LIBRARY_PATH) CRASH_LIBDIR=$(CRASH_LIBDIR) PATH=$(SYSTEMTAP_PATH):$$PATH $(srcdir)/execrc runtest"
diff --git a/testsuite/Makefile.in b/testsuite/Makefile.in
index 99acf141..c8b07bdc 100644
--- a/testsuite/Makefile.in
+++ b/testsuite/Makefile.in
@@ -49,8 +49,6 @@ CONFIG_CLEAN_FILES =
SOURCES =
DIST_SOURCES =
DEJATOOL = $(PACKAGE)
-RUNTESTDEFAULTFLAGS = --tool $$tool --srcdir $$srcdir
-EXPECT = expect
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
distdir = $(PACKAGE)-$(VERSION)
top_distdir = $(distdir)
@@ -107,6 +105,7 @@ build_alias = @build_alias@
builddir = @builddir@
datadir = @datadir@
datarootdir = @datarootdir@
+dejazilla = @dejazilla@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
@@ -134,8 +133,9 @@ target_alias = @target_alias@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
AUTOMAKE_OPTIONS = dejagnu
+DEJAZILLA = @dejazilla@
SRCDIR = $(shell cd $(srcdir); pwd)
-EXTRA_DIST = config lib systemtap \
+EXTRA_DIST = execrc config lib systemtap \
parseok parseko semok semko transok transko buildok buildok \
systemtap.syscall systemtap.stress systemtap.string \
systemtap.pass1-4 systemtap.samples systemtap.printf \
@@ -149,7 +149,9 @@ SYSTEMTAP_TAPSET = $(DESTDIR)$(pkgdatadir)/tapset
LD_LIBRARY_PATH = $(DESTDIR)$(libdir)/systemtap
CRASH_LIBDIR = $(DESTDIR)$(libdir)/systemtap
SYSTEMTAP_PATH = $(DESTDIR)$(bindir)
-RUNTEST = "env SYSTEMTAP_RUNTIME=$(SYSTEMTAP_RUNTIME) SYSTEMTAP_TAPSET=$(SYSTEMTAP_TAPSET) LD_LIBRARY_PATH=$(LD_LIBRARY_PATH) CRASH_LIBDIR=$(CRASH_LIBDIR) PATH=$(SYSTEMTAP_PATH):$$PATH runtest"
+RUNTESTDEFAULTFLAGS = --tool $$tool --srcdir $$srcdir
+EXPECT = expect
+RUNTEST = "env SYSTEMTAP_RUNTIME=$(SYSTEMTAP_RUNTIME) SYSTEMTAP_TAPSET=$(SYSTEMTAP_TAPSET) LD_LIBRARY_PATH=$(LD_LIBRARY_PATH) CRASH_LIBDIR=$(CRASH_LIBDIR) PATH=$(SYSTEMTAP_PATH):$$PATH $(srcdir)/execrc runtest"
all: all-am
.SUFFIXES:
@@ -351,7 +353,7 @@ distcleancheck: distclean
$(distcleancheck_listfiles) ; \
exit 1; } >&2
check-am: all-am
- $(MAKE) $(AM_MAKEFLAGS) check-DEJAGNU
+ $(MAKE) $(AM_MAKEFLAGS) check-DEJAGNU check-local
check: check-am
all-am: Makefile all-local
installdirs:
@@ -362,8 +364,6 @@ uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
-
-installcheck: installcheck-am
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
@@ -414,7 +414,7 @@ install-pdf: install-pdf-am
install-ps: install-ps-am
-installcheck-am: installcheck-local
+installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -f $(am__CONFIG_DISTCLEAN_FILES)
@@ -439,30 +439,38 @@ uninstall-am:
.MAKE: install-am install-strip
.PHONY: all all-am all-local am--refresh check check-DEJAGNU check-am \
- clean clean-generic clean-local dist dist-all dist-bzip2 \
- dist-gzip dist-shar dist-tarZ dist-zip distcheck distclean \
- distclean-DEJAGNU distclean-generic distcleancheck distdir \
- distuninstallcheck dvi dvi-am html html-am info info-am \
- install install-am install-data install-data-am install-dvi \
- install-dvi-am install-exec install-exec-am install-html \
- install-html-am install-info install-info-am install-man \
- install-pdf install-pdf-am install-ps install-ps-am \
- install-strip installcheck installcheck-am installcheck-local \
+ check-local clean clean-generic clean-local dist dist-all \
+ dist-bzip2 dist-gzip dist-shar dist-tarZ dist-zip distcheck \
+ distclean distclean-DEJAGNU distclean-generic distcleancheck \
+ distdir distuninstallcheck dvi dvi-am html html-am info \
+ info-am install install-am install-data install-data-am \
+ install-dvi install-dvi-am install-exec install-exec-am \
+ install-html install-html-am install-info install-info-am \
+ install-man install-pdf install-pdf-am install-ps \
+ install-ps-am install-strip installcheck installcheck-am \
installdirs maintainer-clean maintainer-clean-generic \
mostlyclean mostlyclean-generic pdf pdf-am ps ps-am uninstall \
uninstall-am
-# The stap symlink is to enable "#! stap" test scripts.
all-local:
@echo Run \"make check\" or \"make installcheck\".
+ @if test -n "$(DEJAZILLA)"; then echo Test results will be emailed to $(DEJAZILLA); fi
clean-local:
-rm -f ./stap site.exp systemtap.sum systemtap.log
- -rm -rf .systemtap .cache_test 2>/dev/null
-
-installcheck-local: clean site.exp
- $(MAKE) AM_RUNTESTFLAGS="--tool_opts install" check-DEJAGNU
+ -rm -rf .systemtap* .cache_test* 2>/dev/null
+
+# automake's dejagnu library already runs check-DEJAGNU before check-local
+# That's why we need to add "execrc" to $(RUNTEST) - to ensure that this
+# subtarget gets run even if runtest per se exits with a failure.
+check-local:
+ if test -n "$(DEJAZILLA)"; then mail $(DEJAZILLA) < systemtap.sum; fi
+
+# but installcheck does not follow an implicit check-DEJAGNU, go figure
+installcheck: site.exp
+ -$(MAKE) $(AM_MAKEFLAGS) check-DEJAGNU RUNTESTFLAGS="$(RUNTESTFLAGS) --tool_opts install"
+ if test -n "$(DEJAZILLA)"; then mail $(DEJAZILLA) < systemtap.sum; fi
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
diff --git a/testsuite/buildok/nfs-all-probes.stp b/testsuite/buildok/nfs-all-probes.stp
index fb492c8c..ebff3472 100755
--- a/testsuite/buildok/nfs-all-probes.stp
+++ b/testsuite/buildok/nfs-all-probes.stp
@@ -1,4 +1,4 @@
-#! stap -p4
+#! stap -wp4
// Tests if all probes in nfs.stp and nfs_proc.stp are resolvable.
diff --git a/testsuite/buildok/rpc-all-probes.stp b/testsuite/buildok/rpc-all-probes.stp
index 2ecc42c7..c85ff80b 100755
--- a/testsuite/buildok/rpc-all-probes.stp
+++ b/testsuite/buildok/rpc-all-probes.stp
@@ -1,4 +1,4 @@
-#! stap -p4
+#! stap -wp4
// Tests if all probes in rpc.stp are resolvable.
diff --git a/testsuite/configure b/testsuite/configure
index bd8237cb..93494726 100755
--- a/testsuite/configure
+++ b/testsuite/configure
@@ -640,6 +640,7 @@ am__untar
MAINTAINER_MODE_TRUE
MAINTAINER_MODE_FALSE
MAINT
+dejazilla
LIBOBJS
LTLIBOBJS'
ac_subst_files=''
@@ -1223,6 +1224,11 @@ Optional Features:
--enable-FEATURE[=ARG] include FEATURE [ARG=yes]
--enable-maintainer-mode enable make rules and dependencies not useful
(and sometimes confusing) to the casual installer
+ --enable-dejazilla[=EMAIL]
+ enable dejazilla support to automatically email test
+ results to a central public collection point
+ (default is disabled). Optional EMAIL overrides the
+ default email address.
Report bugs to <systemtap@sources.redhat.com>.
_ACEOF
@@ -2160,6 +2166,22 @@ fi
+# Check whether --enable-dejazilla was given.
+if test "${enable_dejazilla+set}" = set; then
+ enableval=$enable_dejazilla;
+fi
+
+case "$enable_dejazilla" in
+ no) dejazilla= ;;
+ yes) dejazilla=dejazilla@elastic.org ;;
+ *) dejazilla="$enable_dejazilla" ;;
+esac
+if test -n "$dejazilla"; then
+ { echo "$as_me:$LINENO: A \"make *check\" will email results to $dejazilla" >&5
+echo "$as_me: A \"make *check\" will email results to $dejazilla" >&6;}
+fi
+
+
ac_config_files="$ac_config_files Makefile"
cat >confcache <<\_ACEOF
@@ -2861,11 +2883,12 @@ am__untar!$am__untar$ac_delim
MAINTAINER_MODE_TRUE!$MAINTAINER_MODE_TRUE$ac_delim
MAINTAINER_MODE_FALSE!$MAINTAINER_MODE_FALSE$ac_delim
MAINT!$MAINT$ac_delim
+dejazilla!$dejazilla$ac_delim
LIBOBJS!$LIBOBJS$ac_delim
LTLIBOBJS!$LTLIBOBJS$ac_delim
_ACEOF
- if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 64; then
+ if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 65; then
break
elif $ac_last_try; then
{ { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5
diff --git a/testsuite/configure.ac b/testsuite/configure.ac
index 70d01e96..0fd78fe7 100644
--- a/testsuite/configure.ac
+++ b/testsuite/configure.ac
@@ -8,5 +8,20 @@ AC_CONFIG_AUX_DIR(..)
AM_INIT_AUTOMAKE([dejagnu foreign])
AM_MAINTAINER_MODE
+AC_ARG_ENABLE([dejazilla],
+ AS_HELP_STRING([--enable-dejazilla@<:@=EMAIL@:>@],
+ [enable dejazilla support to automatically email test results to a
+ central public collection point (default is disabled). Optional
+ EMAIL overrides the default email address.]))
+case "$enable_dejazilla" in
+ no) dejazilla= ;;
+ yes) dejazilla=dejazilla@elastic.org ;;
+ *) dejazilla="$enable_dejazilla" ;;
+esac
+if test -n "$dejazilla"; then
+ AC_MSG_NOTICE([A "make *check" will email results to $dejazilla])
+fi
+AC_SUBST(dejazilla)
+
AC_CONFIG_FILES(Makefile)
AC_OUTPUT
diff --git a/testsuite/execrc b/testsuite/execrc
new file mode 100755
index 00000000..deff87e7
--- /dev/null
+++ b/testsuite/execrc
@@ -0,0 +1,5 @@
+#! /bin/sh
+
+# Run given program, but return a successful rc anyway.
+eval $@
+exit 0
diff --git a/testsuite/lib/stap_run.exp b/testsuite/lib/stap_run.exp
index 42efa4f8..43964d8e 100644
--- a/testsuite/lib/stap_run.exp
+++ b/testsuite/lib/stap_run.exp
@@ -33,7 +33,6 @@ proc stap_run { TEST_NAME {LOAD_GEN_FUNCTION ""} {OUTPUT_CHECK_STRING ""} args }
eval spawn $cmd
expect {
-timeout 180
- -re {^Warning: using '-m' disables cache support.\r\n} {exp_continue}
-re {^WARNING: cannot find module [^\r]*DWARF[^\r]*\r\n} {exp_continue}
-re {^Pass\ ([1234]):[^\r]*\ in\ ([0-9]+)usr/([0-9]+)sys/([0-9]+)real\ ms\.\r\n}
{set pass$expect_out(1,string) "\t$expect_out(2,string)\t$expect_out(3,string)\t$expect_out(4,string)"; exp_continue}
diff --git a/testsuite/lib/systemtap.exp b/testsuite/lib/systemtap.exp
index d458e98f..0f6a69dd 100644
--- a/testsuite/lib/systemtap.exp
+++ b/testsuite/lib/systemtap.exp
@@ -38,8 +38,9 @@ proc setup_systemtap_environment {} {
set env(SRCDIR) $srcdir/..
}
- # Use a local systemtap directory and cache
- set env(SYSTEMTAP_DIR) [exec pwd]/.systemtap
+ # Use a local systemtap directory and cache. Add user name so
+ # make check and sudo make check don't clobber each other.
+ set env(SYSTEMTAP_DIR) [exec pwd]/.systemtap-[exec whoami]
# PATH, SYSTEMTAP_TAPSET, SYSTEMTAP_RUNTIME, LD_LIBRARY_PATH are already set.
foreach var {PATH STAP SRCDIR SYSTEMTAP_TAPSET SYSTEMTAP_RUNTIME SYSTEMTAP_DIR LD_LIBRARY_PATH} {
diff --git a/testsuite/parseko/preprocess08.stp b/testsuite/parseko/preprocess08.stp
index 6665983d..ba0d68e2 100755
--- a/testsuite/parseko/preprocess08.stp
+++ b/testsuite/parseko/preprocess08.stp
@@ -1,4 +1,4 @@
#! stap -p1
-# missing "then" token
-%( arch == "2.6" %?
+# premature EOF during THEN tokens
+%( 0 == 0 %?
diff --git a/testsuite/parseko/preprocess08b.stp b/testsuite/parseko/preprocess08b.stp
new file mode 100755
index 00000000..a9697c28
--- /dev/null
+++ b/testsuite/parseko/preprocess08b.stp
@@ -0,0 +1,4 @@
+#! stap -p1
+
+# premature EOF during ELSE tokens
+%( 0 == 1 %? %:
diff --git a/testsuite/semok/syscall_return.stp b/testsuite/semok/syscall_return.stp
new file mode 100755
index 00000000..9a0ca7c4
--- /dev/null
+++ b/testsuite/semok/syscall_return.stp
@@ -0,0 +1,4 @@
+#!/bin/sh
+# Per bz6588, this should get through the semantic pass without warnings.
+stap -p2 -e 'probe syscall.*.return { printf("%s returns %s\n", name, retstr) }' 2>&1 | grep -q WARNING && exit 1
+exit 0
diff --git a/testsuite/systemtap.base/cache.exp b/testsuite/systemtap.base/cache.exp
index 26d7b0ef..f7ed2786 100644
--- a/testsuite/systemtap.base/cache.exp
+++ b/testsuite/systemtap.base/cache.exp
@@ -65,8 +65,9 @@ proc stap_compile { TEST_NAME flags script args } {
}
# Since we need a clean cache directory, we'll use a temporary
-# systemtap directory and cache
-set local_systemtap_dir [exec pwd]/.cache_test
+# systemtap directory and cache (add user name so make check and
+# sudo make installcheck don't clobber each others)
+set local_systemtap_dir [exec pwd]/.cache_test-[exec whoami]
exec /bin/rm -rf $local_systemtap_dir
if [info exists env(SYSTEMTAP_DIR)] {
set old_systemtap_dir $env(SYSTEMTAP_DIR)
diff --git a/testsuite/systemtap.base/cmd_parse.exp b/testsuite/systemtap.base/cmd_parse.exp
index cbce0455..e33bfa85 100644
--- a/testsuite/systemtap.base/cmd_parse.exp
+++ b/testsuite/systemtap.base/cmd_parse.exp
@@ -84,3 +84,40 @@ expect {
eof {fail "cmd_parse8: unexpected EOF"}
}
wait
+
+spawn stap -e {probe begin { printf("%d %s\n", argc, argv[$1]) exit() }} 1
+expect {
+ -timeout 60
+ "1 1" { pass cmd_parse9 }
+ timeout { fail "cmd_parse9 timeout" }
+ eof { fail "cmd_parse9 eof" }
+}
+wait
+
+spawn stap -e {probe begin { printf("%d %s\n", argc, argv[$1]) exit() }} 5 a b c d
+expect {
+ -timeout 60
+ "5 d" { pass cmd_parse10 }
+ timeout { fail "cmd_parse10 timeout" }
+ eof { fail "cmd_parse10 eof" }
+}
+wait
+
+spawn stap -e {probe begin { printf("%d %s\n", argc, argv[$1]) exit() }} 10 a b c d
+expect {
+ -timeout 60
+ "5 " { pass cmd_parse11 }
+ timeout { fail "cmd_parse11 timeout" }
+ eof { fail "cmd_parse11 eof" }
+}
+wait
+
+spawn stap -e {probe begin { printf("%d %s\n", argc, argv[0]) exit() }}
+expect {
+ -timeout 60
+ "0 " { pass cmd_parse12 }
+ timeout { fail "cmd_parse12 timeout" }
+ eof { fail "cmd_parse12 eof" }
+}
+wait
+
diff --git a/testsuite/systemtap.base/debugpath.exp b/testsuite/systemtap.base/debugpath.exp
index b0b12207..9c42295d 100644
--- a/testsuite/systemtap.base/debugpath.exp
+++ b/testsuite/systemtap.base/debugpath.exp
@@ -10,7 +10,8 @@ expect {
wait
set test "debugpath-good"
-spawn env SYSTEMTAP_DEBUGINFO_PATH=:/usr/lib/debug stap -e "probe kernel.function(\"sys_open\") {}" -p2
+set uname [exec /bin/uname -r]
+spawn env SYSTEMTAP_DEBUGINFO_PATH=/lib/modules/$uname/build stap -e "probe kernel.function(\"sys_open\") {}" -p2
expect {
-re {kernel.function.*pc=} { pass $test }
timeout { fail "$test (timeout2)" }
diff --git a/testsuite/systemtap.base/error_fn.exp b/testsuite/systemtap.base/error_fn.exp
new file mode 100644
index 00000000..c0de850f
--- /dev/null
+++ b/testsuite/systemtap.base/error_fn.exp
@@ -0,0 +1,7 @@
+# check that errors in nested functions are not lost on return
+# bugzilla 6529
+
+set test "error_fn"
+
+stap_run $srcdir/$subdir/$test.stp no_load ".*synthetic error.*"
+
diff --git a/testsuite/systemtap.base/error_fn.stp b/testsuite/systemtap.base/error_fn.stp
new file mode 100644
index 00000000..2e68026f
--- /dev/null
+++ b/testsuite/systemtap.base/error_fn.stp
@@ -0,0 +1,17 @@
+probe begin {
+ println("systemtap starting probe")
+ println("systemtap ending probe")
+}
+
+function generate_error:long() {
+ error("synthetic error")
+ return 1
+}
+
+function compute:long() {
+ return generate_error()
+}
+
+probe end {
+ compute()
+}
diff --git a/testsuite/systemtap.base/optim_arridx.exp b/testsuite/systemtap.base/optim_arridx.exp
index 0987dec6..f4308db5 100644
--- a/testsuite/systemtap.base/optim_arridx.exp
+++ b/testsuite/systemtap.base/optim_arridx.exp
@@ -9,7 +9,7 @@ arr3:long [long]
fna:long (a:long)
return a
fnb:long (a:long, b:long)
-return (a) + (b)
+return ((a) + (b)) + (printf(""))
exit:unknown ()
%{
atomic_set (&session_state, STAP_SESSION_STOPPING);
diff --git a/testsuite/systemtap.base/optim_arridx.stp b/testsuite/systemtap.base/optim_arridx.stp
index 20710c7f..3e4f8fd2 100644
--- a/testsuite/systemtap.base/optim_arridx.stp
+++ b/testsuite/systemtap.base/optim_arridx.stp
@@ -1,7 +1,7 @@
global arr1, arr2, arr3, elide_idx1, elide_global_a, elide_global_b
function fna(a:long) {return a}
-function fnb(a:long, b:long) {return a+b}
+function fnb(a:long, b:long) {return a+b+printf("")}
probe begin {
// array indices
diff --git a/testsuite/systemtap.base/optim_voidstmt.exp b/testsuite/systemtap.base/optim_voidstmt.exp
new file mode 100644
index 00000000..186dabad
--- /dev/null
+++ b/testsuite/systemtap.base/optim_voidstmt.exp
@@ -0,0 +1,5 @@
+# Make sure that optimization works with void statements
+
+set test "optim_voidstmt"
+
+stap_run $srcdir/$subdir/$test.stp no_load $all_pass_string -g
diff --git a/testsuite/systemtap.base/optim_voidstmt.stp b/testsuite/systemtap.base/optim_voidstmt.stp
new file mode 100644
index 00000000..343f81b3
--- /dev/null
+++ b/testsuite/systemtap.base/optim_voidstmt.stp
@@ -0,0 +1,95 @@
+/*
+ * optim_voidstmt.stp
+ *
+ * Verify statement optimizations in void contexts.
+ */
+
+/* The printfs here force it not to be pure. */
+function goodL() { printf(""); return 1 }
+function goodS() { printf(""); return "1" }
+
+/* These two functions lie about being pure, so they should be optimized out.
+ * If they get called, you get an error, and the test fails.
+ */
+function badL:long() %{ /* pure */ CONTEXT->last_error = "NOSEE"; %}
+function badS:string() %{ /* pure */ CONTEXT->last_error = "NOSEE"; %}
+
+function fn1(x) { return x }
+function fn2(x, y) { return x * y }
+
+probe begin {
+ println("systemtap starting probe")
+}
+
+probe end {
+ println("systemtap ending probe")
+
+ // most of these wouldn't have been optimized before, because part of the
+ // expression has an apparant side-effect in the good* calls
+
+ // unary numeric operators
+ (+(goodL() + badL()))
+ (-(goodL() + badL()))
+ (!(goodL() + badL()))
+ (~(goodL() + badL()))
+
+ // binary numeric operators
+ goodL() * badL()
+ goodL() / badL()
+ goodL() % badL()
+ goodL() + badL()
+ goodL() - badL()
+ goodL() >> badL()
+ goodL() << badL()
+ goodL() & badL()
+ goodL() ^ badL()
+ goodL() | badL()
+ goodL() < badL()
+ goodL() > badL()
+ goodL() <= badL()
+ goodL() >= badL()
+ goodL() == badL()
+ goodL() != badL()
+
+ // logical operators
+ goodL() && badL()
+ badL() && badL()
+ goodL() || badL()
+ badL() || badL()
+
+ // ternary operator
+ goodL() ? badL() : goodL()
+ goodL() ? goodL() : badL()
+ badL() ? badL() : badL()
+
+ // binary string operators
+ goodS() . badS()
+ goodS() < badS()
+ goodS() > badS()
+ goodS() <= badS()
+ goodS() >= badS()
+ goodS() == badS()
+ goodS() != badS()
+
+ // string-printing
+ sprintf("%d\n", goodL() + badL())
+ sprintf("%d %d %s %s\n", goodL(), badL(), goodS(), badS())
+
+ // function calls
+ fn1(badL() + goodL())
+ fn2(badL(), goodL())
+
+ // something complex, but harmless enough that only
+ // the good* calls should survive
+ fn1(fn2(goodL() - strlen(badL() + badL() * badL() / strlen(goodS()) ?
+ badS() . badS() . sprint(badL())
+ : sprint(badL(), badS())),
+ badL() < badL() || badS() == badS()) +
+ goodL() % strlen(goodS()))
+
+ println("systemtap test success")
+}
+
+probe never {
+ print(goodL(), badL(), goodS(), badS(), fn1(1), fn2(1, 1))
+}
diff --git a/testsuite/systemtap.base/stmt_rel.exp b/testsuite/systemtap.base/stmt_rel.exp
new file mode 100644
index 00000000..25156d9b
--- /dev/null
+++ b/testsuite/systemtap.base/stmt_rel.exp
@@ -0,0 +1,9 @@
+# test integer limits. Set and print variables and print constants.
+
+set test "stmt_rel"
+set ::result_string {PASS bio_init
+PASS line number
+PASS wildcard
+}
+
+stap_run2 $srcdir/$subdir/$test.stp
diff --git a/testsuite/systemtap.base/stmt_rel.stp b/testsuite/systemtap.base/stmt_rel.stp
new file mode 100644
index 00000000..13066161
--- /dev/null
+++ b/testsuite/systemtap.base/stmt_rel.stp
@@ -0,0 +1,71 @@
+global stack2pp, stack2func, stack3pp, stack3func
+global wildcardpp, wild_count
+
+probe kernel.statement("bio_init@fs/bio.c+2") {
+ # stack2 = tokenize(backtrace(), " ")
+ stack2func = probefunc()
+ stack2pp = pp()
+}
+probe kernel.statement("bio_init@fs/bio.c+3") {
+ # stack3 = tokenize(backtrace(), " " )
+ stack3func = probefunc()
+ stack3pp = pp()
+}
+
+probe kernel.statement("bio_put@fs/bio.c:*") {
+ line = tokenize(pp(),":")
+ line = tokenize("",":")
+ line = substr(line,0,strlen(line)-2)
+ wildcardpp[strtol(line,10)]++
+
+ if (wild_count++ <= 10) {
+ next
+ }
+
+ stack2pp = tokenize(stack2pp,":")
+ stack2pp = tokenize("",":")
+ stack3pp = tokenize(stack3pp,":")
+ stack3pp = tokenize("",":")
+
+ stack2line = strtol (substr(stack2pp,0,strlen(stack2pp)-2), 10)
+ stack3line = strtol (substr(stack3pp,0,strlen(stack3pp)-2), 10)
+
+ # Did functions for both bio_init probes match?
+ if (stack2func == stack3func) {
+ printf ("PASS %s\n", stack2func)
+ }
+ else {
+ printf ("FAIL %s %s\n", stack2func, stack3func)
+ }
+
+ # Was line # for bio_init probe +2 < line # for bio_init probe +3?
+ if ((stack2line + 1) == stack3line) {
+ printf ("PASS line number\n")
+ }
+ else {
+ printf ("FAIL line number %d %d\n", stack2line, stack3line)
+ }
+
+ # This test does not take optimized code into account
+ # Was address for bio_init probe +2 < address for bio_init probe +3?
+ # if (stack2 < stack3) {
+ # printf ("PASS address\n")
+ # }
+ # else {
+ # printf ("FAIL address %s %s\n", stack2, stack3)
+ # }
+
+ # Did wildcard probe hit at least 5 different statements?
+ foreach ([i] in wildcardpp) {
+ statement_count += 1
+ }
+ if (statement_count >= 5) {
+ printf ("PASS wildcard\n")
+ }
+ else
+ {
+ printf ("FAIL wildcard %d\n", statement_count)
+ }
+
+ exit()
+}
diff --git a/testsuite/systemtap.base/stmtvars.exp b/testsuite/systemtap.base/stmtvars.exp
index 6e950ea0..822e0d7e 100644
--- a/testsuite/systemtap.base/stmtvars.exp
+++ b/testsuite/systemtap.base/stmtvars.exp
@@ -5,9 +5,8 @@ set pc 0
set vars ""
spawn stap -e "probe kernel.function(\"sys_open\") {\$foo}" -p4 -vv -u
expect {
- -re {probe sys_open.*pc=(0x.*)\r\n} { set pc $expect_out(1,string); exp_continue }
- -re {alternatives: ([^\r\n]*) identifier [^\r\n]*\r\n} { set vars $expect_out(1,string)
- exp_continue }
+ -re {probe sys_open[^\r\n]*pc=(0x[^\r\n]*)\r\n} { set pc $expect_out(1,string); exp_continue }
+ -re {alternatives: ([^\r\n]*)\): identifier [^\r\n]*\r\n} { set vars $expect_out(1,string); exp_continue }
timeout { fail "$test (timeout)" }
eof
}
@@ -19,9 +18,8 @@ set pc2 0
set vars2 ""
spawn stap -e "probe kernel.statement($pc) {\$foo}" -p4 -vv -u
expect {
- -re {probe sys_open.*pc=(0x.*)\r\n} { set pc2 $expect_out(1,string); exp_continue }
- -re {alternatives: ([^\r\n]*) identifier [^\r\n]*\r\n} { set vars2 $expect_out(1,string)
- exp_continue }
+ -re {probe sys_open[^\r\n]*pc=(0x[^\r\n]*)\r\n} { set pc2 $expect_out(1,string); exp_continue }
+ -re {alternatives: ([^\r\n]*)\): identifier [^\r\n]*\r\n} { set vars2 $expect_out(1,string); exp_continue }
timeout { fail "$test (timeout)" }
eof
}
diff --git a/testsuite/systemtap.base/utrace_p4.exp b/testsuite/systemtap.base/utrace_p4.exp
index eb6ea685..5544ee55 100644
--- a/testsuite/systemtap.base/utrace_p4.exp
+++ b/testsuite/systemtap.base/utrace_p4.exp
@@ -49,11 +49,12 @@ proc stap_compile { TEST_NAME compile script args } {
# Initialize variables
set utrace_support_found 0
-set clone_script {"probe process(\"/bin/ls\").clone { print(\"ls clone\") }"}
-set death_script {"probe process(\"/bin/ls\").death { print(\"ls death\") }"}
+set begin_script {"probe process(\"/bin/ls\").begin { print(\"ls begin\") }"}
+set end_script {"probe process(\"/bin/ls\").end { print(\"ls end\") }"}
set syscall_script {"probe process(\"/bin/ls\").syscall { printf(\"|%d\", \$syscall) }"}
set syscall_return_script {"probe process(\"/bin/ls\").syscall.return { printf(\"|%d\", \$syscall) }"}
-set exec_script {"probe process(\"/bin/ls\").exec { print(\"ls exec\") }"}
+set thread_begin_script {"probe process(\"/bin/ls\").thread.begin { print(\"ls thread.begin\") }"}
+set thread_end_script {"probe process(\"/bin/ls\").thread.end { print(\"ls thread.end\") }"}
# Try to find utrace_attach symbol in /proc/kallsyms
set path "/proc/kallsyms"
@@ -69,16 +70,16 @@ set TEST_NAME "UTRACE_P4_01"
if {$utrace_support_found == 0} {
untested "$TEST_NAME : no kernel utrace support found"
} else {
- # Try compiling a clone script
- stap_compile $TEST_NAME 1 $clone_script
+ # Try compiling a begin script
+ stap_compile $TEST_NAME 1 $begin_script
}
set TEST_NAME "UTRACE_P4_02"
if {$utrace_support_found == 0} {
untested "$TEST_NAME : no kernel utrace support found"
} else {
- # Try compiling a death script
- stap_compile $TEST_NAME 1 $death_script
+ # Try compiling a end script
+ stap_compile $TEST_NAME 1 $end_script
}
set TEST_NAME "UTRACE_P4_03"
@@ -101,6 +102,14 @@ set TEST_NAME "UTRACE_P4_05"
if {$utrace_support_found == 0} {
untested "$TEST_NAME : no kernel utrace support found"
} else {
- # Try compiling an exec script
- stap_compile $TEST_NAME 1 $exec_script
+ # Try compiling an thread.begin script
+ stap_compile $TEST_NAME 1 $thread_begin_script
+}
+
+set TEST_NAME "UTRACE_P4_06"
+if {$utrace_support_found == 0} {
+ untested "$TEST_NAME : no kernel utrace support found"
+} else {
+ # Try compiling an thread.end script
+ stap_compile $TEST_NAME 1 $thread_end_script
}
diff --git a/testsuite/systemtap.base/utrace_p5.exp b/testsuite/systemtap.base/utrace_p5.exp
index cbb867d1..fcd617fe 100644
--- a/testsuite/systemtap.base/utrace_p5.exp
+++ b/testsuite/systemtap.base/utrace_p5.exp
@@ -3,24 +3,27 @@
# Initialize variables
set utrace_support_found 0
set exepath "[pwd]/cat_[pid]"
+set multi_srcpath "$srcdir/systemtap.base/utrace_p5_multi.c"
+set multi_exepath "[pwd]/utrace_p5_multi_[pid]"
+set multi_flags "libs=-lpthread"
-set death_script {
- global death_probes_fired = 0
+set end_script {
+ global end_probes_fired = 0
probe begin { printf("systemtap starting probe\n") }
- probe process("%s").death { death_probes_fired++ }
+ probe process("%s").end { end_probes_fired++ }
probe end { printf("systemtap ending probe\n")
- printf("deaths = %%d\n", death_probes_fired) }
+ printf("end probes = %%d\n", end_probes_fired) }
}
-set death_script_output "deaths = 1\r\n"
+set end_script_output "end probes = 1\r\n"
-set exec_script {
- global exec_probes_fired = 0
+set begin_script {
+ global begin_probes_fired = 0
probe begin { printf("systemtap starting probe\n") }
- probe process("%s").exec { exec_probes_fired++ }
+ probe process("%s").begin { begin_probes_fired++ }
probe end { printf("systemtap ending probe\n")
- printf("execs = %%d\n", exec_probes_fired) }
+ printf("begin probes = %%d\n", begin_probes_fired) }
}
-set exec_script_output "execs = 1\r\n"
+set begin_script_output "begin probes = 1\r\n"
set syscall_script {
global syscall_probes_fired = 0
@@ -46,17 +49,29 @@ set syscall_return_script {
}
set syscall_return_script_output "syscall_returns = \\d+\r\n"
-set clone_script {
- global clone_probes_fired = 0
+set thread_begin_script {
+ global thread_begin_probes_fired = 0
probe begin { printf("systemtap starting probe\n") }
- probe process(%d).clone { clone_probes_fired++ }
+ probe process("%s").thread.begin { thread_begin_probes_fired++ }
probe end { printf("systemtap ending probe\n")
- if (clone_probes_fired > 0) {
- printf("clones = %%d\n", clone_probes_fired)
+ if (thread_begin_probes_fired > 0) {
+ printf("thread_begins = %%d\n", thread_begin_probes_fired)
}
}
}
-set clone_script_output "clones = \\d+\r\n"
+set thread_begin_script_output "thread_begins = \\d+\r\n"
+
+set thread_end_script {
+ global thread_end_probes_fired = 0
+ probe begin { printf("systemtap starting probe\n") }
+ probe process("%s").thread.end { thread_end_probes_fired++ }
+ probe end { printf("systemtap ending probe\n")
+ if (thread_end_probes_fired > 0) {
+ printf("thread_ends = %%d\n", thread_end_probes_fired)
+ }
+ }
+}
+set thread_end_script_output "thread_ends = \\d+\r\n"
# Try to find utrace_attach symbol in /proc/kallsyms
set path "/proc/kallsyms"
@@ -86,14 +101,33 @@ proc run_cat_5_sec {} {
return 0;
}
+# Compile our multi-threaded test program.
+set res [target_compile $multi_srcpath $multi_exepath executable $multi_flags]
+if { $res != "" } {
+ verbose "target_compile failed: $res" 2
+ fail "unable to compile $multi_srcpath"
+ return
+}
+
+# "load" generation function for stap_run. It spawns our
+# multi-threaded test program and waits for it to finish.
+proc run_utrace_p5_multi {} {
+ global multi_exepath
+
+ if {[catch {exec $multi_exepath} res]} {
+ verbose "unable to run $multi_exepath: $res"
+ }
+ return 0;
+}
+
set TEST_NAME "UTRACE_P5_01"
if {$utrace_support_found == 0} {
untested "$TEST_NAME : no kernel utrace support found"
} elseif {![installtest_p]} {
untested "$TEST_NAME"
} else {
- set script [format $death_script $exepath]
- stap_run $TEST_NAME run_cat_5_sec $death_script_output -e $script
+ set script [format $end_script $exepath]
+ stap_run $TEST_NAME run_cat_5_sec $end_script_output -e $script
}
set TEST_NAME "UTRACE_P5_02"
@@ -102,8 +136,8 @@ if {$utrace_support_found == 0} {
} elseif {![installtest_p]} {
untested "$TEST_NAME"
} else {
- set script [format $exec_script $exepath]
- stap_run $TEST_NAME run_cat_5_sec $exec_script_output -e $script
+ set script [format $begin_script $exepath]
+ stap_run $TEST_NAME run_cat_5_sec $begin_script_output -e $script
}
set TEST_NAME "UTRACE_P5_03"
@@ -132,9 +166,21 @@ if {$utrace_support_found == 0} {
} elseif {![installtest_p]} {
untested "$TEST_NAME"
} else {
- set script [format $clone_script [pid]]
- stap_run $TEST_NAME run_cat_5_sec $clone_script_output -e $script
+ set script [format $thread_begin_script $multi_exepath]
+ stap_run $TEST_NAME run_utrace_p5_multi $thread_begin_script_output \
+ -e $script
+}
+
+set TEST_NAME "UTRACE_P5_06"
+if {$utrace_support_found == 0} {
+ untested "$TEST_NAME : no kernel utrace support found"
+} elseif {![installtest_p]} {
+ untested "$TEST_NAME"
+} else {
+ set script [format $thread_end_script $multi_exepath]
+ stap_run $TEST_NAME run_utrace_p5_multi $thread_end_script_output \
+ -e $script
}
# Cleanup
-exec rm -f $exepath
+exec rm -f $exepath $multi_exepath
diff --git a/testsuite/systemtap.base/utrace_p5_multi.c b/testsuite/systemtap.base/utrace_p5_multi.c
new file mode 100644
index 00000000..153243d0
--- /dev/null
+++ b/testsuite/systemtap.base/utrace_p5_multi.c
@@ -0,0 +1,45 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <pthread.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+void *thread_function( void *ptr );
+
+struct thread_data {
+ int tnum;
+};
+
+int
+main()
+{
+ pthread_t thread1, thread2;
+ int iret1, iret2;
+
+ /* Create independent threads each of which will execute function */
+ struct thread_data t1 = { 1 };
+ struct thread_data t2 = { 2 };
+ iret1 = pthread_create(&thread1, NULL, thread_function, (void*) &t1);
+ iret2 = pthread_create(&thread2, NULL, thread_function, (void*) &t2);
+
+ /* Wait till threads are complete before main continues. Unless we
+ * wait we run the risk of executing an exit which will terminate
+ * the process and all threads before the threads have
+ * completed. */
+ pthread_join(thread1, NULL);
+ pthread_join(thread2, NULL);
+
+ printf("Thread 1 returns: %d\n", iret1);
+ printf("Thread 2 returns: %d\n", iret2);
+ exit(0);
+}
+
+void *thread_function(void *ptr)
+{
+ struct thread_data *td = ptr;
+ if (td->tnum == 1) {
+ int fd = open("/dev/null", O_RDONLY);
+ close(fd);
+ }
+}
diff --git a/testsuite/systemtap.base/warnings.exp b/testsuite/systemtap.base/warnings.exp
index 6cff723d..b56d7a98 100644
--- a/testsuite/systemtap.base/warnings.exp
+++ b/testsuite/systemtap.base/warnings.exp
@@ -9,7 +9,7 @@ expect {
eof { }
}
wait
-if {$ok == 22} {
+if {$ok == 14} {
pass $test
} else {
fail "$test ($ok)"
diff --git a/testsuite/systemtap.base/warnings.stp b/testsuite/systemtap.base/warnings.stp
index a2ac5afc..94ed57b3 100644
--- a/testsuite/systemtap.base/warnings.stp
+++ b/testsuite/systemtap.base/warnings.stp
@@ -1,4 +1,4 @@
-# PR 1119, 6538
+# PR 1119
global elide_me1
function elide_me2 () {}
@@ -6,3 +6,12 @@ function foo:long () { elide_me3 = 1 }
function bar() { print(elide+me1) ; ; ; }
probe never { elide_me4 = 1; (elide_me5+5); print (foo()) }
probe never { print(elide+me1) bar () }
+
+# PR 6611
+
+probe probea = kernel.statement("bio_init@fs/bio.c:135")
+ { printf("%d", funca(2)); elide_me6="foo" }
+probe probea { printf("%d", funcb(2,3)); printf("%s",var) }
+
+function funcb(a:long, b:long) {return a + b}
+function funca(a:long) {a=b; elide_me7=1; return a}
diff --git a/testsuite/systemtap.context/backtrace.tcl b/testsuite/systemtap.context/backtrace.tcl
index 6c8aee40..aaec4cb8 100644
--- a/testsuite/systemtap.context/backtrace.tcl
+++ b/testsuite/systemtap.context/backtrace.tcl
@@ -20,11 +20,11 @@ expect {
incr m1
expect {
-timeout 5
- -re {^ 0x[a-f0-9]+ : yyy_func2[^\[]+\[systemtap_test_module2\]\r\n} {
+ -re {^ 0x[a-f0-9]+ : yyy_func2[^\[]+\[systemtap_test_module2\]( \(inexact\))?\r\n} {
if {$m1 == 1} {incr m1}
exp_continue
}
- -re {^ 0x[a-f0-9]+ : yyy_func1[^\[]+\[systemtap_test_module2\]\r\n} {
+ -re {^ 0x[a-f0-9]+ : yyy_func1[^\[]+\[systemtap_test_module2\]( \(inexact\))?\r\n} {
if {$m1 == 2} {incr m1}
}
}
@@ -34,11 +34,11 @@ expect {
incr m2
expect {
-timeout 5
- -re {^ 0x[a-f0-9]+ : yyy_func2[^\[]+\[systemtap_test_module2\]\r\n} {
+ -re {^ 0x[a-f0-9]+ : yyy_func2[^\[]+\[systemtap_test_module2\]( \(inexact\))?\r\n} {
if {$m2 == 1} {incr m2}
exp_continue
}
- -re {^ 0x[a-f0-9]+ : yyy_func1[^\[]+\[systemtap_test_module2\]\r\n} {
+ -re {^ 0x[a-f0-9]+ : yyy_func1[^\[]+\[systemtap_test_module2\]( \(inexact\))?\r\n} {
if {$m2 == 2} {incr m2}
}
}
@@ -50,15 +50,15 @@ expect {
incr m3
expect {
-timeout 5
- -re {^ 0x[a-f0-9]+ : yyy_func3[^\[]+\[systemtap_test_module2\]\r\n} {
+ -re {^ 0x[a-f0-9]+ : yyy_func3[^\[]+\[systemtap_test_module2\]( \(inexact\))?\r\n} {
if {$m3 == 1} {incr m3}
exp_continue
}
- -re {^ 0x[a-f0-9]+ : yyy_func2[^\[]+\[systemtap_test_module2\]\r\n} {
+ -re {^ 0x[a-f0-9]+ : yyy_func2[^\[]+\[systemtap_test_module2\]( \(inexact\))?\r\n} {
if {$m3 == 2} {incr m3}
exp_continue
}
- -re {^ 0x[a-f0-9]+ : yyy_func1[^\[]+\[systemtap_test_module2\]\r\n} {
+ -re {^ 0x[a-f0-9]+ : yyy_func1[^\[]+\[systemtap_test_module2\]( \(inexact\))?\r\n} {
if {$m3 == 3} {incr m3}
}
}
@@ -68,11 +68,11 @@ expect {
incr m4
expect {
-timeout 5
- -re {^ 0x[a-f0-9]+ : yyy_func3[^\[]+\[systemtap_test_module2\]\r\n} {
+ -re {^ 0x[a-f0-9]+ : yyy_func3[^\[]+\[systemtap_test_module2\]( \(inexact\))?\r\n} {
if {$m4 == 1} {incr m4}
exp_continue
}
- -re {^ 0x[a-f0-9]+ : yyy_func2[^\[]+\[systemtap_test_module2\]\r\n} {
+ -re {^ 0x[a-f0-9]+ : yyy_func2[^\[]+\[systemtap_test_module2\]( \(inexact\))?\r\n} {
if {$m4 == 2} {incr m4}
exp_continue
}
@@ -88,19 +88,19 @@ expect {
incr m5
expect {
-timeout 5
- -re {^ 0x[a-f0-9]+ : yyy_func4[^\[]+\[systemtap_test_module2\]\r\n} {
+ -re {^ 0x[a-f0-9]+ : yyy_func4[^\[]+\[systemtap_test_module2\]( \(inexact\))?\r\n} {
if {$m5 == 1} {incr m5}
exp_continue
}
- -re {^ 0x[a-f0-9]+ : yyy_func3[^\[]+\[systemtap_test_module2\]\r\n} {
+ -re {^ 0x[a-f0-9]+ : yyy_func3[^\[]+\[systemtap_test_module2\]( \(inexact\))?\r\n} {
if {$m5 == 2} {incr m5}
exp_continue
}
- -re {^ 0x[a-f0-9]+ : yyy_func2[^\[]+\[systemtap_test_module2\]\r\n} {
+ -re {^ 0x[a-f0-9]+ : yyy_func2[^\[]+\[systemtap_test_module2\]( \(inexact\))?\r\n} {
if {$m5 == 3} {incr m5}
exp_continue
}
- -re {^ 0x[a-f0-9]+ : yyy_func1[^\[]+\[systemtap_test_module2\]\r\n} {
+ -re {^ 0x[a-f0-9]+ : yyy_func1[^\[]+\[systemtap_test_module2\]( \(inexact\))?\r\n} {
if {$m5 == 4} {incr m5}
}
}
@@ -110,19 +110,19 @@ expect {
incr m6
expect {
-timeout 5
- -re {^ 0x[a-f0-9]+ : yyy_func4[^\[]+\[systemtap_test_module2\]\r\n} {
+ -re {^ 0x[a-f0-9]+ : yyy_func4[^\[]+\[systemtap_test_module2\]( \(inexact\))?\r\n} {
if {$m6 == 1} {incr m6}
exp_continue
}
- -re {^ 0x[a-f0-9]+ : yyy_func3[^\[]+\[systemtap_test_module2\]\r\n} {
+ -re {^ 0x[a-f0-9]+ : yyy_func3[^\[]+\[systemtap_test_module2\]( \(inexact\))?\r\n} {
if {$m6 == 2} {incr m6}
exp_continue
}
- -re {^ 0x[a-f0-9]+ : yyy_func2[^\[]+\[systemtap_test_module2\]\r\n} {
+ -re {^ 0x[a-f0-9]+ : yyy_func2[^\[]+\[systemtap_test_module2\]( \(inexact\))?\r\n} {
if {$m6 == 3} {incr m6}
exp_continue
}
- -re {^ 0x[a-f0-9]+ : yyy_func1[^\[]+\[systemtap_test_module2\]\r\n} {
+ -re {^ 0x[a-f0-9]+ : yyy_func1[^\[]+\[systemtap_test_module2\]( \(inexact\))?\r\n} {
if {$m6 == 4} {incr m6}
}
}
diff --git a/testsuite/systemtap.context/context.exp b/testsuite/systemtap.context/context.exp
index 71201a58..010db445 100644
--- a/testsuite/systemtap.context/context.exp
+++ b/testsuite/systemtap.context/context.exp
@@ -1,4 +1,4 @@
-set testlist {backtrace args pid}
+set testlist {backtrace args pid num_args}
if {![installtest_p]} {
foreach test $testlist {
diff --git a/testsuite/systemtap.context/num_args.stp b/testsuite/systemtap.context/num_args.stp
new file mode 100644
index 00000000..9f15bb01
--- /dev/null
+++ b/testsuite/systemtap.context/num_args.stp
@@ -0,0 +1,53 @@
+%( arch == "i386" %? global ir = "eax", lr = "eax" %)
+%( arch == "i686" %? global ir = "eax", lr = "eax" %)
+%( arch == "x86_64" %? global ir = "eax", lr = "rax" %)
+%( arch == "ppc64" %? global ir = "r3", lr = "r3" %)
+
+probe module("systemtap_test_module2").function("yyy_int") {
+ printf("yyy_int %d %d %d\n", int_arg(1), int_arg(2), int_arg(3))
+}
+probe module("systemtap_test_module2").function("yyy_int").return {
+ printf("yyy_int returns %d\n", register(ir))
+}
+probe module("systemtap_test_module2").function("yyy_uint") {
+ printf("yyy_uint %d %d %d\n", uint_arg(1), uint_arg(2), uint_arg(3))
+}
+probe module("systemtap_test_module2").function("yyy_uint").return {
+ printf("yyy_uint returns %d\n", u_register(ir))
+}
+probe module("systemtap_test_module2").function("yyy_long") {
+ printf("yyy_long %d %d %d\n", long_arg(1), long_arg(2), long_arg(3))
+}
+probe module("systemtap_test_module2").function("yyy_long").return {
+ printf("yyy_long returns %d\n", register(lr))
+}
+probe module("systemtap_test_module2").function("yyy_int64") {
+# On i386, kernel is built with -mregparm=3. The first arg occupies the
+# first two registers. The 2nd arg is not split between the 3rd register
+# and the stack, but rather passed entirely on the stack.
+ printf("yyy_int64 %d %d %d\n",
+%( arch == "i386" %? s64_arg(1), s64_arg(4), s64_arg(6)
+%: %( arch == "i686" %? s64_arg(1), s64_arg(4), s64_arg(6)
+ %: s64_arg(1), s64_arg(2), s64_arg(3)
+ %)
+%)
+ )
+}
+probe module("systemtap_test_module2").function("yyy_int64").return {
+ printf("yyy_int64 returns %d\n", register(ir))
+}
+probe module("systemtap_test_module2").function("yyy_char") {
+ printf("yyy_char %1b %1b %1b\n", int_arg(1), int_arg(2), int_arg(3))
+}
+probe module("systemtap_test_module2").function("yyy_char").return {
+ printf("yyy_char returns %1b\n", register(ir))
+}
+probe module("systemtap_test_module2").function("yyy_str") {
+ printf("yyy_str %s-%s-%s\n", kernel_string(pointer_arg(1)), kernel_string(pointer_arg(2)), kernel_string(pointer_arg(3)))
+}
+probe module("systemtap_test_module2").function("yyy_str").return {
+ printf("yyy_str returns %s\n", kernel_string(register(lr)))
+}
+probe begin {
+ printf("READY\n")
+}
diff --git a/testsuite/systemtap.context/num_args.tcl b/testsuite/systemtap.context/num_args.tcl
new file mode 100644
index 00000000..48e83f4d
--- /dev/null
+++ b/testsuite/systemtap.context/num_args.tcl
@@ -0,0 +1,62 @@
+set arglists {{} {--kelf --ignore-dwarf}}
+foreach arglist $arglists {
+set tag [concat numeric $arglist]
+eval spawn stap $arglist $srcdir/$subdir/num_args.stp
+expect {
+ -timeout 240
+ "READY" {
+ exec echo 1 > /proc/stap_test_cmd
+ expect {
+ -timeout 5
+ "yyy_int -1 200 300\r\nyyy_int returns 499\r\n" {
+ pass "integer function arguments -- $tag"
+ }
+ timeout {fail "integer function arguments -- $tag"}
+ }
+ exec echo 2 > /proc/stap_test_cmd
+ expect {
+ -timeout 5
+ "yyy_uint 4294967295 200 300\r\nyyy_uint returns 499\r\n" {
+ pass "unsigned function arguments -- $tag"
+ }
+ timeout {fail "unsigned function arguments -- $tag"}
+ }
+ exec echo 3 > /proc/stap_test_cmd
+ expect {
+ -timeout 5
+ "yyy_long -1 200 300\r\nyyy_long returns 499\r\n" {
+ pass "long function arguments -- $tag"
+ }
+ timeout {fail "long function arguments -- $tag"}
+ }
+ exec echo 4 > /proc/stap_test_cmd
+ expect {
+ -timeout 5
+ "yyy_int64 -1 200 300\r\nyyy_int64 returns 499\r\n" {
+ pass "int64 function arguments -- $tag"
+ }
+ timeout {fail "int64 function arguments -- $tag"}
+ }
+ exec echo 5 > /proc/stap_test_cmd
+ expect {
+ -timeout 5
+ "yyy_char a b c\r\nyyy_char returns Q\r\n" {
+ pass "char function arguments -- $tag"
+ }
+ timeout {fail "char function arguments -- $tag"}
+ }
+ exec echo 6 > /proc/stap_test_cmd
+ expect {
+ -timeout 5
+ "yyy_str Hello-System-Tap\r\nyyy_str returns XYZZY\r\n" {
+ pass "string function arguments -- $tag"
+ }
+ timeout {fail "string function arguments -- $tag"}
+ }
+ }
+ eof {fail "function arguments -- $tag: unexpected timeout"}
+}
+exec kill -INT -[exp_pid]
+close
+wait
+}
diff --git a/testsuite/systemtap.examples/ChangeLog b/testsuite/systemtap.examples/ChangeLog
index 743e7adf..b1c34347 100644
--- a/testsuite/systemtap.examples/ChangeLog
+++ b/testsuite/systemtap.examples/ChangeLog
@@ -1,3 +1,23 @@
+2008-06-20 William Cohen <wcohen@redhat.com>
+
+ * traceio2.meta: Correct test_check and test_installcheck commands.
+
+2008-06-20 William Cohen <wcohen@redhat.com>
+
+ * traceio2.stp, traceio2.meta: New.
+
+2008-06-18 William Cohen <wcohen@redhat.com>
+
+ * sleepingBeauties.stp, sleepingBeauties.meta: New.
+
+2008-06-17 William Cohen <wcohen@redhat.com>
+
+ * graphs.stp, graphs.meta: New.
+
+2008-06-12 William Cohen <wcohen@redhat.com>
+
+ * thread-times.stp, thread-times.meta: New.
+
2008-05-20 William Cohen <wcohen@redhat.com>
* io_submit.stp, io_submit.meta:
diff --git a/testsuite/systemtap.examples/graphs.meta b/testsuite/systemtap.examples/graphs.meta
new file mode 100644
index 00000000..60a522b3
--- /dev/null
+++ b/testsuite/systemtap.examples/graphs.meta
@@ -0,0 +1,13 @@
+title: Graphing Disk and CPU Utilization
+name: graphs.stp
+version: 1.0
+author: anonymous
+keywords: disk cpu use graph
+subsystem: disk cpu
+status: production
+exit: user-controlled
+output: plot data
+scope: system-wide
+description: The script tracks the disk and CPU utilization. The resulting output of the script can be piped into gnuplot to generate a graph of disk and CPU USE.
+test_check: stap -p4 graphs.stp
+test_installcheck: stap graphs.stp -c "sleep 1"
diff --git a/testsuite/systemtap.examples/graphs.stp b/testsuite/systemtap.examples/graphs.stp
new file mode 100644
index 00000000..0c8e3796
--- /dev/null
+++ b/testsuite/systemtap.examples/graphs.stp
@@ -0,0 +1,60 @@
+#! stap
+
+# ------------------------------------------------------------------------
+# data collection
+
+# disk I/O stats
+probe begin { qnames["ioblock"] ++; qsq_start ("ioblock") }
+probe ioblock.request { qs_wait ("ioblock") qs_run("ioblock") }
+probe ioblock.end { qs_done ("ioblock") }
+
+# CPU utilization
+probe begin { qnames["cpu"] ++; qsq_start ("cpu") }
+probe scheduler.cpu_on { if (!idle) {qs_wait ("cpu") qs_run ("cpu") }}
+probe scheduler.cpu_off { if (!idle) qs_done ("cpu") }
+
+
+# ------------------------------------------------------------------------
+# utilization history tracking
+
+global N
+probe begin { N = 50 }
+
+global qnames, util, histidx
+
+function qsq_util_reset(q) {
+ u=qsq_utilization (q, 100)
+ qsq_start (q)
+ return u
+}
+
+probe timer.ms(100) { # collect utilization percentages frequently
+ histidx = (histidx + 1) % N # into circular buffer
+ foreach (q in qnames)
+ util[histidx,q] = qsq_util_reset(q)
+}
+
+
+# ------------------------------------------------------------------------
+# general gnuplot graphical report generation
+
+probe timer.ms(1000) {
+ # emit gnuplot command to display recent history
+
+ printf ("set yrange [0:100]\n")
+ printf ("plot ")
+ foreach (q in qnames+)
+ {
+ if (++nq >= 2) printf (", ")
+ printf ("'-' title \"%s\" with lines", q)
+ }
+ printf ("\n")
+
+ foreach (q in qnames+) {
+ for (i = (histidx + 1) % N; i != histidx; i = (i + 1) % N)
+ printf("%d\n", util[i,q])
+ printf ("e\n")
+ }
+
+ printf ("pause 1\n")
+}
diff --git a/testsuite/systemtap.examples/sleepingBeauties.meta b/testsuite/systemtap.examples/sleepingBeauties.meta
new file mode 100644
index 00000000..95e08361
--- /dev/null
+++ b/testsuite/systemtap.examples/sleepingBeauties.meta
@@ -0,0 +1,13 @@
+title: Generating Backtraces of Threads Waiting for IO Operations
+name: sleepingBeauties.stp
+version: 1.0
+author: anonymous
+keywords: io scheduler
+subsystem: scheduler
+status: production
+exit: user-controlled
+output: trace
+scope: system-wide
+description: The script monitor time threads spend waiting for IO operations (in "D" state) in the wait_for_completion function. If a thread spends over 10ms wall-clock time waiting, information is printed out describing the thread number and executable name. When slow the wait_for_completion function complete, backtraces for the long duration calls are printed out.
+test_check: stap -p4 sleepingBeauties.stp
+test_installcheck: stap sleepingBeauties.stp -c "sleep 1"
diff --git a/testsuite/systemtap.examples/sleepingBeauties.stp b/testsuite/systemtap.examples/sleepingBeauties.stp
new file mode 100644
index 00000000..64c563a3
--- /dev/null
+++ b/testsuite/systemtap.examples/sleepingBeauties.stp
@@ -0,0 +1,58 @@
+#! /usr/bin/stap
+
+function time () { return gettimeofday_ms() }
+global time_name = "ms"
+global boredom = 10 # in time units
+global name, back, backtime, bored
+
+/* Note: the order that the probes are listed should not matter.
+ However, the following order for
+ probe kernel.function("wait_for_completion").return and
+ probe kernel.function("wait_for_completion").call
+ avoids have the kretprobe stuff in the backtrace.
+ for more information see:
+ http://sources.redhat.com/bugzilla/show_bug.cgi?id=6436
+*/
+
+
+probe kernel.function("wait_for_completion").return
+{
+ t=tid()
+
+ if ([t] in bored) {
+ patience = time() - backtime[t]
+ printf ("thread %d (%s) bored for %d %s\n",
+ t, name[t], patience, time_name)
+ }
+
+ delete bored[t]
+ delete back[t]
+ delete name[t]
+ delete backtime[t]
+}
+
+
+probe kernel.function("wait_for_completion").call
+{
+ t=tid()
+ back[t]=backtrace()
+ name[t]=execname()
+ backtime[t]=time()
+ delete bored[t]
+}
+
+
+probe timer.profile {
+ foreach (tid+ in back) {
+ if ([tid] in bored) continue
+
+ patience = time() - backtime[tid]
+ if (patience >= boredom) {
+ printf ("thread %d (%s) impatient after %d %s\n",
+ tid, name[tid], patience, time_name)
+ print_stack (back[tid])
+ printf ("\n")
+ bored[tid] = 1 # defer further reports to wakeup
+ }
+ }
+}
diff --git a/testsuite/systemtap.examples/thread-times.meta b/testsuite/systemtap.examples/thread-times.meta
new file mode 100644
index 00000000..fcbf062e
--- /dev/null
+++ b/testsuite/systemtap.examples/thread-times.meta
@@ -0,0 +1,13 @@
+title: Profile kernel functions
+name: thread-times.stp
+version: 1.0
+author: anonymous
+keywords: profiling
+subsystem: kernel
+status: production
+exit: user-controlled
+output: sorted-list
+scope: system-wide
+description: The thread-times.stp script sets up time-based sampling. Every five seconds it prints out a sorted list with the top twenty processes with samples broken down into percentage total time spent in user-space and kernel-space.
+test_check: stap -p4 thread-times.stp
+test_installcheck: stap thread-times.stp -c "sleep 1"
diff --git a/testsuite/systemtap.examples/thread-times.stp b/testsuite/systemtap.examples/thread-times.stp
new file mode 100644
index 00000000..1aeb2037
--- /dev/null
+++ b/testsuite/systemtap.examples/thread-times.stp
@@ -0,0 +1,32 @@
+#! /usr/bin/stap
+
+probe timer.profile {
+ tid=tid()
+ if (!user_mode())
+ kticks[tid] <<< 1
+ else
+ uticks[tid] <<< 1
+ ticks <<< 1
+ tids[tid] <<< 1
+}
+
+global uticks, kticks, ticks
+
+global tids
+
+probe timer.s(5), end {
+ allticks = @count(ticks)
+ printf ("%5s %7s %7s (of %d ticks)\n", "tid", "%user", "%kernel", allticks)
+ foreach (tid in tids- limit 20) {
+ uscaled = @count(uticks[tid])*10000/allticks
+ kscaled = @count(kticks[tid])*10000/allticks
+ printf ("%5d %3d.%02d%% %3d.%02d%%\n",
+ tid, uscaled/100, uscaled%100, kscaled/100, kscaled%100)
+ }
+ printf("\n")
+
+ delete uticks
+ delete kticks
+ delete ticks
+ delete tids
+}
diff --git a/testsuite/systemtap.examples/traceio2.meta b/testsuite/systemtap.examples/traceio2.meta
new file mode 100644
index 00000000..e6bca1a9
--- /dev/null
+++ b/testsuite/systemtap.examples/traceio2.meta
@@ -0,0 +1,13 @@
+title: Watch I/O Activity on a Particular Device
+name: traceio2.stp
+version: 1.0
+author: Red Hat
+keywords: io
+subsystem: io
+status: production
+exit: user-controlled
+output: trace
+scope: system-wide
+description: Print out the executable name and process number as reads and writes to the specified device occur.
+test_check: stap -p4 traceio2.stp 0x0801
+test_installcheck: /bin/sh eval stap traceio2.stp 0x0801 -c "sleep 1"
diff --git a/testsuite/systemtap.examples/traceio2.stp b/testsuite/systemtap.examples/traceio2.stp
new file mode 100644
index 00000000..656c38b3
--- /dev/null
+++ b/testsuite/systemtap.examples/traceio2.stp
@@ -0,0 +1,20 @@
+global device_of_interest
+
+probe begin {
+ /* The following is not the most efficient way to do this.
+ One could directly put the result of usrdev2kerndev()
+ into device_of_interest. However, want to test out
+ the other device functions */
+ dev = usrdev2kerndev($1)
+ device_of_interest = MKDEV(MAJOR(dev), MINOR(dev))
+}
+
+probe kernel.function ("vfs_write"),
+ kernel.function ("vfs_read")
+{
+ dev_nr = $file->f_path->dentry->d_inode->i_sb->s_dev
+
+ if (dev_nr == device_of_interest)
+ printf ("%s(%d) %s 0x%x\n",
+ execname(), pid(), probefunc(), dev_nr)
+}
diff --git a/testsuite/systemtap.pass1-4/buildok.exp b/testsuite/systemtap.pass1-4/buildok.exp
index 07580550..08d50fb5 100644
--- a/testsuite/systemtap.pass1-4/buildok.exp
+++ b/testsuite/systemtap.pass1-4/buildok.exp
@@ -9,6 +9,9 @@ foreach file [lsort [glob -nocomplain $srcdir/$self/*.stp]] {
buildok/twentysix.stp {setup_kfail 4105 *-*-*}
buildok/twentyseven.stp {setup_kfail 4166 *-*-*}
buildok/sched_test.stp {setup_kfail 1155 *-*-*}
+ buildok/process_test.stp {setup_kfail 1155 *-*-*}
+ buildok/rpc-all-probes.stp {setup_kfail 4413 *-*-*}
+ buildok/nfs-all-probes.stp {setup_kfail 4413 *-*-*}
}
if {$rc == 0} { pass $test } else { fail $test }
}
diff --git a/testsuite/systemtap.samples/profile.exp b/testsuite/systemtap.samples/profile.exp
index 9ca9da15..87174d2c 100644
--- a/testsuite/systemtap.samples/profile.exp
+++ b/testsuite/systemtap.samples/profile.exp
@@ -12,4 +12,4 @@ expect {
#FIXME does not handle case of hanging primes.stp correctly
wait
-if {$ok > 0} { pass "$test ($ok)" } { fail "$test" }
+if {$ok > 0} { pass $test } { fail $test }
diff --git a/translate.cxx b/translate.cxx
index b1037fef..433b82be 100644
--- a/translate.cxx
+++ b/translate.cxx
@@ -1,6 +1,6 @@
// translation pass
// Copyright (C) 2005-2008 Red Hat Inc.
-// Copyright (C) 2005-2007 Intel Corporation.
+// Copyright (C) 2005-2008 Intel Corporation.
//
// This file is part of systemtap, and is free software. You can
// redistribute it and/or modify it under the terms of the GNU General
@@ -14,6 +14,7 @@
#include "session.h"
#include "tapsets.h"
#include "util.h"
+#include "dwarf_wrappers.h"
#include <cstdlib>
#include <iostream>
@@ -43,6 +44,7 @@ struct c_unparser: public unparser, public visitor
functiondecl* current_function;
unsigned tmpvar_counter;
unsigned label_counter;
+ unsigned action_counter;
bool probe_or_function_needs_deref_fault_handler;
varuse_collecting_visitor vcv_needs_global_locks;
@@ -110,7 +112,7 @@ struct c_unparser: public unparser, public visitor
void collect_map_index_types(vector<vardecl* > const & vars,
set< pair<vector<exp_type>, exp_type> > & types);
- void visit_statement (statement* s, unsigned actions, bool stmtize);
+ void record_actions (unsigned actions, bool update=false);
void visit_block (block* s);
void visit_embeddedcode (embeddedcode* s);
@@ -619,10 +621,10 @@ struct mapvar
else
throw semantic_error("adding a value of an unsupported map type");
- res += "; if (unlikely(rc)) c->last_error = \"Array overflow, check " +
+ res += "; if (unlikely(rc)) { c->last_error = \"Array overflow, check " +
stringify(maxsize > 0 ?
"size limit (" + stringify(maxsize) + ")" : "MAXMAPENTRIES")
- + "\"; }";
+ + "\"; goto out; }}";
return res;
}
@@ -640,10 +642,10 @@ struct mapvar
else
throw semantic_error("setting a value of an unsupported map type");
- res += "; if (unlikely(rc)) c->last_error = \"Array overflow, check " +
+ res += "; if (unlikely(rc)) { c->last_error = \"Array overflow, check " +
stringify(maxsize > 0 ?
"size limit (" + stringify(maxsize) + ")" : "MAXMAPENTRIES")
- + "\"; }";
+ + "\"; goto out; }}";
return res;
}
@@ -870,9 +872,7 @@ c_unparser::emit_common_header ()
o->newline() << "const char *last_error;";
// NB: last_error is used as a health flag within a probe.
// While it's 0, execution continues
- // When it's "", current function or probe unwinds and returns early
// When it's "something", probe code unwinds, _stp_error's, sets error state
- // See c_unparser::visit_statement()
o->newline() << "const char *last_stmt;";
o->newline() << "struct pt_regs *regs;";
o->newline() << "unsigned long *unwaddr;";
@@ -1087,27 +1087,18 @@ c_unparser::emit_module_init ()
// one may install the incorrect debuginfo or -devel RPM, and try to
// run a probe compiled for a different version. Catch this early,
// just in case modversions didn't.
- o->newline() << "down_read (& uts_sem);";
o->newline() << "{";
- o->indent(1);
+ o->newline(1) << "const char* release = UTS_RELEASE;";
- // Args, linux 2.6.19+ did a switcheroo on system_utsname to utsname().
- o->newline() << "#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)";
- o->newline() << "const char* machine = utsname()->machine;";
- o->newline() << "const char* release = utsname()->release;";
- o->newline() << "#else";
- o->newline() << "const char* machine = system_utsname.machine;";
- o->newline() << "const char* release = system_utsname.release;";
- o->newline() << "#endif";
+ // NB: This UTS_RELEASE compile-time macro directly checks only that
+ // the compile-time kbuild tree matches the compile-time debuginfo/etc.
+ // It does not check the run time kernel value. However, this is
+ // probably OK since the kbuild modversions system aims to prevent
+ // mismatches between kbuild and runtime versions at module-loading time.
- o->newline() << "if (strcmp (machine, "
- << lex_cast_qstring (session->architecture) << ")) {";
- o->newline(1) << "_stp_error (\"module machine mismatch (%s vs %s)\", "
- << "machine, "
- << lex_cast_qstring (session->architecture)
- << ");";
- o->newline() << "rc = -EINVAL;";
- o->newline(-1) << "}";
+ // o->newline() << "const char* machine = UTS_MACHINE;";
+ // NB: We could compare UTS_MACHINE too, but on x86 it lies
+ // (UTS_MACHINE=i386, but uname -m is i686). Sheesh.
o->newline() << "if (strcmp (release, "
<< lex_cast_qstring (session->kernel_release) << ")) {";
@@ -1118,8 +1109,9 @@ c_unparser::emit_module_init ()
o->newline() << "rc = -EINVAL;";
o->newline(-1) << "}";
+ // XXX: perform buildid-based checking if able
+
o->newline(-1) << "}";
- o->newline() << "up_read (& uts_sem);";
o->newline() << "if (rc) goto out;";
o->newline() << "(void) probe_point;";
@@ -1315,9 +1307,8 @@ c_unparser::emit_module_exit ()
o->newline() << "struct stat_data *stats = _stp_stat_get (time_"
<< p->name
<< ", 0);";
- o->newline() << "const char *error;";
o->newline() << "if (stats->count) {";
- o->newline(1) << "int64_t avg = _stp_div64 (&error, stats->sum, stats->count);";
+ o->newline(1) << "int64_t avg = _stp_div64 (NULL, stats->sum, stats->count);";
o->newline() << "_stp_printf (\"probe %s (%s), hits: %lld, cycles: %lldmin/%lldavg/%lldmax\\n\",";
o->newline() << "probe_point, decl_location, (long long) stats->count, (long long) stats->min, (long long) avg, (long long) stats->max);";
o->newline(-1) << "}";
@@ -1352,6 +1343,7 @@ c_unparser::emit_function (functiondecl* v)
this->current_probe = 0;
this->current_function = v;
this->tmpvar_counter = 0;
+ this->action_counter = 0;
o->newline()
<< "struct function_" << c_varname (v->name) << "_locals * "
@@ -1400,26 +1392,21 @@ c_unparser::emit_function (functiondecl* v)
this->current_function = 0;
- o->newline(-1) << "out:";
- o->newline(1) << ";";
-
- // Function prologue: this is why we redirect the "return" above.
- // Decrement nesting level.
- o->newline() << "c->nesting --;";
- // Reset last_error to NULL if it was set to "" by script-level return()
- o->newline() << "if (c->last_error && ! c->last_error[0])";
- o->newline(1) << "c->last_error = 0;";
- o->indent(-1);
+ record_actions(0, true);
if (this->probe_or_function_needs_deref_fault_handler) {
// Emit this handler only if the body included a
// print/printf/etc. using a string or memory buffer!
- o->newline(1) << "return;";
o->newline() << "CATCH_DEREF_FAULT ();";
- o->newline() << "goto out;";
- o->indent(-1);
}
+ o->newline(-1) << "out:";
+ o->newline(1) << ";";
+
+ // Function prologue: this is why we redirect the "return" above.
+ // Decrement nesting level.
+ o->newline() << "c->nesting --;";
+
o->newline() << "#undef CONTEXT";
o->newline() << "#undef THIS";
o->newline(-1) << "}\n";
@@ -1436,6 +1423,7 @@ c_unparser::emit_probe (derived_probe* v)
this->current_function = 0;
this->current_probe = v;
this->tmpvar_counter = 0;
+ this->action_counter = 0;
// If we about to emit a probe that is exactly the same as another
// probe previously emitted, make the second probe just call the
@@ -1555,6 +1543,14 @@ c_unparser::emit_probe (derived_probe* v)
v->body->visit (this);
+ record_actions(0, true);
+
+ if (this->probe_or_function_needs_deref_fault_handler) {
+ // Emit this handler only if the body included a
+ // print/printf/etc. using a string or memory buffer!
+ o->newline() << "CATCH_DEREF_FAULT ();";
+ }
+
o->newline(-1) << "out:";
// NB: no need to uninitialize locals, except if arrays/stats can
// someday be local
@@ -1566,14 +1562,6 @@ c_unparser::emit_probe (derived_probe* v)
if (v->needs_global_locks ())
emit_unlocks (vut);
- if (this->probe_or_function_needs_deref_fault_handler) {
- // Emit this handler only if the body included a
- // print/printf/etc. using a string or memory buffer!
- o->newline() << "return;";
- o->newline() << "CATCH_DEREF_FAULT ();";
- o->newline() << "goto out;";
- }
-
o->newline(-1) << "}\n";
}
@@ -2049,18 +2037,22 @@ c_unparser_assignment::c_assignop(tmpvar & res,
o->newline() << lval << " = " << rval << ";";
res = rval;
}
- else
- {
- if (macop == "/=")
- o->newline() << lval << " = _stp_div64 (&c->last_error, "
- << lval << ", " << rval << ");";
- else if (macop == "%=")
- o->newline() << lval << " = _stp_mod64 (&c->last_error, "
- << lval << ", " << rval << ");";
+ else
+ {
+ if (macop == "/=" || macop == "%=")
+ {
+ o->newline() << "if (unlikely(!" << rval << ")) {";
+ o->newline(1) << "c->last_error = \"division by 0\";";
+ o->newline() << "goto out;";
+ o->newline(-1) << "}";
+ o->newline() << lval << " = "
+ << ((macop == "/=") ? "_stp_div64" : "_stp_mod64")
+ << " (NULL, " << lval << ", " << rval << ");";
+ }
else
o->newline() << lval << " " << macop << " " << rval << ";";
res = lval;
- }
+ }
}
}
else
@@ -2210,39 +2202,24 @@ c_unparser::getiter(symbol *s)
}
-
-// An artificial common "header" for each statement. This is where
-// activity counts limits and error state early exits are enforced.
+// Queue up some actions to remove from actionremaining. Set update=true at
+// the end of basic blocks to actually update actionremaining and check it
+// against MAXACTION.
void
-c_unparser::visit_statement (statement *s, unsigned actions, bool stmtize)
+c_unparser::record_actions (unsigned actions, bool update)
{
- // For some constructs, it is important to avoid an error branch
- // right to the bottom of the probe/function. The foreach()
- // iteration construct is one example. Instead, if we are nested
- // within a loop, we branch merely to its "break" label. The next
- // statement will branch one level higher, and so on, until we can
- // go straight "out".
- string outlabel = "out";
- unsigned loops = loop_break_labels.size();
- if (loops > 0)
- outlabel = loop_break_labels[loops-1];
-
- if (s)
- {
- o->newline() << "if (unlikely (c->last_error)) goto " << outlabel << ";";
- assert (s->tok);
- if (stmtize)
- o->newline() << "c->last_stmt = " << lex_cast_qstring(*s->tok) << ";";
- }
+ action_counter += actions;
- if (actions > 0)
+ // Update if needed, or after queueing up a few actions, in case of very
+ // large code sequences.
+ if ((update && action_counter > 0) || action_counter >= 10/*<-arbitrary*/)
{
- o->newline() << "c->actionremaining -= " << actions << ";";
- // XXX: This check is inserted too frequently.
+ o->newline() << "c->actionremaining -= " << action_counter << ";";
o->newline() << "if (unlikely (c->actionremaining <= 0)) {";
o->newline(1) << "c->last_error = \"MAXACTION exceeded\";";
- o->newline() << "goto " << outlabel << ";";
+ o->newline() << "goto out;";
o->newline(-1) << "}";
+ action_counter = 0;
}
}
@@ -2253,13 +2230,6 @@ c_unparser::visit_block (block *s)
o->newline() << "{";
o->indent (1);
- // visit_statement (s, 0, false);
- //
- // NB: this is not necessary, since the last_error can be handled
- // just as easily by the first real body statement, and the
- // last_stmt won't be used since this nesting structure cannot
- // itself cause an error.
-
for (unsigned i=0; i<s->statements.size(); i++)
{
try
@@ -2279,12 +2249,6 @@ c_unparser::visit_block (block *s)
void
c_unparser::visit_embeddedcode (embeddedcode *s)
{
- // visit_statement (s, 1, true);
- //
- // NB: this is not necessary, since this can occur only at the top
- // level of a function (so no errors can be pending), and the
- // action-count is already incremented at the point of call.
-
o->newline() << "{";
o->newline(1) << s->code;
o->newline(-1) << "}";
@@ -2294,12 +2258,6 @@ c_unparser::visit_embeddedcode (embeddedcode *s)
void
c_unparser::visit_null_statement (null_statement *)
{
- // visit_statement (s, 0, false);
- //
- // NB: this is not necessary, since the last_error can be handled just as
- // easily by the next statement, and the last_stmt won't be used since this
- // statement cannot cause an error.
-
o->newline() << "/* null */;";
}
@@ -2307,17 +2265,17 @@ c_unparser::visit_null_statement (null_statement *)
void
c_unparser::visit_expr_statement (expr_statement *s)
{
- visit_statement (s, 1, false);
o->newline() << "(void) ";
s->value->visit (this);
o->line() << ";";
+ record_actions(1);
}
void
c_unparser::visit_if_statement (if_statement *s)
{
- visit_statement (s, 1, false);
+ record_actions(1, true);
o->newline() << "if (";
o->indent (1);
s->condition->visit (this);
@@ -2325,12 +2283,14 @@ c_unparser::visit_if_statement (if_statement *s)
o->line() << ") {";
o->indent (1);
s->thenblock->visit (this);
+ record_actions(0, true);
o->newline(-1) << "}";
if (s->elseblock)
{
o->newline() << "else {";
o->indent (1);
s->elseblock->visit (this);
+ record_actions(0, true);
o->newline(-1) << "}";
}
}
@@ -2380,8 +2340,6 @@ c_tmpcounter::visit_for_loop (for_loop *s)
void
c_unparser::visit_for_loop (for_loop *s)
{
- visit_statement (s, 1, false);
-
string ctr = stringify (label_counter++);
string toplabel = "top_" + ctr;
string contlabel = "continue_" + ctr;
@@ -2389,6 +2347,7 @@ c_unparser::visit_for_loop (for_loop *s)
// initialization
if (s->init) s->init->visit (this);
+ record_actions(1, true);
// condition
o->newline(-1) << toplabel << ":";
@@ -2397,7 +2356,7 @@ c_unparser::visit_for_loop (for_loop *s)
// Equivalently, it can stand for the evaluation of the condition
// expression.
o->indent(1);
- visit_statement (0, 1, false);
+ record_actions(1);
o->newline() << "if (! (";
if (s->cond->type != pe_long)
@@ -2409,6 +2368,7 @@ c_unparser::visit_for_loop (for_loop *s)
loop_break_labels.push_back (breaklabel);
loop_continue_labels.push_back (contlabel);
s->block->visit (this);
+ record_actions(0, true);
loop_break_labels.pop_back ();
loop_continue_labels.pop_back ();
@@ -2529,8 +2489,6 @@ c_unparser::visit_foreach_loop (foreach_loop *s)
if (array)
{
- visit_statement (s, 1, false);
-
mapvar mv = getmap (array->referent, s->tok);
itervar iv = getiter (array);
vector<var> keys;
@@ -2555,9 +2513,10 @@ c_unparser::visit_foreach_loop (foreach_loop *s)
// aggregate array if required
if (mv.is_parallel())
{
- o->newline() << "if (unlikely(NULL == " << mv.calculate_aggregate() << "))";
+ o->newline() << "if (unlikely(NULL == " << mv.calculate_aggregate() << ")) {";
o->newline(1) << "c->last_error = \"aggregation overflow in " << mv << "\";";
- o->indent(-1);
+ o->newline() << "goto out;";
+ o->newline(-1) << "}";
// sort array if desired
if (s->sort_direction)
@@ -2624,6 +2583,8 @@ c_unparser::visit_foreach_loop (foreach_loop *s)
o->newline() << *limitv << " = 0LL;";
}
+ record_actions(1, true);
+
// condition
o->newline(-1) << toplabel << ":";
@@ -2631,7 +2592,7 @@ c_unparser::visit_foreach_loop (foreach_loop *s)
// Equivalently, it can stand for the evaluation of the
// condition expression.
o->indent(1);
- visit_statement (0, 1, false);
+ record_actions(1);
o->newline() << "if (! (" << iv << ")) goto " << breaklabel << ";";
@@ -2659,6 +2620,7 @@ c_unparser::visit_foreach_loop (foreach_loop *s)
c_assign (v, iv.get_key (v.type(), i), s->tok);
}
s->block->visit (this);
+ record_actions(0, true);
o->newline(-1) << "}";
loop_break_labels.pop_back ();
loop_continue_labels.pop_back ();
@@ -2703,6 +2665,7 @@ c_unparser::visit_foreach_loop (foreach_loop *s)
}
// XXX: break / continue don't work here yet
+ record_actions(1, true);
o->newline() << "for (" << bucketvar << " = 0; "
<< bucketvar << " < " << v.buckets() << "; "
<< bucketvar << "++) { ";
@@ -2720,6 +2683,7 @@ c_unparser::visit_foreach_loop (foreach_loop *s)
}
s->block->visit (this);
+ record_actions(1, true);
o->newline(-1) << "}";
}
}
@@ -2728,8 +2692,6 @@ c_unparser::visit_foreach_loop (foreach_loop *s)
void
c_unparser::visit_return_statement (return_statement* s)
{
- visit_statement (s, 1, false);
-
if (current_function == 0)
throw semantic_error ("cannot 'return' from probe", s->tok);
@@ -2738,21 +2700,19 @@ c_unparser::visit_return_statement (return_statement* s)
"vs", s->tok);
c_assign ("l->__retvalue", s->value, "return value");
- o->newline() << "c->last_error = \"\";";
- // NB: last_error needs to get reset to NULL in the caller
- // probe/function
+ record_actions(1, true);
+ o->newline() << "goto out;";
}
void
c_unparser::visit_next_statement (next_statement* s)
{
- visit_statement (s, 1, false);
-
if (current_probe == 0)
throw semantic_error ("cannot 'next' from function", s->tok);
- o->newline() << "c->last_error = \"\";";
+ record_actions(1, true);
+ o->newline() << "goto out;";
}
@@ -2879,19 +2839,19 @@ c_tmpcounter::visit_delete_statement (delete_statement* s)
void
c_unparser::visit_delete_statement (delete_statement* s)
{
- visit_statement (s, 1, false);
delete_statement_operand_visitor dv (this);
s->value->visit (&dv);
+ record_actions(1);
}
void
c_unparser::visit_break_statement (break_statement* s)
{
- visit_statement (s, 1, false);
if (loop_break_labels.size() == 0)
throw semantic_error ("cannot 'break' outside loop", s->tok);
+ record_actions(1, true);
string label = loop_break_labels[loop_break_labels.size()-1];
o->newline() << "goto " << label << ";";
}
@@ -2900,10 +2860,10 @@ c_unparser::visit_break_statement (break_statement* s)
void
c_unparser::visit_continue_statement (continue_statement* s)
{
- visit_statement (s, 1, false);
if (loop_continue_labels.size() == 0)
throw semantic_error ("cannot 'continue' outside loop", s->tok);
+ record_actions(1, true);
string label = loop_continue_labels[loop_continue_labels.size()-1];
o->newline() << "goto " << label << ";";
}
@@ -3001,8 +2961,6 @@ c_unparser::visit_binary_expression (binary_expression* e)
o->line() << "({";
o->indent(1);
- // NB: Need last_stmt set here because of possible last_error generation
- o->newline() << "c->last_stmt = " << lex_cast_qstring(*e->tok) << ";";
if (e->left->tok->type == tok_number)
left.override(c_expression(e->left));
@@ -3022,8 +2980,13 @@ c_unparser::visit_binary_expression (binary_expression* e)
o->line() << ";";
}
+ o->newline() << "if (unlikely(!" << right << ")) {";
+ o->newline(1) << "c->last_error = \"division by 0\";";
+ o->newline() << "c->last_stmt = " << lex_cast_qstring(*e->tok) << ";";
+ o->newline() << "goto out;";
+ o->newline(-1) << "}";
o->newline() << ((e->op == "/") ? "_stp_div64" : "_stp_mod64")
- << " (&c->last_error, " << left << ", " << right << ");";
+ << " (NULL, " << left << ", " << right << ");";
o->newline(-1) << "})";
}
@@ -3741,16 +3704,19 @@ c_unparser::visit_arrayindex (arrayindex* e)
// PR 2142+2610: empty aggregates
o->newline() << "if (unlikely (" << agg.value() << " == NULL)"
- << " || " << agg.value() << "->count == 0)";
+ << " || " << agg.value() << "->count == 0) {";
o->newline(1) << "c->last_error = \"empty aggregate\";";
- o->newline(-1) << "else {";
+ o->newline() << "goto out;";
+ o->newline(-1) << "} else {";
o->newline(1) << "if (" << histogram_index_check(*v, idx[0]) << ")";
o->newline(1) << res << " = " << agg << "->histogram[" << idx[0] << "];";
- o->newline(-1) << "else";
+ o->newline(-1) << "else {";
o->newline(1) << "c->last_error = \"histogram index out of range\";";
+ o->newline() << "goto out;";
+ o->newline(-1) << "}";
o->newline(-1) << "}";
- o->newline(-1) << res << ";";
+ o->newline() << res << ";";
delete v;
}
@@ -3954,6 +3920,7 @@ c_unparser::visit_functioncall (functioncall* e)
// call function
o->newline() << "function_" << c_varname (r->name) << " (c);";
+ o->newline() << "if (unlikely(c->last_error)) goto out;";
// return result from retvalue slot
if (r->type == pe_unknown)
@@ -4050,6 +4017,7 @@ c_unparser::visit_print_format (print_format* e)
<< " || " << agg.value() << "->count == 0) {";
o->newline(1) << "c->last_error = \"empty aggregate\";";
o->newline() << "c->last_stmt = " << lex_cast_qstring(*e->tok) << ";";
+ o->newline() << "goto out;";
o->newline(-1) << "} else";
o->newline(1) << "_stp_stat_print_histogram (" << v->hist() << ", " << agg.value() << ");";
o->indent(-1);
@@ -4144,9 +4112,7 @@ c_unparser::visit_print_format (print_format* e)
components[0].type = print_format::conv_literal;
}
- // Make the [s]printf call, but not if there was an error evaluating the args
- o->newline() << "if (likely (! c->last_error)) {";
- o->indent(1);
+ // Make the [s]printf call...
// Generate code to check that any pointer arguments are actually accessible. */
int arg_ix = 0;
@@ -4187,7 +4153,6 @@ c_unparser::visit_print_format (print_format* e)
o->line() << tmp[0].value() << ");";
else
o->line() << '"' << format_string << "\");";
- o->newline(-1) << "}";
return;
}
if (use_print)
@@ -4197,7 +4162,6 @@ c_unparser::visit_print_format (print_format* e)
o->line() << tmp[0].value() << ");";
else
o->line() << '"' << format_string << "\");";
- o->newline(-1) << "}";
return;
}
@@ -4232,7 +4196,6 @@ c_unparser::visit_print_format (print_format* e)
}
o->line() << ");";
- o->newline(-1) << "}";
o->newline() << res.value() << ";";
}
}
@@ -4307,16 +4270,18 @@ c_unparser::visit_stat_op (stat_op* e)
else
{
o->newline() << "if (unlikely (" << agg.value() << " == NULL)"
- << " || " << agg.value() << "->count == 0)";
+ << " || " << agg.value() << "->count == 0) {";
o->newline(1) << "c->last_error = \"empty aggregate\";";
- o->indent(-1);
+ o->newline() << "c->last_stmt = " << lex_cast_qstring(*e->tok) << ";";
+ o->newline() << "goto out;";
+ o->newline(-1) << "}";
}
o->newline() << "else";
o->indent(1);
switch (e->ctype)
{
case sc_average:
- c_assign(res, ("_stp_div64(&c->last_error, " + agg.value() + "->sum, "
+ c_assign(res, ("_stp_div64(NULL, " + agg.value() + "->sum, "
+ agg.value() + "->count)"),
e->tok);
break;
@@ -4361,36 +4326,50 @@ c_unparser::visit_hist_op (hist_op*)
}
-static map< Dwarf_Addr, string> addrmap;
-
-#include <string.h>
-static int
-kernel_filter (const char *module, const char *file __attribute__((unused)))
+struct unwindsym_dump_context
{
- return !strcmp(module,"kernel");
-}
+ systemtap_session& session;
+ ostream& output;
+};
+
static int
-get_symbols (Dwfl_Module *m,
- void **userdata __attribute__ ((unused)),
- const char *name __attribute__ ((unused)),
- Dwarf_Addr base __attribute__ ((unused)),
- void *arg __attribute__ ((unused)))
+dump_unwindsyms (Dwfl_Module *m,
+ void **userdata __attribute__ ((unused)),
+ const char *name,
+ Dwarf_Addr base,
+ void *arg)
{
+ unwindsym_dump_context* c = (unwindsym_dump_context*) arg;
+ assert (c);
+
+ string modname = name;
+
+ // skip modules/files we're not actually interested in
+ if (c->session.unwindsym_modules.find(modname) == c->session.unwindsym_modules.end())
+ return DWARF_CB_OK;
+
+ if (c->session.verbose > 1)
+ clog << "dump_unwindsyms " << name << " base=0x" << hex << base << dec << endl;
+
+ // We want to extract several bits of information:
+ // - parts of the program-header that map the file's physical offsets to the text section
+ // - symbol table of the text section
+ // - the contents .debug_frame section
+ // In the future, we'll also care about data symbols.
+
int syments = dwfl_module_getsymtab(m);
assert(syments);
for (int i = 1; i < syments; ++i)
{
GElf_Sym sym;
const char *name = dwfl_module_getsym(m, i, &sym, NULL);
- if (name) {
- if (GELF_ST_TYPE (sym.st_info) == STT_FUNC ||
- strcmp(name, "_etext") == 0 ||
- strcmp(name, "_stext") == 0 ||
- strcmp(name, "modules_op") == 0)
- addrmap[sym.st_value] = name;
- }
+ if (name)
+ {
+ if (GELF_ST_TYPE (sym.st_info) == STT_FUNC)
+ ; // addrmap[sym.st_value] = name;
+ }
}
return DWARF_CB_OK;
}
@@ -4399,26 +4378,23 @@ get_symbols (Dwfl_Module *m,
void
emit_symbol_data (systemtap_session& s)
{
- ofstream kallsyms_out ((s.tmpdir + "/stap-symbols.h").c_str());
- s.op->newline() << "\n\n#include \"stap-symbols.h\"";
+ string symfile = "stap-symbols.h";
+ ofstream kallsyms_out ((s.tmpdir + "/" + symfile).c_str());
- if (s.verbose > 1)
- {
- std::set<std::string>::iterator it = s.unwindsym_modules.begin();
- clog << "unwindsym modules: ";
- while (it != s.unwindsym_modules.end())
- {
- clog << *(it++) << " ";
- }
- clog << endl;
- }
+ unwindsym_dump_context ctx = { s, kallsyms_out };
+
+ s.op->newline() << "\n\n#include \"" << symfile << "\"";
+ // XXX: copied from tapsets.cxx, sadly
static char debuginfo_path_arr[] = "-:.debug:/usr/lib/debug:build";
static char *debuginfo_env_arr = getenv("SYSTEMTAP_DEBUGINFO_PATH");
static char *debuginfo_path = (debuginfo_env_arr ?
- debuginfo_env_arr : debuginfo_path_arr);
-
+ debuginfo_env_arr : debuginfo_path_arr);
+ static const char *debug_path = (debuginfo_env_arr ?
+ debuginfo_env_arr : s.kernel_release.c_str());
+
+ // ---- step 1: process any kernel modules listed
static const Dwfl_Callbacks kernel_callbacks =
{
dwfl_linux_kernel_find_elf,
@@ -4431,27 +4407,55 @@ emit_symbol_data (systemtap_session& s)
if (!dwfl)
throw semantic_error ("cannot open dwfl");
dwfl_report_begin (dwfl);
-
- int rc = dwfl_linux_kernel_report_offline (dwfl,
- s.kernel_release.c_str(),
- kernel_filter);
+ int rc = dwfl_linux_kernel_report_offline (dwfl, debug_path, NULL /* XXX: filtering callback */);
dwfl_report_end (dwfl, NULL, NULL);
- if (rc < 0)
- throw semantic_error ("dwfl rc");
-
- dwfl_getmodules (dwfl, &get_symbols, NULL, 0);
+ dwfl_assert ("dwfl_linux_kernel_report_offline", rc);
+ ptrdiff_t off = 0;
+ do
+ {
+ if (pending_interrupts) return;
+ off = dwfl_getmodules (dwfl, &dump_unwindsyms, (void *) &ctx, 0);
+ }
+ while (off > 0);
+ dwfl_assert("dwfl_getmodules", off == 0);
dwfl_end(dwfl);
-
- int i = 0;
- map< Dwarf_Addr, string>::iterator pos;
- kallsyms_out << "struct _stp_symbol _stp_kernel_symbols [] = {";
- for (pos = addrmap.begin(); pos != addrmap.end(); pos++) {
- kallsyms_out << " { 0x" << hex << pos->first << ", " << "\"" << pos->second << "\" },\n";
- i++;
- }
-
- kallsyms_out << "};\n";
- kallsyms_out << "unsigned _stp_num_kernel_symbols = " << dec << i << ";\n";
+
+
+ // ---- step 2: process any user modules (files) listed
+ static const Dwfl_Callbacks user_callbacks =
+ {
+ NULL, /* dwfl_linux_kernel_find_elf, */
+ dwfl_standard_find_debuginfo,
+ dwfl_offline_section_address,
+ & debuginfo_path
+ };
+
+ for (std::set<std::string>::iterator it = s.unwindsym_modules.begin();
+ it != s.unwindsym_modules.end();
+ it++)
+ {
+ string modname = *it;
+ assert (modname.length() != 0);
+ if (modname[0] != '/') continue; // user-space files must be full paths
+
+ Dwfl *dwfl = dwfl_begin (&user_callbacks);
+ if (!dwfl)
+ throw semantic_error ("cannot create dwfl for " + modname);
+
+ dwfl_report_begin (dwfl);
+ Dwfl_Module* mod = dwfl_report_offline (dwfl, modname.c_str(), modname.c_str(), -1);
+ dwfl_report_end (dwfl, NULL, NULL);
+ dwfl_assert ("dwfl_report_offline", mod);
+ ptrdiff_t off = 0;
+ do
+ {
+ if (pending_interrupts) return;
+ off = dwfl_getmodules (dwfl, &dump_unwindsyms, (void *) &ctx, 0);
+ }
+ while (off > 0);
+ dwfl_assert("dwfl_getmodules", off == 0);
+ dwfl_end(dwfl);
+ }
}
@@ -4532,7 +4536,10 @@ translate_pass (systemtap_session& s)
s.op->newline() << "#include <linux/delay.h>";
s.op->newline() << "#include <linux/profile.h>";
s.op->newline() << "#include <linux/random.h>";
+ s.op->newline() << "#include <linux/utsrelease.h>";
s.op->newline() << "#include <linux/utsname.h>";
+ s.op->newline() << "#include <linux/version.h>";
+ s.op->newline() << "#include <linux/compile.h>";
s.op->newline() << "#include \"loc2c-runtime.h\" ";
// XXX: old 2.6 kernel hack