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,60 @@ 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( dead_code, reason = "field used to hold the lock until the end of the scope" ) ]
55+ pub struct LockGuard < ' a > ( std:: sync:: MutexGuard < ' a , ( ) > ) ;
56+
57+ pub fn lock ( ) -> LockGuard < ' static > {
58+ LockGuard ( GDB_REGISTRATION . lock ( ) . unwrap ( ) )
59+ }
60+ }
61+
62+ #[ cfg( not( feature = "std" ) ) ]
63+ mod gdb_registration {
64+ use core:: sync:: atomic:: { AtomicBool , Ordering } ;
65+
66+ /// In no_std mode, we use an atomic boolean to control access to the
67+ /// __jit_debug_descriptor. This is a simple lock mechanism.
68+ pub static GDB_REGISTRATION : AtomicBool = AtomicBool :: new ( false ) ;
69+
70+ /// The lock guard for the GDB registration lock.
71+ pub struct LockGuard ;
72+
73+ /// When the `LockGuard` is dropped, it releases the lock by setting
74+ /// `GDB_REGISTRATION` to false.
75+ impl Drop for LockGuard {
76+ fn drop ( & mut self ) {
77+ GDB_REGISTRATION . store ( false , Ordering :: Release ) ;
78+ }
79+ }
80+
81+ /// Locks the GDB registration lock. If the lock is already held, it panics
82+ pub fn lock ( ) -> LockGuard {
83+ // Try to acquire the lock. If already held, panic as per PR feedback.
84+ if GDB_REGISTRATION
85+ . compare_exchange ( false , true , Ordering :: Acquire , Ordering :: Relaxed )
86+ . is_err ( )
87+ {
88+ panic ! ( "GDB JIT registration lock contention detected in no_std mode" ) ;
89+ }
90+ LockGuard
91+ }
92+ }
4393
4494/// Registration for JIT image
4595pub struct GdbJitImageRegistration {
@@ -87,7 +137,7 @@ unsafe impl Sync for GdbJitImageRegistration {}
87137
88138unsafe fn register_gdb_jit_image ( entry : * mut JITCodeEntry ) {
89139 unsafe {
90- let _lock = GDB_REGISTRATION . lock ( ) . unwrap ( ) ;
140+ let _lock = gdb_registration :: lock ( ) ;
91141 let desc = & mut * wasmtime_jit_debug_descriptor ( ) ;
92142
93143 // Add it to the linked list in the JIT descriptor.
@@ -109,7 +159,7 @@ unsafe fn register_gdb_jit_image(entry: *mut JITCodeEntry) {
109159
110160unsafe fn unregister_gdb_jit_image ( entry : * mut JITCodeEntry ) {
111161 unsafe {
112- let _lock = GDB_REGISTRATION . lock ( ) . unwrap ( ) ;
162+ let _lock = gdb_registration :: lock ( ) ;
113163 let desc = & mut * wasmtime_jit_debug_descriptor ( ) ;
114164
115165 // Remove the code entry corresponding to the code from the linked list.
0 commit comments