dtrace script matching lot of probes simply resets on i386
Mark Johnston
markj at freebsd.org
Wed Nov 6 15:36:34 UTC 2019
On Tue, Nov 05, 2019 at 11:23:28AM +0000, Bjoern A. Zeeb wrote:
> Hi,
>
> I had an i386 kernel (amd64 machine) simply going to POST. After a lot
> of “doh” I realised that it was a dtrace script which was matching a
> lot of probes running as part of some automated stuff.
>
> The problematic part from the middle of that script was a section which
> I can reduce to
>
> fbt:kernel::entry # or simply :::
> /self->foo == 1/
> {
>
> printf(“Hello\n”);
> }
>
> Anyone wants to investigate this or should I open a PR?
Can you test this patch? I only tried to compile it. Basically, we
must handle FBT probes before calling trap().
diff --git a/sys/i386/i386/exception.s b/sys/i386/i386/exception.s
index b288543dafe1..8a8de5fb1d09 100644
--- a/sys/i386/i386/exception.s
+++ b/sys/i386/i386/exception.s
@@ -175,7 +175,7 @@ alltraps_with_regs_pushed:
FAKE_MCOUNT(TF_EIP(%esp))
calltrap:
pushl %esp
- movl $trap,%eax
+ movl $trap_check,%eax
call *%eax
add $4, %esp
@@ -317,7 +317,7 @@ dbg_user:
movl $handle_ibrs_entry,%eax
call *%eax
pushl %esp
- movl $trap,%eax
+ movl $trap_check,%eax
call *%eax
add $4, %esp
movl $T_RESERVED, TF_TRAPNO(%esp)
diff --git a/sys/i386/i386/trap.c b/sys/i386/i386/trap.c
index bb71317de000..83ac97887feb 100644
--- a/sys/i386/i386/trap.c
+++ b/sys/i386/i386/trap.c
@@ -112,6 +112,7 @@ PMC_SOFT_DEFINE( , , page_fault, write);
#endif
void trap(struct trapframe *frame);
+void trap_check(struct trapframe *frame);
void syscall(struct trapframe *frame);
static int trap_pfault(struct trapframe *, bool, vm_offset_t, int *, int *);
@@ -186,6 +187,21 @@ SYSCTL_INT(_machdep, OID_AUTO, uprintf_signal, CTLFLAG_RW,
&uprintf_signal, 0,
"Print debugging information on trap signal to ctty");
+/*
+ * Ensure that we ignore any DTrace-induced faults. This function cannot
+ * be instrumented, so it cannot generate such faults itself.
+ */
+void
+trap_check(struct trapframe *frame)
+{
+#ifdef KDTRACE_HOOKS
+ if (dtrace_trap_func != NULL &&
+ (*dtrace_trap_func)(frame, frame->tf_trapno))
+ return;
+#endif
+ trap(frame);
+}
+
/*
* Exception, fault, and trap interface to the FreeBSD kernel.
* This common code is called from assembly language IDT gate entry
@@ -260,19 +276,6 @@ trap(struct trapframe *frame)
return;
}
-#ifdef KDTRACE_HOOKS
- /*
- * A trap can occur while DTrace executes a probe. Before
- * executing the probe, DTrace blocks re-scheduling and sets
- * a flag in its per-cpu flags to indicate that it doesn't
- * want to fault. On returning from the probe, the no-fault
- * flag is cleared and finally re-scheduling is enabled.
- */
- if ((type == T_PROTFLT || type == T_PAGEFLT) &&
- dtrace_trap_func != NULL && (*dtrace_trap_func)(frame, type))
- return;
-#endif
-
/*
* We must not allow context switches until %cr2 is read.
* Also, for some Cyrix CPUs, %cr2 is clobbered by interrupts.
More information about the freebsd-dtrace
mailing list