]> sourceware.org Git - systemtap.git/commitdiff
PR30434 continuation: CONFIG_UTRACE mentions removed and "if" branches related to...
authorHousam Alamour <halamour@redhat.com>
Fri, 11 Aug 2023 16:15:37 +0000 (12:15 -0400)
committerHousam Alamour <halamour@redhat.com>
Thu, 24 Aug 2023 15:07:53 +0000 (11:07 -0400)
23 files changed:
Makefile.am
Makefile.in
bpf-translate.cxx
po/POTFILES.in
po/cs.gmo
po/cs.po
po/en.po
po/fr.gmo
po/fr.po
po/pl.po
po/systemtap.pot
runtime/linux/runtime.h
runtime/linux/task_finder.c
runtime/sym.c
runtime/task_finder_vma.c
runtime/vma.c
tapset-itrace.cxx [deleted file]
tapset-utrace.cxx
tapsets.cxx
testsuite/lib/systemtap.exp
testsuite/systemtap.base/itrace.exp
testsuite/systemtap.base/valid_pid.exp
testsuite/systemtap.unprivileged/unprivileged_myproc.exp

index b59c3cf589710896df9d3fd7af7c7741bd08487e..e1bfa485e0519f29323122e288c907bc391e56c6 100644 (file)
@@ -47,7 +47,7 @@ stap_SOURCES = main.cxx session.cxx \
        tapsets.cxx buildrun.cxx loc2stap.cxx hash.cxx mdfour.c \
        cache.cxx util.cxx coveragedb.cxx dwarf_wrappers.cxx \
        tapset-been.cxx tapset-procfs.cxx tapset-timers.cxx tapset-netfilter.cxx \
-       tapset-perfmon.cxx tapset-mark.cxx tapset-itrace.cxx \
+       tapset-perfmon.cxx tapset-mark.cxx \
        tapset-utrace.cxx task_finder.cxx dwflpp.cxx rpm_finder.cxx \
        setupdwfl.cxx remote.cxx privilege.cxx cmdline.cxx \
        tapset-dynprobe.cxx tapset-method.cxx translator-output.cxx \
index 628abfe9d6b07b59477cddce4ed8378092d44af9..f323c5cd1fc01e783cce5746b5d762f6a324f406 100644 (file)
@@ -204,7 +204,6 @@ am__dirstamp = $(am__leading_dot)dirstamp
 @BUILD_TRANSLATOR_TRUE@        stap-tapset-netfilter.$(OBJEXT) \
 @BUILD_TRANSLATOR_TRUE@        stap-tapset-perfmon.$(OBJEXT) \
 @BUILD_TRANSLATOR_TRUE@        stap-tapset-mark.$(OBJEXT) \
-@BUILD_TRANSLATOR_TRUE@        stap-tapset-itrace.$(OBJEXT) \
 @BUILD_TRANSLATOR_TRUE@        stap-tapset-utrace.$(OBJEXT) \
 @BUILD_TRANSLATOR_TRUE@        stap-task_finder.$(OBJEXT) \
 @BUILD_TRANSLATOR_TRUE@        stap-dwflpp.$(OBJEXT) \
@@ -356,7 +355,6 @@ am__depfiles_remade = ./$(DEPDIR)/stap-analysis.Po \
        ./$(DEPDIR)/stap-stringtable.Po \
        ./$(DEPDIR)/stap-tapset-been.Po \
        ./$(DEPDIR)/stap-tapset-dynprobe.Po \
-       ./$(DEPDIR)/stap-tapset-itrace.Po \
        ./$(DEPDIR)/stap-tapset-mark.Po \
        ./$(DEPDIR)/stap-tapset-method.Po \
        ./$(DEPDIR)/stap-tapset-netfilter.Po \
@@ -699,10 +697,10 @@ oldinclude_HEADERS = includes/sys/sdt.h includes/sys/sdt-config.h
 @BUILD_TRANSLATOR_TRUE@        dwarf_wrappers.cxx tapset-been.cxx \
 @BUILD_TRANSLATOR_TRUE@        tapset-procfs.cxx tapset-timers.cxx \
 @BUILD_TRANSLATOR_TRUE@        tapset-netfilter.cxx tapset-perfmon.cxx \
-@BUILD_TRANSLATOR_TRUE@        tapset-mark.cxx tapset-itrace.cxx \
-@BUILD_TRANSLATOR_TRUE@        tapset-utrace.cxx task_finder.cxx \
-@BUILD_TRANSLATOR_TRUE@        dwflpp.cxx rpm_finder.cxx setupdwfl.cxx \
-@BUILD_TRANSLATOR_TRUE@        remote.cxx privilege.cxx cmdline.cxx \
+@BUILD_TRANSLATOR_TRUE@        tapset-mark.cxx tapset-utrace.cxx \
+@BUILD_TRANSLATOR_TRUE@        task_finder.cxx dwflpp.cxx \
+@BUILD_TRANSLATOR_TRUE@        rpm_finder.cxx setupdwfl.cxx remote.cxx \
+@BUILD_TRANSLATOR_TRUE@        privilege.cxx cmdline.cxx \
 @BUILD_TRANSLATOR_TRUE@        tapset-dynprobe.cxx tapset-method.cxx \
 @BUILD_TRANSLATOR_TRUE@        translator-output.cxx stapregex.cxx \
 @BUILD_TRANSLATOR_TRUE@        stapregex-tree.cxx stapregex-parse.cxx \
@@ -1129,7 +1127,6 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stap-stringtable.Po@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stap-tapset-been.Po@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stap-tapset-dynprobe.Po@am__quote@ # am--include-marker
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stap-tapset-itrace.Po@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stap-tapset-mark.Po@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stap-tapset-method.Po@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stap-tapset-netfilter.Po@am__quote@ # am--include-marker
@@ -1509,20 +1506,6 @@ stap-tapset-mark.obj: tapset-mark.cxx
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(stap_CPPFLAGS) $(CPPFLAGS) $(stap_CXXFLAGS) $(CXXFLAGS) -c -o stap-tapset-mark.obj `if test -f 'tapset-mark.cxx'; then $(CYGPATH_W) 'tapset-mark.cxx'; else $(CYGPATH_W) '$(srcdir)/tapset-mark.cxx'; fi`
 
-stap-tapset-itrace.o: tapset-itrace.cxx
-@am__fastdepCXX_TRUE@  $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(stap_CPPFLAGS) $(CPPFLAGS) $(stap_CXXFLAGS) $(CXXFLAGS) -MT stap-tapset-itrace.o -MD -MP -MF $(DEPDIR)/stap-tapset-itrace.Tpo -c -o stap-tapset-itrace.o `test -f 'tapset-itrace.cxx' || echo '$(srcdir)/'`tapset-itrace.cxx
-@am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) $(DEPDIR)/stap-tapset-itrace.Tpo $(DEPDIR)/stap-tapset-itrace.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@     $(AM_V_CXX)source='tapset-itrace.cxx' object='stap-tapset-itrace.o' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(stap_CPPFLAGS) $(CPPFLAGS) $(stap_CXXFLAGS) $(CXXFLAGS) -c -o stap-tapset-itrace.o `test -f 'tapset-itrace.cxx' || echo '$(srcdir)/'`tapset-itrace.cxx
-
-stap-tapset-itrace.obj: tapset-itrace.cxx
-@am__fastdepCXX_TRUE@  $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(stap_CPPFLAGS) $(CPPFLAGS) $(stap_CXXFLAGS) $(CXXFLAGS) -MT stap-tapset-itrace.obj -MD -MP -MF $(DEPDIR)/stap-tapset-itrace.Tpo -c -o stap-tapset-itrace.obj `if test -f 'tapset-itrace.cxx'; then $(CYGPATH_W) 'tapset-itrace.cxx'; else $(CYGPATH_W) '$(srcdir)/tapset-itrace.cxx'; fi`
-@am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) $(DEPDIR)/stap-tapset-itrace.Tpo $(DEPDIR)/stap-tapset-itrace.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@     $(AM_V_CXX)source='tapset-itrace.cxx' object='stap-tapset-itrace.obj' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(stap_CPPFLAGS) $(CPPFLAGS) $(stap_CXXFLAGS) $(CXXFLAGS) -c -o stap-tapset-itrace.obj `if test -f 'tapset-itrace.cxx'; then $(CYGPATH_W) 'tapset-itrace.cxx'; else $(CYGPATH_W) '$(srcdir)/tapset-itrace.cxx'; fi`
-
 stap-tapset-utrace.o: tapset-utrace.cxx
 @am__fastdepCXX_TRUE@  $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(stap_CPPFLAGS) $(CPPFLAGS) $(stap_CXXFLAGS) $(CXXFLAGS) -MT stap-tapset-utrace.o -MD -MP -MF $(DEPDIR)/stap-tapset-utrace.Tpo -c -o stap-tapset-utrace.o `test -f 'tapset-utrace.cxx' || echo '$(srcdir)/'`tapset-utrace.cxx
 @am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) $(DEPDIR)/stap-tapset-utrace.Tpo $(DEPDIR)/stap-tapset-utrace.Po
@@ -2392,7 +2375,6 @@ distclean: distclean-recursive
        -rm -f ./$(DEPDIR)/stap-stringtable.Po
        -rm -f ./$(DEPDIR)/stap-tapset-been.Po
        -rm -f ./$(DEPDIR)/stap-tapset-dynprobe.Po
-       -rm -f ./$(DEPDIR)/stap-tapset-itrace.Po
        -rm -f ./$(DEPDIR)/stap-tapset-mark.Po
        -rm -f ./$(DEPDIR)/stap-tapset-method.Po
        -rm -f ./$(DEPDIR)/stap-tapset-netfilter.Po
@@ -2511,7 +2493,6 @@ maintainer-clean: maintainer-clean-recursive
        -rm -f ./$(DEPDIR)/stap-stringtable.Po
        -rm -f ./$(DEPDIR)/stap-tapset-been.Po
        -rm -f ./$(DEPDIR)/stap-tapset-dynprobe.Po
-       -rm -f ./$(DEPDIR)/stap-tapset-itrace.Po
        -rm -f ./$(DEPDIR)/stap-tapset-mark.Po
        -rm -f ./$(DEPDIR)/stap-tapset-method.Po
        -rm -f ./$(DEPDIR)/stap-tapset-netfilter.Po
index 9d555e829b1e26ea84a84b24731abca73426448c..1a93024632d4539e211e009d81e1667f7a14a295 100644 (file)
@@ -5349,8 +5349,6 @@ translate_bpf_pass (systemtap_session& s)
       // XXX PR26234: need to warn about other probe groups....
       if (s.hwbkpt_derived_probes)
         warn_for_bpf(s, s.hwbkpt_derived_probes, "hardware breakpoint probe");
-      if (s.itrace_derived_probes)
-        warn_for_bpf(s, s.itrace_derived_probes, "process.insn probe");
       if (s.netfilter_derived_probes)
         warn_for_bpf(s, s.netfilter_derived_probes, "netfilter probe");
       if (s.profile_derived_probes)
index e0ad5ed5e9bb34b513be1d50dd165920438745b9..ca2280d9b933974d9f3e0c74b64379d797548bd9 100644 (file)
@@ -93,7 +93,6 @@ stringtable.h
 tapset-been.cxx
 tapset-dynprobe.cxx
 tapset-dynprobe.h
-tapset-itrace.cxx
 tapset-mark.cxx
 tapset-method.cxx
 tapset-netfilter.cxx
index 720479216739894426a40bb2c0316cd1a70ea8c6..98c810bf5c6b12c03fe3615304542f0437fad7fb 100644 (file)
Binary files a/po/cs.gmo and b/po/cs.gmo differ
index e5c2d7f5bc58fbfc09bd620ac623ab9a5de4a9a7..8e03191d780d6938ccce0704db669564f19e4f98 100644 (file)
--- a/po/cs.po
+++ b/po/cs.po
@@ -6068,7 +6068,7 @@ msgstr ""
 msgid "update_visitor dtor has unused values"
 msgstr "update_visitor nemá definovanou hodnotu"
 
-#: tapset-itrace.cxx:326 tapset-itrace.cxx:341 tapset-mark.cxx:575
+#: tapset-mark.cxx:575
 #: tapset-netfilter.cxx:432 tapset-python.cxx:236 tapset-python.cxx:244
 #: tapsets.cxx:11020 tapset-timers.cxx:580 tapset-utrace.cxx:1323
 #: tapset-utrace.cxx:1337
index b022f6ba63546f87aeaf8878bcfd7fe881c4453e..886c15d6a0e8de9adc9ad30c7fd6465e1ad2d2f2 100644 (file)
--- a/po/en.po
+++ b/po/en.po
@@ -5921,7 +5921,7 @@ msgstr ""
 msgid "update_visitor dtor has unused values"
 msgstr ""
 
-#: tapset-itrace.cxx:326 tapset-itrace.cxx:341 tapset-mark.cxx:575
+#: tapset-mark.cxx:575
 #: tapset-netfilter.cxx:432 tapset-python.cxx:236 tapset-python.cxx:244
 #: tapsets.cxx:11020 tapset-timers.cxx:580 tapset-utrace.cxx:1323
 #: tapset-utrace.cxx:1337
index ccb0b220a17abfd0597943a590648c130094e4ea..e37936d6f528c59ab1c2ebea90ac462028818aeb 100644 (file)
Binary files a/po/fr.gmo and b/po/fr.gmo differ
index 4577dc5accf2e6be5251b380f470eff75b7074b3..291089f7d2520e8c500bcb40d7552d7f8a6c3121 100644 (file)
--- a/po/fr.po
+++ b/po/fr.po
@@ -6075,7 +6075,7 @@ msgstr ""
 msgid "update_visitor dtor has unused values"
 msgstr ""
 
