In perl.git, the branch blead has been updated <http://perl5.git.perl.org/perl.git/commitdiff/79403e7734f5035577af0aa30b949ca081ec503c?hp=358c04b72260b75d5a00491f60fc675c4790fe11>
- Log ----------------------------------------------------------------- commit 79403e7734f5035577af0aa30b949ca081ec503c Author: Nicholas Clark <[email protected]> Date: Wed Jun 26 18:24:19 2013 +0200 For -DPERL_GLOBAL_STRUCT, eliminate local variable plvarsp in main(). M ext/ExtUtils-Miniperl/lib/ExtUtils/Miniperl.pm M lib/ExtUtils/t/Embed.t M miniperlmain.c commit 5c64bffd0d9c35e88b9ac48fc997977163abcc50 Author: Nicholas Clark <[email protected]> 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 ext/ExtUtils-Miniperl/lib/ExtUtils/Miniperl.pm M lib/ExtUtils/t/Embed.t M miniperlmain.c M perl.c M perlvars.h M util.c ----------------------------------------------------------------------- Summary of changes: ext/ExtUtils-Miniperl/lib/ExtUtils/Miniperl.pm | 13 +++++++++---- lib/ExtUtils/t/Embed.t | 13 +++++++++---- miniperlmain.c | 13 +++++++++---- perl.c | 6 +++++- perlvars.h | 9 ++++++--- util.c | 4 ++++ 6 files changed, 42 insertions(+), 16 deletions(-) diff --git a/ext/ExtUtils-Miniperl/lib/ExtUtils/Miniperl.pm b/ext/ExtUtils-Miniperl/lib/ExtUtils/Miniperl.pm index be9385b..730c565 100644 --- a/ext/ExtUtils-Miniperl/lib/ExtUtils/Miniperl.pm +++ b/ext/ExtUtils-Miniperl/lib/ExtUtils/Miniperl.pm @@ -95,12 +95,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 @@ -176,7 +175,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/lib/ExtUtils/t/Embed.t b/lib/ExtUtils/t/Embed.t index 7a83c98..fb9db91 100644 --- a/lib/ExtUtils/t/Embed.t +++ b/lib/ExtUtils/t/Embed.t @@ -169,10 +169,9 @@ int main(int argc, char **argv, char **env) { #endif PerlInterpreter *my_perl; #ifdef PERL_GLOBAL_STRUCT - dVAR; - 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 */ @@ -209,7 +208,13 @@ int 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 */ return 0; diff --git a/miniperlmain.c b/miniperlmain.c index 71b9424..a1ef2f1 100644 --- a/miniperlmain.c +++ b/miniperlmain.c @@ -66,12 +66,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 @@ -147,7 +146,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 7ebe990..ee36fd1 100644 --- a/perl.c +++ b/perl.c @@ -1380,7 +1380,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..aa724e8 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 ffd41b9..f09cd92 100644 --- a/util.c +++ b/util.c @@ -5456,6 +5456,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
