Perl / perl5

🐪 The Perl programming language
https://dev.perl.org/perl5/
Other
1.9k stars 540 forks source link

[Win32] Unable to build 64-bit blead using gcc-4.8.2 #14556

Closed p5pRT closed 9 years ago

p5pRT commented 9 years ago

Migrated from rt.perl.org#123976 (status was 'resolved')

Searchable as RT123976$

p5pRT commented 9 years ago

From @sisyphus

Hi\,

This is a bug report following on from the p5p thread http​://www.nntp.perl.org/group/perl.perl5.porters/2014/12/msg223791.html

AFAIK\, no bug report was filed for this\, but the issue is still unresolved. (As Tony Cook pointed out in that thread\, there's no such problem if we use gcc-4.7.3.)

To re-iterate\, early on in the 'dmake' stage we get​:

..\miniperl.exe -I..\lib -f ..\write_buildcustomize.pl .. Attempt to free unreferenced scalar​: SV 0x6cb218 at ..\lib/strict.pm line 38. dmake​: Warning​: -- Found file corresponding to virtual target [..\uudmap.h]. dmake​: Error code 244\, while making '..\lib\buildcustomize.pl'

Cheers\, Rob

p5pRT commented 9 years ago

From @tonycoz

On Tue Mar 03 18​:22​:30 2015\, sisyphus wrote​:

Hi\,

This is a bug report following on from the p5p thread http​://www.nntp.perl.org/group/perl.perl5.porters/2014/12/msg223791.html

Attached is a dump with the breakpoint in the correct place.

Tony

p5pRT commented 9 years ago

From @tonycoz

(gdb) dir .. Source directories searched​: j​:\dev\perl\git\perl\win32/..;$cdir;$cwd (gdb) list gv.c​:2285\,+6 2285 else gv = *gvp\, addmg = 0; 2286 if (full_len == 8 && strEQ(nambeg\, "all_bits")) { 2287 Perl_warn(aTHX_ "Perl_gv_fetchpvn_flags()​: $​::{all_bits} = \n"); 2288 sv_dump((SV*)gv); 2289 } 2290 /* From this point on\, addmg means gv has not been inserted in the 2291 symtab yet. */ (gdb) b gv.c​:2287 Breakpoint 1 at 0x429d13​: file ..\gv.c\, line 2287. (gdb) r -I..\lib -f ../write_buildcustomize.pl .. Starting program​: j​:\dev\perl\git\perl\miniperl.exe -I..\lib -f ../write_buildcustomize.pl .. [New Thread 5860.0x1be8]

Breakpoint 1\, Perl_gv_fetchpvn_flags (nambeg=\\, full_len=8\,   flags=2\, sv_type=SVt_PVGV) at ..\gv.c​:2287 2287 Perl_warn(aTHX_ "Perl_gv_fetchpvn_flags()​: $​::{all_bits} = \n"); (gdb) c Continuing. Perl_gv_fetchpvn_flags()​: $​::{all_bits} = SV = NULL(0x0) at 0x278eed0   REFCNT = 1   FLAGS = () Perl_gv_init_pvn()​: pre-upgrade GV= SV = NULL(0x0) at 0x278eed0   REFCNT = 1   FLAGS = () Perl_gv_init_pvn()​: post-upgrade GV= SV = PVGV(0x2784070) at 0x278eed0   REFCNT = 1   FLAGS = ()   IV = 0   NV = 0   PV = 0 Perl_gv_init_pvn()​: prior to assert\, GV = SV = PVGV(0x2784070) at 0x278eed0   REFCNT = 1   FLAGS = ()   IV = 0   NV = 0   PV = 0

Breakpoint 1\, Perl_gv_fetchpvn_flags (nambeg=\\, full_len=8\,   flags=0\, sv_type=sv_type@​entry=SVt_PVGV) at ..\gv.c​:2287 2287 Perl_warn(aTHX_ "Perl_gv_fetchpvn_flags()​: $​::{all_bits} = \n"); (gdb) fin Run till exit from #0 Perl_gv_fetchpvn_flags (nambeg=\\,   full_len=8\, flags=0\, sv_type=sv_type@​entry=SVt_PVGV) at ..\gv.c​:2287 Perl_gv_fetchpvn_flags()​: $​::{all_bits} = SV = PVGV(0x2784070) at 0x278eed0   REFCNT = 1   FLAGS = (MULTI)   NAME = "all_bits"   NAMELEN = 8   GvSTASH = 0x278e9a8 "strict"   FLAGS = 0x2   GP = 0x27a33f0   SV = 0x0   REFCNT = 1   IO = 0x0   FORM = 0x0
  AV = 0x0   HV = 0x0   CV = 0x0   CVGEN = 0x0   GPFLAGS = 0x0 ()   LINE = 31   FILE = "..\lib/strict.pm"   EGV = 0x278eed0 "all_bits" Perl_gv_fetchsv (name=name@​entry=0x278eeb8\, flags=0\, sv_type=SVt_PVGV)   at ..\gv.c​:1538 1538 } Value returned is $1 = (GV *) 0x278eed0 (gdb) fin Run till exit from #0 Perl_gv_fetchsv (name=name@​entry=0x278eeb8\, flags=0\,   sv_type=SVt_PVGV) at ..\gv.c​:1538 Perl_ck_rvconst (o=0x27a0ef8) at op.c​:9831 9831 if (gv) { Value returned is $2 = (GV *) 0x278eed0 (gdb) n 9817 gv = gv_fetchsv(kidsv\, (gdb) 9831 if (gv) { (gdb) 9832 if (!isGV(gv)) { (gdb) 9839 OpTYPE_set(kid\, OP_GV); (gdb) 9840 SvREFCNT_dec(kid->op_sv); (gdb) 9839 OpTYPE_set(kid\, OP_GV); (gdb) 9840 SvREFCNT_dec(kid->op_sv); (gdb) 9839 OpTYPE_set(kid\, OP_GV); (gdb) 9840 SvREFCNT_dec(kid->op_sv); (gdb) 9848 kid->op_sv = SvREFCNT_inc_simple_NN(gv); (gdb) 9850 kid->op_private = 0; (gdb) 9856 } (gdb) call Perl_sv_dump((SV*)0x278eed0) SV = PVGV(0x2784070) at 0x278eed0   REFCNT = 2   FLAGS = (MULTI)   NAME = "all_bits"   NAMELEN = 8   GvSTASH = 0x278e9a8 "strict"   FLAGS = 0x2   GP = 0x27a33f0   SV = 0x0   REFCNT = 1   IO = 0x0   FORM = 0x0
  AV = 0x0   HV = 0x0   CV = 0x0   CVGEN = 0x0   GPFLAGS = 0x0 ()   LINE = 31   FILE = "..\lib/strict.pm"   EGV = 0x278eed0 "all_bits" (gdb) n 9848 kid->op_sv = SvREFCNT_inc_simple_NN(gv); (gdb) 9852 SvFAKE_off(gv); (gdb) 9856 } (gdb) Perl_newUNOP (type=type@​entry=14\, flags=\\, flags@​entry=16\,   first=0x27a0f38) at op.c​:4816 4816 if (unop->op_next) (gdb) 4815 unop = (UNOP*) CHECKOP(type\, unop); (gdb) p unop $3 = \ (gdb) n 4816 if (unop->op_next) (gdb) 4819 return fold_constants(op_integerize(op_std_init((OP *) unop))); (gdb) c Continuing. Attempt to free unreferenced scalar​: SV 0x269268 at ..\lib/strict.pm line 38.