-#: tapset-itrace.cxx:326 tapset-itrace.cxx:341 tapset-mark.cxx:575
+#: tapset-mark.cxx:575
 #: tapset-netfilter.cxx:432 tapset-python.cxx:236 tapset-python.cxx:244
 #: tapsets.cxx:11020 tapset-timers.cxx:580 tapset-utrace.cxx:1323
 #: tapset-utrace.cxx:1337
index 4b6e20292628e5981442937f8cc5f5738665d2cf..8182a9026ecfda8731fcd28c8b52007bd91c2871 100644 (file)
--- a/po/pl.po
+++ b/po/pl.po
@@ -5745,7 +5745,7 @@ msgstr ""
 #: staptree.h:1355
 msgid "update_visitor dtor has unused values"
 msgstr ""
-#: tapset-itrace.cxx:326 tapset-itrace.cxx:341 tapset-mark.cxx:575
+#: tapset-mark.cxx:575
 #: tapset-netfilter.cxx:432 tapset-python.cxx:236 tapset-python.cxx:244
 #: tapsets.cxx:11020 tapset-timers.cxx:580 tapset-utrace.cxx:1323
 #: tapset-utrace.cxx:1337
index d6421ffaf76c938a1bcb34ab914db2170f7e9197..83ebe514ac2124d271d01907258fcbbfcf07255a 100644 (file)
@@ -5730,7 +5730,7 @@ msgstr ""
 msgid "update_visitor dtor has unused values"
 msgstr ""
 
-#: tapset-itrace.cxx:326 tapset-itrace.cxx:341 tapset-mark.cxx:575
+#: tapset-mark.cxx:575
 #: tapset-netfilter.cxx:432 tapset-python.cxx:236 tapset-python.cxx:244
 #: tapsets.cxx:11020 tapset-timers.cxx:580 tapset-utrace.cxx:1323
 #: tapset-utrace.cxx:1337
index f7b3cdcf080ddc2b6b0be287e488ca63fdfd7fed..8ed3cad4cd878e6f5b910a2fa90cf1f7c26c80dd 100644 (file)
@@ -279,7 +279,7 @@ static void *kallsyms_get_mm_exe_file;
 #include "../regs.c"
 #include "regs-ia64.c"
 
-#if (defined(CONFIG_UTRACE) || defined(STAPCONF_UTRACE_VIA_TRACEPOINTS))
+#if (defined(STAPCONF_UTRACE_VIA_TRACEPOINTS))
 #define HAVE_TASK_FINDER
 #include "task_finder.c"
 #else
index 8b95f3e1a26cda0294d79c5745d2433dfb044184..2094df4cc6b9ca75de0232f7ade0c04ff0b8730c 100644 (file)
 
 /*
  * Which utrace shall we use?
- * (1) Built-in kernel utrace (preferred), indicated by
- * CONFIG_UTRACE.
+ * (1) Built-in kernel utrace (preferred)
  * (2) Internal utrace.  Requires STAPCONF_UTRACE_VIA_TRACEPOINTS.
  * (3) If we don't have either (old kernels or new kernels without all
  * the pre-requisites), error.
  */
 
 #ifndef HAVE_TASK_FINDER
-#error "Process probes not available without kernel CONFIG_UTRACE or CONFIG_TRACEPOINTS/CONFIG_ARCH_SUPPORTS_UPROBES/CONFIG_UPROBES. The latter method also requires specific tracepoints and task_work_add()."
+#error "Process probes not available without kernel CONFIG_TRACEPOINTS/CONFIG_ARCH_SUPPORTS_UPROBES/CONFIG_UPROBES. The latter method also requires specific tracepoints and task_work_add()."
 #else  /* HAVE_TASK_FINDER */
-#if !defined(CONFIG_UTRACE)
 #include "task_finder2.c"
