Date: Wed, 6 Nov 2019 10:36:29 -0500 From: Mark Johnston <markj@freebsd.org> To: "Bjoern A. Zeeb" <bzeeb-lists@lists.zabbadoz.net> Cc: freebsd-dtrace@freebsd.org Subject: Re: dtrace script matching lot of probes simply resets on i386 Message-ID: <20191106153629.GC65703@raichu> In-Reply-To: <71FB27F2-31DD-4646-BAA8-69E686D811DE@lists.zabbadoz.net> References: <71FB27F2-31DD-4646-BAA8-69E686D811DE@lists.zabbadoz.net>
next in thread | previous in thread | raw e-mail | index | archive | help
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.
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20191106153629.GC65703>