svn commit: r305897 - head/sys/ddb
Bruce Evans
bde at FreeBSD.org
Sat Sep 17 11:43:53 UTC 2016
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;
More information about the svn-src-head
mailing list