-#else  /* CONFIG_UTRACE */
-#include <linux/utrace.h>
-#include <linux/list.h>
-#include <linux/binfmts.h>
-#include <linux/mount.h>
-#ifndef STAPCONF_TASK_UID
-#include <linux/cred.h>
-#endif
-#include "../uidgid_compatibility.h"
-#include "syscall.h"
-#include "utrace_compatibility.h"
-#include "task_finder_map.c"
-#include "task_finder_vma.c"
-
-static LIST_HEAD(__stp_task_finder_list);
-
-struct stap_task_finder_target;
-
-#define __STP_TF_UNITIALIZED   0
-#define __STP_TF_STARTING      1
-#define __STP_TF_RUNNING       2
-#define __STP_TF_STOPPING      3
-#define __STP_TF_STOPPED       4
-static atomic_t __stp_task_finder_state = ATOMIC_INIT(__STP_TF_UNITIALIZED);
-static atomic_t __stp_inuse_count = ATOMIC_INIT (0);
-
-#define __stp_tf_handler_start() (atomic_inc(&__stp_inuse_count))
-#define __stp_tf_handler_end() (atomic_dec(&__stp_inuse_count))
-
-#ifdef DEBUG_TASK_FINDER
-static 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, inuse count: %d\n", \
-                                             atomic_read(&__stp_attach_count), \
-                                             atomic_read(&__stp_inuse_count)))
-#else
-#define debug_task_finder_attach()     /* empty */
-#define debug_task_finder_detach()     /* empty */
-#define debug_task_finder_report()     /* empty */
-#endif /* !DEBUG_TASK_FINDER */
-
-typedef int (*stap_task_finder_callback)(struct stap_task_finder_target *tgt,
-                                        struct task_struct *tsk,
-                                        int register_p,
-                                        int process_p);
-
-typedef int
-(*stap_task_finder_mmap_callback)(struct stap_task_finder_target *tgt,
-                                 struct task_struct *tsk,
-                                 char *path,
-                                 struct dentry *dentry,
-                                 unsigned long addr,
-                                 unsigned long length,
-                                 unsigned long offset,
-                                 unsigned long vm_flags);
-typedef int
-(*stap_task_finder_munmap_callback)(struct stap_task_finder_target *tgt,
-                                   struct task_struct *tsk,
-                                   unsigned long addr,
-                                   unsigned long length);
-
-typedef int
-(*stap_task_finder_mprotect_callback)(struct stap_task_finder_target *tgt,
-                                     struct task_struct *tsk,
-                                     unsigned long addr,
-                                     unsigned long length,
-                                     int prot);
-
-struct stap_task_finder_target {
-/* private: */
-       struct list_head list;          /* __stp_task_finder_list linkage */
-       struct list_head callback_list_head;
-       struct list_head callback_list;
-       struct utrace_engine_ops ops;
-       size_t pathlen;
-       unsigned engine_attached:1;
-       unsigned mmap_events:1;
-       unsigned munmap_events:1;
-       unsigned mprotect_events:1;
-
-/* public: */
-       pid_t pid;
-        int build_id_len;
-        uint64_t build_id_vaddr;
-        const char *build_id;
-       const char *procname;
-        const char *purpose;
-       stap_task_finder_callback callback;
-       stap_task_finder_mmap_callback mmap_callback;
-       stap_task_finder_munmap_callback munmap_callback;
-       stap_task_finder_mprotect_callback mprotect_callback;
-};
-
-#ifdef UTRACE_ORIG_VERSION
-static u32
-__stp_utrace_task_finder_target_exec(struct utrace_engine *engine,
-                                    struct task_struct *tsk,
-                                    const struct linux_binprm *bprm,
-                                    struct pt_regs *regs);
-#else
-#if defined(UTRACE_API_VERSION) && (UTRACE_API_VERSION >= 20091216)
-static u32
-__stp_utrace_task_finder_target_exec(u32 action,
-                                    struct utrace_engine *engine,
-                                    const struct linux_binfmt *fmt,
-                                    const struct linux_binprm *bprm,
-                                    struct pt_regs *regs);
-#else
-static u32
-__stp_utrace_task_finder_target_exec(enum utrace_resume_action action,
-                                    struct utrace_engine *engine,
-                                    struct task_struct *tsk,
-                                    const struct linux_binfmt *fmt,
-                                    const struct linux_binprm *bprm,
-                                    struct pt_regs *regs);
-#endif
-#endif
-
-#if defined(UTRACE_API_VERSION) && (UTRACE_API_VERSION >= 20091216)
-static u32
-__stp_utrace_task_finder_target_exit(u32 action, struct utrace_engine *engine,
-                                    long orig_code, long *code);
-#else
-static u32
-__stp_utrace_task_finder_target_exit(struct utrace_engine *engine,
-                                    struct task_struct *tsk,
-                                    long orig_code, long *code);
-#endif
-
-#ifdef UTRACE_ORIG_VERSION
-static u32
-__stp_utrace_task_finder_target_quiesce(struct utrace_engine *engine,
-                                       struct task_struct *tsk);
-#else
-#if defined(UTRACE_API_VERSION) && (UTRACE_API_VERSION >= 20091216)
-static u32
-__stp_utrace_task_finder_target_quiesce(u32 action,
-                                       struct utrace_engine *engine,
-                                       unsigned long event);
-#else
-static u32
-__stp_utrace_task_finder_target_quiesce(enum utrace_resume_action action,
-                                       struct utrace_engine *engine,
-                                       struct task_struct *tsk,
-                                       unsigned long event);
-#endif
-#endif
-
-#ifdef UTRACE_ORIG_VERSION
-static u32
-__stp_utrace_task_finder_target_syscall_entry(struct utrace_engine *engine,
-                                             struct task_struct *tsk,
-                                             struct pt_regs *regs);
-#else
-#if defined(UTRACE_API_VERSION) && (UTRACE_API_VERSION >= 20091216)
-static u32
-__stp_utrace_task_finder_target_syscall_entry(u32 action,
-                                             struct utrace_engine *engine,
-                                             struct pt_regs *regs);
-#else
-static u32
-__stp_utrace_task_finder_target_syscall_entry(enum utrace_resume_action action,
-                                             struct utrace_engine *engine,
-                                             struct task_struct *tsk,
-                                             struct pt_regs *regs);
-#endif
-#endif
-
-#ifdef UTRACE_ORIG_VERSION
-static u32
-__stp_utrace_task_finder_target_syscall_exit(struct utrace_engine *engine,
-                                            struct task_struct *tsk,
-                                            struct pt_regs *regs);
-#else
-#if defined(UTRACE_API_VERSION) && (UTRACE_API_VERSION >= 20091216)
-static u32
-__stp_utrace_task_finder_target_syscall_exit(u32 action,
-                                            struct utrace_engine *engine,
-                                            struct pt_regs *regs);
-#else
-static u32
-__stp_utrace_task_finder_target_syscall_exit(enum utrace_resume_action action,
-                                            struct utrace_engine *engine,
-                                            struct task_struct *tsk,
-                                            struct pt_regs *regs);
-#endif
-#endif
-
-static int
-stap_register_task_finder_target(struct stap_task_finder_target *new_tgt)
-{
-       // Since this __stp_task_finder_list is (currently) only
-       // written to in one big setup operation before the task
-       // finder process is started, we don't need to lock it.
-       struct list_head *node;
-       struct stap_task_finder_target *tgt = NULL;
-       int found_node = 0;
-
-       if (atomic_read(&__stp_task_finder_state) != __STP_TF_UNITIALIZED) {
-               _stp_error("task_finder already started, no new targets allowed");
-               return EBUSY;
-       }
-
-       if (new_tgt == NULL)
-               return EFAULT;
-
-       if (new_tgt->procname != NULL)
-               new_tgt->pathlen = strlen(new_tgt->procname);
-       else
-               new_tgt->pathlen = 0;
-
-       // Make sure everything is initialized properly.
-       new_tgt->engine_attached = 0;
-       new_tgt->mmap_events = 0;
-       new_tgt->munmap_events = 0;
-       new_tgt->mprotect_events = 0;
-       memset(&new_tgt->ops, 0, sizeof(new_tgt->ops));
-       new_tgt->ops.report_exec = &__stp_utrace_task_finder_target_exec;
-       new_tgt->ops.report_exit = &__stp_utrace_task_finder_target_exit;
-       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 procname/pid.
-       list_for_each(node, &__stp_task_finder_list) {
-               tgt = list_entry(node, struct stap_task_finder_target, list);
-               if (tgt == new_tgt) {
-                       _stp_error("target already registered");
-                       return EINVAL;
-               }
-               if (tgt != NULL
-                   /* procname-based target */
-                   && ((new_tgt->pathlen > 0
-                        && tgt->pathlen == new_tgt->pathlen
-                        && strcmp(tgt->procname, new_tgt->procname) == 0)
-                       /* pid-based target (a specific pid or all
-                        * pids) */
-                       || (new_tgt->pathlen == 0 && tgt->pathlen == 0
-                           && tgt->pid == new_tgt->pid))) {
-                       found_node = 1;
-                       break;
-               }
-       }
-
-       // If we didn't find a matching existing entry, add the new
-       // target to the task list.
-       if (! found_node) {
-               INIT_LIST_HEAD(&new_tgt->callback_list_head);
-               list_add(&new_tgt->list, &__stp_task_finder_list);
-               tgt = new_tgt;
-       }
-
-       // Add this target to the callback list for this task.
-       list_add_tail(&new_tgt->callback_list, &tgt->callback_list_head);
-
-       // If the new target has any m* callbacks, remember this.
-       if (new_tgt->mmap_callback != NULL)
-               tgt->mmap_events = 1;
-       if (new_tgt->munmap_callback != NULL)
-               tgt->munmap_events = 1;
-       if (new_tgt->mprotect_callback != NULL)
-               tgt->mprotect_events = 1;
-       return 0;
-}
-
-static int
-__stap_utrace_detach(struct task_struct *tsk,
-                    const struct utrace_engine_ops *ops,
-                    int *ops_matched)
-{
-       struct utrace_engine *engine;
-       struct mm_struct *mm;
-       int rc = 0;
-
-       if (ops_matched)
-               *ops_matched = 0;
-
-       // Ignore invalid tasks.
-       if (tsk == NULL || tsk->pid <= 0)
-               return 0;
-
-#ifdef PF_KTHREAD
-       // Ignore kernel threads.  On systems without PF_KTHREAD,
-       // we're ok, since kernel threads won't be matched by the
-       // utrace_attach_task() call below.
-       if (tsk->flags & PF_KTHREAD)
-               return 0;
-#endif
-
-       // Notice we're not calling get_task_mm() here.  Normally we
-       // avoid tasks with no mm, because those are kernel threads.
-       // So, why is this function different?  When a thread is in
-       // the process of dying, its mm gets freed.  Then, later the
-       // thread gets in the dying state and the thread's DEATH event
-       // handler gets called (if any).
-       //
-       // If a thread is in this "mortally wounded" state - no mm
-       // but not dead - and at that moment this function is called,
-       // we'd miss detaching from it if we were checking to see if
-       // it had an mm.
-
-       engine = utrace_attach_task(tsk, UTRACE_ATTACH_MATCH_OPS, ops, 0);
-       if (IS_ERR(engine)) {
-               rc = -PTR_ERR(engine);
-               if (rc != ENOENT) {
-                       _stp_error("utrace_attach_task returned error %d on pid %d",
-                                  rc, tsk->pid);
-               }
-               else {
-                       rc = 0;
-               }
-       }
-       else if (unlikely(engine == NULL)) {
-               _stp_error("utrace_attach returned NULL on pid %d",
-                          (int)tsk->pid);
-               rc = EFAULT;
-       }
-       else {
-               if (ops_matched)
-                       *ops_matched = 1;
-               rc = utrace_control(tsk, engine, UTRACE_DETACH);
-               switch (rc) {
-               case 0:                 /* success */
-                       debug_task_finder_detach();
-                       break;
-               case -ESRCH:        /* REAP callback already begun */
-               case -EALREADY:     /* DEATH callback already begun */
-                       rc = 0;     /* ignore these errors */
-                       break;
-               case -EINPROGRESS:
-                       do {
-                               rc = utrace_barrier(tsk, engine);
-                       } while (rc == -ERESTARTSYS);
-                       if (rc == 0 || rc == -ESRCH || rc == -EALREADY) {
-                               rc = 0;
-                               debug_task_finder_detach();
-                       } else {
-                               rc = -rc;
-                               _stp_error("utrace_barrier returned error %d on pid %d", rc, tsk->pid);
-                       }
-                       break;
-               default:
-                       rc = -rc;
-                       _stp_error("utrace_control returned error %d on pid %d",
-                                  rc, tsk->pid);
-                       break;
-               }
-               utrace_engine_put(engine);
-       }
-       return rc;
-}
-
-static int
-stap_utrace_detach(struct task_struct *tsk,
-                  const struct utrace_engine_ops *ops)
-{
-       return __stap_utrace_detach(tsk, ops, NULL);
-}
-
-static void
-stap_utrace_detach_ops(struct utrace_engine_ops *ops)
-{
-       struct task_struct *grp, *tsk;
-       struct utrace_engine *engine;
-       pid_t pid = 0;
-       int rc = 0;
-       int ops_matched;
-       int iterations = 0;
-
-       // We're going to do the detach in a loop. Why?
-       // do_each_thread() presents a snapshot of the list of
-       // processes on the system. If the system is currently
-       // creating lots of processes, we'll miss some during this
-       // loop (especially since utrace_barrier() can wait for a
-       // handler to finish).
-       //
-       // So, we'll repeat the loop until we longer find any
-       // processes that have this ops attached to it.
-       do {
-               // Notice we're not calling get_task_mm() in this
-               // loop. In every other instance when calling
-               // do_each_thread, we avoid tasks with no mm, because
-               // those are kernel threads.  So, why is this function
-               // different?  When a thread is in the process of
-               // dying, its mm gets freed.  Then, later the thread
-               // gets in the dying state and the thread's
-               // UTRACE_EVENT(DEATH) event handler gets called (if
-               // any).
-               //
-               // If a thread is in this "mortally wounded" state -
-               // no mm but not dead - and at that moment this
-               // function is called, we'd miss detaching from it if
-               // we were checking to see if it had an mm.
-
-               ops_matched = 0;
-               rcu_read_lock();
-               do_each_thread(grp, tsk) {
-                       int matched = 0;
-#ifdef PF_KTHREAD
-                       // Ignore kernel threads.  On systems without
-                       // PF_KTHREAD, we're ok, since kernel threads
-                       // won't be matched by the
-                       // __stap_utrace_detach() call.
-                       if (tsk->flags & PF_KTHREAD)
-                               continue;
-#endif
-
-                       /* Notice we're purposefully ignoring errors
-                        * from __stap_utrace_detach().  Even if we
-                        * got an error on this task, we need to keep
-                        * detaching from other tasks.  But warn, we
-                        * might be unloading and dangling engines are
-                        * bad news. */
-                       rc = __stap_utrace_detach(tsk, ops, &matched);
-                       if (rc != 0)
-                               _stp_error("stap_utrace_detach returned error %d on pid %d", rc, tsk->pid);
-                       WARN_ON(rc != 0);
-                       ops_matched |= matched;
-               } while_each_thread(grp, tsk);
-               rcu_read_unlock();
-               debug_task_finder_report();
-               iterations++;
-       } while (ops_matched && iterations < 10);
-#ifdef DEBUG_TASK_FINDER
-       _stp_dbug(__FUNCTION__, __LINE__, "took %d attempts\n", iterations);
-#endif
-}
-
-static void
-__stp_task_finder_cleanup(void)
-{
-       struct list_head *tgt_node, *tgt_next;
-       struct stap_task_finder_target *tgt;
-
-       // Walk the main list, cleaning up as we go.
-       list_for_each_safe(tgt_node, tgt_next, &__stp_task_finder_list) {
-               tgt = list_entry(tgt_node, struct stap_task_finder_target,
-                                list);
-               if (tgt == NULL)
-                       continue;
-
-               if (tgt->engine_attached) {
-                       stap_utrace_detach_ops(&tgt->ops);
-                       tgt->engine_attached = 0;
-               }
-
-               // Notice we're not walking the callback_list here.
-               // There isn't anything to clean up and doing it would
-               // mess up callbacks in progress.
-
-               list_del(&tgt->list);
-       }
-}
-
-static char *
-__stp_get_mm_path(struct mm_struct *mm, char *buf, int buflen)
-{
-       struct file *vm_file = stap_find_exe_file(mm);
-       char *rc = NULL;
-
-       if (vm_file) {
-#ifdef STAPCONF_DPATH_PATH
-               rc = d_path(&(vm_file->f_path), buf, buflen);
-#else
-               rc = d_path(vm_file->f_dentry, vm_file->f_vfsmnt,
-                           buf, buflen);
-#endif
-               fput(vm_file);
-       }
-       else {
-               *buf = '\0';
-               rc = ERR_PTR(-ENOENT);
-       }
-       return rc;
-}
-
-/*
- * All user threads get an engine with __STP_TASK_FINDER_EVENTS events
- * attached to it so the task_finder layer can monitor new thread
- * creation/death.
- */
-#define __STP_TASK_FINDER_EVENTS (UTRACE_EVENT(CLONE)          \
-                                 | UTRACE_EVENT(EXEC)          \
-                                 | UTRACE_EVENT(EXIT))
-
-/*
- * __STP_TASK_BASE_EVENTS: base events for stap_task_finder_target's
- * without map callback's
- *
- * __STP_TASK_VM_BASE_EVENTS: base events for
- * stap_task_finder_target's with map callback's
- */
-#define __STP_TASK_BASE_EVENTS (UTRACE_EVENT(EXIT)|UTRACE_EVENT(EXEC))
-
-#define __STP_TASK_VM_BASE_EVENTS (__STP_TASK_BASE_EVENTS      \
-                                  | UTRACE_EVENT(SYSCALL_ENTRY)\
-                                  | UTRACE_EVENT(SYSCALL_EXIT))
-
-/*
- * All "interesting" threads get an engine with
- * __STP_ATTACHED_TASK_EVENTS events attached to it.  After the thread
- * quiesces, we reset the events to __STP_ATTACHED_TASK_BASE_EVENTS
- * events.
- */
-#define __STP_ATTACHED_TASK_EVENTS (UTRACE_EVENT(EXIT)         \
-                                   | UTRACE_EVENT(QUIESCE))
-
-#define __STP_ATTACHED_TASK_BASE_EVENTS(tgt)                   \
-       (((tgt)->mmap_events || (tgt)->munmap_events            \
-         || (tgt)->mprotect_events)                            \
-        ? __STP_TASK_VM_BASE_EVENTS : __STP_TASK_BASE_EVENTS)
-
-/* Helper function for __stp_utrace_attach or __stp_utrace_attach_atomic.  */
-static int
-__stp_utrace_attach_flags(struct task_struct *tsk,
-                         const struct utrace_engine_ops *ops, void *data,
-                         unsigned long event_flags,
-                         int attach_flags,
-                         enum utrace_resume_action action)
-{
-       struct utrace_engine *engine;
-       int rc = 0;
-
-       // Ignore invalid tasks.
-       if (tsk == NULL || tsk->pid <= 0)
-               return EPERM;
-
-#ifdef PF_KTHREAD
-       // Ignore kernel threads
-       if (tsk->flags & PF_KTHREAD)
-               return EPERM;
-#endif
-
-       // Ignore threads with no mm (which are either kernel threads
-       // or "mortally wounded" threads).
-       //
-       // Note we're not calling get_task_mm()/mmput() here.  Since
-       // we're in the the context of that task, the mm should stick
-       // around without locking it (and mmput() can sleep).
-       if (! tsk->mm)
-               return EPERM;
-
-       engine = utrace_attach_task(tsk, UTRACE_ATTACH_CREATE | attach_flags,
-                                   ops, data);
-       if (IS_ERR(engine)) {
-               int error = -PTR_ERR(engine);
-               if (error != ESRCH && error != ENOENT) {
-                       _stp_error("utrace_attach returned error %d on pid %d",
-                                  error, (int)tsk->pid);
-                       rc = error;
-               }
-       }
-       else if (unlikely(engine == NULL)) {
-               _stp_error("utrace_attach returned NULL on pid %d",
-                          (int)tsk->pid);
-               rc = EFAULT;
-       }
-       else {
-               rc = utrace_set_events(tsk, engine, event_flags);
-               if (rc == -EINPROGRESS) {
-                       /*
-                        * It's running our callback, so we have to
-                        * synchronize.  We can't keep rcu_read_lock,
-                        * so the task pointer might die.  But it's
-                        * safe to call utrace_barrier() even with a
-                        * stale task pointer, if we have an engine
-                        * ref.
-                        */
-                       do {
-                               rc = utrace_barrier(tsk, engine);
-                       } while (rc == -ERESTARTSYS);
-                       if (rc != 0 && rc != -ESRCH && rc != -EALREADY)
-                               _stp_error("utrace_barrier returned error %d on pid %d",
-                                          rc, (int)tsk->pid);
-               }
-               if (rc == 0) {
-                       debug_task_finder_attach();
-
-                       if (action != UTRACE_RESUME) {
-                               rc = utrace_control(tsk, engine, action);
-                               /* If utrace_control() returns
-                                * EINPROGRESS when we're trying to
-                                * stop/interrupt, that means the task
-                                * hasn't stopped quite yet, but will
-                                * soon.  Ignore this error. */
-                               if (rc != 0 && rc != -EINPROGRESS) {
-                                       _stp_error("utrace_control returned error %d on pid %d",
-                                                  rc, (int)tsk->pid);
-                               }
-                               rc = 0;
-                       }
-               }
-               else if (rc != -ESRCH && rc != -EALREADY)
-                       _stp_error("utrace_set_events2 returned error %d on pid %d",
-                                  rc, (int)tsk->pid);
-               utrace_engine_put(engine);
-       }
-       return rc;
-}
-
-static int
-__stp_utrace_attach(struct task_struct *tsk,
-                   const struct utrace_engine_ops *ops, void *data,
-                   unsigned long event_flags,
-                   enum utrace_resume_action action)
-{
-       return __stp_utrace_attach_flags(tsk, ops, data, event_flags,
-                                        0, action);
-}
-
-static int
-__stp_utrace_attach_atomic(struct task_struct *tsk,
-                          const struct utrace_engine_ops *ops, void *data,
-                          unsigned long event_flags,
-                          enum utrace_resume_action action)
-{
-       return __stp_utrace_attach_flags(tsk, ops, data, event_flags,
-                                        UTRACE_ATTACH_ATOMIC, action);
-}
-
-static int
-stap_utrace_attach(struct task_struct *tsk,
-                  const struct utrace_engine_ops *ops, void *data,
-                  unsigned long event_flags)
-{
-       return __stp_utrace_attach(tsk, ops, data, event_flags, UTRACE_RESUME);
-}
-
-static inline void
-__stp_call_callbacks(struct stap_task_finder_target *tgt,
-                    struct task_struct *tsk, int register_p, int process_p)
-{
-       struct list_head *cb_node;
-       int rc;
-
-       if (tgt == NULL || tsk == NULL)
-               return;
-
-       list_for_each(cb_node, &tgt->callback_list_head) {
-               struct stap_task_finder_target *cb_tgt;
-
-               cb_tgt = list_entry(cb_node, struct stap_task_finder_target,
-                                   callback_list);
-               if (cb_tgt == NULL || cb_tgt->callback == NULL)
-                       continue;
-
-               rc = cb_tgt->callback(cb_tgt, tsk, register_p, process_p);
-               if (rc != 0) {
-                       _stp_warn("task_finder %s%scallback for task %d failed: %d",
-                                  (cb_tgt->purpose?:""), (cb_tgt->purpose?" ":""),
-                                  (int)tsk->pid, rc);
-               }
-       }
-}
-
-static void
-__stp_call_mmap_callbacks(struct stap_task_finder_target *tgt,
-                         struct task_struct *tsk, char *path,
-                         struct dentry *dentry,
-                         unsigned long addr, unsigned long length,
-                         unsigned long offset, unsigned long vm_flags)
-{
-       struct list_head *cb_node;
-       int rc;
-
-       if (tgt == NULL || tsk == NULL)
-               return;
-
-       dbug_task_vma(1,
-                 "pid %d, a/l/o/p/path 0x%lx  0x%lx  0x%lx  %c%c%c%c  %s\n",
-                 tsk->pid, addr, length, offset,
-                 vm_flags & VM_READ ? 'r' : '-',
-                 vm_flags & VM_WRITE ? 'w' : '-',
-                 vm_flags & VM_EXEC ? 'x' : '-',
-                 vm_flags & VM_MAYSHARE ? 's' : 'p',
-                 path);
-       list_for_each(cb_node, &tgt->callback_list_head) {
-               struct stap_task_finder_target *cb_tgt;
-
-               cb_tgt = list_entry(cb_node, struct stap_task_finder_target,
-                                   callback_list);
-               if (cb_tgt == NULL || cb_tgt->mmap_callback == NULL)
-                       continue;
-
-               rc = cb_tgt->mmap_callback(cb_tgt, tsk, path, dentry,
-                                         addr, length, offset, vm_flags);
-               if (rc != 0) {
-                       _stp_warn("task_finder mmap %s%scallback for task %d failed: %d",
-                                  (cb_tgt->purpose?:""), (cb_tgt->purpose?" ":""),
-                                  (int)tsk->pid, rc);
-               }
-       }
-}
-
-
-static 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 void
-__stp_call_mmap_callbacks_with_addr(struct stap_task_finder_target *tgt,
-                                   struct task_struct *tsk,
-                                   unsigned long addr)
-{
-       struct mm_struct *mm;
-       struct vm_area_struct *vma;
-       char *mmpath_buf = NULL;
-       char *mmpath = NULL;
-       struct dentry *dentry = NULL;
-       unsigned long length = 0;
-       unsigned long offset = 0;
-       unsigned long vm_flags = 0;
-
-       // __stp_call_mmap_callbacks_with_addr() is only called when
-       // tsk is current, so there isn't any danger of mm going
-       // away.  So, we don't need to call get_task_mm()/mmput()
-       // (which avoids the possibility of sleeping).
-       mm = tsk->mm;
-       if (! mm)
-               return;
-
-       // The down_read() function can sleep, so we'll call
-       // down_read_trylock() instead, which can fail.
-       if (! down_read_trylock(&mm->mmap_sem))
-               return;
-       vma = __stp_find_file_based_vma(mm, addr);
-       if (vma) {
-               // Cache information we need from the vma
-               addr = vma->vm_start;
-               length = vma->vm_end - vma->vm_start;
-               offset = (vma->vm_pgoff << PAGE_SHIFT);
-               vm_flags = vma->vm_flags;
-#ifdef STAPCONF_DPATH_PATH
-               dentry = vma->vm_file->f_path.dentry;
-#else
-               dentry = vma->vm_file->f_dentry;
-#endif
-
-               // Allocate space for a path
-               mmpath_buf = _stp_kmalloc(PATH_MAX);
-               if (mmpath_buf == NULL) {
-                       up_read(&mm->mmap_sem);
-                       _stp_error("Unable to allocate space for path");
-                       return;
-               }
-               else {
-                       // Grab the path associated with this vma.
-#ifdef STAPCONF_DPATH_PATH
-                       mmpath = d_path(&(vma->vm_file->f_path), mmpath_buf,
-                                       PATH_MAX);
-#else
-                       mmpath = d_path(vma->vm_file->f_dentry,
-                                       vma->vm_file->f_vfsmnt, mmpath_buf,
-                                       PATH_MAX);
-#endif
-                       if (mmpath == NULL || IS_ERR(mmpath)) {
-                               long err = ((mmpath == NULL) ? 0
-                                           : -PTR_ERR(mmpath));
-                               _stp_error("Unable to get path (error %ld) for pid %d",
-                                          err, (int)tsk->pid);
-                               mmpath = NULL;
-                       }
-               }
-       }
-
-       // At this point, we're done with the vma (assuming we found
-       // one).  We can't hold the 'mmap_sem' semaphore while making
-       // callbacks.
-       up_read(&mm->mmap_sem);
-               
-       if (mmpath)
-               __stp_call_mmap_callbacks(tgt, tsk, mmpath, dentry, addr,
-                                         length, offset, vm_flags);
-
-       // Cleanup.
-       if (mmpath_buf)
-               _stp_kfree(mmpath_buf);
-       return;
-}
-
-
-static inline void
-__stp_call_munmap_callbacks(struct stap_task_finder_target *tgt,
-                           struct task_struct *tsk, unsigned long addr,
-                           unsigned long length)
-{
-       struct list_head *cb_node;
-       int rc;
-
-       if (tgt == NULL || tsk == NULL)
-               return;
-
-       list_for_each(cb_node, &tgt->callback_list_head) {
-               struct stap_task_finder_target *cb_tgt;
-
-               cb_tgt = list_entry(cb_node, struct stap_task_finder_target,
-                                   callback_list);
-               if (cb_tgt == NULL || cb_tgt->munmap_callback == NULL)
-                       continue;
-
-               rc = cb_tgt->munmap_callback(cb_tgt, tsk, addr, length);
-               if (rc != 0) {
-                       _stp_warn("task_finder munmap %s%scallback for task %d failed: %d",
-                                  (cb_tgt->purpose?:""), (cb_tgt->purpose?" ":""),
-                                  (int)tsk->pid, rc);
-               }
-       }
-}
-
-static inline void
-__stp_call_mprotect_callbacks(struct stap_task_finder_target *tgt,
-                             struct task_struct *tsk, unsigned long addr,
-                             unsigned long length, int prot)
-{
-       struct list_head *cb_node;
-       int rc;
-
-       if (tgt == NULL || tsk == NULL)
-               return;
-
-       list_for_each(cb_node, &tgt->callback_list_head) {
-               struct stap_task_finder_target *cb_tgt;
-
-               cb_tgt = list_entry(cb_node, struct stap_task_finder_target,
-                                   callback_list);
-               if (cb_tgt == NULL || cb_tgt->mprotect_callback == NULL)
-                       continue;
-
-               rc = cb_tgt->mprotect_callback(cb_tgt, tsk, addr, length,
-                                              prot);
-               if (rc != 0) {
-                       _stp_warn("task_finder mprotect %s%scallback for task %d failed: %d",
-                                  (cb_tgt->purpose?:""), (cb_tgt->purpose?" ":""),
-                                  (int)tsk->pid, rc);
-               }
-       }
-}
-
-static inline void
-__stp_utrace_attach_match_filename(struct task_struct *tsk,
-                                  const char * const filename,
-                                  int process_p)
-{
-       size_t filelen;
-       struct list_head *tgt_node;
-       struct stap_task_finder_target *tgt;
-       uid_t tsk_euid;
-
-#ifdef STAPCONF_TASK_UID
-       tsk_euid = tsk->euid;
-#else
-#if defined(CONFIG_USER_NS) || (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
-       tsk_euid = from_kuid_munged(current_user_ns(), task_euid(tsk));
-#else
-       tsk_euid = task_euid(tsk);
-#endif
-#endif
-       filelen = strlen(filename);
-       list_for_each(tgt_node, &__stp_task_finder_list) {
-               int rc;
-
-               tgt = list_entry(tgt_node, struct stap_task_finder_target,
-                                list);
-               // If we've got a matching procname or we're probing
-               // all threads, we've got a match.  We've got to keep
-               // matching since a single thread could match a
-               // procname and match an "all thread" probe.
-               if (tgt == NULL)
-                       continue;
-               else if (tgt->pathlen > 0
-                        && (tgt->pathlen != filelen
-                            || strcmp(tgt->procname, filename) != 0))
-                       continue;
-               /* Ignore pid-based target, they were handled at startup. */
-               else if (tgt->pid != 0)
-                       continue;
-               /* Notice that "pid == 0" (which means to probe all
-                * threads) falls through. */
-
-#if ! STP_PRIVILEGE_CONTAINS (STP_PRIVILEGE, STP_PR_STAPDEV) && \
-    ! STP_PRIVILEGE_CONTAINS (STP_PRIVILEGE, STP_PR_STAPSYS)
-               /* Make sure unprivileged users only probe their own threads. */
-               if (_stp_uid != tsk_euid) {
-                       if (tgt->pid != 0) {
-                               _stp_warn("Process %d does not belong to unprivileged user %d",
-                                         tsk->pid, _stp_uid);
-                       }
-                       continue;
-               }
-#endif
-
-
-               // Set up events we need for attached tasks. We won't
-               // actually call the callbacks here - we'll call them
-               // when the thread gets quiesced.
-               rc = __stp_utrace_attach(tsk, &tgt->ops,
-                                        tgt,
-                                        __STP_ATTACHED_TASK_EVENTS,
-                                        UTRACE_STOP);
-               if (rc != 0 && rc != EPERM)
-                       break;
-               tgt->engine_attached = 1;
-       }
-}
-
-// This function handles the details of getting a task's associated
-// procname, and calling __stp_utrace_attach_match_filename() to
-// attach to it if we find the procname "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 process_p)
-{
-       struct mm_struct *mm;
-       char *mmpath_buf;
-       char *mmpath;
-
-       if (path_tsk == NULL || path_tsk->pid <= 0
-           || match_tsk == NULL || match_tsk->pid <= 0)
-               return;
-
-       // Grab the path associated with the path_tsk.
-       //
-       // Note we're not calling get_task_mm()/mmput() here.  Since
-       // we're in the the context of path_task, the mm should stick
-       // around without locking it (and mmput() can sleep).
-       mm = path_tsk->mm;
-       if (! mm) {
-               /* If the thread doesn't have a mm_struct, it is
-                * a kernel thread which we need to skip. */
-               return;
-       }
-
-       // 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 the new task
-       mmpath = __stp_get_mm_path(mm, mmpath_buf, PATH_MAX);
-       if (mmpath == NULL || IS_ERR(mmpath)) {
-               int rc = -PTR_ERR(mmpath);
-               if (rc != ENOENT)
-                       _stp_error("Unable to get path (error %d) for pid %d",
-                                  rc, (int)path_tsk->pid);
-       }
-       else {
-               __stp_utrace_attach_match_filename(match_tsk, mmpath,
-                                                  process_p);
-       }
-
-       _stp_kfree(mmpath_buf);
-       return;
-}
-
-#ifdef UTRACE_ORIG_VERSION
-static u32
-__stp_utrace_task_finder_report_clone(struct utrace_engine *engine,
-                                     struct task_struct *parent,
-                                     unsigned long clone_flags,
-                                     struct task_struct *child)
-#else
-#if defined(UTRACE_API_VERSION) && (UTRACE_API_VERSION >= 20091216)
-static u32
-__stp_utrace_task_finder_report_clone(u32 action,
-                                     struct utrace_engine *engine,
-                                     unsigned long clone_flags,
-                                     struct task_struct *child)
-#else
-static u32
-__stp_utrace_task_finder_report_clone(enum utrace_resume_action action,
-                                     struct utrace_engine *engine,
-                                     struct task_struct *parent,
-                                     unsigned long clone_flags,
-                                     struct task_struct *child)
-#endif
-#endif
-{
-#if defined(UTRACE_API_VERSION) && (UTRACE_API_VERSION >= 20091216)
-       struct task_struct *parent = current;
-#endif
-       int rc;
-
-       __stp_tf_handler_start();
-       if (atomic_read(&__stp_task_finder_state) != __STP_TF_RUNNING) {
-               debug_task_finder_detach();
-               __stp_tf_handler_end();
-               return UTRACE_DETACH;
-       }
-
-       // On clone, attach to the child.
-       rc = __stp_utrace_attach(child, engine->ops, 0,
-                                __STP_TASK_FINDER_EVENTS, UTRACE_RESUME);
-       if (rc != 0 && rc != EPERM) {
-               __stp_tf_handler_end();
-               return UTRACE_RESUME;
-       }
-
-       __stp_utrace_attach_match_tsk(parent, child,
-                                     (clone_flags & CLONE_THREAD) == 0);
-       __stp_tf_handler_end();
-       return UTRACE_RESUME;
-}
-
-#ifdef UTRACE_ORIG_VERSION
-static u32
-__stp_utrace_task_finder_report_exec(struct utrace_engine *engine,
-                                    struct task_struct *tsk,
-                                    const struct linux_binprm *bprm,
-                                    struct pt_regs *regs)
-#else
-#if defined(UTRACE_API_VERSION) && (UTRACE_API_VERSION >= 20091216)
-static u32
-__stp_utrace_task_finder_report_exec(u32 action,
-                                    struct utrace_engine *engine,
-                                    const struct linux_binfmt *fmt,
-                                    const struct linux_binprm *bprm,
-                                    struct pt_regs *regs)
-#else
-static u32
-__stp_utrace_task_finder_report_exec(enum utrace_resume_action action,
-                                    struct utrace_engine *engine,
-                                    struct task_struct *tsk,
-                                    const struct linux_binfmt *fmt,
-                                    const struct linux_binprm *bprm,
-                                    struct pt_regs *regs)
-#endif
-#endif
-{
-#if defined(UTRACE_API_VERSION) && (UTRACE_API_VERSION >= 20091216)
-       struct task_struct *tsk = current;
-#endif
-       size_t filelen;
-       struct list_head *tgt_node;
-       struct stap_task_finder_target *tgt;
-       int found_node = 0;
-
-       __stp_tf_handler_start();
-       if (atomic_read(&__stp_task_finder_state) != __STP_TF_RUNNING) {
-               debug_task_finder_detach();
-               __stp_tf_handler_end();
-               return UTRACE_DETACH;
-       }
-
-       // If the original task was "interesting",
-       // __stp_utrace_task_finder_target_exec() will handle calling
-       // callbacks. 
-
-       // 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);
-
-       __stp_tf_handler_end();
-       return UTRACE_RESUME;
-}
-
-
-#if defined(UTRACE_API_VERSION) && (UTRACE_API_VERSION >= 20091216)
-static u32
-stap_utrace_task_finder_report_exit(u32 action, struct utrace_engine *engine,
-                                   long orig_code, long *code)
-#else
-static u32
-stap_utrace_task_finder_report_exit(struct utrace_engine *engine,
-                                   struct task_struct *tsk,
-                                   long orig_code, long *code)
-#endif
-{
-       debug_task_finder_detach();
-       return UTRACE_DETACH;
-}
-
-#ifdef UTRACE_ORIG_VERSION
-static u32
-__stp_utrace_task_finder_target_exec(struct utrace_engine *engine,
-                                    struct task_struct *tsk,
-                                    const struct linux_binprm *bprm,
-                                    struct pt_regs *regs)
-#else
-#if defined(UTRACE_API_VERSION) && (UTRACE_API_VERSION >= 20091216)
-static u32
-__stp_utrace_task_finder_target_exec(u32 action,
-                                    struct utrace_engine *engine,
-                                    const struct linux_binfmt *fmt,
-                                    const struct linux_binprm *bprm,
-                                    struct pt_regs *regs)
-#else
-static u32
-__stp_utrace_task_finder_target_exec(enum utrace_resume_action action,
-                                    struct utrace_engine *engine,
-                                    struct task_struct *tsk,
-                                    const struct linux_binfmt *fmt,
-                                    const struct linux_binprm *bprm,
-                                    struct pt_regs *regs)
-#endif
-#endif
-{
-#if defined(UTRACE_API_VERSION) && (UTRACE_API_VERSION >= 20091216)
-       struct task_struct *tsk = current;
-#endif
-       struct stap_task_finder_target *tgt = engine->data;
-       int rc;
-
-       __stp_tf_handler_start();
-       if (atomic_read(&__stp_task_finder_state) != __STP_TF_RUNNING) {
-               debug_task_finder_detach();
-               __stp_tf_handler_end();
-               return UTRACE_DETACH;
-       }
-
-       // We'll hardcode this as a process end.  If a thread
-       // calls exec() (which it isn't supposed to), the kernel
-       // "promotes" it to being a process.  Call the callbacks.
-       if (tgt != NULL && tsk != NULL) {
-               __stp_call_callbacks(tgt, tsk, 0, 1);
-       }
-
-       // Note that we don't want to set engine_attached to 0 here -
-       // only when *all* threads using this engine have been
-       // detached.
-
-       // Let __stp_utrace_task_finder_report_exec() call
-       // __stp_utrace_attach_match_tsk() to figure out if the
-       // exec'ed program is "interesting".
-
-       debug_task_finder_detach();
-       __stp_tf_handler_end();
-       return UTRACE_DETACH;
-}
-
-#if defined(UTRACE_API_VERSION) && (UTRACE_API_VERSION >= 20091216)
-static u32
-__stp_utrace_task_finder_target_exit(u32 action, struct utrace_engine *engine,
-                                    long orig_code, long *code)
-#else
-static u32
-__stp_utrace_task_finder_target_exit(struct utrace_engine *engine,
-                                    struct task_struct *tsk,
-                                    long orig_code, long *code)
-#endif
-{
-#if defined(UTRACE_API_VERSION) && (UTRACE_API_VERSION >= 20091216)
-       struct task_struct *tsk = current;
-#endif
-       struct stap_task_finder_target *tgt = engine->data;
-
-       __stp_tf_handler_start();
-       if (atomic_read(&__stp_task_finder_state) != __STP_TF_RUNNING) {
-               debug_task_finder_detach();
-               __stp_tf_handler_end();
-               return UTRACE_DETACH;
-       }
-
-       // The first implementation of this added a
-       // UTRACE_EVENT(DEATH) handler to
-       // __stp_utrace_task_finder_ops.  However, dead threads don't
-       // have a mm_struct, so we can't find the exe's path.  So, we
-       // don't know which callback(s) to call.
-       //
-       // So, now when an "interesting" thread is found, we add a
-       // separate UTRACE_EVENT(EXIT) handler for each attached
-       // handler.
-       if (tgt != NULL && tsk != NULL) {
-               __stp_call_callbacks(tgt, tsk, 0, (tsk->pid == tsk->tgid));
-       }
-
-       debug_task_finder_detach();
-       __stp_tf_handler_end();
-       return UTRACE_DETACH;
-}
-
-static void
-__stp_call_mmap_callbacks_for_task(struct stap_task_finder_target *tgt,
-                                  struct task_struct *tsk)
-{
-       struct mm_struct *mm;
-       char *mmpath_buf;
-       char *mmpath;
-       struct vm_area_struct *vma;
-       int file_based_vmas = 0;
-       struct vma_cache_t {
-#ifdef STAPCONF_DPATH_PATH
-               struct path f_path;
-#else
-               struct vfsmount *f_vfsmnt;
-#endif
-               struct dentry *dentry;
-               unsigned long addr;
-               unsigned long length;
-               unsigned long offset;
-               unsigned long vm_flags;
-       };
-       struct vma_cache_t *vma_cache = NULL;
-       struct vma_cache_t *vma_cache_p; 
-
-       // Call the mmap_callback for every vma associated with
-       // a file.
-       //
-       // Note we're not calling get_task_mm()/mmput() here.  Since
-       // we're in the the context of that task, the mm should stick
-       // around without locking it (and mmput() can sleep).
-       mm = tsk->mm;
-       if (! mm)
-               return;
-
-       // Allocate space for a path
-       mmpath_buf = _stp_kmalloc(PATH_MAX);
-       if (mmpath_buf == NULL) {
-               _stp_error("Unable to allocate space for path");
-               return;
-       }
-
-       // The down_read() function can sleep, so we'll call
-       // down_read_trylock() instead, which can fail.
-       if (! down_read_trylock(&mm->mmap_sem)) {
-               _stp_kfree(mmpath_buf);
-               return;
-       }
-
-       // First find the number of file-based vmas.
-       vma = mm->mmap;
-       while (vma) {
-               if (vma->vm_file)
-                       file_based_vmas++;
-               vma = vma->vm_next;
-       }
-
-       // Now allocate an array to cache vma information in.
-       if (file_based_vmas > 0)
-               vma_cache = _stp_vzalloc(sizeof(struct vma_cache_t)
-                                        * file_based_vmas);
-       if (vma_cache != NULL) {
-               // Loop through the vmas again, and cache needed information.
-               vma = mm->mmap;
-               vma_cache_p = vma_cache;
-               while (vma) {
-                       if (vma->vm_file) {
-#ifdef STAPCONF_DPATH_PATH
-                           // Notice we're increasing the reference
-                           // count for 'f_path'.  This way it won't
-                           // get deleted from out under us.
-                           vma_cache_p->f_path = vma->vm_file->f_path;
-                           path_get(&vma_cache_p->f_path);
-                           vma_cache_p->dentry = vma->vm_file->f_path.dentry;
-#else
-                           // Notice we're increasing the reference
-                           // count for 'dentry' and 'f_vfsmnt'.
-                           // This way they won't get deleted from
-                           // out under us.
-                           vma_cache_p->dentry = vma->vm_file->f_dentry;
-                           dget(vma_cache_p->dentry);
-                           vma_cache_p->f_vfsmnt = vma->vm_file->f_vfsmnt;
-                           mntget(vma_cache_p->f_vfsmnt);
-                           vma_cache_p->dentry = vma->vm_file->f_dentry;
-#endif
-                           vma_cache_p->addr = vma->vm_start;
-                           vma_cache_p->length = vma->vm_end - vma->vm_start;
-                           vma_cache_p->offset = (vma->vm_pgoff << PAGE_SHIFT);
-                           vma_cache_p->vm_flags = vma->vm_flags;
-                           vma_cache_p++;
-                       }
-                       vma = vma->vm_next;
-               }
-       }
-
-       // At this point, we're done with the vmas (assuming we found
-       // any).  We can't hold the 'mmap_sem' semaphore while making
-       // callbacks.
-       up_read(&mm->mmap_sem);
-
-       if (vma_cache) {
-               int i;
-
-               // Loop over our cached information and make callbacks
-               // based on it.
-               vma_cache_p = vma_cache;
-               for (i = 0; i < file_based_vmas; i++) {
-#ifdef STAPCONF_DPATH_PATH
-                       mmpath = d_path(&vma_cache_p->f_path, mmpath_buf,
-                                       PATH_MAX);
-                       path_put(&vma_cache_p->f_path);
-#else
-                       mmpath = d_path(vma_cache_p->dentry,
-                                       vma_cache_p->f_vfsmnt, mmpath_buf,
-                                       PATH_MAX);
-                       dput(vma_cache_p->dentry);
-                       mntput(vma_cache_p->f_vfsmnt);
-#endif
-                       if (mmpath == NULL || IS_ERR(mmpath)) {
-                               long err = ((mmpath == NULL) ? 0
-                                           : -PTR_ERR(mmpath));
-                               _stp_error("Unable to get path (error %ld) for pid %d",
-                                          err, (int)tsk->pid);
-                       }
-                       else {
-                               __stp_call_mmap_callbacks(tgt, tsk, mmpath,
-                                                         vma_cache_p->dentry,
-                                                         vma_cache_p->addr,
-                                                         vma_cache_p->length,
-                                                         vma_cache_p->offset,
-                                                         vma_cache_p->vm_flags);
-                       }
-                       vma_cache_p++;
-               }
-               _stp_vfree(vma_cache);
-       }
-
-       _stp_kfree(mmpath_buf);
-}
-
-#ifdef UTRACE_ORIG_VERSION
-static u32
-__stp_utrace_task_finder_target_quiesce(struct utrace_engine *engine,
-                                       struct task_struct *tsk)
-#else
-#if defined(UTRACE_API_VERSION) && (UTRACE_API_VERSION >= 20091216)
-static u32
-__stp_utrace_task_finder_target_quiesce(u32 action,
-                                       struct utrace_engine *engine,
-                                       unsigned long event)
-#else
-static u32
-__stp_utrace_task_finder_target_quiesce(enum utrace_resume_action action,
-                                       struct utrace_engine *engine,
-                                       struct task_struct *tsk,
-                                       unsigned long event)
-#endif
-#endif
-{
-#if defined(UTRACE_API_VERSION) && (UTRACE_API_VERSION >= 20091216)
-       struct task_struct *tsk = current;
-#endif
-       struct stap_task_finder_target *tgt = engine->data;
-       int rc;
-
-       __stp_tf_handler_start();
-       if (atomic_read(&__stp_task_finder_state) != __STP_TF_RUNNING) {
-               debug_task_finder_detach();
-               __stp_tf_handler_end();
-               return UTRACE_DETACH;
-       }
-
-       if (tgt == NULL || tsk == NULL) {
-               debug_task_finder_detach();
-               __stp_tf_handler_end();
-               return UTRACE_DETACH;
-       }
-
-       // Turn off quiesce handling
-       rc = utrace_set_events(tsk, engine,
-                              __STP_ATTACHED_TASK_BASE_EVENTS(tgt));
-
-       if (rc == -EINPROGRESS) {
-               /*
-                * It's running our callback, so we have to
-                * synchronize.  We can't keep rcu_read_lock,
-                * so the task pointer might die.  But it's
-                * safe to call utrace_barrier() even with
-                * a stale task pointer, if we have an engine ref.
-                */
-               do {
-                       rc = utrace_barrier(tsk, engine);
-               } while (rc == -ERESTARTSYS);
-               if (rc == 0)
-                       rc = utrace_set_events(tsk, engine,
-                                              __STP_ATTACHED_TASK_BASE_EVENTS(tgt));
-               else if (rc != -ESRCH && rc != -EALREADY)
-                       _stp_error("utrace_barrier returned error %d on pid %d",
-                                  rc, (int)tsk->pid);
-       }
-       if (rc != 0)
-               _stp_error("utrace_set_events returned error %d on pid %d",
-                          rc, (int)tsk->pid);
-
-       /* NB make sure we run mmap callbacks before other callbacks
-        * like 'probe process.begin' handlers so that the vma tracker
-        * is already initialized in the latter contexts */
-
-       /* If this is just a thread other than the thread group leader,
-           don't bother inform map callback clients about its memory map,
-           since they will simply duplicate each other. */
-       if (tgt->mmap_events == 1 && tsk->tgid == tsk->pid) {
-               __stp_call_mmap_callbacks_for_task(tgt, tsk);
-       }
-
-       /* Call the callbacks.  Assume that if the thread is a
-        * thread group leader, it is a process. */
-       __stp_call_callbacks(tgt, tsk, 1, (tsk->pid == tsk->tgid));
-
-       __stp_tf_handler_end();
-       return UTRACE_RESUME;
-}
-
-
-#ifdef UTRACE_ORIG_VERSION
-static u32
-__stp_utrace_task_finder_target_syscall_entry(struct utrace_engine *engine,
-                                             struct task_struct *tsk,
-                                             struct pt_regs *regs)
-#else
-#if defined(UTRACE_API_VERSION) && (UTRACE_API_VERSION >= 20091216)
-static u32
-__stp_utrace_task_finder_target_syscall_entry(u32 action,
-                                             struct utrace_engine *engine,
-                                             struct pt_regs *regs)
-#else
-static u32
-__stp_utrace_task_finder_target_syscall_entry(enum utrace_resume_action action,
-                                             struct utrace_engine *engine,
-                                             struct task_struct *tsk,
-                                             struct pt_regs *regs)
-#endif
-#endif
-{
-#if defined(UTRACE_API_VERSION) && (UTRACE_API_VERSION >= 20091216)
-       struct task_struct *tsk = current;
-#endif
-       struct stap_task_finder_target *tgt = engine->data;
-       long syscall_no;
-       unsigned long args[3] = { 0L };
-       int rc;
-       int is_mmap_or_mmap2 = 0;
-       int is_mprotect = 0;
-       int is_munmap = 0;
-
-       __stp_tf_handler_start();
-       if (atomic_read(&__stp_task_finder_state) != __STP_TF_RUNNING) {
-               debug_task_finder_detach();
-               __stp_tf_handler_end();
-               return UTRACE_DETACH;
-       }
-
-       if (tgt == NULL) {
-               __stp_tf_handler_end();
-               return UTRACE_RESUME;
-       }
-
-       // See if syscall is one we're interested in.  On x86_64, this
-       // is a potentially expensive operation (since we have to
-       // check and see if it is a 32-bit task).  So, cache the
-       // results.
-       //
-       // FIXME: do we need to handle mremap()?
-       syscall_no = _stp_syscall_get_nr(tsk, regs);
-       is_mmap_or_mmap2 = (syscall_no == MMAP_SYSCALL_NO(tsk)
-                           || syscall_no == MMAP2_SYSCALL_NO(tsk) ? 1 : 0);
-       if (!is_mmap_or_mmap2) {
-               is_mprotect = (syscall_no == MPROTECT_SYSCALL_NO(tsk) ? 1 : 0);
-               if (!is_mprotect) {
-                       is_munmap = (syscall_no == MUNMAP_SYSCALL_NO(tsk)
-                                    ? 1 : 0);
-               }
-       }
-       if (!is_mmap_or_mmap2 && !is_mprotect && !is_munmap) {
-               __stp_tf_handler_end();
-               return UTRACE_RESUME;
-       }
-
-       // The syscall is one we're interested in, but do we have a
-       // handler for it?
-       if ((is_mmap_or_mmap2 && tgt->mmap_events == 0)
-           || (is_mprotect && tgt->mprotect_events == 0)
-           || (is_munmap && tgt->munmap_events == 0)) {
-               __stp_tf_handler_end();
-               return UTRACE_RESUME;
-       }
-
-       // Save the needed arguments.  Note that for mmap, we really
-       // just need the return value, so there is no need to save
-       // any arguments.
-       if (is_munmap) {
-               // We need 2 arguments for munmap()
-               _stp_syscall_get_arguments(tsk, regs, 0, 2, args);
-       }
-       else if (is_mprotect) {
-               // We need 3 arguments for mprotect()
-               _stp_syscall_get_arguments(tsk, regs, 0, 3, args);
-       }
-
-       // Remember the syscall information
-       rc = __stp_tf_add_map(tsk, syscall_no, args[0], args[1], args[2]);
-       if (rc != 0)
-               _stp_error("__stp_tf_add_map returned error %d on pid %d",
-                          rc, tsk->pid);
-       __stp_tf_handler_end();
-       return UTRACE_RESUME;
-}
-
-#ifdef UTRACE_ORIG_VERSION
-static u32
-__stp_utrace_task_finder_target_syscall_exit(struct utrace_engine *engine,
-                                            struct task_struct *tsk,
-                                            struct pt_regs *regs)
-#else
-#if defined(UTRACE_API_VERSION) && (UTRACE_API_VERSION >= 20091216)
-static u32
-__stp_utrace_task_finder_target_syscall_exit(u32 action,
-                                            struct utrace_engine *engine,
-                                            struct pt_regs *regs)
-#else
-static u32
-__stp_utrace_task_finder_target_syscall_exit(enum utrace_resume_action action,
-                                            struct utrace_engine *engine,
-                                            struct task_struct *tsk,
-                                            struct pt_regs *regs)
-#endif
-#endif
-{
-#if defined(UTRACE_API_VERSION) && (UTRACE_API_VERSION >= 20091216)
-       struct task_struct *tsk = current;
-#endif
-       struct stap_task_finder_target *tgt = engine->data;
-       unsigned long rv;
-       struct __stp_tf_map_entry *entry;
-
-       __stp_tf_handler_start();
-       if (atomic_read(&__stp_task_finder_state) != __STP_TF_RUNNING) {
-               debug_task_finder_detach();
-               __stp_tf_handler_end();
-               return UTRACE_DETACH;
-       }
-
-       if (tgt == NULL) {
-               __stp_tf_handler_end();
-               return UTRACE_RESUME;
-       }
-
-       // See if we can find saved syscall info.  If we can, it must
-       // be one of the syscalls we are interested in (and we must
-       // have callbacks to call for it).
-       entry = __stp_tf_get_map_entry(tsk);
-       if (entry == NULL) {
-               __stp_tf_handler_end();
-               return UTRACE_RESUME;
-       }
-
-       // Get return value
-       rv = syscall_get_return_value(tsk, regs);
-
-       dbug_task_vma(1,
-                 "tsk %d found %s(0x%lx), returned 0x%lx\n",
-                 tsk->pid,
-                 ((entry->syscall_no == MMAP_SYSCALL_NO(tsk)) ? "mmap"
-                  : ((entry->syscall_no == MMAP2_SYSCALL_NO(tsk)) ? "mmap2"
-                     : ((entry->syscall_no == MPROTECT_SYSCALL_NO(tsk))
-                        ? "mprotect"
-                        : ((entry->syscall_no == MUNMAP_SYSCALL_NO(tsk))
-                           ? "munmap"
-                           : "UNKNOWN")))),
-                 entry->arg0, rv);
-
-       if (entry->syscall_no == MUNMAP_SYSCALL_NO(tsk)) {
-               // Call the callbacks
-               __stp_call_munmap_callbacks(tgt, tsk, entry->arg0, entry->arg1);
-       }
-       else if (entry->syscall_no == MMAP_SYSCALL_NO(tsk)
-                || entry->syscall_no == MMAP2_SYSCALL_NO(tsk)) {
-               // Call the callbacks
-               __stp_call_mmap_callbacks_with_addr(tgt, tsk, rv);
-       }
-       else {                          // mprotect
-               // Call the callbacks
-               __stp_call_mprotect_callbacks(tgt, tsk, entry->arg0,
-                                             entry->arg1, entry->arg2);
-       }
-
-       __stp_tf_remove_map_entry(entry);
-       __stp_tf_handler_end();
-       return UTRACE_RESUME;
-}
-
-static 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,
-       .report_exit = stap_utrace_task_finder_report_exit,
-};
-
-static int
-stap_start_task_finder(void)
-{
-       int rc = 0;
-       struct task_struct *grp, *tsk;
-       char *mmpath_buf;
-       uid_t tsk_euid;
-
-       if (atomic_inc_return(&__stp_task_finder_state) != __STP_TF_STARTING) {
-               atomic_dec(&__stp_task_finder_state);
-               _stp_error("task_finder already started");
-               return EBUSY;
-       }
-
-       mmpath_buf = _stp_kmalloc(PATH_MAX);
-       if (mmpath_buf == NULL) {
-               _stp_error("Unable to allocate space for path");
-               return ENOMEM;
-       }
-
-        __stp_tf_map_initialize();
-
-       atomic_set(&__stp_task_finder_state, __STP_TF_RUNNING);
-
-       rcu_read_lock();
-       do_each_thread(grp, tsk) {
-               struct mm_struct *mm;
-               char *mmpath;
-               size_t mmpathlen;
-               struct list_head *tgt_node;
-
-               /* If in stap -c/-x mode, skip over other processes. */
-               if (_stp_target && tsk->tgid != _stp_target)
-                       continue;
-
-               // Called under lock, so needs atomic.
-               rc = __stp_utrace_attach_atomic(tsk,
-                                        &__stp_utrace_task_finder_ops, 0,
-                                        __STP_TASK_FINDER_EVENTS,
-                                        UTRACE_RESUME);
-               if (rc == EPERM) {
-                       /* Ignore EPERM errors, which mean this wasn't
-                        * a thread we can attach to. */
-                       rc = 0;
-                       continue;
-               }
-               else if (rc != 0) {
-                       /* If we get a real error, quit. */
-                       goto stf_err;
-               }
-
-               // Grab the path associated with this task.
-               //
-               // Note we aren't calling get_task_mm()/mmput() here.
-               // Instead we're calling task_lock()/task_unlock().
-               // We really only need to lock the mm, but mmput() can
-               // sleep so we can't call it.  Also note that
-               // __stp_get_mm_path() grabs the mmap semaphore, which
-               // should also keep us safe.
-               task_lock(tsk);
-               if (! tsk->mm) {
-                       /* If the thread doesn't have a mm_struct, it is
-                        * a kernel thread which we need to skip. */
-                       task_unlock(tsk);
-                       continue;
-               }
-               mmpath = __stp_get_mm_path(tsk->mm, mmpath_buf, PATH_MAX);
-               task_unlock(tsk);
-               if (mmpath == NULL || IS_ERR(mmpath)) {
-                       rc = PTR_ERR(mmpath);
-                       /* If this was our target then it's a fatal error */
-                       if (!_stp_target && rc == -ENOENT) {
-                               _stp_warn("Unable to get path (error %d) for pid %d",
-                                          rc, (int)tsk->pid);
-                               rc = 0; /* ignore ENOENT */
-                               continue;
-                       }
-                       else {
-                               _stp_error("Unable to get path (error %d) for pid %d",
-                                          rc, (int)tsk->pid);
-                               goto stf_err;
-                       }
-               }
-
-               /* Check the thread's exe's path/pid against our list. */
-#ifdef STAPCONF_TASK_UID
-               tsk_euid = tsk->euid;
-#else
-#if defined(CONFIG_USER_NS) || (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
-               tsk_euid = from_kuid_munged(current_user_ns(), task_euid(tsk));
-#else
-               tsk_euid = task_euid(tsk);
-#endif
-#endif
-               mmpathlen = strlen(mmpath);
-               list_for_each(tgt_node, &__stp_task_finder_list) {
-                       struct stap_task_finder_target *tgt;
-
-                       tgt = list_entry(tgt_node,
-                                        struct stap_task_finder_target, list);
-                       if (tgt == NULL)
-                               continue;
-                       /* procname-based target */
-                       else if (tgt->pathlen > 0
-                                && (tgt->pathlen != mmpathlen
-                                    || strcmp(tgt->procname, mmpath) != 0))
-                                continue;
-                       /* pid-based target */
-                       else if (tgt->pid != 0 && tgt->pid != tsk->pid)
-                               continue;
-                       /* Notice that "pid == 0" (which means to
-                        * probe all threads) falls through. */
-
-#if ! STP_PRIVILEGE_CONTAINS (STP_PRIVILEGE, STP_PR_STAPDEV) && \
-    ! STP_PRIVILEGE_CONTAINS (STP_PRIVILEGE, STP_PR_STAPSYS)
-                       /* Make sure unprivileged users only probe their own threads.  */
-                       if (_stp_uid != tsk_euid) {
-                               if (tgt->pid != 0 || _stp_target) {
-                                       _stp_warn("Process %d does not belong to unprivileged user %d",
-                                                 tsk->pid, _stp_uid);
-                               }
-                               continue;
-                       }
-#endif
-
-                       // Set up events we need for attached tasks.
-                       // Called under lock, so needs atomic.
-                       rc = __stp_utrace_attach_atomic(tsk, &tgt->ops, tgt,
-                                                __STP_ATTACHED_TASK_EVENTS,
-                                                UTRACE_STOP);
-                       if (rc != 0 && rc != EPERM)
-                               goto stf_err;
-                       rc = 0;         /* ignore EPERM */
-                       tgt->engine_attached = 1;
-               }
-       } while_each_thread(grp, tsk);
-stf_err:
-       rcu_read_unlock();
-       _stp_kfree(mmpath_buf);
-       debug_task_finder_report(); // report at end for utrace engine counting
-       return rc;
-}
-
-static void
-stap_task_finder_post_init(void)
-{
-       /* With the original version of utrace UTRACE_STOP also does
-        * UTRACE_INTERRUPT, so we don't really need this function. */
-#if !defined(UTRACE_ORIG_VERSION)
-       struct task_struct *grp, *tsk;
-
-       if (atomic_read(&__stp_task_finder_state) != __STP_TF_RUNNING) {
-               _stp_error("task_finder not running?");
-               return;
-       }
-
-       rcu_read_lock();
-       do_each_thread(grp, tsk) {
-               struct list_head *tgt_node;
-
-               /* If in stap -c/-x mode, skip over other processes. */
-               if (_stp_target && tsk->tgid != _stp_target)
-                       continue;
-
-               /* Only "poke" thread group leaders. */
-               if (tsk->tgid != tsk->pid)
-                       continue;
-
-               /* See if we need to "poke" this thread. */
-               list_for_each(tgt_node, &__stp_task_finder_list) {
-                       struct stap_task_finder_target *tgt;
-                       struct utrace_engine *engine;
-
-                       tgt = list_entry(tgt_node,
-                                        struct stap_task_finder_target, list);
-                       if (tgt == NULL || !tgt->engine_attached)
-                               continue;
-
-                       // If we found an "interesting" task earlier,
-                       // stop it.
-                       engine = utrace_attach_task(tsk,
-                                                   UTRACE_ATTACH_MATCH_OPS,
-                                                   &tgt->ops, tgt);
-                       if (engine != NULL && !IS_ERR(engine)) {
-                               /* We found a target task. Stop it. */
-                               int rc = utrace_control(tsk, engine,
-                                                       UTRACE_INTERRUPT);
-                               /* If utrace_control() returns
-                                * EINPROGRESS when we're trying to
-                                * stop/interrupt, that means the task
-                                * hasn't stopped quite yet, but will
-                                * soon.  Ignore this error. */
-                               if (rc != 0 && rc != -EINPROGRESS) {
-                                       _stp_error("utrace_control returned error %d on pid %d",
-                                                  rc, (int)tsk->pid);
-                               }
-                               utrace_engine_put(engine);
-
-                               /* Since we only need to interrupt
-                                * the task once, not once per
-                                * engine, get out of this loop. */
-                               break;
-                       }
-               }
-       } while_each_thread(grp, tsk);
-       rcu_read_unlock();
-#endif
-       return;
-}
-
-
-static void
-stap_stop_task_finder(void)
-{
-#ifdef DEBUG_TASK_FINDER
-       int i = 0;
-#endif
-
-       if (atomic_read(&__stp_task_finder_state) == __STP_TF_UNITIALIZED)
-               return;
-
-       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);
-
-       /* Now that all the engines are detached, make sure
-        * all the callbacks are finished.  If they aren't, we'll
-        * crash the kernel when the module is removed. */
-       while (atomic_read(&__stp_inuse_count) != 0) {
-               schedule();
-#ifdef DEBUG_TASK_FINDER
-               i++;
-#endif
-       }
-#ifdef DEBUG_TASK_FINDER
-       if (i > 0)
-               printk(KERN_ERR "it took %d polling loops to quit.\n", i);
-#endif
-       debug_task_finder_report();
-}
-
-#endif /* CONFIG_UTRACE */
 #endif /* HAVE_TASK_FINDER */
 #endif /* TASK_FINDER_C */