Breakpoint 1\, Perl_gv_fetchpvn_flags (nambeg=\\, full_len=8\,   flags=64\, sv_type=sv_type@​entry=SVt_PVCV) at ..\gv.c​:2287 2287 Perl_warn(aTHX_ "Perl_gv_fetchpvn_flags()​: $​::{all_bits} = \n"); (gdb) n Perl_gv_fetchpvn_flags()​: $​::{all_bits} = 2288 sv_dump((SV*)gv); (gdb) SV = PVAV(0x26b298) at 0x278eed0   REFCNT = 1   FLAGS = ()   ARRAY = 0x0   FILL = -1   MAX = -1   ARYLEN = 0x0   FLAGS = (REAL) 2293 if (SvTYPE(gv) == SVt_PVGV) { (gdb) q A debugging session is active.

  Inferior 1 [process 5860] will be killed.

Quit anyway? (y or n) [answered Y; input not from terminal]

p5pRT commented 9 years ago

The RT System itself - Status changed from 'new' to 'open'

p5pRT commented 9 years ago

From @tonycoz

On Tue Mar 31 17​:56​:12 2015\, tonyc wrote​:

On Tue Mar 03 18​:22​:30 2015\, sisyphus wrote​:

Hi\,

This is a bug report following on from the p5p thread http​://www.nntp.perl.org/group/perl.perl5.porters/2014/12/msg223791.html

Attached is a dump with the breakpoint in the correct place.

Here's a simpler reproducer​:

BEGIN {   my $bits = 0;   *foo = sub () { $bits }; } foo();

Produces​:

Attempt to free unreferenced scalar​: SV 0x346ec0.

*without* the call to foo().

Tony

p5pRT commented 9 years ago

From @tonycoz

On Tue Mar 31 19​:08​:05 2015\, tonyc wrote​:

On Tue Mar 31 17​:56​:12 2015\, tonyc wrote​:

On Tue Mar 03 18​:22​:30 2015\, sisyphus wrote​:

Hi\,

This is a bug report following on from the p5p thread http​://www.nntp.perl.org/group/perl.perl5.porters/2014/12/msg223791.html

Attached is a dump with the breakpoint in the correct place.

Here's a simpler reproducer​:

BEGIN { my $bits = 0; *foo = sub () { $bits }; } foo();

You don't need the variable\, so just​:

BEGIN {   *foo = sub () { 0 }; } foo();

will produce the "Attempt to free unreferenced scalar" and the assertion failure.

Tony

p5pRT commented 9 years ago

From @tonycoz

On Tue Mar 03 18​:22​:30 2015\, sisyphus wrote​:

Hi\,

This is a bug report following on from the p5p thread http​://www.nntp.perl.org/group/perl.perl5.porters/2014/12/msg223791.html

The attached seems to fix the problem for me\, though I'm not sure if it's fixing a real problem or just beating a possible bug in gcc's optimizer.

Tony

p5pRT commented 9 years ago

From @tonycoz

0001-prevent-any-other-code-from-freeing-the-op-s-gv-whil.patch ```diff From 5078dd92544f00fa245a5272bc399e690d5711a6 Mon Sep 17 00:00:00 2001 From: Tony Cook Date: Wed, 1 Apr 2015 16:36:51 +1100 Subject: [PATCH 1/2] prevent any other code from freeing the op's gv while we do assuming I understand why this is breaking, which is unlikely --- op.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/op.c b/op.c index ad0b0b0..efacd31 100644 --- a/op.c +++ b/op.c @@ -824,17 +824,22 @@ void S_op_clear_gv(pTHX_ OP *o, SV**svp) so any *valid* code that happens to do this during global destruction might well trigger premature cleanup. */ bool still_valid = gv && SvREFCNT(gv); +#ifdef USE_ITHREADS + PADOFFSET ix = *ixp; +#else + SV *sv = *svp; +#endif if (still_valid) SvREFCNT_inc_simple_void(gv); #ifdef USE_ITHREADS - if (*ixp > 0) { - pad_swipe(*ixp, TRUE); + if (ix > 0) { *ixp = 0; + pad_swipe(ix, TRUE); } #else - SvREFCNT_dec(*svp); *svp = NULL; + SvREFCNT_dec(sv); #endif if (still_valid) { int try_downgrade = SvREFCNT(gv) == 2; -- 1.9.5.msysgit.0 ```
p5pRT commented 9 years ago

From @iabyn

On Tue\, Mar 31\, 2015 at 10​:44​:34PM -0700\, Tony Cook via RT wrote​:

The attached seems to fix the problem for me\, though I'm not sure if it's fixing a real problem or just beating a possible bug in gcc's optimizer.

Hmm\, I've stared and stared at it and can't see a real problem there. Perhaps you should single step through S_op_clear_gv() and see if the value of *ixp changes at any point\, or whether pad_swipe() is called with the wrong value.

One slightly odd thing about that particular bit of perl code is that the BEGIN cv is freed by this code in perly.y​:

  for (i=0; i\< parser->yylen; i++) {   SvREFCNT_dec(ps[-i].compcv);   }

and at that point\, PL_curpad is null - so all the pad manipulation that would be done by S_op_clear_gv() and pad_swipe() is in fact skipped. I'm not sure whether that's a bug or not.

-- Red sky at night - gerroff my land! Red sky at morning - gerroff my land!   -- old farmers' sayings #14

p5pRT commented 9 years ago

From @tonycoz

On Wed Apr 01 05​:43​:08 2015\, davem wrote​:

On Tue\, Mar 31\, 2015 at 10​:44​:34PM -0700\, Tony Cook via RT wrote​:

The attached seems to fix the problem for me\, though I'm not sure if it's fixing a real problem or just beating a possible bug in gcc's optimizer.

Hmm\, I've stared and stared at it and can't see a real problem there. Perhaps you should single step through S_op_clear_gv() and see if the value of *ixp changes at any point\, or whether pad_swipe() is called with the wrong value.

One slightly odd thing about that particular bit of perl code is that the BEGIN cv is freed by this code in perly.y​:

for (i=0; i\< parser->yylen; i++) { SvREFCNT_dec(ps[-i].compcv); }

and at that point\, PL_curpad is null - so all the pad manipulation that would be done by S_op_clear_gv() and pad_swipe() is in fact skipped. I'm not sure whether that's a bug or not.

miniperl is built as non-threaded on Win32\, so PL_curpad isn't checked and *ixp is irrelevant.

I've added a trace through of S_op_clear_gv - which asserts on the second SvREFCNT_dec()

Tony

p5pRT commented 9 years ago

From @tonycoz

On Wed Apr 01 15​:43​:20 2015\, tonyc wrote​:

I've added a trace through of S_op_clear_gv - which asserts on the second SvREFCNT_dec()

Really added now.

Tony

p5pRT commented 9 years ago

From @tonycoz

j​:\dev\perl\git\perl\win32>gdb ..\miniperl.exe gdb ..\miniperl.exe GNU gdb (GDB) 7.7.1 Copyright (C) 2014 Free Software Foundation\, Inc. License GPLv3+​: GNU GPL version 3 or later \<http​://gnu.org/licenses/gpl.html> This is free software​: you are free to change and redistribute it. There is NO WARRANTY\, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "x86_64-w64-mingw32". Type "show configuration" for configuration details. For bug reporting instructions\, please see​: \<http​://www.gnu.org/software/gdb/bugs/>. Find the GDB manual and other documentation resources online at​: \<http​://www.gnu.org/software/gdb/documentation/>. For help\, type "help". Type "apropos word" to search for commands related to "word"... Reading symbols from ..\miniperl.exe...done. (gdb) b S_op_clear_gv Breakpoint 1 at 0x462450​: file op.c\, line 802. (gdb) r ..\..\123976.pl Starting program​: j​:\dev\perl\git\perl\miniperl.exe ..\..\123976.pl [New Thread 7084.0xd90]

Breakpoint 1\, S_op_clear_gv (o=o@​entry=0x2784d38\, svp=svp@​entry=0x2784d60)   at op.c​:802 802 op.c​: No such file or directory. (gdb) dir .. Source directories searched​: j​:\dev\perl\git\perl\win32/..;$cdir;$cwd (gdb) n 805 || o->op_type == OP_MULTIDEREF) (gdb) p *svp $1 = (SV *) 0x277e7b8 (gdb) n 802 { (gdb) 805 || o->op_type == OP_MULTIDEREF) (gdb) 810 ? (GV*)(*svp) : NULL; (gdb) 826 bool still_valid = gv && SvREFCNT(gv); (gdb) p gv $2 = (GV *) 0x277e7b8 (gdb) b op.c​:845 Breakpoint 2 at 0x4624bd​: file op.c\, line 845. (gdb) display *svp 1​: *svp = (SV *) 0x277e7b8 (gdb) n 829 SvREFCNT_inc_simple_void(gv); 1​: *svp = (SV *) 0x277e7b8 (gdb) 826 bool still_valid = gv && SvREFCNT(gv); 1​: *svp = (SV *) 0x277e7b8 (gdb) 836 SvREFCNT_dec(*svp); 1​: *svp = (SV *) 0x277e7b8 (gdb) 829 SvREFCNT_inc_simple_void(gv); 1​: *svp = (SV *) 0x277e7b8 (gdb) 836 SvREFCNT_dec(*svp); 1​: *svp = (SV *) 0x277e7b8 (gdb) 839 if (still_valid) { 1​: *svp = (SV *) 0x277e7b8 (gdb) 837 *svp = NULL; 1​: *svp = (SV *) 0x277e7b8 (gdb) 839 if (still_valid) { 1​: *svp = (SV *) 0x0 (gdb) 840 int try_downgrade = SvREFCNT(gv) == 2; 1​: *svp = (SV *) 0x0 (gdb) 841 SvREFCNT_dec_NN(gv); 1​: *svp = (SV *) 0x0 (gdb) 845 } 1​: *svp = (SV *) 0x0 (gdb) 841 SvREFCNT_dec_NN(gv); 1​: *svp = (SV *) 0x0 (gdb)

This application has requested the Runtime to terminate it in an unusual way. Please contact the application's support team for more information. A s s e r t i o n f a i l e d !

P r o g r a m : j : \ d e v \ p e r l \ g i t \ p e r l \ m i n i p e r l . e x e F i l e : . . \ g v . c \, L i n e 4 1 0

E x p r e s s i o n : S v T Y P E ( g v ) = = S V t _ P V G V | | S v T Y P E ( g v ) = = S V t _ P V L V [Inferior 1 (process 7084) exited with code 03] (gdb) q

p5pRT commented 9 years ago

From @iabyn

On Wed\, Apr 01\, 2015 at 03​:43​:21PM -0700\, Tony Cook via RT wrote​:

miniperl is built as non-threaded on Win32\, so PL_curpad isn't checked and *ixp is irrelevant.

Ah\, I hadn't realised.

I've added a trace through of S_op_clear_gv - which asserts on the second SvREFCNT_dec()

I'm not sure that's the case. The optimised code is showing enough random jumping about between the lines under the debugger that that's probably a red herring. The assert is in Perl_gv_init_pvn()\, and it would be interesting to see the call stack at that point.

On my system\, Perl_gv_init_pvn() isn't invoked at all around that time. The following session (with extraneous output trimmed) shows that after the first call call to S_op_clear_gv()\, there aren't any calls to Perl_gv_init_pvn() until destruct time​:

$ cat /tmp/p BEGIN { *foo = sub () { 0 } } foo();

$ gdb ./miniperl (gdb) b S_op_clear_gv (gdb) run /tmp/p Breakpoint 1\, S_op_clear_gv (o=0xa4ffb8\, svp=0xa4ffe0) at op.c​:804 804 GV *gv = (o->op_type == OP_GV || o->op_type == OP_GVSV (gdb) b Perl_gv_init_pvn (gdb) c Breakpoint 1\, S_op_clear_gv (o=0xa4fc68\, svp=0xa4fc90) at op.c​:804 804 GV *gv = (o->op_type == OP_GV || o->op_type == OP_GVSV (gdb) c Breakpoint 2\, Perl_gv_init_pvn (gv=0xa2d2c8\, stash=0xa41ae0\,   name=0x7bb5c1 "DESTROY"\, len=0x7\, flags=0x2) at gv.c​:367 367 const U32 old_type = SvTYPE(gv); (gdb) bt ... #10 0x0000000000595bef in Perl_sv_clean_objs () at sv.c​:662 #11 0x00000000004059e5 in perl_destruct (my_perl=0xa2b010) at perl.c​:801 #12 0x0000000000451161 in main (argc=0x2\, argv=0x7fffffffe0b8\,   env=0x7fffffffe0d0) at miniperlmain.c​:133

-- Fire extinguisher (n) a device for holding open fire doors.

p5pRT commented 9 years ago

From @tonycoz

On Thu Apr 02 11​:20​:19 2015\, davem wrote​:

Ah\, I hadn't realised.

I've added a trace through of S_op_clear_gv - which asserts on the second SvREFCNT_dec()

I'm not sure that's the case. The optimised code is showing enough random jumping about between the lines under the debugger that that's probably a red herring. The assert is in Perl_gv_init_pvn()\, and it would be interesting to see the call stack at that point.

You're right\, it wasn't in the SvREFCNT_dec().

Here's the backtrace\, I added code to break into the debugger when the SvTYPE() was wrong\, and to dump gv just before the second Sv.REFCNT_dec​:

(gdb) list gv.c​:411 406 } else 407 Safefree(SvPVX_mutable(gv)); 408 } 409 SvIOK_off(gv); 410 if (!(SvTYPE(gv) == SVt_PVGV || SvTYPE(gv) == SVt_PVLV)) { 411 sv_dump((SV*)gv); 412 *(char *)0 = 0; 413 } 414 isGV_with_GP_on(gv); 415
(gdb) list op.c​:841 836 SvREFCNT_dec(*svp); 837 *svp = NULL; 838 #endif 839 if (still_valid) { 840 int try_downgrade = SvREFCNT(gv) == 2; 841 sv_dump((SV*)gv); 842 SvREFCNT_dec_NN(gv); 843 if (try_downgrade) 844 gv_try_downgrade(gv); 845 } (gdb) r ..\..\123976.pl Starting program​: j​:\dev\perl\git\perl\miniperl.exe ..\..\123976.pl [New Thread 6848.0x1b50] SV = PVGV(0x27d3da0) at 0x27de7b8   REFCNT = 1   FLAGS = (MULTI\,ASSUMECV)   NAME = "foo"   NAMELEN = 3   GvSTASH = 0xec8ff8 "main"   FLAGS = 0x6   GP = 0x27e4e00   SV = 0x0   REFCNT = 1   IO = 0x0   FORM = 0x0
  AV = 0x0   HV = 0x0   CV = 0x27de848   CVGEN = 0x0   GPFLAGS = 0x0 ()   LINE = 2   FILE = "..\..\123976.pl"   EGV = 0x27de7b8 "foo" SV = UNKNOWN(0xff) (0x27de7d0) at 0x27de7b8   REFCNT = 0   FLAGS = ()

Program received signal SIGSEGV\, Segmentation fault. Perl_gv_init_pvn (gv=0x27de7b8\, stash=0xec8ff8\, name=0x27e0d50 "foo"\, len=3\,   flags=flags@​entry=0) at ..\gv.c​:412 412 *(char *)0 = 0; (gdb) bt #0 Perl_gv_init_pvn (gv=0x27de7b8\, stash=0xec8ff8\, name=0x27e0d50 "foo"\,   len=3\, flags=flags@​entry=0) at ..\gv.c​:412 #1 0x0000000000429f2c in Perl_gv_fetchpvn_flags (nambeg=0x27e0d50 "foo"\,   full_len=\\, flags=\\,   sv_type=sv_type@​entry=SVt_PVCV) at ..\gv.c​:2334 #2 0x000000000042d26e in Perl_gv_fetchsv (name=name@​entry=0x27de770\,   flags=64\, sv_type=SVt_PVCV) at ..\gv.c​:1526 #3 0x0000000000467408 in Perl_ck_rvconst (o=0x27e4878) at op.c​:9817 #4 0x000000000046c147 in Perl_newUNOP (type=type@​entry=17\,   flags=\\, flags@​entry=8192\, first=0x27e48b8) at op.c​:4815 #5 0x000000000046cafb in Perl_newCVREF (flags=flags@​entry=8192\,   o=\) at op.c​:9380 #6 0x00000000005da770 in Perl_yylex () at ..\toke.c​:6680 #7 0x000000000049c283 in Perl_yyparse (gramtype=gramtype@​entry=258)   at ..\perly.c​:322 #8 0x0000000000499902 in S_parse_body (xsinit=0x2c\,   env=0x4013b5 \<__tmainCRTStartup+565>) at perl.c​:2296 #9 perl_parse (my_perl=\\, xsinit=0x2c\,   xsinit@​entry=0x608520 \<xs_init>\, argc=\\,   argv=\\, env=env@​entry=0x0) at perl.c​:1626 #10 0x00000000006225d0 in main (argc=2\, argv=0xec4ef0\, env=0xec2e30)   at ..\miniperlmain.c​:120 (gdb)

I also traced to see what was freeing the GV​:

(gdb) b S_op_clear_gv Breakpoint 1 at 0x462470​: file op.c\, line 802. (gdb) r ..\..\123976.pl Starting program​: j​:\dev\perl\git\perl\miniperl.exe ..\..\123976.pl [New Thread 6876.0x194c]

Breakpoint 1\, S_op_clear_gv (o=o@​entry=0x2884218\, svp=svp@​entry=0x2884240)   at op.c​:802 802 { (gdb) n 805 || o->op_type == OP_MULTIDEREF) (gdb) 802 { (gdb) 805 || o->op_type == OP_MULTIDEREF) (gdb) 810 ? (GV*)(*svp) : NULL; (gdb) 826 bool still_valid = gv && SvREFCNT(gv); (gdb) p gv $1 = (GV *) 0x287dc88 (gdb) p gv->sv_refcnt $2 = 2 (gdb) watch -l gv->sv_refcnt Hardware watchpoint 2​: -location gv->sv_refcnt (gdb) c Continuing. Hardware watchpoint 2​: -location gv->sv_refcnt

Old value = 2 New value = 3 S_op_clear_gv (o=o@​entry=0x2884218\, svp=svp@​entry=0x2884240) at op.c​:836 836 SvREFCNT_dec(*svp); (gdb) c Continuing. Hardware watchpoint 2​: -location gv->sv_refcnt

Old value = 3 New value = 1 S_op_clear_gv (o=o@​entry=0x2884218\, svp=svp@​entry=0x2884240) at op.c​:837 837 *svp = NULL; (gdb) c Continuing. SV = PVGV(0x2873640) at 0x287dc88   REFCNT = 1   FLAGS = (MULTI\,ASSUMECV)   NAME = "foo"   NAMELEN = 3   GvSTASH = 0x11783b8 "main"   FLAGS = 0x6   GP = 0x28842e0   SV = 0x0   REFCNT = 1   IO = 0x0   FORM = 0x0
  AV = 0x0   HV = 0x0   CV = 0x287dd18   CVGEN = 0x0   GPFLAGS = 0x0 ()   LINE = 2   FILE = "..\..\123976.pl"   EGV = 0x287dc88 "foo" Hardware watchpoint 2​: -location gv->sv_refcnt

Old value = 1 New value = 0 Perl_sv_free2 (sv=sv@​entry=0x287dc88\, rc=1) at ..\sv.c​:7021 7021 if (SvTEMP(sv)) { (gdb) bt #0 Perl_sv_free2 (sv=sv@​entry=0x287dc88\, rc=1) at ..\sv.c​:7021 #1 0x0000000000462558 in S_SvREFCNT_dec_NN (sv=0x287dc88) at ../inline.h​:177 #2 S_op_clear_gv (o=o@​entry=0x2884218\, svp=svp@​entry=0x2884240) at op.c​:842 #3 0x00000000004628d0 in Perl_op_clear (o=o@​entry=0x2884218) at op.c​:875 #4 0x0000000000462b48 in Perl_op_free (o=0x2884218) at op.c​:784 #5 0x0000000000462b12 in Perl_op_free (o=0x28841d8) at op.c​:767 #6 0x000000000048f409 in Perl_cv_undef_flags (cv=cv@​entry=0x287dc40\,   flags=flags@​entry=0) at ..\pad.c​:337 #7 0x000000000048fb27 in Perl_cv_undef (cv=cv@​entry=0x287dc40)   at ..\pad.c​:299 #8 0x0000000000585955 in Perl_sv_clear (orig_sv=orig_sv@​entry=0x287dc40)   at ..\sv.c​:6603 #9 0x0000000000586874 in Perl_sv_free2 (sv=0x287dc40\, rc=\)   at ..\sv.c​:7033 #10 0x000000000049bdff in S_SvREFCNT_dec (sv=\)   at ../inline.h​:166 #11 Perl_yyparse (gramtype=gramtype@​entry=258) at ..\perly.c​:423 #12 0x0000000000499902 in S_parse_body (xsinit=0x2c\,   env=0x4013b5 \<__tmainCRTStartup+565>) at perl.c​:2296 #13 perl_parse (my_perl=\\, xsinit=0x2c\,   xsinit@​entry=0x608520 \<xs_init>\, argc=\\,   argv=\\, env=env@​entry=0x0) at perl.c​:1626 #14 0x00000000006225d0 in main (argc=2\, argv=0x11722d0\, env=0x1172a70)   at ..\miniperlmain.c​:120 (gdb) c Continuing. SV = UNKNOWN(0xff) (0x287dca0) at 0x287dc88   REFCNT = 0   FLAGS = ()

Program received signal SIGSEGV\, Segmentation fault. Perl_gv_init_pvn (gv=0x287dc88\, stash=0x11783b8\, name=0x28842e0 "foo"\, len=3\,   flags=flags@​entry=0) at ..\gv.c​:412 412 *(char *)0 = 0; (gdb) q

I'm not sure that tells us anything useful.

Tony

p5pRT commented 9 years ago

From @iabyn

On Thu\, Apr 02\, 2015 at 02​:58​:01PM -0700\, Tony Cook via RT wrote​:

I also traced to see what was freeing the GV​: [snip] 836 SvREFCNT_dec(*svp); (gdb) c Continuing. Hardware watchpoint 2​: -location gv->sv_refcnt

Old value = 3 New value = 1 S_op_clear_gv (o=o@​entry=0x2884218\, svp=svp@​entry=0x2884240) at op.c​:837 837 *svp = NULL;

I think that's the error. SvREFCNT_dec() appears to be decreasing the refcount by *2* at that point; the "SvREFCNT_dec_NN(gv)" a few lines later then reduces the count from 1 to 0 and so prematurely frees the gv. By comparison\, S_op_clear_gv() on my system changes the refcount in steps as 2 => 3 => 2 => 1

I suspect that's a compiler bug.

-- The optimist believes that he lives in the best of all possible worlds. As does the pessimist.

p5pRT commented 9 years ago

From @bulk88

On Fri Apr 03 01​:30​:31 2015\, davem wrote​:

I think that's the error. SvREFCNT_dec() appears to be decreasing the refcount by *2* at that point; the "SvREFCNT_dec_NN(gv)" a few lines later then reduces the count from 1 to 0 and so prematurely frees the gv. By comparison\, S_op_clear_gv() on my system changes the refcount in steps as 2 => 3 => 2 => 1

I suspect that's a compiler bug.

Can someone attach the broken binary? I want to take a peek in it.

-- bulk88 ~ bulk88 at hotmail.com

p5pRT commented 9 years ago

From @steve-m-hay

On Fri Apr 03 08​:35​:00 2015\, bulk88 wrote​:

On Fri Apr 03 01​:30​:31 2015\, davem wrote​:

I think that's the error. SvREFCNT_dec() appears to be decreasing the refcount by *2* at that point; the "SvREFCNT_dec_NN(gv)" a few lines later then reduces the count from 1 to 0 and so prematurely frees the gv. By comparison\, S_op_clear_gv() on my system changes the refcount in steps as 2 => 3 => 2 => 1

I suspect that's a compiler bug.

Can someone attach the broken binary? I want to take a peek in it.

Attached.

C​:\Dev\Git\perl\win32>..\miniperl.exe -I..\lib -f ..\write_buildcustomize.pl .. Attempt to free unreferenced scalar​: SV 0x389ca8 at ..\lib/strict.pm line 38.

p5pRT commented 9 years ago

From @steve-m-hay

miniperl.exe.gz

p5pRT commented 9 years ago

From @bulk88

On Fri Apr 03 10​:09​:21 2015\, shay wrote​:

Attached.

C​:\Dev\Git\perl\win32>..\miniperl.exe -I..\lib -f ..\write_buildcustomize.pl .. Attempt to free unreferenced scalar​: SV 0x389ca8 at ..\lib/strict.pm line 38.

Does the perl521.dll version crash and can you attach the crashing perl.exe and perl521.dll\, preferably unstripped? I can't really analyze the GCC miniperl.exe since it doesn't export anything (except accidental exports) and doesn't have symbols. Mingw64-64 4.8.2 isn't crashing for me\, with out Cfg=Debug and with it on.

C​:\p521\srcpara>gcc -v Using built-in specs. COLLECT_GCC=gcc COLLECT_LTO_WRAPPER=c​:/sources/mingw64/bin/../libexec/gcc/i686-w64-mingw32/4.8.2 /lto-wrapper.exe Target​: i686-w64-mingw32 Configured with​: ../../../src/gcc-4.8.2/configure --host=i686-w64-mingw32 --buil d=i686-w64-mingw32 --target=i686-w64-mingw32 --prefix=/mingw32 --with-sysroot=/t mp/i686-482-win32-sjlj-rt_v3-r0/mingw32 --enable-shared --enable-static --enable -targets=all --enable-multilib --enable-languages=ada\,c\,c++\,fortran\,objc\,obj-c++ \,lto --enable-libstdcxx-time=yes --enable-threads=win32 --enable-libgomp --enabl e-lto --enable-graphite --enable-checking=release --enable-fully-dynamic-string --enable-version-specific-runtime-libs --enable-sjlj-exceptions --disable-isl-ve rsion-check --disable-cloog-version-check --disable-libstdcxx-pch --disable-libs tdcxx-debug --enable-bootstrap --disable-rpath --disable-win32-registry --disabl e-nls --disable-werror --disable-symvers --with-gnu-as --with-gnu-ld --with-arch -32=i686 --with-arch-64=nocona --with-tune-32=generic --with-tune-64=core2 --wit h-libiconv --with-system-zlib --with-gmp=/tmp/prerequisites/i686-w64-mingw32-sta tic --with-mpfr=/tmp/prerequisites/i686-w64-mingw32-static --with-mpc=/tmp/prere quisites/i686-w64-mingw32-static --with-isl=/tmp/prerequisites/i686-w64-mingw32- static --with-cloog=/tmp/prerequisites/i686-w64-mingw32-static --enable-cloog-ba ckend=isl --with-pkgversion='rev0\, Built by MinGW-W64 project' --with-bugurl=htt p​://sourceforge.net/projects/mingw-w64 CFLAGS='-O2 -pipe -I/tmp/i686-482-win32-s jlj-rt_v3-r0/mingw32/opt/include -I/tmp/prerequisites/i686-zlib-static/include - I/tmp/prerequisites/i686-w64-mingw32-static/include' CXXFLAGS='-O2 -pipe -I/tmp/ i686-482-win32-sjlj-rt_v3-r0/mingw32/opt/include -I/tmp/prerequisites/i686-zlib- static/include -I/tmp/prerequisites/i686-w64-mingw32-static/include' CPPFLAGS= L DFLAGS='-pipe -L/tmp/i686-482-win32-sjlj-rt_v3-r0/mingw32/opt/lib -L/tmp/prerequ isites/i686-zlib-static/lib -L/tmp/prerequisites/i686-w64-mingw32-static/lib -Wl \,--large-address-aware' Thread model​: win32 gcc version 4.8.2 (rev0\, Built by MinGW-W64 project)

C​:\p521\srcpara>


BEGIN {   my $bits = 0;   *foo = sub () { $bits }; } foo();


C​:\p521\srcpara>miniperl.exe -Ilib c.pl

C​:\p521\srcpara>


Also Strawberry 5.20-32 comes with 4.8.3\, not 4.8.2\, and it doesn't crash either.

-v reproduced below of SP 5.20's GCC


Using built-in specs. COLLECT_GCC=gcc COLLECT_LTO_WRAPPER=C​:/sp3220/c/bin/../libexec/gcc/i686-w64-mingw32/4.8.3/lto-wr apper.exe Target​: i686-w64-mingw32 Configured with​: ../../../src/gcc-4.8.3/configure --host=i686-w64-mingw32 --buil d=i686-w64-mingw32 --target=i686-w64-mingw32 --prefix=/mingw32 --with-gxx-includ e-dir=/mingw32/i686-w64-mingw32/include/c++ --enable-shared --enable-static --di sable-multilib --enable-languages=c\,c++\,fortran\,lto --enable-libstdcxx-time=yes --enable-threads=posix --enable-libgomp --enable-lto --enable-graphite --enable- checking=release --enable-fully-dynamic-string --enable-version-specific-runtime -libs --enable-sjlj-exceptions --disable-isl-version-check --disable-cloog-versi on-check --disable-libstdcxx-pch --disable-libstdcxx-debug --disable-bootstrap - -disable-rpath --disable-win32-registry --disable-nls --disable-werror --disable -symvers --with-gnu-as --with-gnu-ld --with-arch=i686 --with-tune=generic --with -libiconv --with-system-zlib --with-gmp=/opt/build/prerequisites/i686-w64-mingw3 2-static --with-mpfr=/opt/build/prerequisites/i686-w64-mingw32-static --with-mpc =/opt/build/prerequisites/i686-w64-mingw32-static --with-isl=/opt/build/prerequi sites/i686-w64-mingw32-static --with-cloog=/opt/build/prerequisites/i686-w64-min gw32-static --enable-cloog-backend=isl --with-pkgversion='i686-posix-sjlj\, built by strawberryperl.com project' CFLAGS='-O2 -pipe -I/opt/build/i686-483-posix-sj lj-rt_v3/mingw32/opt/include -I/opt/build/prerequisites/i686-zlib-static/include -I/opt/build/prerequisites/i686-w64-mingw32-static/include' CXXFLAGS='-O2 -pipe -I/opt/build/i686-483-posix-sjlj-rt_v3/mingw32/opt/include -I/opt/build/prerequ isites/i686-zlib-static/include -I/opt/build/prerequisites/i686-w64-mingw32-stat ic/include' CPPFLAGS= LDFLAGS='-pipe -L/opt/build/i686-483-posix-sjlj-rt_v3/ming w32/opt/lib -L/opt/build/prerequisites/i686-zlib-static/lib -L/opt/build/prerequ isites/i686-w64-mingw32-static/lib' Thread model​: posix gcc version 4.8.3 (i686-posix-sjlj\, built by strawberryperl.com project)


-- bulk88 ~ bulk88 at hotmail.com

p5pRT commented 9 years ago

From @steve-m-hay

On Sun Apr 05 02​:08​:22 2015\, bulk88 wrote​:

On Fri Apr 03 10​:09​:21 2015\, shay wrote​:

Attached.

C​:\Dev\Git\perl\win32>..\miniperl.exe -I..\lib -f ..\write_buildcustomize.pl .. Attempt to free unreferenced scalar​: SV 0x389ca8 at ..\lib/strict.pm line 38.

Does the perl521.dll version crash and can you attach the crashing perl.exe and perl521.dll\, preferably unstripped? I can't really analyze the GCC miniperl.exe since it doesn't export anything (except accidental exports) and doesn't have symbols. Mingw64-64 4.8.2 isn't crashing for me\, with out Cfg=Debug and with it on.

It doesn't get as far as building perl521.dll/perl.exe because the miniperl.exe that would be used to build them crashes. It crashes in either release or debug (CFG=Debug) configurations. I've attached the miniperl.exe from a debug build in case its of any use\, but it sounds like it won't be.

I will try putting a miniperl from a different perl build in place and see if that lets the build continue to produce a perl521.dll/perl.exe...

Meanwhile\, here is the configuration of the MinGW-w64 gcc-4.8.0 that I'm using (It's a 64-bit Windows build which targets 64-bit Windows. The download file is called "x86_64-w64-mingw32-gcc-4.8.0-win64_rubenvb.7z" and I downloaded it from http​://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win64/Personal%20Builds/rubenvb/gcc-4.8-release/ )​:

Using built-in specs. COLLECT_GCC=gcc COLLECT_LTO_WRAPPER=c​:/dev/software/mingw-w64/x64/4.8.0/bin/../libexec/gcc/x86_64-w64-mingw32/4.8.0/lto-wrapper.exe Target​: x86_64-w64-mingw32 Configured with​: /home/ruben/mingw-w64/src/gcc/configure --host=x86_64-w64-mingw32 --build=x86_64-linux-gnu --target=x86_64-w64-mingw32 --with-sysroot=/home/ruben/mingw-w64/mingw64mingw64/mingw64 --prefix=/home/ruben/mingw-w64/mingw64mingw64/mingw64 --with-gmp=/home/ruben/mingw-w64/prereq/x86_64-w64-mingw32/install --with-mpfr=/home/ruben/mingw-w64/prereq/x86_64-w64-mingw32/install --with-mpc=/home/ruben/mingw-w64/prereq/x86_64-w64-mingw32/install --with-cloog=/home/ruben/mingw-w64/prereq/x86_64-w64-mingw32/install --disable-cloog-version-check --with-isl=/home/ruben/mingw-w64/prereq/x86_64-w64-mingw32/install --enable-cloog-backend=isl --with-host-libstdcxx='-static -lstdc++ -lm' --enable-shared --enable-static --enable-threads=win32 --enable-plugins --disable-multilib --enable-languages=c\,lto\,c++\,objc\,obj-c++\,fortran\,java --enable-libgomp --enable-fully-dynamic-string --enable-libstdcxx-time --disable-nls --disable-werror --enable-checking=release --with-gnu-as --with-gnu-ld --disable-win32-registry --disable-rpath --disable-werror --with-libiconv-prefix=/home/ruben/mingw-w64/prereq/x86_64-w64-mingw32/install --with-pkgversion=rubenvb-4.8.0 --with-bugurl=mingw-w64-public@​lists.sourceforge.net CC= CFLAGS='-O2 -march=nocona -mtune=core2 -fomit-frame-pointer -momit-leaf-frame-pointer' CXXFLAGS='-O2 -march=nocona -mtune=core2 -fomit-frame-pointer -momit-leaf-frame-pointer' LDFLAGS= 'BOOT_CFLAGS=-O2 -march=nocona -mtune=core2 -fomit-frame-pointer -momit-leaf-frame-pointer' 'BOOT_CXXFLAGS=-O2 -march=nocona -mtune=core2 -fomit-frame-pointer -momit-leaf-frame-pointer' BOOT_LDFLAGS= 'CFLAGS_FOR_TARGET= -O2 -march=nocona -mtune=core2 -fgraphite-identity -floop-interchange -floop-block -floop-parallelize-all' 'CXXFLAGS_FOR_TARGET= -O2 -march=nocona -mtune=core2 -fgraphite-identity -floop-interchange -floop-block -floop-parallelize-all' LDFLAGS_FOR_TARGET= Thread model​: win32 gcc version 4.8.0 (rubenvb-4.8.0)

p5pRT commented 9 years ago

From @steve-m-hay

miniperl.exe.gz

p5pRT commented 9 years ago

From @steve-m-hay

On Sun Apr 05 09​:40​:01 2015\, shay wrote​:

On Sun Apr 05 02​:08​:22 2015\, bulk88 wrote​:

On Fri Apr 03 10​:09​:21 2015\, shay wrote​:

Attached.

C​:\Dev\Git\perl\win32>..\miniperl.exe -I..\lib -f ..\write_buildcustomize.pl .. Attempt to free unreferenced scalar​: SV 0x389ca8 at ..\lib/strict.pm line 38.

Does the perl521.dll version crash and can you attach the crashing perl.exe and perl521.dll\, preferably unstripped? I can't really analyze the GCC miniperl.exe since it doesn't export anything (except accidental exports) and doesn't have symbols. Mingw64-64 4.8.2 isn't crashing for me\, with out Cfg=Debug and with it on.

It doesn't get as far as building perl521.dll/perl.exe because the miniperl.exe that would be used to build them crashes. It crashes in either release or debug (CFG=Debug) configurations. I've attached the miniperl.exe from a debug build in case its of any use\, but it sounds like it won't be.

I will try putting a miniperl from a different perl build in place and see if that lets the build continue to produce a perl521.dll/perl.exe...

I put a miniperl.exe from a gcc-4.7.2 build into place and that allowed the gcc-4.8.0 build to complete\, but the resulting perl.exe doesn't suffer the same problem as the miniperl.exe did\, even when used to run the same write_buildcustomize.pl command.

p5pRT commented 9 years ago

From @bulk88

On Sun Apr 05 10​:05​:55 2015\, shay wrote​:

I put a miniperl.exe from a gcc-4.7.2 build into place and that allowed the gcc-4.8.0 build to complete\, but the resulting perl.exe doesn't suffer the same problem as the miniperl.exe did\, even when used to run the same write_buildcustomize.pl command.

I can reproduce now with the rubenvb build. But if I breath at the bug\, the attempt to free unreferenced goes away. This tiny little patch fixed it for me. Also -O0 and -O1 dont have the bug.

-- bulk88 ~ bulk88 at hotmail.com

p5pRT commented 9 years ago

From @bulk88

0001-add-watchsv.patch ```diff From 564879a4ea0ae4391693b5f1c8c9237f96c64da8 Mon Sep 17 00:00:00 2001 From: Daniel Dragan Date: Sun, 5 Apr 2015 19:21:58 -0400 Subject: [PATCH] add watchsv --- inline.h | 4 ++++ perlvars.h | 1 + sv.c | 1 + 3 files changed, 6 insertions(+) diff --git a/inline.h b/inline.h index 46a8cb6..2919384 100644 --- a/inline.h +++ b/inline.h @@ -159,6 +159,8 @@ PERL_STATIC_INLINE void S_SvREFCNT_dec(pTHX_ SV *sv) { if (LIKELY(sv != NULL)) { + if(sv == PL_watch_sv) + DebugBreak(); U32 rc = SvREFCNT(sv); if (LIKELY(rc > 1)) SvREFCNT(sv) = rc - 1; @@ -171,6 +173,8 @@ PERL_STATIC_INLINE void S_SvREFCNT_dec_NN(pTHX_ SV *sv) { U32 rc = SvREFCNT(sv); + if(sv == PL_watch_sv) + DebugBreak(); if (LIKELY(rc > 1)) SvREFCNT(sv) = rc - 1; else diff --git a/perlvars.h b/perlvars.h index 7bafa40..c2262e8 100644 --- a/perlvars.h +++ b/perlvars.h @@ -237,3 +237,4 @@ PERLVAR(G, malloc_mutex, perl_mutex) /* Mutex for malloc */ PERLVARI(G, hash_seed_set, bool, FALSE) /* perl.c */ PERLVARA(G, hash_seed, PERL_HASH_SEED_BYTES, unsigned char) /* perl.c and hv.h */ +PERLVARI(G, watch_sv, SV *, NULL) diff --git a/sv.c b/sv.c index 467dc24..67524cc 100644 --- a/sv.c +++ b/sv.c @@ -7066,6 +7066,7 @@ Perl_sv_free2(pTHX_ SV *const sv, const U32 rc) } #endif /* This may not return: */ + DebugBreak(); Perl_warner(aTHX_ packWARN(WARN_INTERNAL), "Attempt to free unreferenced scalar: SV 0x%"UVxf pTHX__FORMAT, PTR2UV(sv) pTHX__VALUE); -- 1.8.0.msysgit.0 ```
p5pRT commented 9 years ago

From @bulk88

On Sun Apr 05 16​:30​:37 2015\, bulk88 wrote​:

PERL_STATIC_INLINE void S_SvREFCNT_dec(pTHX_ SV *sv) {   if (LIKELY(sv != NULL)) {   volatile U32 rc = SvREFCNT(sv);   if (LIKELY(rc > 1))   SvREFCNT(sv) = rc - 1;   else   Perl_sv_free2(aTHX_ sv\, rc);   } }

fixes it. IDK why yet.

-- bulk88 ~ bulk88 at hotmail.com

p5pRT commented 9 years ago

From @bulk88

The sin that http​://perl5.git.perl.org/perl.git/commitdiff/ab57679753417e2765475e79c13a2adc48615ac0 "add S_op_clear_gv() to op.c" did was creating a pointer alias. GV * gv\, in 1 one branch might be created from "(GV*(*svp)".

Then in quick succession\, and function call free (side effects dont have to be stored to mem until the next function call (ABI reasons))\, this executes\, ++ the SV/GV *'s refcnt by 1.


  if (still_valid)   SvREFCNT_inc_simple_void(gv);


then right after


#ifdef USE_ITHREADS   if (*ixp > 0) {/* IGNORE THIS COMPILED OUT */   pad_swipe(*ixp\, TRUE);   *ixp = 0;   } #else   SvREFCNT_dec(*svp);   *svp = NULL; #endif


we -- the same SV *\, but through a different C auto.

Since GCC -O2 always includes "-fstrict-aliasing" by default\, 2 different C autos holding the same ptr is forbidden on paper (if I understand the concept correctly). VC doesn't do such dangerous optimizations so life is easy in VC land :D

I've included 2 pics of the asm code showing how the volatile version that writes to C stack\, writes\, then reads\, while the version without volatile\, READS\, THEN WRITES a stale copy. Doing the read before the write\, is http​://en.wikipedia.org/wiki/Instruction-level_parallelism or breaking up dependencies/pipline stalls in the CPU. In designing a CPU\, writes to memory can be slower/lazier than reads from memory\, since a slow read stops the CPU\, while a slow write is invisible\, and the next instruction can execute immediately. So GCC's "instruction scheduler" reordered them.

The real bug is GCC Win32 miniperl failed to do -fno-strict-aliasing the way Win32 GCC full perl does. The -fno-strict-aliasing for full Win32 perl is from http​://perl5.git.perl.org/perl.git/commitdiff/7a1f88acf2a2aec3c61c878c837070234df78c08 from 2000 with nothing that I can find (maybe you can find somethign) on the ML from Sarathy so it is unknown why he did that. I've attached a patch which fixes the lack of Win32 GCC miniperl not having fno-strict-aliasing. I have no comment on whether fno-strict-aliasing is appropriate for the perl 5 project or not but I did find this thread from 1999 when GCC first implemented the optimization. http​://markmail.org/message/v5r4lylkgv5zk2uk

-- bulk88 ~ bulk88 at hotmail.com

p5pRT commented 9 years ago

From @bulk88

0001-fix-123976-Win32-GCC-miniperl-needs-fno-strict-alias.patch ```diff From 72e70f1bc568a8c06a2dd1d6ee9eef356e05d945 Mon Sep 17 00:00:00 2001 From: Daniel Dragan Date: Sun, 5 Apr 2015 21:39:14 -0400 Subject: [PATCH] fix #123976 Win32 GCC miniperl needs -fno-strict-aliasing just like full perl uses -fno-strict-aliasing --- win32/makefile.mk | 1 + 1 file changed, 1 insertion(+) diff --git a/win32/makefile.mk b/win32/makefile.mk index 5fd10dc..34dd7e9 100644 --- a/win32/makefile.mk +++ b/win32/makefile.mk @@ -511,6 +511,7 @@ EXEOUT_FLAG = -o LIBOUT_FLAG = BUILDOPT += -fno-strict-aliasing -mms-bitfields +MINIBUILDOPT += -fno-strict-aliasing .ELSE -- 1.8.0.msysgit.0 ```
p5pRT commented 9 years ago

From @bulk88

0001-selective-volatile-in-S_SvREFCNT_dec.patch ```diff From 270a7da6c53a7fbe98992b850a9271a8bd808425 Mon Sep 17 00:00:00 2001 From: Daniel Dragan Date: Sun, 5 Apr 2015 21:15:39 -0400 Subject: [PATCH] selective volatile in S_SvREFCNT_dec --- inline.h | 3 +++ op.c | 32 ++++++++++++++++++++++++++++++-- 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/inline.h b/inline.h index 46a8cb6..92fe94b 100644 --- a/inline.h +++ b/inline.h @@ -155,6 +155,8 @@ S_SvREFCNT_inc_void(SV *sv) if (LIKELY(sv != NULL)) SvREFCNT(sv)++; } + +#ifndef NODEC PERL_STATIC_INLINE void S_SvREFCNT_dec(pTHX_ SV *sv) { @@ -166,6 +168,7 @@ S_SvREFCNT_dec(pTHX_ SV *sv) Perl_sv_free2(aTHX_ sv, rc); } } +#endif PERL_STATIC_INLINE void S_SvREFCNT_dec_NN(pTHX_ SV *sv) diff --git a/op.c b/op.c index ad0b0b0..cc59ad4 100644 --- a/op.c +++ b/op.c @@ -97,7 +97,8 @@ recursive, but it's recursive on basic blocks, not on tree nodes. saves the current C on the save stack, so that it will be correctly restored when any inner compiling scope is exited. */ - +#define NODEC +#define S_SvREFCNT_dec S_SvREFCNT_decNV #include "EXTERN.h" #define PERL_IN_OP_C #include "perl.h" @@ -105,6 +106,29 @@ recursive, but it's recursive on basic blocks, not on tree nodes. #include "feature.h" #include "regcomp.h" +PERL_STATIC_INLINE void +S_SvREFCNT_decV(pTHX_ SV *sv) +{ + if (LIKELY(sv != NULL)) { + volatile U32 rc = SvREFCNT(sv); + if (LIKELY(rc > 1)) + SvREFCNT(sv) = rc - 1; + else + Perl_sv_free2(aTHX_ sv, rc); + } +} +PERL_STATIC_INLINE void +S_SvREFCNT_decNV(pTHX_ SV *sv) +{ + if (LIKELY(sv != NULL)) { + U32 rc = SvREFCNT(sv); + if (LIKELY(rc > 1)) + SvREFCNT(sv) = rc - 1; + else + Perl_sv_free2(aTHX_ sv, rc); + } +} + #define CALL_PEEP(o) PL_peepp(aTHX_ o) #define CALL_RPEEP(o) PL_rpeepp(aTHX_ o) #define CALL_OPFREEHOOK(o) if (PL_opfreehook) PL_opfreehook(aTHX_ o) @@ -800,7 +824,9 @@ void S_op_clear_gv(pTHX_ OP *o, PADOFFSET *ixp) void S_op_clear_gv(pTHX_ OP *o, SV**svp) #endif { - +/* change from S_SvREFCNT_decV to S_SvREFCNT_decNV to see crash */ +#undef S_SvREFCNT_dec +#define S_SvREFCNT_dec S_SvREFCNT_decV GV *gv = (o->op_type == OP_GV || o->op_type == OP_GVSV || o->op_type == OP_MULTIDEREF) #ifdef USE_ITHREADS @@ -842,6 +868,8 @@ void S_op_clear_gv(pTHX_ OP *o, SV**svp) if (try_downgrade) gv_try_downgrade(gv); } +#undef S_SvREFCNT_dec +#define S_SvREFCNT_dec S_SvREFCNT_decNV } -- 1.8.0.msysgit.0 ```
p5pRT commented 9 years ago

From @bulk88

withoutvol.PNG

p5pRT commented 9 years ago

From @bulk88

withvol.PNG

p5pRT commented 9 years ago

From @iabyn

On Sun\, Apr 05\, 2015 at 06​:55​:57PM -0700\, bulk88 via RT wrote​:

The sin that http​://perl5.git.perl.org/perl.git/commitdiff/ab57679753417e2765475e79c13a2adc48615ac0 "add S_op_clear_gv() to op.c" did was creating a pointer alias. GV * gv\, in 1 one branch might be created from "(GV*(*svp)".

That commit didn't introduce the aliasing - that was already present - it just moved the code into a separate function.

I've attached a patch which fixes the lack of Win32 GCC miniperl not having fno-strict-aliasing.

I think that is the correct approach.

I have no comment on whether fno-strict-aliasing is appropriate for the perl 5 project or not

I think it's its definitely needed. For example it's a common core practice to create an aliased var with a cast for convenience\, e.g.

  switch (sv->sv_type) {   case SVt_PVHV​: {   HV *hv = (HV*)sv;   ....   }   ....   }

(Although it's perhaps less common to continue using the first var after the alias has been created.)

-- My Dad used to say 'always fight fire with fire'\, which is probably why he got thrown out of the fire brigade.

p5pRT commented 9 years ago

From @steve-m-hay

On 6 April 2015 at 11​:20\, Dave Mitchell \davem@&#8203;iabyn\.com wrote​:

On Sun\, Apr 05\, 2015 at 06​:55​:57PM -0700\, bulk88 via RT wrote​:

The sin that http​://perl5.git.perl.org/perl.git/commitdiff/ab57679753417e2765475e79c13a2adc48615ac0 "add S_op_clear_gv() to op.c" did was creating a pointer alias. GV * gv\, in 1 one branch might be created from "(GV*(*svp)".

That commit didn't introduce the aliasing - that was already present - it just moved the code into a separate function.

I've attached a patch which fixes the lack of Win32 GCC miniperl not having fno-strict-aliasing.

I think that is the correct approach.

Confirmed it fixes the problem here too\, so now applied in commit c0388966161bb22622ebac402bb1ebe081ad0b39.

Many thanks for fixing this!

p5pRT commented 9 years ago

@steve-m-hay - Status changed from 'open' to 'pending release'

p5pRT commented 9 years ago

From @khwilliamson

Thank you for submitting this ticket.

The issue should now be resolved with the release today of Perl v5.22\, which is available at http​://www.perl.org/get.html -- Karl Williamson for the Perl 5 team

p5pRT commented 9 years ago

@khwilliamson - Status changed from 'pending release' to 'resolved'