@@ -81,14 +81,39 @@ fd_spad_pop_debug( fd_spad_t * spad ) {
81
81
SELECT_DEBUG_IMPL (fd_spad_pop )( spad );
82
82
}
83
83
84
+ #if FD_SPAD_TAG_CHECK
85
+ static void
86
+ fd_spad_check_tag ( fd_spad_t * spad ,
87
+ ulong tag ) {
88
+
89
+ ulong * tag_mem_used = (ulong * )(spad + 1UL );
90
+ if ( FD_UNLIKELY ( tag_mem_used [ spad -> frame_free * spad -> tag_max + tag ] >
91
+ tag_mem_used [ FD_SPAD_FRAME_MAX * spad -> tag_max + tag ] ) ) {
92
+ FD_LOG_CRIT (( "tag %lu overflow %lu > %lu" ,
93
+ tag ,
94
+ tag_mem_used [ spad -> frame_free * spad -> tag_max + tag ],
95
+ tag_mem_used [ FD_SPAD_FRAME_MAX * spad -> tag_max + tag ] ));
96
+ }
97
+
98
+ }
99
+ #endif
100
+
84
101
void *
85
102
fd_spad_alloc_debug ( fd_spad_t * spad ,
86
103
ulong align ,
87
- ulong sz ) {
104
+ ulong sz ,
105
+ ulong tag ) {
88
106
if ( FD_UNLIKELY ( !fd_spad_frame_used ( spad ) ) ) FD_LOG_CRIT (( "not in a frame" ));
89
- if ( FD_UNLIKELY ( (!!align ) & (!fd_ulong_is_pow2 ( align ) ) ) ) FD_LOG_CRIT (( "bad align" ));
90
- if ( FD_UNLIKELY ( fd_spad_alloc_max ( spad , align )< sz ) ) FD_LOG_CRIT (( "bad sz" ));
91
- return SELECT_DEBUG_IMPL (fd_spad_alloc )( spad , align , sz );
107
+ if ( FD_UNLIKELY ( (!!align ) & (!fd_ulong_is_pow2 ( align ) ) ) ) FD_LOG_CRIT (( "bad align %lu" , align ));
108
+ if ( FD_UNLIKELY ( fd_spad_alloc_max ( spad , align )< sz ) ) FD_LOG_CRIT (( "bad sz %lu align %lu max %lu alloc_max %lu" , sz , align , fd_spad_mem_max ( spad ), fd_spad_alloc_max ( spad , align ) ));
109
+ #if FD_SPAD_TAG_CHECK
110
+ if ( FD_UNLIKELY ( fd_spad_tag_max ( spad )<=tag ) ) FD_LOG_CRIT (( "bad tag %lu tag_max %lu" , tag , fd_spad_tag_max ( spad ) ));
111
+ #endif
112
+ void * rv = SELECT_DEBUG_IMPL (fd_spad_alloc )( spad , align , sz , tag );
113
+ #if FD_SPAD_TAG_CHECK
114
+ fd_spad_check_tag ( spad , tag );
115
+ #endif
116
+ return rv ;
92
117
}
93
118
94
119
void
@@ -103,11 +128,19 @@ fd_spad_trim_debug( fd_spad_t * spad,
103
128
void *
104
129
fd_spad_prepare_debug ( fd_spad_t * spad ,
105
130
ulong align ,
106
- ulong max ) {
131
+ ulong max ,
132
+ ulong tag ) {
107
133
if ( FD_UNLIKELY ( !fd_spad_frame_used ( spad ) ) ) FD_LOG_CRIT (( "not in a frame" ));
108
- if ( FD_UNLIKELY ( (!!align ) & (!fd_ulong_is_pow2 ( align ) ) ) ) FD_LOG_CRIT (( "bad align" ));
109
- if ( FD_UNLIKELY ( fd_spad_alloc_max ( spad , align )< max ) ) FD_LOG_CRIT (( "bad max of %lu" , max ));
110
- return SELECT_DEBUG_IMPL (fd_spad_prepare )( spad , align , max );
134
+ if ( FD_UNLIKELY ( (!!align ) & (!fd_ulong_is_pow2 ( align ) ) ) ) FD_LOG_CRIT (( "bad align %lu" , align ));
135
+ if ( FD_UNLIKELY ( fd_spad_alloc_max ( spad , align )< max ) ) FD_LOG_CRIT (( "bad max %lu align %lu max %lu alloc_max %lu" , max , align , fd_spad_mem_max ( spad ), fd_spad_alloc_max ( spad , align ) ));
136
+ #if FD_SPAD_TAG_CHECK
137
+ if ( FD_UNLIKELY ( fd_spad_tag_max ( spad )<=tag ) ) FD_LOG_CRIT (( "bad tag %lu tag_max %lu" , tag , fd_spad_tag_max ( spad ) ));
138
+ #endif
139
+ void * rv = SELECT_DEBUG_IMPL (fd_spad_prepare )( spad , align , max , tag );
140
+ #if FD_SPAD_TAG_CHECK
141
+ fd_spad_check_tag ( spad , tag );
142
+ #endif
143
+ return rv ;
111
144
}
112
145
113
146
void
@@ -126,6 +159,10 @@ fd_spad_publish_debug( fd_spad_t * spad,
126
159
/* FIXME: check if in prepare? needs extra state and a lot of extra
127
160
tracking that state */
128
161
SELECT_DEBUG_IMPL (fd_spad_publish )( spad , sz );
162
+
163
+ #if FD_SPAD_TAG_CHECK
164
+ fd_spad_check_tag ( spad , spad -> inprep_tag );
165
+ #endif
129
166
}
130
167
131
168
#undef SELECT_DEBUG_IMPL
@@ -199,15 +236,16 @@ fd_spad_pop_sanitizer_impl( fd_spad_t * spad ) {
199
236
void *
200
237
fd_spad_alloc_sanitizer_impl ( fd_spad_t * spad ,
201
238
ulong align ,
202
- ulong sz ) {
239
+ ulong sz ,
240
+ ulong tag ) {
203
241
/* enforce a minimum alignment of FD_ASAN_ALIGN or FD_MSAN_ALIGN when running ASAN or MSAN respectively */
204
242
#if FD_HAS_DEEPASAN
205
243
align = fd_ulong_if ( align > 0UL , fd_ulong_max ( align , FD_ASAN_ALIGN ), FD_SPAD_ALLOC_ALIGN_DEFAULT ); /* typically compile time */
206
244
#elif FD_HAS_MSAN
207
245
align = fd_ulong_if ( align > 0UL , fd_ulong_max ( align , FD_MSAN_ALIGN ), FD_SPAD_ALLOC_ALIGN_DEFAULT ); /* typically compile time */
208
246
#endif
209
247
210
- void * buf = fd_spad_alloc_impl ( spad , align , sz );
248
+ void * buf = fd_spad_alloc_impl ( spad , align , sz , tag );
211
249
212
250
/* first poison from buf to mem_max to cancel any in-progress prepare.
213
251
buf is guaranteed to be an 8-byte aligned adddress */
@@ -253,15 +291,16 @@ fd_spad_trim_sanitizer_impl( fd_spad_t * spad,
253
291
void *
254
292
fd_spad_prepare_sanitizer_impl ( fd_spad_t * spad ,
255
293
ulong align ,
256
- ulong max ) {
294
+ ulong max ,
295
+ ulong tag ) {
257
296
/* enforce a minimum alignment of FD_ASAN_ALIGN or FD_MSAN_ALIGN when running ASAN or MSAN respectively */
258
297
#if FD_HAS_DEEPASAN
259
298
align = fd_ulong_if ( align > 0UL , fd_ulong_max ( align , FD_ASAN_ALIGN ), FD_SPAD_ALLOC_ALIGN_DEFAULT ); /* typically compile time */
260
299
#elif FD_HAS_MSAN
261
300
align = fd_ulong_if ( align > 0UL , fd_ulong_max ( align , FD_MSAN_ALIGN ), FD_SPAD_ALLOC_ALIGN_DEFAULT ); /* typically compile time */
262
301
#endif
263
302
264
- void * buf = fd_spad_prepare_impl ( spad , align , max );
303
+ void * buf = fd_spad_prepare_impl ( spad , align , max , tag );
265
304
266
305
/* unpoison memory starting at buf, which is guaranteed to be 8 byte aligned */
267
306
fd_asan_unpoison ( buf , spad -> mem_max - spad -> mem_used );
0 commit comments