Skip to content

Commit 80dd2cf

Browse files
riptlripatel-fd
authored andcommitted
Add map_chain_para MAP_PEDANTIC feature
Core dump on record map corruption instead of gracefully exiting.
1 parent 0ac9e25 commit 80dd2cf

File tree

3 files changed

+107
-10
lines changed

3 files changed

+107
-10
lines changed

src/funk/fd_funk_rec.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#define MAP_NEXT map_next
2222
#define MAP_MAGIC (0xf173da2ce77ecdb0UL) /* Firedancer rec db version 0 */
2323
#define MAP_IMPL_STYLE 2
24+
#define MAP_PEDANTIC 1
2425
#include "../util/tmpl/fd_map_chain_para.c"
2526

2627
static fd_funk_txn_t *

src/funk/fd_funk_rec.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ FD_STATIC_ASSERT( sizeof(fd_funk_rec_t) == 3U*FD_FUNK_REC_ALIGN, record size is
7979
#define MAP_NEXT map_next
8080
#define MAP_MAGIC (0xf173da2ce77ecdb0UL) /* Firedancer rec db version 0 */
8181
#define MAP_IMPL_STYLE 1
82+
#define MAP_PEDANTIC 1
8283
#include "../util/tmpl/fd_map_chain_para.c"
8384

8485
typedef fd_funk_rec_map_query_t fd_funk_rec_query_t;

src/util/tmpl/fd_map_chain_para.c

Lines changed: 105 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1195,6 +1195,13 @@
11951195
#define MAP_IMPL_STYLE 0
11961196
#endif
11971197

1198+
/* If MAP_PEDANTIC is defined to non-zero, aborts with FD_LOG_CRIT
1199+
instead of gracefully returning if corruption is found. */
1200+
1201+
#ifndef MAP_PEDANTIC
1202+
#define MAP_PEDANTIC 0
1203+
#endif
1204+
11981205
/* Implementation *****************************************************/
11991206

12001207
#define MAP_VER_WIDTH (64-MAP_CNT_WIDTH)
@@ -1960,16 +1967,25 @@ MAP_(remove)( MAP_(t) * join,
19601967
query->ver_cnt = ver_cnt;
19611968

19621969
if( FD_UNLIKELY( ele_cnt>ele_max ) ) { /* optimize for not corrupt */
1970+
# if MAP_PEDANTIC
1971+
FD_LOG_NOTICE(( "Corrupt map chain %p (memo %016lx): ele_cnt=%lu > ele_max=%lu", (void *)chain, memo, ele_cnt, ele_max ));
1972+
# else
19631973
err = FD_MAP_ERR_CORRUPT;
19641974
goto done;
1975+
# endif /* MAP_PEDANTIC */
19651976
}
19661977

19671978
MAP_IDX_T * cur = &chain->head_cidx;
19681979
for( ulong ele_rem=ele_cnt; ele_rem; ele_rem-- ) { /* guarantee bounded exec under corruption */
19691980
ulong ele_idx = MAP_(private_idx)( *cur );
19701981
if( FD_UNLIKELY( ele_idx>=ele_max ) ) { /* optimize for not corrupt */
1982+
# if MAP_PEDANTIC
1983+
FD_LOG_CRIT(( "Corrupt MAP_NEXT pointer at node %p (memo %016lx, ele_rem=%lu, ele_cnt=%lu): map_next=%lu >= ele_max=%lu",
1984+
(void *)cur, memo, ele_rem, ele_cnt, ele_idx, ele_max ));
1985+
# else
19711986
err = FD_MAP_ERR_CORRUPT;
19721987
goto done;
1988+
# endif /* MAP_PEDANTIC */
19731989
}
19741990

19751991
if(
@@ -1992,8 +2008,13 @@ MAP_(remove)( MAP_(t) * join,
19922008

19932009
ulong ele_idx = MAP_(private_idx)( *cur );
19942010
if( FD_UNLIKELY( !MAP_(private_idx_is_null( ele_idx ) ) ) ) { /* optimize for not corrupt */
2011+
# if MAP_PEDANTIC
2012+
FD_LOG_CRIT(( "Corrupt map chain %p (memo %016lx, ele_cnt=%lu): Found element past chain: ele_idx=%lu",
2013+
(void *)chain, memo, ele_cnt, ele_idx ));
2014+
# else
19952015
err = FD_MAP_ERR_CORRUPT;
19962016
goto done;
2017+
# endif /* MAP_PEDANTIC */
19972018
}
19982019

19992020
err = FD_MAP_ERR_KEY;
@@ -2042,16 +2063,25 @@ MAP_(modify_try)( MAP_(t) * join,
20422063

20432064
ulong ele_cnt = MAP_(private_vcnt_cnt)( ver_cnt );
20442065
if( FD_UNLIKELY( ele_cnt>ele_max ) ) { /* optimize for not corrupt */
2066+
# if MAP_PEDANTIC
2067+
FD_LOG_NOTICE(( "Corrupt map chain %p (memo %016lx): ele_cnt=%lu > ele_max=%lu", (void *)chain, memo, ele_cnt, ele_max ));
2068+
# else
20452069
err = FD_MAP_ERR_CORRUPT;
20462070
goto done;
2071+
# endif /* MAP_PEDANTIC */
20472072
}
20482073

20492074
MAP_IDX_T * cur = &chain->head_cidx;
20502075
for( ulong ele_rem=ele_cnt; ele_rem; ele_rem-- ) { /* guarantee bounded exec under corruption */
20512076
ulong ele_idx = MAP_(private_idx)( *cur );
20522077
if( FD_UNLIKELY( ele_idx>=ele_max ) ) { /* optimize for not corrupt */
2078+
# if MAP_PEDANTIC
2079+
FD_LOG_CRIT(( "Corrupt MAP_NEXT pointer at node %p (memo %016lx, ele_rem=%lu, ele_cnt=%lu): map_next=%lu >= ele_max=%lu",
2080+
(void *)cur, memo, ele_rem, ele_cnt, ele_idx, ele_max ));
2081+
# else
20532082
err = FD_MAP_ERR_CORRUPT;
20542083
goto done;
2084+
# endif /* MAP_PEDANTIC */
20552085
}
20562086

20572087
if(
@@ -2075,8 +2105,13 @@ MAP_(modify_try)( MAP_(t) * join,
20752105

20762106
ulong ele_idx = MAP_(private_idx)( *cur );
20772107
if( FD_UNLIKELY( !MAP_(private_idx_is_null( ele_idx ) ) ) ) { /* optimize for not corrupt */
2108+
# if MAP_PEDANTIC
2109+
FD_LOG_CRIT(( "Corrupt map chain %p (memo %016lx, ele_cnt=%lu): Found element past chain: ele_idx=%lu",
2110+
(void *)chain, memo, ele_cnt, ele_idx ));
2111+
# else
20782112
err = FD_MAP_ERR_CORRUPT;
20792113
goto done;
2114+
# endif /* MAP_PEDANTIC */
20802115
}
20812116

20822117
err = FD_MAP_ERR_KEY;
@@ -2133,7 +2168,13 @@ MAP_(query_try)( MAP_(t) const * join,
21332168
query->ver_cnt = then;
21342169

21352170
if( FD_UNLIKELY( (now!=then) | (!!(then & (1UL<<MAP_CNT_WIDTH))) ) ) return FD_MAP_ERR_AGAIN;
2136-
if( FD_UNLIKELY( ele_cnt>ele_max ) ) return FD_MAP_ERR_CORRUPT;
2171+
if( FD_UNLIKELY( ele_cnt>ele_max ) ) {
2172+
# if MAP_PEDANTIC
2173+
FD_LOG_NOTICE(( "Corrupt map chain %p (memo %016lx): ele_cnt=%lu > ele_max=%lu", (void *)chain, memo, ele_cnt, ele_max ));
2174+
# else
2175+
return FD_MAP_ERR_CORRUPT;
2176+
# endif /* MAP_PEDANTIC */
2177+
}
21372178

21382179
/* Search the chain for key. Since we know the numer of elements on
21392180
the chain, we can bound this search to avoid corruption causing out
@@ -2171,7 +2212,14 @@ MAP_(query_try)( MAP_(t) const * join,
21712212
FD_COMPILER_MFENCE();
21722213

21732214
if( FD_UNLIKELY( now!=then ) ) return FD_MAP_ERR_AGAIN;
2174-
if( FD_UNLIKELY( corrupt ) ) return FD_MAP_ERR_CORRUPT;
2215+
if( FD_UNLIKELY( corrupt ) ) {
2216+
# if MAP_PEDANTIC
2217+
FD_LOG_CRIT(( "Corrupt MAP_NEXT pointer at node %p (memo %016lx, ele_rem=%lu, ele_cnt=%lu): map_next=%lu >= ele_max=%lu",
2218+
(void *)cur, memo, ele_rem, ele_cnt, ele_idx, ele_max ));
2219+
# else
2220+
return FD_MAP_ERR_CORRUPT;
2221+
# endif /* MAP_PEDANTIC */
2222+
}
21752223

21762224
if( FD_LIKELY( found ) ) { /* Optimize for found */
21772225
query->ele = (MAP_ELE_T *)&ele[ ele_idx ];
@@ -2196,7 +2244,14 @@ MAP_(query_try)( MAP_(t) const * join,
21962244
FD_COMPILER_MFENCE();
21972245

21982246
if( FD_UNLIKELY( now!=then ) ) return FD_MAP_ERR_AGAIN;
2199-
if( FD_UNLIKELY( !MAP_(private_idx_is_null( ele_idx ) ) ) ) return FD_MAP_ERR_CORRUPT;
2247+
if( FD_UNLIKELY( !MAP_(private_idx_is_null( ele_idx ) ) ) ) {
2248+
# if MAP_PEDANTIC
2249+
FD_LOG_CRIT(( "Corrupt map chain %p (memo %016lx, ele_cnt=%lu): Found element past chain: ele_idx=%lu",
2250+
(void *)chain, memo, ele_cnt, ele_idx ));
2251+
# else
2252+
return FD_MAP_ERR_CORRUPT;
2253+
# endif /* MAP_PEDANTIC */
2254+
}
22002255

22012256
return FD_MAP_ERR_KEY;
22022257
}
@@ -2470,12 +2525,25 @@ MAP_(txn_remove)( MAP_(t) * join,
24702525
query->chain = chain;
24712526
query->ver_cnt = ver_cnt;
24722527

2473-
if( FD_UNLIKELY( ele_cnt>ele_max ) ) return FD_MAP_ERR_CORRUPT; /* optimize for not corrupt */
2528+
if( FD_UNLIKELY( ele_cnt>ele_max ) ) { /* optimize for not corrupt */
2529+
# if MAP_PEDANTIC
2530+
FD_LOG_NOTICE(( "Corrupt map chain %p (memo %016lx): ele_cnt=%lu > ele_max=%lu", (void *)chain, memo, ele_cnt, ele_max ));
2531+
# else
2532+
return FD_MAP_ERR_CORRUPT;
2533+
# endif /* MAP_PEDANTIC */
2534+
}
24742535

24752536
MAP_IDX_T * cur = &chain->head_cidx;
24762537
for( ulong ele_rem=ele_cnt; ele_rem; ele_rem-- ) { /* guarantee bounded exec under corruption */
24772538
ulong ele_idx = MAP_(private_idx)( *cur );
2478-
if( FD_UNLIKELY( ele_idx>=ele_max ) ) return FD_MAP_ERR_CORRUPT; /* optimize for not corrupt */
2539+
if( FD_UNLIKELY( ele_idx>=ele_max ) ) { /* optimize for not corrupt */
2540+
# if MAP_PEDANTIC
2541+
FD_LOG_CRIT(( "Corrupt MAP_NEXT pointer at node %p (memo %016lx, ele_rem=%lu, ele_cnt=%lu): map_next=%lu >= ele_max=%lu",
2542+
(void *)cur, memo, ele_rem, ele_cnt, ele_idx, ele_max ));
2543+
# else
2544+
return FD_MAP_ERR_CORRUPT;
2545+
# endif /* MAP_PEDANTIC */
2546+
}
24792547

24802548
if(
24812549
# if MAP_MEMOIZE && MAP_KEY_EQ_IS_SLOW
@@ -2492,7 +2560,14 @@ MAP_(txn_remove)( MAP_(t) * join,
24922560
}
24932561

24942562
ulong ele_idx = MAP_(private_idx)( *cur );
2495-
if( FD_UNLIKELY( !MAP_(private_idx_is_null( ele_idx ) ) ) ) return FD_MAP_ERR_CORRUPT; /* optimize for not found */
2563+
if( FD_UNLIKELY( !MAP_(private_idx_is_null( ele_idx ) ) ) ) { /* optimize for not found */
2564+
# if MAP_PEDANTIC
2565+
FD_LOG_CRIT(( "Corrupt map chain %p (memo %016lx, ele_cnt=%lu): Found element past chain: ele_idx=%lu",
2566+
(void *)chain, memo, ele_cnt, ele_idx ));
2567+
# else
2568+
return FD_MAP_ERR_CORRUPT;
2569+
# endif /* MAP_PEDANTIC */
2570+
}
24962571
return FD_MAP_ERR_KEY;
24972572
}
24982573

@@ -2522,13 +2597,26 @@ MAP_(txn_modify)( MAP_(t) * join,
25222597
query->chain = chain;
25232598
query->ver_cnt = ver_cnt;
25242599

2525-
if( FD_UNLIKELY( ele_cnt>ele_max ) ) return FD_MAP_ERR_CORRUPT; /* optimize for not corrupt */
2600+
if( FD_UNLIKELY( ele_cnt>ele_max ) ) { /* optimize for not corrupt */
2601+
# if MAP_PEDANTIC
2602+
FD_LOG_NOTICE(( "Corrupt map chain %p (memo %016lx): ele_cnt=%lu > ele_max=%lu", (void *)chain, memo, ele_cnt, ele_max ));
2603+
# else
2604+
return FD_MAP_ERR_CORRUPT;
2605+
# endif /* MAP_PEDANTIC */
2606+
}
25262607

25272608
MAP_IDX_T * cur = &chain->head_cidx;
25282609
for( ulong ele_rem=ele_cnt; ele_rem; ele_rem-- ) {
25292610
ulong ele_idx = MAP_(private_idx)( *cur );
25302611

2531-
if( FD_UNLIKELY( ele_idx>=ele_max ) ) return FD_MAP_ERR_CORRUPT; /* optimize for not corrupt */
2612+
if( FD_UNLIKELY( ele_idx>=ele_max ) ) { /* optimize for not corrupt */
2613+
# if MAP_PEDANTIC
2614+
FD_LOG_CRIT(( "Corrupt MAP_NEXT pointer at node %p (memo %016lx, ele_rem=%lu, ele_cnt=%lu): map_next=%lu >= ele_max=%lu",
2615+
(void *)cur, memo, ele_rem, ele_cnt, ele_idx, ele_max ));
2616+
# else
2617+
return FD_MAP_ERR_CORRUPT;
2618+
# endif /* MAP_PEDANTIC */
2619+
}
25322620

25332621
if(
25342622
# if MAP_MEMOIZE && MAP_KEY_EQ_IS_SLOW
@@ -2548,7 +2636,14 @@ MAP_(txn_modify)( MAP_(t) * join,
25482636
}
25492637

25502638
ulong ele_idx = MAP_(private_idx)( *cur );
2551-
if( FD_UNLIKELY( !MAP_(private_idx_is_null( ele_idx ) ) ) ) return FD_MAP_ERR_CORRUPT; /* optimize for not corrupt */
2639+
if( FD_UNLIKELY( !MAP_(private_idx_is_null( ele_idx ) ) ) ) { /* optimize for not corrupt */
2640+
# if MAP_PEDANTIC
2641+
FD_LOG_CRIT(( "Corrupt map chain %p (memo %016lx, ele_cnt=%lu): Found element past chain: ele_idx=%lu",
2642+
(void *)chain, memo, ele_cnt, ele_idx ));
2643+
# else
2644+
return FD_MAP_ERR_CORRUPT;
2645+
# endif /* MAP_PEDANTIC */
2646+
}
25522647

25532648
return FD_MAP_ERR_KEY;
25542649
}
@@ -2811,7 +2906,7 @@ MAP_(strerror)( int err ) {
28112906
#undef MAP_
28122907
#undef MAP_STATIC
28132908
#undef MAP_VER_WIDTH
2814-
2909+
#undef MAP_PEDANTIC
28152910
#undef MAP_IMPL_STYLE
28162911
#undef MAP_MAGIC
28172912
#undef MAP_ALIGN

0 commit comments

Comments
 (0)