@@ -75,7 +75,7 @@ struct LockDep {
7575}
7676
7777#[ cfg( feature = "backtrace" ) ]
78- fn get_construction_location ( backtrace : & Backtrace ) -> String {
78+ fn get_construction_location ( backtrace : & Backtrace ) -> ( String , Option < u32 > ) {
7979 // Find the first frame that is after `debug_sync` (or that is in our tests) and use
8080 // that as the mutex construction site. Note that the first few frames may be in
8181 // the `backtrace` crate, so we have to ignore those.
@@ -86,13 +86,7 @@ fn get_construction_location(backtrace: &Backtrace) -> String {
8686 let symbol_name = symbol. name ( ) . unwrap ( ) . as_str ( ) . unwrap ( ) ;
8787 if !sync_mutex_constr_regex. is_match ( symbol_name) {
8888 if found_debug_sync {
89- if let Some ( col) = symbol. colno ( ) {
90- return format ! ( "{}:{}:{}" , symbol. filename( ) . unwrap( ) . display( ) , symbol. lineno( ) . unwrap( ) , col) ;
91- } else {
92- // Windows debug symbols don't support column numbers, so fall back to
93- // line numbers only if no `colno` is available
94- return format ! ( "{}:{}" , symbol. filename( ) . unwrap( ) . display( ) , symbol. lineno( ) . unwrap( ) ) ;
95- }
89+ return ( format ! ( "{}:{}" , symbol. filename( ) . unwrap( ) . display( ) , symbol. lineno( ) . unwrap( ) ) , symbol. colno ( ) ) ;
9690 }
9791 } else { found_debug_sync = true ; }
9892 }
@@ -116,8 +110,13 @@ impl LockMetadata {
116110 let lock_constr_location = get_construction_location ( & res. _lock_construction_bt ) ;
117111 LOCKS_INIT . call_once ( || { unsafe { LOCKS = Some ( StdMutex :: new ( HashMap :: new ( ) ) ) ; } } ) ;
118112 let mut locks = unsafe { LOCKS . as_ref ( ) } . unwrap ( ) . lock ( ) . unwrap ( ) ;
119- match locks. entry ( lock_constr_location) {
120- hash_map:: Entry :: Occupied ( e) => return Arc :: clone ( e. get ( ) ) ,
113+ match locks. entry ( lock_constr_location. 0 ) {
114+ hash_map:: Entry :: Occupied ( e) => {
115+ assert_eq ! ( lock_constr_location. 1 ,
116+ get_construction_location( & e. get( ) . _lock_construction_bt) . 1 ,
117+ "Because Windows doesn't support column number results in backtraces, we cannot construct two mutexes on the same line or we risk lockorder detection false positives." ) ;
118+ return Arc :: clone ( e. get ( ) )
119+ } ,
121120 hash_map:: Entry :: Vacant ( e) => { e. insert ( Arc :: clone ( & res) ) ; } ,
122121 }
123122 }
@@ -138,7 +137,7 @@ impl LockMetadata {
138137 #[ cfg( feature = "backtrace" ) ]
139138 debug_assert ! ( _double_lock_self_allowed,
140139 "Tried to acquire a lock while it was held!\n Lock constructed at {}" ,
141- get_construction_location( & this. _lock_construction_bt) ) ;
140+ get_construction_location( & this. _lock_construction_bt) . 0 ) ;
142141 #[ cfg( not( feature = "backtrace" ) ) ]
143142 panic ! ( "Tried to acquire a lock while it was held!" ) ;
144143 }
@@ -148,8 +147,10 @@ impl LockMetadata {
148147 if * locked_dep_idx == this. lock_idx && * locked_dep_idx != locked. lock_idx {
149148 #[ cfg( feature = "backtrace" ) ]
150149 panic ! ( "Tried to violate existing lockorder.\n Mutex that should be locked after the current lock was created at the following backtrace.\n Note that to get a backtrace for the lockorder violation, you should set RUST_BACKTRACE=1\n Lock being taken constructed at: {} ({}):\n {:?}\n Lock constructed at: {} ({})\n {:?}\n \n Lock dep created at:\n {:?}\n \n " ,
151- get_construction_location( & this. _lock_construction_bt) , this. lock_idx, this. _lock_construction_bt,
152- get_construction_location( & locked. _lock_construction_bt) , locked. lock_idx, locked. _lock_construction_bt,
150+ get_construction_location( & this. _lock_construction_bt) . 0 ,
151+ this. lock_idx, this. _lock_construction_bt,
152+ get_construction_location( & locked. _lock_construction_bt) . 0 ,
153+ locked. lock_idx, locked. _lock_construction_bt,
153154 _locked_dep. _lockdep_trace) ;
154155 #[ cfg( not( feature = "backtrace" ) ) ]
155156 panic ! ( "Tried to violate existing lockorder. Build with the backtrace feature for more info." ) ;
0 commit comments