Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 16 Mar 2008 21:13:26 GMT
From:      John Birrell <jb@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 137864 for review
Message-ID:  <200803162113.m2GLDQTQ063263@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=137864

Change 137864 by jb@jb_freebsd8 on 2008/03/16 21:12:39

	Add a reset mechanism to the double trap handler to cater for
	those occasions when fbt enables a probe on something that ends
	up being called unexpectedly from the probe context. We need to
	reset the probe points so that the double trap is handled
	properly and we end up back in ddb.
	
	In fbt itself, do not instrument functions with names starting
	with two underscores. There are one or two of these that can
	cause a double fault when instrumented with fbt, so the simple
	solution is to avoid doing that.
	
	rwatson: this is the "bewm" problem you saw. :-)

Affected files ...

.. //depot/projects/dtrace/src/sys/cddl/dev/fbt/fbt.c#9 edit
.. //depot/projects/dtrace/src/sys/i386/i386/trap.c#28 edit
.. //depot/projects/dtrace/src/sys/sys/dtrace_bsd.h#14 edit

Differences ...

==== //depot/projects/dtrace/src/sys/cddl/dev/fbt/fbt.c#9 (text+ko) ====

@@ -59,6 +59,7 @@
 #include <machine/stdarg.h>
 
 #include <sys/dtrace.h>
+#include <sys/dtrace_bsd.h>
 
 MALLOC_DEFINE(M_FBT, "fbt", "Function Boundary Tracing");
 
@@ -147,6 +148,20 @@
 static int			fbt_probetab_mask;
 static int			fbt_verbose = 0;
 
+static void
+fbt_doubletrap(void)
+{
+	fbt_probe_t *fbt;
+	int i;
+
+	for (i = 0; i < fbt_probetab_size; i++) {
+		fbt = fbt_probetab[i];
+
+		for (; fbt != NULL; fbt = fbt->fbtp_next)
+			*fbt->fbtp_patchpoint = fbt->fbtp_savedval;
+	}
+}
+
 static int
 fbt_invop(uintptr_t addr, uintptr_t *stack, uintptr_t rval)
 {
@@ -228,6 +243,9 @@
 		return (0);
 	}
 
+	if (name[0] == '_' && name[1] == '_')
+		return (0);
+
 	size = symval->size;
 
 	instr = (u_int8_t *) symval->value;
@@ -1321,6 +1339,7 @@
 	fbt_probetab =
 	    malloc(fbt_probetab_size * sizeof (fbt_probe_t *), M_FBT, M_WAITOK | M_ZERO);
 
+	dtrace_doubletrap_func = fbt_doubletrap;
 	dtrace_invop_add(fbt_invop);
 
 	if (dtrace_register("fbt", &fbt_attr, DTRACE_PRIV_USER,
@@ -1337,6 +1356,8 @@
 	/* De-register the invalid opcode handler. */
 	dtrace_invop_remove(fbt_invop);
 
+	dtrace_doubletrap_func = NULL;
+
 	/* De-register this DTrace provider. */
 	if ((error = dtrace_unregister(fbt_id)) != 0)
 		return (error);

==== //depot/projects/dtrace/src/sys/i386/i386/trap.c#28 (text+ko) ====

@@ -113,6 +113,8 @@
  */
 dtrace_trap_func_t	dtrace_trap_func;
 
+dtrace_doubletrap_func_t	dtrace_doubletrap_func;
+
 /*
  * This is a hook which is initialised by the systrace module
  * when it is loaded. This keeps the DTrace syscall provider
@@ -952,6 +954,10 @@
 void
 dblfault_handler()
 {
+#ifdef KDTRACE_HOOKS
+	if (dtrace_doubletrap_func != NULL)
+		(*dtrace_doubletrap_func)();
+#endif
 	printf("\nFatal double fault:\n");
 	printf("eip = 0x%x\n", PCPU_GET(common_tss.tss_eip));
 	printf("esp = 0x%x\n", PCPU_GET(common_tss.tss_esp));

==== //depot/projects/dtrace/src/sys/sys/dtrace_bsd.h#14 (text+ko) ====

@@ -62,9 +62,11 @@
 
 /* Used by the machine dependent trap() code. */
 typedef	int (*dtrace_invop_func_t)(uintptr_t, uintptr_t *, uintptr_t);
+typedef void (*dtrace_doubletrap_func_t)(void);
 
-/* Global variable in trap.c */
+/* Global variables in trap.c */
 extern	dtrace_invop_func_t	dtrace_invop_func;
+extern	dtrace_doubletrap_func_t	dtrace_doubletrap_func;
 
 /* Virtual time hook function type. */
 typedef	void (*dtrace_vtime_switch_func_t)(struct thread *);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200803162113.m2GLDQTQ063263>