1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171
|
commit b09fc46ccc343a461a255b6ae1fea14ab7180846
Author: Serhei Makarov <serhei@serhei.io>
Date: Wed Jul 23 16:13:52 2025 -0400
PR33045: fix for kernel 6.16.0 sched_process_exit change
Kernel commit 3e816361e94a0e79b1aabf44abec552e9698b196
adds a group_dead argument to sched_process_exit tracepoint.
Create a new runtime/transport/autoconf-utrace-via-tracepoints2.c
and STAPCONF_UTRACE_VIA_TRACEPOINTS2 option
and adjust runtime/stp_utrace.c to use the updated API
where appropriate.
Signed-off-by: Serguei Makarov <smakarov@redhat.com>
diff --git a/buildrun.cxx b/buildrun.cxx
index 47cfb2e8d..aeff75575 100644
--- a/buildrun.cxx
+++ b/buildrun.cxx
@@ -448,6 +448,7 @@ compile_pass (systemtap_session& s)
output_autoconf(s, o, cs, "autoconf-module-sect-attrs.c", "STAPCONF_MODULE_SECT_ATTRS", NULL);
output_autoconf(s, o, cs, "autoconf-kernel_read-new-args.c", "STAPCONF_KERNEL_READ_NEW_ARGS", NULL);
output_autoconf(s, o, cs, "autoconf-utrace-via-tracepoints.c", "STAPCONF_UTRACE_VIA_TRACEPOINTS", NULL);
+ output_autoconf(s, o, cs, "autoconf-utrace-via-tracepoints2.c", "STAPCONF_UTRACE_VIA_TRACEPOINTS2", NULL);
output_autoconf(s, o, cs, "autoconf-task_work-struct.c", "STAPCONF_TASK_WORK_STRUCT", NULL);
output_autoconf(s, o, cs, "autoconf-twa_resume.c", "STAPCONF_TWA_RESUME", NULL);
output_autoconf(s, o, cs, "autoconf-vm-area-pte.c", "STAPCONF_VM_AREA_PTE", NULL);
diff --git a/runtime/linux/autoconf-utrace-via-tracepoints2.c b/runtime/linux/autoconf-utrace-via-tracepoints2.c
new file mode 100644
index 000000000..b4e66c1ca
--- /dev/null
+++ b/runtime/linux/autoconf-utrace-via-tracepoints2.c
@@ -0,0 +1,81 @@
+/* variant of autoconf_utrace_via_tracepoints.c post
+ kernel commit 3e816361e94a0e79b1aabf44abec552e9698b196
+ adding group_dead argument to sched_process_exit */
+
+#include <linux/mm.h>
+#include <trace/events/sched.h>
+#include <trace/events/syscalls.h>
+#include <linux/task_work.h>
+
+// The utrace-less task_finder needs 5 specific tracepoints and
+// <linux/task_work.h>.
+
+// NB: in kernels which do have the requisite pieces, just unconfigured, then
+// everything below will compile just fine, only returning ENOSYS at runtime.
+// To get the compile-time error that autoconf needs, check it directly:
+#ifndef CONFIG_TRACEPOINTS
+#error "CONFIG_TRACEPOINTS is not enabled"
+#endif
+
+void __sched_process_fork(void *cb_data __attribute__((unused)),
+ struct task_struct *parent __attribute__((unused)),
+ struct task_struct *child __attribute__((unused)));
+
+void __sched_process_fork(void *cb_data __attribute__((unused)),
+ struct task_struct *parent __attribute__((unused)),
+ struct task_struct *child __attribute__((unused)))
+{
+ return;
+}
+
+void __sched_process_exit(void *cb_data __attribute__((unused)),
+ struct task_struct *task __attribute__((unused)),
+ bool group_dead __attribute__((unused)));
+void __sched_process_exit(void *cb_data __attribute__((unused)),
+ struct task_struct *task __attribute__((unused)),
+ bool group_dead __attribute__((unused)))
+{
+ return;
+}
+
+void __sched_process_exec(void *cb_data __attribute__ ((unused)),
+ struct task_struct *task __attribute__((unused)),
+ pid_t old_pid __attribute__((unused)),
+ struct linux_binprm *bprm __attribute__((unused)));
+void __sched_process_exec(void *cb_data __attribute__ ((unused)),
+ struct task_struct *task __attribute__((unused)),
+ pid_t old_pid __attribute__((unused)),
+ struct linux_binprm *bprm __attribute__((unused)))
+{
+ return;
+}
+
+void __sys_enter(void *cb_data __attribute__ ((unused)),
+ struct pt_regs *regs __attribute__((unused)),
+ long id __attribute__((unused)));
+void __sys_enter(void *cb_data __attribute__ ((unused)),
+ struct pt_regs *regs __attribute__((unused)),
+ long id __attribute__((unused)))
+{
+ return;
+}
+
+void __sys_exit(void *cb_data __attribute__ ((unused)),
+ struct pt_regs *regs __attribute__((unused)),
+ long ret __attribute__((unused)));
+void __sys_exit(void *cb_data __attribute__ ((unused)),
+ struct pt_regs *regs __attribute__((unused)),
+ long ret __attribute__((unused)))
+{
+ return;
+}
+
+void __autoconf_func(void);
+void __autoconf_func(void)
+{
+ (void) register_trace_sched_process_fork(__sched_process_fork, NULL);
+ (void) register_trace_sched_process_exit(__sched_process_exit, NULL);
+ (void) register_trace_sched_process_exec(__sched_process_exec, NULL);
+ (void) register_trace_sys_enter(__sys_enter, NULL);
+ (void) register_trace_sys_exit(__sys_exit, NULL);
+}
diff --git a/runtime/linux/runtime.h b/runtime/linux/runtime.h
index bd9307385..44aab7b99 100644
--- a/runtime/linux/runtime.h
+++ b/runtime/linux/runtime.h
@@ -342,7 +342,7 @@ __noendbr void ibt_restore(u64 save)
#include "../regs.c"
#include "regs-ia64.c"
-#if (defined(STAPCONF_UTRACE_VIA_TRACEPOINTS))
+#if (defined(STAPCONF_UTRACE_VIA_TRACEPOINTS) || defined(STAPCONF_UTRACE_VIA_TRACEPOINTS2))
#define HAVE_TASK_FINDER
#include "task_finder.c"
#else
diff --git a/runtime/stp_utrace.c b/runtime/stp_utrace.c
index 9ddd67ada..52b53bd83 100644
--- a/runtime/stp_utrace.c
+++ b/runtime/stp_utrace.c
@@ -13,7 +13,7 @@
#ifndef _STP_UTRACE_C
#define _STP_UTRACE_C
-#if (!defined(STAPCONF_UTRACE_VIA_TRACEPOINTS))
+#if (!defined(STAPCONF_UTRACE_VIA_TRACEPOINTS) && !defined(STAPCONF_UTRACE_VIA_TRACEPOINTS2))
#error "STAPCONF_UTRACE_VIA_TRACEPOINTS must be defined."
#endif
@@ -258,8 +258,14 @@ static const struct utrace_engine_ops utrace_detached_ops; /* forward decl */
static void utrace_report_clone(void *cb_data __attribute__ ((unused)),
struct task_struct *task,
struct task_struct *child);
+#ifdef STAPCONF_UTRACE_VIA_TRACEPOINTS2
+static void utrace_report_death(void *cb_data __attribute__ ((unused)),
+ struct task_struct *task,
+ bool group_dead __attribute__ ((unused)));
+#else
static void utrace_report_death(void *cb_data __attribute__ ((unused)),
struct task_struct *task);
+#endif
static void utrace_report_syscall_entry(void *cb_data __attribute__ ((unused)),
struct pt_regs *regs, long id);
static void utrace_report_syscall_exit(void *cb_data __attribute__ ((unused)),
@@ -2767,8 +2773,14 @@ static void utrace_finish_vfork(struct task_struct *task)
* For this reason, utrace_release_task checks for the event bits that get
* us here, and delays its cleanup for us to do.
*/
+#ifdef STAPCONF_UTRACE_VIA_TRACEPOINTS2
+static void utrace_report_death(void *cb_data __attribute__ ((unused)),
+ struct task_struct *task,
+ bool group_dead __attribute__ ((unused)))
+#else
static void utrace_report_death(void *cb_data __attribute__ ((unused)),
struct task_struct *task)
+#endif
{
struct utrace_bucket *bucket;
struct utrace *utrace;
|