In perl.git, the branch smoke-me/nicholas/PERL_GLOBAL_STRUCT_PRIVATE has been updated
<http://perl5.git.perl.org/perl.git/commitdiff/560cfab8402460c0893a24087a4da927069c45d6?hp=ec79994d178a58009af5b2b0b22e1d93a4787c7a> - Log ----------------------------------------------------------------- commit 560cfab8402460c0893a24087a4da927069c45d6 Author: Nicholas Clark <n...@ccl4.org> Date: Wed Jun 26 18:24:19 2013 +0200 For -DPERL_GLOBAL_STRUCT, eliminate local variable plvarsp in main(). M miniperlmain.c commit 39afa1df5516cca4796a1ffa1d34b53373978857 Author: Nicholas Clark <n...@ccl4.org> Date: Wed Jun 26 18:01:09 2013 +0200 Fix SEGVs and test failures for -DPERL_GLOBAL_STRUCT_PRIVATE With PERL_GLOBAL_STRUCT_PRIVATE "global" variables are in a structure in malloc()ed memory, not in global static variables or a global static structure. Hence no global variables are implicitly initialised to zero. * PL_curinterp and PL_op_sequence need initialising to NULL * The global structure is free()d before handlers registered with atexit() run, so be defensive about this. * Some C code checks SvOK(PL_sv_placeholder) so ensure that its SvFLAGS() are 0. * Zero PL_hash_seed M miniperlmain.c M perl.c M perlvars.h M util.c ----------------------------------------------------------------------- Summary of changes: miniperlmain.c | 13 +++++++++---- perl.c | 6 +++++- perlvars.h | 9 ++++++--- util.c | 4 ++++ 4 files changed, 24 insertions(+), 8 deletions(-) diff --git a/miniperlmain.c b/miniperlmain.c index 61358f7..7da543e 100644 --- a/miniperlmain.c +++ b/miniperlmain.c @@ -60,12 +60,11 @@ int main(int argc, char **argv, char **env) #endif { - dVAR; int exitstatus, i; #ifdef PERL_GLOBAL_STRUCT - struct perl_vars *plvarsp = init_global_struct(); + struct perl_vars *my_vars = init_global_struct(); # ifdef PERL_GLOBAL_STRUCT_PRIVATE - my_vars = my_plvarsp = plvarsp; + my_plvarsp = my_vars; # endif #endif /* PERL_GLOBAL_STRUCT */ #ifndef NO_ENV_ARRAY_IN_MAIN @@ -141,7 +140,13 @@ main(int argc, char **argv, char **env) PERL_SYS_TERM(); #ifdef PERL_GLOBAL_STRUCT - free_global_struct(plvarsp); + free_global_struct(my_vars); +# ifdef PERL_GLOBAL_STRUCT_PRIVATE + my_plvarsp = NULL; + /* Remember, functions registered with atexit() can run after this point, + and may access "global" variables, and hence end up calling + Perl_GetVarsPrivate() */ +#endif #endif /* PERL_GLOBAL_STRUCT */ exit(exitstatus); diff --git a/perl.c b/perl.c index 1f8bae5..8863868 100644 --- a/perl.c +++ b/perl.c @@ -1356,7 +1356,11 @@ __attribute__((destructor)) perl_fini(void) { dVAR; - if (PL_curinterp && !PL_veto_cleanup) + if ( +#ifdef PERL_GLOBAL_STRUCT_PRIVATE + my_vars && +#endif + PL_curinterp && !PL_veto_cleanup) FREE_THREAD_KEY; } diff --git a/perlvars.h b/perlvars.h index 96dfe04..eaf6712 100644 --- a/perlvars.h +++ b/perlvars.h @@ -32,7 +32,7 @@ all interpreters and all threads in a process. #if defined(USE_ITHREADS) PERLVAR(G, op_mutex, perl_mutex) /* Mutex for op refcounting */ #endif -PERLVAR(G, curinterp, PerlInterpreter *) +PERLVARI(G, curinterp, PerlInterpreter *, NULL) /* currently running interpreter * (initial parent interpreter under * useithreads) */ @@ -217,7 +217,7 @@ the Perl core) will normally return C<KEYWORD_PLUGIN_DECLINE>. PERLVARI(G, keyword_plugin, Perl_keyword_plugin_t, Perl_keyword_plugin_standard) -PERLVAR(G, op_sequence, HV *) /* dump.c */ +PERLVARI(G, op_sequence, HV *, NULL) /* dump.c */ PERLVARI(G, op_seq, UV, 0) /* dump.c */ #ifdef USE_ITHREADS @@ -225,7 +225,10 @@ PERLVAR(G, dollarzero_mutex, perl_mutex) /* Modifying $0 */ #endif /* Restricted hashes placeholder value. - * The contents are never used, only the address. */ + In theory, the contents are never used, only the address. + In practice, &PL_sv_placeholder is returned by some APIs, and the calling + code is checking SvOK(). */ + PERLVAR(G, sv_placeholder, SV) #if defined(MYMALLOC) && defined(USE_ITHREADS) diff --git a/util.c b/util.c index 11a7863..7f1bdbd 100644 --- a/util.c +++ b/util.c @@ -5451,6 +5451,10 @@ Perl_init_global_struct(pTHX) # ifdef PERL_SET_VARS PERL_SET_VARS(plvarsp); # endif +# ifdef PERL_GLOBAL_STRUCT_PRIVATE + plvarsp->Gsv_placeholder.sv_flags = 0; + memset(plvarsp->Ghash_seed, 0, sizeof(plvarsp->Ghash_seed)); +# endif # undef PERL_GLOBAL_STRUCT_INIT # endif return plvarsp; -- Perl5 Master Repository