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;
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to