index cc5c7c4dd0e59d86c1a9d36e740fde8b9ef9753d..8793f2761e7af96d50f7b5e79efd40d8c3cbe026 100644 (file)
@@ -686,10 +686,6 @@ static int _stp_build_id_check (struct _stp_module *m,
 #endif
 
       /*
-       * Why check CONFIG_UTRACE here? If we're using real in-kernel
-       * utrace, we can always just call get_user() (since we're
-       * either reading kernel memory or tsk == current).
-       *
        * Since we're only reading here, we can call
        * __access_process_vm_noflush(), which only calls things that
        * are exported.
@@ -697,9 +693,7 @@ static int _stp_build_id_check (struct _stp_module *m,
        * PR26811: Kernel 5.10+ after set_fs() removal no longer supports
        * reading kernel addresses with get_user.
        */
-#if defined(CONFIG_UTRACE) && !defined(STAPCONF_SET_FS)
-      rc = get_user(practice, ((unsigned char*)(void*)(notes_addr + j)));
-#elif defined(STAPCONF_SET_FS)
+#if defined(STAPCONF_SET_FS)
       if (!tsk || tsk == current) {
        rc = get_user(practice, ((unsigned char*)(void*)(notes_addr + j)));
       }
index 5d8bab8db35803f91abec21d273b8a4219a83a1c..13889483d573481c4cf5e3ee746f24fa8e79dd22 100644 (file)
@@ -103,11 +103,7 @@ __stp_tf_vma_new_entry(void)
        // callback freeing the entries will not depend on using a function
        // within this module to free the allocated memory (_stp_kfree), which
        // lets us omit a costly rcu_barrier operation upon module unload.
-#ifdef CONFIG_UTRACE
-       entry = kmalloc(sizeof(*entry), STP_ALLOC_SLEEP_FLAGS);
-#else
        entry = kmalloc(sizeof(*entry), STP_ALLOC_FLAGS);
-#endif
        return entry;
 }
 
