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