A test in op/threads.t roughly equivalent to this:
use threads;
sub f {};
async \&f;
was randomly failing smokes under the combination of PERL_GLOBAL_STRUCT and
ASan.
This is due to the fact that, under PERL_GLOBAL_STRUCT, "global" vars
are actually allocated, and are freed as the very last thing before
exiting (later than perl_destruct()). In the code above, the created
thread is still exeecuting at this point, and so may access those "global"
vars. ASan can detect that such a var is being accessed after being
freed; in this case due to PL_ppaddr being indexed in call_sv().
This is easily fixed using the PL_veto_cleanup mechanism; don't do those
final frees if there are still threads running.
void
Perl_free_global_struct(pTHX_ struct perl_vars *plvarsp)
{
+ int veto = plvarsp->Gveto_cleanup;
+
PERL_ARGS_ASSERT_FREE_GLOBAL_STRUCT;
# ifdef PERL_GLOBAL_STRUCT
# ifdef PERL_UNSET_VARS
PERL_UNSET_VARS(plvarsp);
# endif
+ if (veto)
+ return;
free(plvarsp->Gppaddr);
free(plvarsp->Gcheck);
# ifdef PERL_GLOBAL_STRUCT_PRIVATE