diff options
author | Visa Hankala <visa@cvs.openbsd.org> | 2018-05-16 14:55:45 +0000 |
---|---|---|
committer | Visa Hankala <visa@cvs.openbsd.org> | 2018-05-16 14:55:45 +0000 |
commit | 81de96a485fcec14fb656663afb72ac9269ef0df (patch) | |
tree | 3d6c657531cab43dd6ca396388a2c54865ed16bc /sys/kern | |
parent | 4f333c3b2e0f1d3454aee26e003bf33ec0fdcdb5 (diff) |
Print stack traces on lock order conflict.
OK mpi@
Diffstat (limited to 'sys/kern')
-rw-r--r-- | sys/kern/subr_witness.c | 37 |
1 files changed, 36 insertions, 1 deletions
diff --git a/sys/kern/subr_witness.c b/sys/kern/subr_witness.c index e47ea4a5b13..31a97cb4856 100644 --- a/sys/kern/subr_witness.c +++ b/sys/kern/subr_witness.c @@ -1,4 +1,4 @@ -/* $OpenBSD: subr_witness.c,v 1.14 2018/05/16 14:53:43 visa Exp $ */ +/* $OpenBSD: subr_witness.c,v 1.15 2018/05/16 14:55:44 visa Exp $ */ /*- * Copyright (c) 2008 Isilon Systems, Inc. @@ -1039,6 +1039,41 @@ witness_checkorder(struct lock_object *lock, int flags, const char *file, lock->lo_name, w->w_type->lt_name, fixup_filename(file), line); } + if (witness_watch > 1) { + struct witness_lock_order_data *wlod1, *wlod2; + + mtx_enter(&w_mtx); + wlod1 = witness_lock_order_get(w, w1); + wlod2 = witness_lock_order_get(w1, w); + mtx_leave(&w_mtx); + + /* + * It is safe to access saved stack traces, + * w_type, and w_class without the lock. + * Once written, they never change. + */ + + if (wlod1 != NULL) { + printf("lock order \"%s\"(%s) -> " + "\"%s\"(%s) first seen at:\n", + w->w_type->lt_name, + w->w_class->lc_name, + w1->w_type->lt_name, + w1->w_class->lc_name); + db_print_stack_trace( + &wlod1->wlod_stack, printf); + } + if (wlod2 != NULL) { + printf("lock order \"%s\"(%s) -> " + "\"%s\"(%s) first seen at:\n", + w1->w_type->lt_name, + w1->w_class->lc_name, + w->w_type->lt_name, + w->w_class->lc_name); + db_print_stack_trace( + &wlod2->wlod_stack, printf); + } + } witness_debugger(0); goto out_splx; } |