index eae4d779e315b32b603558d9eb0aac42c12b4fe5..4d2a70e7a8ba3224d4574fd6ddc7e7ff27931d19 100644 (file)
@@ -72,17 +72,10 @@ static void _stp_vma_match_vdso(struct task_struct *tsk)
                unsigned char b;
 
                /*
-                * Why check CONFIG_UTRACE here? If we're using real
-                * in-kernel utrace, we can always just call
-                * get_user() (since tsk == current).
-                *
                 * Since we're only reading here, we can call
                 * __access_process_vm_noflush(), which only calls
                 * things that are exported.
                 */
-#ifdef CONFIG_UTRACE
-               rc = copy_from_user(&b, (void*)(notes_addr + j), 1);
-#else
                if (tsk == current)
                  {
                    rc = copy_from_user(&b, (void*)(notes_addr + j), 1);
@@ -92,7 +85,6 @@ static void _stp_vma_match_vdso(struct task_struct *tsk)
                    rc = (__access_process_vm_noflush(tsk, (notes_addr + j),
                                                      &b, 1, 0) != 1);
                  }
-#endif
                if (rc || b != m->build_id_bits[j])
                  {
                    dbug_task_vma(1,"darn, not equal (rc=%d) at %d (0x%x != 0x%x)\n",
@@ -294,8 +286,7 @@ static int _stp_vma_init(void)
 /* Get rid of the vma tracker (memory). */
 static void _stp_vma_done(void)
 {
-/* NB HAVE_TASK_FINDER already includes the case of CONFIG_UTRACE.
- * See runtime/linux/runtime.h for more details. See also PR26123 */
+/* See runtime/linux/runtime.h for more details. See also PR26123 */
 #ifdef HAVE_TASK_FINDER
        stap_destroy_vma_map();
 #endif
diff --git a/tapset-itrace.cxx b/tapset-itrace.cxx
deleted file mode 100644 (file)
index 238b4d5..0000000
+++ /dev/null
@@ -1,368 +0,0 @@
-// tapset for timers
-// Copyright (C) 2005-2013 Red Hat Inc.
-// Copyright (C) 2005-2007 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
-// Public License (GPL); either version 2, or (at your option) any
-// later version.
-
-
-#include "session.h"
-#include "tapsets.h"
-#include "task_finder.h"
-#include "translate.h"
-#include "util.h"
-
-#include <cstring>
-#include <string>
-
-
-using namespace std;
-using namespace __gnu_cxx;
-
-
-static const string TOK_PROCESS("process");
-static const string TOK_INSN("insn");
-static const string TOK_BLOCK("block");
-
-
-// ------------------------------------------------------------------------
-// itrace user-space probes
-// ------------------------------------------------------------------------
-
-
-struct itrace_derived_probe: public derived_probe
-{
-  bool has_path;
-  interned_string path;
-  int64_t pid;
-  int single_step;
-
-  itrace_derived_probe (systemtap_session &s, probe* p, probe_point* l,
-                        bool hp, interned_string pn, int64_t pd, int ss
-                       );
-  void join_group (systemtap_session& s);
-};
-
-
-struct itrace_derived_probe_group: public generic_dpg<itrace_derived_probe>
-{
-private:
-  map<string, vector<itrace_derived_probe*> > probes_by_path;
-  typedef map<string, vector<itrace_derived_probe*> >::iterator p_b_path_iterator;
-  map<int64_t, vector<itrace_derived_probe*> > probes_by_pid;
-  typedef map<int64_t, vector<itrace_derived_probe*> >::iterator p_b_pid_iterator;
-  unsigned num_probes;
-
-  void emit_probe_decl (systemtap_session& s, itrace_derived_probe *p);
-
-public:
-  itrace_derived_probe_group(): num_probes(0) { }
-
-  void enroll (itrace_derived_probe* probe);
-  void emit_module_decls (systemtap_session& s);
-  void emit_module_init (systemtap_session& s);
-  void emit_module_exit (systemtap_session& s);
-
-  friend void warn_for_bpf(systemtap_session& s,
-                           itrace_derived_probe_group *dpg,
-                           const std::string& kind);
-};
-
-
-itrace_derived_probe::itrace_derived_probe (systemtap_session &s,
-                                            probe* p, probe_point* l,
-                                            bool hp, interned_string pn, int64_t pd,
-                                           int ss
-                                           ):
-  derived_probe(p, l), has_path(hp), path(pn), pid(pd), single_step(ss)
-{
-  if (s.kernel_config["CONFIG_UTRACE"] != string("y"))
-    throw SEMANTIC_ERROR (_("process probes not available without kernel CONFIG_UTRACE"));
-}
-
-
-void
-itrace_derived_probe::join_group (systemtap_session& s)
-{
-  if (! s.itrace_derived_probes)
-    s.itrace_derived_probes = new itrace_derived_probe_group ();
-
-  s.itrace_derived_probes->enroll (this);
-  this->group = s.itrace_derived_probes;
-
-  enable_task_finder(s);
-}
-
-struct itrace_builder: public derived_probe_builder
-{
-  itrace_builder() {}
-  virtual void build(systemtap_session & sess,
-                    probe * base,
-                    probe_point * location,
-                    literal_map_t const & parameters,
-                    vector<derived_probe *> & finished_results)
-  {
-    interned_string path, path_tgt;
-    int64_t pid = 0;
-    int single_step;
-
-    bool has_path = get_param (parameters, TOK_PROCESS, path);
-    bool has_pid = get_param (parameters, TOK_PROCESS, pid);
-    // XXX: PR 6445 needs !has_path && !has_pid support
-    assert (has_path || has_pid);
-
-    single_step = ! has_null_param (parameters, TOK_BLOCK);
-
-    // If we have a path, we need to validate it.
-    if (has_path)
-      {
-        path = find_executable (path, sess.sysroot, sess.sysenv);
-        sess.unwindsym_modules.insert (path);
-        path_tgt = path_remove_sysroot(sess, path);
-      }
-    else // (has_pid)
-      {
-       string pid_err_msg;
-       if (!is_valid_pid(pid, pid_err_msg))
-         throw SEMANTIC_ERROR(pid_err_msg);
-      }
-
-    finished_results.push_back(new itrace_derived_probe(sess, base, location,
-                                                       has_path, path_tgt, pid,
-                                                       single_step
-                                                       ));
-  }
-
-  virtual string name() { return "itrace builder"; }
-};
-
-
-void
-itrace_derived_probe_group::enroll (itrace_derived_probe* p)
-{
-  if (p->has_path)
-    probes_by_path[p->path].push_back(p);
-  else
-    probes_by_pid[p->pid].push_back(p);
-  num_probes++;
-
-  // XXX: multiple exec probes (for instance) for the same path (or
-  // pid) should all share a itrace report function, and have their
-  // handlers executed sequentially.
-}
-
-
-void
-itrace_derived_probe_group::emit_probe_decl (systemtap_session& s,
-                                            itrace_derived_probe *p)
-{
-  s.op->newline() << "{";
-  s.op->line() << " .tgt={";
-  s.op->line() << " .purpose=\"itrace\",";
-
-  if (p->has_path)
-    {
-      s.op->line() << " .procname=\"" << p->path << "\",";
-      s.op->line() << " .pid=0,";
-    }
-  else
-    {
-      s.op->line() << " .procname=NULL,";
-      s.op->line() << " .pid=" << p->pid << ",";
-    }
-
-  s.op->line() << " .callback=&_stp_itrace_probe_cb,";
-  s.op->line() << " },";
-  s.op->line() << " .probe=" << common_probe_init (p) << ",";
-  s.op->line() << " .single_step=" << p->single_step << ",";
-  s.op->line() << " },";
-}
-
-
-void
-itrace_derived_probe_group::emit_module_decls (systemtap_session& s)
-{
-  if (probes_by_path.empty() && probes_by_pid.empty())
-    return;
-
-  s.op->newline();
-  s.op->newline() << "/* ---- itrace probes ---- */";
-
-  s.op->newline() << "struct stap_itrace_probe {";
-  s.op->indent(1);
-  s.op->newline() << "struct stap_task_finder_target tgt;";
-  s.op->newline() << "const struct stap_probe * const probe;";
-  s.op->newline() << "int single_step;";
-  s.op->newline(-1) << "};";
-  s.op->newline() << "static void enter_itrace_probe(struct stap_itrace_probe *p, struct pt_regs *regs, void *data);";
-  s.op->newline() << "#include \"linux/itrace.c\"";
-
-  // output routine to call itrace probe
-  s.op->newline() << "static void enter_itrace_probe(struct stap_itrace_probe *p, struct pt_regs *regs, void *data) {";
-  s.op->indent(1);
-
-  common_probe_entryfn_prologue (s, "STAP_SESSION_RUNNING", "", "p->probe",
-                                "stp_probe_type_itrace");
-  s.op->newline() << "c->uregs = regs;";
-  s.op->newline() << "c->user_mode_p = 1;";
-
-  // call probe function
-  s.op->newline() << "(*p->probe->ph) (c);";
-  common_probe_entryfn_epilogue (s, true, otf_safe_context(s));
-
-  s.op->newline() << "return;";
-  s.op->newline(-1) << "}";
-
-  // Output task finder callback routine that gets called for all
-  // itrace probe types.
-  s.op->newline() << "static int _stp_itrace_probe_cb(struct stap_task_finder_target *tgt, struct task_struct *tsk, int register_p, int process_p) {";
-  s.op->indent(1);
-  s.op->newline() << "int rc = 0;";
-  s.op->newline() << "struct stap_itrace_probe *p = container_of(tgt, struct stap_itrace_probe, tgt);";
-
-  s.op->newline() << "if (register_p) ";
-  s.op->indent(1);
-
-  s.op->newline() << "rc = usr_itrace_init(p->single_step, tsk, p);";
-  s.op->newline(-1) << "else";
-  s.op->newline(1) << "remove_usr_itrace_info(find_itrace_info(tsk));";
-  s.op->newline(-1) << "return rc;";
-  s.op->newline(-1) << "}";
-
-  s.op->newline() << "static struct stap_itrace_probe stap_itrace_probes[] = {";
-  s.op->indent(1);
-
-  // Set up 'process(PATH)' probes
-  if (! probes_by_path.empty())
-    {
-      for (p_b_path_iterator it = probes_by_path.begin();
-          it != probes_by_path.end(); it++)
-        {
-         for (unsigned i = 0; i < it->second.size(); i++)
-           {
-             itrace_derived_probe *p = it->second[i];
-             emit_probe_decl(s, p);
-           }
-       }
-    }
-
-  // Set up 'process(PID)' probes
-  if (! probes_by_pid.empty())
-    {
-      for (p_b_pid_iterator it = probes_by_pid.begin();
-          it != probes_by_pid.end(); it++)
-        {
-         for (unsigned i = 0; i < it->second.size(); i++)
-           {
-             itrace_derived_probe *p = it->second[i];
-             emit_probe_decl(s, p);
-           }
-       }
-    }
-  s.op->newline(-1) << "};";
-}
-
-
-void
-itrace_derived_probe_group::emit_module_init (systemtap_session& s)
-{
-  if (probes_by_path.empty() && probes_by_pid.empty())
-    return;
-
-  s.op->newline();
-  s.op->newline() << "/* ---- itrace probes ---- */";
-
-  s.op->newline() << "for (i=0; i<" << num_probes << "; i++) {";
-  s.op->indent(1);
-  s.op->newline() << "struct stap_itrace_probe *p = &stap_itrace_probes[i];";
-
-  // 'arch_has_single_step' needs to be defined for either single step mode
-  // or branch mode.
-  s.op->newline() << "if (!arch_has_single_step()) {";
-  s.op->indent(1);
-  s.op->newline() << "_stp_error (\"insn probe init: arch does not support step mode\");";
-  s.op->newline() << "rc = -EPERM;";
-  s.op->newline() << "break;";
-  s.op->newline(-1) << "}";
-  s.op->newline() << "if (!p->single_step && !arch_has_block_step()) {";
-  s.op->indent(1);
-  s.op->newline() << "_stp_error (\"insn probe init: arch does not support block step mode\");";
-  s.op->newline() << "rc = -EPERM;";
-  s.op->newline() << "break;";
-  s.op->newline(-1) << "}";
-
-  s.op->newline() << "rc = stap_register_task_finder_target(&p->tgt);";
-  s.op->newline(-1) << "}";
-}
-
-
-void
-itrace_derived_probe_group::emit_module_exit (systemtap_session& s)
-{
-  if (probes_by_path.empty() && probes_by_pid.empty()) return;
-  s.op->newline();
-  s.op->newline() << "/* ---- itrace probes ---- */";
-  s.op->newline() << "cleanup_usr_itrace();";
-}
-
-
-// PR26234: Not supported by stapbpf.
-void
-warn_for_bpf(systemtap_session& s,
-             itrace_derived_probe_group *dpg,
-             const std::string& kind)
-{
-  if (! dpg->probes_by_path.empty())
-    {
-      for (itrace_derived_probe_group::p_b_path_iterator it
-             = dpg->probes_by_path.begin();
-          it != dpg->probes_by_path.end(); it++)
-        {
-         for (unsigned i = 0; i < it->second.size(); i++)
-           {
-             itrace_derived_probe *p = it->second[i];
-              s.print_warning(_F("%s will be ignored by bpf backend",
-                                 kind.c_str()),
-                              p->tok);
-           }
-       }
-    }
-  if (! dpg->probes_by_pid.empty())
-    {
-      for (itrace_derived_probe_group::p_b_pid_iterator it
-             = dpg->probes_by_pid.begin();
-          it != dpg->probes_by_pid.end(); it++)
-        {
-         for (unsigned i = 0; i < it->second.size(); i++)
-           {
-             itrace_derived_probe *p = it->second[i];
-              s.print_warning(_F("%s will be ignored by bpf backend",
-                                 kind.c_str()),
-                              p->tok);
-           }
-       }
-    }
-}
-
-
-void
-register_tapset_itrace(systemtap_session& s)
-{
-  match_node* root = s.pattern_root;
-  derived_probe_builder *builder = new itrace_builder();
-
-  root->bind_str(TOK_PROCESS)->bind(TOK_INSN)
-    ->bind(builder);
-  root->bind_num(TOK_PROCESS)->bind(TOK_INSN)
-    ->bind(builder);
-  root->bind_str(TOK_PROCESS)->bind(TOK_INSN)->bind(TOK_BLOCK)
-    ->bind(builder);
-  root->bind_num(TOK_PROCESS)->bind(TOK_INSN)->bind(TOK_BLOCK)
-    ->bind(builder);
-}
-
-
-
-/* vim: set sw=2 ts=8 cino=>4,n-2,{2,^-2,t0,(0,u0,w1,M1 : */
index 975961b81a2a3bccf181dc42b8bf9d1e85459bc6..60cdba8d7513e55bb5d802e603fab4d375e37411 100644 (file)
@@ -791,24 +791,14 @@ utrace_derived_probe_group::emit_linux_probe_decl (systemtap_session& s,
     // stops the thread, that works around bug 6841.
     case UDPF_SYSCALL:
       s.op->line() << " .flags=(UDPF_SYSCALL),";
-      s.op->newline() << "#if !defined(CONFIG_UTRACE)";
       s.op->newline() << " .ops={ .report_syscall_entry=stap_utrace_probe_syscall,  .report_death=stap_utrace_task_finder_report_death },";
       s.op->line() << " .events=(UTRACE_EVENT(SYSCALL_ENTRY)|UTRACE_EVENT(DEATH)),";
-      s.op->newline() << "#else";
-      s.op->newline() << " .ops={ .report_syscall_entry=stap_utrace_probe_syscall,  .report_exit=stap_utrace_task_finder_report_exit },";
-      s.op->line() << " .events=(UTRACE_EVENT(SYSCALL_ENTRY)|UTRACE_EVENT(EXIT)),";
-      s.op->newline() << "#endif";
       s.op->newline();
       break;
     case UDPF_SYSCALL_RETURN:
       s.op->line() << " .flags=(UDPF_SYSCALL_RETURN),";
-      s.op->newline() << "#if !defined(CONFIG_UTRACE)";
       s.op->newline() << " .ops={ .report_syscall_exit=stap_utrace_probe_syscall, .report_death=stap_utrace_task_finder_report_death },";
       s.op->line() << " .events=(UTRACE_EVENT(SYSCALL_EXIT)|UTRACE_EVENT(DEATH)),";
-      s.op->newline() << "#else";
-      s.op->newline() << " .ops={ .report_syscall_exit=stap_utrace_probe_syscall, .report_exit=stap_utrace_task_finder_report_exit },";
-      s.op->line() << " .events=(UTRACE_EVENT(SYSCALL_EXIT)|UTRACE_EVENT(EXIT)),";
-      s.op->newline() << "#endif";
       s.op->newline();
       break;
 
@@ -1269,16 +1259,12 @@ utrace_derived_probe_group::emit_module_linux_exit (systemtap_session& s)
 {
   if (probes_by_path.empty() && probes_by_pid.empty()) return;
 
-  // Only runtime/linux/task_finder.c uses stap_utrace_detach_ops()
-  if (s.kernel_config["CONFIG_UTRACE"] != string("y")) return;
-
   s.op->newline();
   s.op->newline() << "/* ---- utrace probes ---- */";
   s.op->newline() << "for (i=0; i<ARRAY_SIZE(stap_utrace_probes); i++) {";
   s.op->newline(1) << "struct stap_utrace_probe *p = &stap_utrace_probes[i];";
 
   s.op->newline() << "if (p->engine_attached) {";
-  s.op->newline(1) << "stap_utrace_detach_ops(&p->ops);";
 
   s.op->newline(-1) << "}";
   s.op->newline(-1) << "}";
index 7b7107371b5f703ff65dac319e89b2f537bf161f..79b27a357caa3cc015980bdd6fa354e8ee270729 100644 (file)
@@ -5484,10 +5484,6 @@ kernel_supports_inode_uretprobes(systemtap_session& s)
 void
 check_process_probe_kernel_support(systemtap_session& s)
 {
-  // If we've got utrace, we're good to go.
-  if (s.kernel_config["CONFIG_UTRACE"] == "y")
-    return;
-
   // We don't have utrace.  For process probes that aren't
   // uprobes-based, we just need the task_finder.  The task_finder
   // needs CONFIG_TRACEPOINTS and specific tracepoints.  There is a
@@ -5505,7 +5501,7 @@ check_process_probe_kernel_support(systemtap_session& s)
       && kernel_supports_inode_uprobes(s))
     return;
 
-  throw SEMANTIC_ERROR (_("process probes not available without kernel CONFIG_UTRACE or CONFIG_TRACEPOINTS/CONFIG_ARCH_SUPPORTS_UPROBES/CONFIG_UPROBES"));
+  throw SEMANTIC_ERROR (_("process probes not available without kernel CONFIG_TRACEPOINTS/CONFIG_ARCH_SUPPORTS_UPROBES/CONFIG_UPROBES"));
 }
 
 
@@ -13186,7 +13182,6 @@ void
 register_standard_tapsets(systemtap_session & s)
 {
   register_tapset_been(s);
-  register_tapset_itrace(s);
   register_tapset_mark(s);
   register_tapset_procfs(s);
   register_tapset_timers(s);
index 103b99f3bbbee7a7580c9d8938c87f09925aa017..4ea6ce07994dfb0298b77da20e17e00ea82e2acd 100644 (file)
@@ -20,15 +20,6 @@ proc grep_kallsyms { pattern } {
 }
 
 
-# Test for kernel built-in utrace (CONFIG_UTRACE).
-# Only original rhel5/6-era utrace need apply.
-proc utrace_orig_p {} {
-    # We want utrace_attach (rhel5) or utrace_attach_task (rhel6), but don't
-    # get confused by the private module version of any active stap module.
-    return [expr [grep_kallsyms "T utrace_attach"] || [grep_kallsyms "T .utrace_attach_task"]]
-}
-
-
 # Test for tracepoint-based utrace, or rather the in-kernel
 # facilities which enable our emulation of utrace.
 proc utrace_emu_p {} {
@@ -46,7 +37,7 @@ proc utrace_emu_p {} {
 
 # Test for utrace - any flavor will do...
 proc utrace_p {} {
-    return [expr [utrace_orig_p] || [utrace_emu_p] ]
+    return [utrace_emu_p]
 }
 
 
@@ -56,7 +47,7 @@ proc classic_uprobes_p {} {
     #
     # Although ia64 has classical utrace, uprobes hasn't been
     # ported there (PR7081).
-    return [expr [utrace_orig_p] && ! [istarget ia64-*-*] ]
+    return [expr ! [istarget ia64-*-*] ]
 }
 
 proc inode_uprobes_p {} {
index 1687ff015c17e33c34fe939943eddbb28d933b48..e32a283ff52399f247122a8ad3ebe4337c2a21f7 100644 (file)
@@ -164,9 +164,7 @@ proc run_ls_1_sec {} {
 # utrace and we're doing install testing)
 set TEST_NAME "itrace single step check"
 set single_step_p 0
-if {![utrace_orig_p]} {
-    untested "$TEST_NAME : no kernel utrace support found"
-} elseif {![installtest_p]} {
+if {![installtest_p]} {
     untested $TEST_NAME
 } else {
     set single_step_p [stap_check_feature $TEST_NAME \
@@ -177,9 +175,7 @@ if {![utrace_orig_p]} {
 # utrace and we're doing install testing)
 set TEST_NAME "itrace block step check"
 set block_step_p 0
-if {![utrace_orig_p]} {
-    untested "$TEST_NAME : no kernel utrace support found"
-} elseif {![installtest_p]} {
+if {![installtest_p]} {
     untested $TEST_NAME
 } else {
     set block_step_p [stap_check_feature $TEST_NAME \
@@ -188,9 +184,7 @@ if {![utrace_orig_p]} {
 
 # Run the single step tests
 set TEST_NAME "itrace_single1"
-if {![utrace_orig_p]} {
-    untested "$TEST_NAME : no kernel utrace support found"
-} elseif {![installtest_p]} {
+if {![installtest_p]} {
     untested $TEST_NAME
 } elseif {$single_step_p != 1} {
     xfail "$TEST_NAME : no kernel single step support"
@@ -200,9 +194,7 @@ if {![utrace_orig_p]} {
 }
 
 set TEST_NAME "itrace_single2"
-if {![utrace_orig_p]} {
-    untested "$TEST_NAME : no kernel utrace support found"
-} elseif {![installtest_p]} {
+if {![installtest_p]} {
     untested $TEST_NAME
 } elseif {$single_step_p != 1} {
     xfail "$TEST_NAME : no kernel single step support"
@@ -213,9 +205,7 @@ if {![utrace_orig_p]} {
 
 # Run the block step tests
 set TEST_NAME "itrace_block1"
-if {![utrace_orig_p]} {
-    untested "$TEST_NAME : no kernel utrace support found"
-} elseif {![installtest_p]} {
+if {![installtest_p]} {
     untested $TEST_NAME
 } elseif {$block_step_p != 1} {
     xfail "$TEST_NAME : no kernel block step support"
@@ -225,9 +215,7 @@ if {![utrace_orig_p]} {
 }
 
 set TEST_NAME "itrace_block2"
-if {![utrace_orig_p]} {
-    untested "$TEST_NAME : no kernel utrace support found"
-} elseif {![installtest_p]} {
+if {![installtest_p]} {
     untested $TEST_NAME
 } elseif {$block_step_p != 1} {
     xfail "$TEST_NAME : no kernel block step support"
index e683e84d15137085bce20493426952ffde0c4c2a..0d39cf5d97c2a292d9e397fb141c0e9d8befc51d 100644 (file)
@@ -31,7 +31,7 @@ set pids "1234567890 $valid_pid"
 foreach test_script $test_scripts {
     foreach pid $pids {
        verbose -log "PID under test is $pid"
-       if {((([regexp {insn} $test_script] || [regexp {statement} $test_script]) && ![utrace_orig_p]) || ![uprobes_p]) || ([regexp {plt} $test_script] && ![plt_probes_p])} {
+       if {((([regexp {insn} $test_script] || [regexp {statement} $test_script]) || ![uprobes_p]) || ([regexp {plt} $test_script] && ![plt_probes_p])} {
             untested "script: $test_script"
             continue
         } else {
index e103b87ec626bf33fce8a07b22a76a841d5bbf9a..0edc73d0bb10f70380e3d619bccddf52ae16cf22 100644 (file)
@@ -406,9 +406,6 @@ proc test_probes { privilege } {
            process(number).insn.block -
            process(string).insn -
            process(string).insn.block
-           {
-               if {![utrace_orig_p]} { setup_kfail ITRACE *-*-* }
-           }
        }
 
        # Test the probe type. If successful, the stap rc will be 0.
This page took 0.108868 seconds and 5 git commands to generate.