22//! the __jit_debug_register_code() and __jit_debug_descriptor to register
33//! or unregister generated object images with debuggers.
44
5- use std:: pin:: Pin ;
6- use std:: ptr;
7- use std:: sync:: Mutex ;
5+ #[ cfg( not( feature = "std" ) ) ]
6+ use alloc:: { boxed:: Box , vec:: Vec } ;
7+ #[ cfg( not( feature = "std" ) ) ]
8+ use core:: { pin:: Pin , ptr} ;
9+ #[ cfg( feature = "std" ) ]
10+ use std:: { boxed:: Box , pin:: Pin , ptr, vec:: Vec } ;
811use wasmtime_versioned_export_macros:: versioned_link;
912
1013#[ repr( C ) ]
@@ -33,13 +36,63 @@ unsafe extern "C" {
3336 fn __jit_debug_register_code ( ) ;
3437}
3538
36- /// The process controls access to the __jit_debug_descriptor by itself --
37- /// the GDB/LLDB accesses this structure and its data at the process startup
38- /// and when paused in __jit_debug_register_code.
39- ///
40- /// The GDB_REGISTRATION lock is needed for GdbJitImageRegistration to protect
41- /// access to the __jit_debug_descriptor within this process.
42- static GDB_REGISTRATION : Mutex < ( ) > = Mutex :: new ( ( ) ) ;
39+ #[ cfg( feature = "std" ) ]
40+ mod gdb_registration {
41+ use std:: sync:: Mutex ;
42+
43+ /// The process controls access to the __jit_debug_descriptor by itself --
44+ /// the GDB/LLDB accesses this structure and its data at the process startup
45+ /// and when paused in __jit_debug_register_code.
46+ ///
47+ /// The GDB_REGISTRATION lock is needed for GdbJitImageRegistration to protect
48+ /// access to the __jit_debug_descriptor within this process.
49+ pub static GDB_REGISTRATION : Mutex < ( ) > = Mutex :: new ( ( ) ) ;
50+
51+ /// The lock guard for the GDB registration lock.
52+ /// The field is not used directly, but it is needed to ensure that the lock
53+ /// is held until the `LockGuard` is dropped.
54+ #[ allow(
55+ dead_code,
56+ reason = "field used to hold the lock until the end of the scope"
57+ ) ]
58+ pub struct LockGuard < ' a > ( std:: sync:: MutexGuard < ' a , ( ) > ) ;
59+
60+ pub fn lock ( ) -> LockGuard < ' static > {
61+ LockGuard ( GDB_REGISTRATION . lock ( ) . unwrap ( ) )
62+ }
63+ }
64+
65+ #[ cfg( not( feature = "std" ) ) ]
66+ mod gdb_registration {
67+ use core:: sync:: atomic:: { AtomicBool , Ordering } ;
68+
69+ /// In no_std mode, we use an atomic boolean to control access to the
70+ /// __jit_debug_descriptor. This is a simple lock mechanism.
71+ pub static GDB_REGISTRATION : AtomicBool = AtomicBool :: new ( false ) ;
72+
73+ /// The lock guard for the GDB registration lock.
74+ pub struct LockGuard ;
75+
76+ /// When the `LockGuard` is dropped, it releases the lock by setting
77+ /// `GDB_REGISTRATION` to false.
78+ impl Drop for LockGuard {
79+ fn drop ( & mut self ) {
80+ GDB_REGISTRATION . store ( false , Ordering :: Release ) ;
81+ }
82+ }
83+
84+ /// Locks the GDB registration lock. If the lock is already held, it panics
85+ pub fn lock ( ) -> LockGuard {
86+ // Try to acquire the lock. If already held, panic as per PR feedback.
87+ if GDB_REGISTRATION
88+ . compare_exchange ( false , true , Ordering :: Acquire , Ordering :: Relaxed )
89+ . is_err ( )
90+ {
91+ panic ! ( "GDB JIT registration lock contention detected in no_std mode" ) ;
92+ }
93+ LockGuard
94+ }
95+ }
4396
4497/// Registration for JIT image
4598pub struct GdbJitImageRegistration {
@@ -87,7 +140,7 @@ unsafe impl Sync for GdbJitImageRegistration {}
87140
88141unsafe fn register_gdb_jit_image ( entry : * mut JITCodeEntry ) {
89142 unsafe {
90- let _lock = GDB_REGISTRATION . lock ( ) . unwrap ( ) ;
143+ let _lock = gdb_registration :: lock ( ) ;
91144 let desc = & mut * wasmtime_jit_debug_descriptor ( ) ;
92145
93146 // Add it to the linked list in the JIT descriptor.
@@ -109,7 +162,7 @@ unsafe fn register_gdb_jit_image(entry: *mut JITCodeEntry) {
109162
110163unsafe fn unregister_gdb_jit_image ( entry : * mut JITCodeEntry ) {
111164 unsafe {
112- let _lock = GDB_REGISTRATION . lock ( ) . unwrap ( ) ;
165+ let _lock = gdb_registration :: lock ( ) ;
113166 let desc = & mut * wasmtime_jit_debug_descriptor ( ) ;
114167
115168 // Remove the code entry corresponding to the code from the linked list.
0 commit comments