Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 17 Sep 2016 11:43:51 +0000 (UTC)
From:      Bruce Evans <bde@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r305897 - head/sys/ddb
Message-ID:  <201609171143.u8HBhpNQ046437@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: bde
Date: Sat Sep 17 11:43:51 2016
New Revision: 305897
URL: https://svnweb.freebsd.org/changeset/base/305897

Log:
  Silently ignore unexpected single-step traps (except for turning
  off single-stepping).  Only do this on arches (only x86 so far)
  which classify single-step traps unambiguously.
  
  This allows other parts of the kernel to be intentionally and
  unintentionally sloppy about generating single-step traps.  On
  x86, at least the following places were unintentionally sloppy:
  - all operations that context-switched [er]flags.  Especially
    spinlock_enter()/exit() and cpu_switch().  When single-stepped,
    saving the flags leaves PSL_T set in the saved flags, so
    restoring gives a trap that is spurious if it occurs after
    single-step mode has been left.  Switching contexts away from
    a low priority thread gives especially long-lived saved copies.
  - the vm86 emulation allows user mode to set PSL_T.  This was
    correct until vm86 bios call mode was unintentionally given
    access to kdb handling its single-step traps.
  Now these places are intentionally sloppy, but unexpected
  debugger traps still cause panics if no debugger that handles
  the trap is attached when the trap is delivered.

Modified:
  head/sys/ddb/db_run.c

Modified: head/sys/ddb/db_run.c
==============================================================================
--- head/sys/ddb/db_run.c	Sat Sep 17 08:10:01 2016	(r305896)
+++ head/sys/ddb/db_run.c	Sat Sep 17 11:43:51 2016	(r305897)
@@ -136,21 +136,29 @@ db_stop_at_pc(int type, int code, bool *
 	*is_breakpoint = false;	/* might be a breakpoint, but not ours */
 
 	/*
+	 * If not stepping, then silently ignore single-step traps
+	 * (except for clearing the single-step-flag above).
+	 *
 	 * If stepping, then abort if the trap type is unexpected.
 	 * Breakpoints owned by us are expected and were handled above.
 	 * Single-steps are expected and are handled below.  All others
 	 * are unexpected.
 	 *
-	 * If the MD layer doesn't tell us when it is stepping, use the
-	 * bad historical default that all unexepected traps.
+	 * Only do either of these if the MD layer claims to classify
+	 * single-step traps unambiguously (by defining IS_SSTEP_TRAP).
+	 * Otherwise, fall through to the bad historical behaviour
+	 * given by turning unexpected traps into expected traps: if not
+	 * stepping, then expect only breakpoints and stop, and if
+	 * stepping, then expect only single-steps and step.
 	 */
-#ifndef IS_SSTEP_TRAP
-#define	IS_SSTEP_TRAP(type, code)	true
-#endif
+#ifdef IS_SSTEP_TRAP
+	if (db_run_mode == STEP_CONTINUE && IS_SSTEP_TRAP(type, code))
+	    return (false);
 	if (db_run_mode != STEP_CONTINUE && !IS_SSTEP_TRAP(type, code)) {
 	    printf("Stepping aborted\n");
 	    return (true);
 	}
+#endif
 
 	if (db_run_mode == STEP_INVISIBLE) {
 	    db_run_mode = STEP_CONTINUE;



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