Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bleadperl breaks TOKUHIROM/Test-SharedFork-0.24 on Windows #13763

Closed
p5pRT opened this issue Apr 23, 2014 · 34 comments
Closed

Bleadperl breaks TOKUHIROM/Test-SharedFork-0.24 on Windows #13763

p5pRT opened this issue Apr 23, 2014 · 34 comments

Comments

@p5pRT
Copy link

p5pRT commented Apr 23, 2014

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

Searchable as RT121721$

@p5pRT
Copy link
Author

p5pRT commented Apr 23, 2014

From @chorny

Created by @chorny

Test 05_nest.t has segfault, but only if tests are called as "&main". With
"main()" all is ok.
Test-SharedFork is a pure-perl module and does not have non-core
dependencies.

Error reported here​: tokuhirom/Test-SharedFork#13

Tested on Strawberry perl 5.9.11.

Perl Info

Flags:
    category=core
    severity=medium

Site configuration information for perl 5.19.11:

Configured by strawberry-perl at Tue Apr 22 08:42:15 2014.

Summary of my perl5 (revision 5 version 19 subversion 11) configuration:

  Platform:
    osname=MSWin32, osvers=6.2, archname=MSWin32-x86-multi-thread-64int
    uname='Win32 strawberry-perl 5.19.11.1 #1 Tue Apr 22 08:40:30 2014 i386'
    config_args='undef'
    hint=recommended, useposix=true, d_sigaction=undef
    useithreads=define, usemultiplicity=define
    use64bitint=define, use64bitall=undef, uselongdouble=undef
    usemymalloc=n, bincompat5005=undef
  Compiler:
    cc='gcc', ccflags =' -s -O2 -DWIN32  -DPERL_TEXTMODE_SCRIPTS
-DPERL_IMPLICIT_CONTEXT -DPERL_IMPLICIT_SYS -DUSE_PERLIO
-fno-strict-aliasing -mms-bitfields',
    optimize='-s -O2',
    cppflags='-DWIN32'
    ccversion='', gccversion='4.8.2', gccosandvers=''
    intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=12345678
    d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=12
    ivtype='long long', ivsize=8, nvtype='double', nvsize=8, Off_t='long
long', lseeksize=8
    alignbytes=8, prototype=define
  Linker and Libraries:
    ld='g++', ldflags ='-s -L"C:\strawberry1911\perl\lib\CORE"
-L"C:\strawberry1911\c\lib"'
    libpth=C:\strawberry1911\c\lib C:\strawberry1911\c\i686-w64-mingw32\lib
C:\strawberry1911\c\lib\gcc\i686-w64-mingw32\4.8.2
    libs=-lmoldname -lkernel32 -luser32 -lgdi32 -lwinspool -lcomdlg32
-ladvapi32 -lshell32 -lole32 -loleaut32 -lnetapi32 -luuid -lws2_32 -lmpr
-lwinmm -lversion -lodbc32 -lodbccp32 -lcomctl32
    perllibs=-lmoldname -lkernel32 -luser32 -lgdi32 -lwinspool -lcomdlg32
-ladvapi32 -lshell32 -lole32 -loleaut32 -lnetapi32 -luuid -lws2_32 -lmpr
-lwinmm -lversion -lodbc32 -lodbccp32 -lcomctl32
    libc=, so=dll, useshrplib=true, libperl=libperl519.a
    gnulibc_version=''
  Dynamic Linking:
    dlsrc=dl_win32.xs, dlext=xs.dll, d_dlsymun=undef, ccdlflags=' '
    cccdlflags=' ', lddlflags='-mdll -s -L"C:\strawberry1911\perl\lib\CORE"
-L"C:\strawberry1911\c\lib"'



@INC for perl 5.19.11:
    C:/strawberry1911/perl/site/lib
    C:/strawberry1911/perl/vendor/lib
    C:/strawberry1911/perl/lib
    .


Environment for perl 5.19.11:
    HOME (unset)
    LANG (unset)
    LANGUAGE (unset)
    LD_LIBRARY_PATH (unset)
    LOGDIR (unset)
    PATH=C:\Program Files\Far
Manager\;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\strawberry1911\c\bin;C:\strawberry1911\perl\site\bin;C:\strawberry1911\perl\bin
    PERL_BADLANG (unset)
    PERL_HASH_SEED=0x11111111
    SHELL (unset)

-- 
Alexandr Ciornii, http://chorny.net

@p5pRT
Copy link
Author

p5pRT commented Apr 23, 2014

From @bulk88

On Wed Apr 23 13​:55​:56 2014, chorny wrote​:

This is a bug report for perl from alexchorny@​gmail.com,
generated with the help of perlbug 1.40 running under perl 5.19.11.

-----------------------------------------------------------------
[Please describe your issue here]

Test 05_nest.t has segfault, but only if tests are called as "&main".
With
"main()" all is ok.
Test-SharedFork is a pure-perl module and does not have non-core
dependencies.

Error reported here​: https://github.com/tokuhirom/Test-
SharedFork/issues/13

Tested on Strawberry perl 5.9.11.

VC 2003 32 bit 5.19.10 ish.


perl519.dll!S_sv_dup_common(interpreter * my_perl=0x00a205ec, const sv * const sstr=0xabababab, clone_params * const param=0x0012fae8) Line 12306 + 0x3 C
  perl519.dll!Perl_sv_dup_inc(interpreter * my_perl=0x00a205ec, const sv * const sstr=0xabababab, clone_params * const param=0x0012fae8) Line 12712 + 0x17 C
  perl519.dll!Perl_cx_dup(interpreter * my_perl=0x00a205ec, context * cxs=0x0036cda4, long ix=1, long max=168, clone_params * param=0x0012fae8) Line 12782 + 0x14 C
  perl519.dll!Perl_si_dup(interpreter * my_perl=0x00a205ec, stackinfo * si=0x0036bd64, clone_params * param=0x0012fae8) Line 12858 + 0x22 C
  perl519.dll!perl_clone_using(interpreter * proto_perl=0x00364824, unsigned long flags=1, IPerlMem * ipM=0x00cd92cc, IPerlMem * ipMS=0x00cd92e8, IPerlMem * ipMP=0x00cd9304, IPerlEnv * ipE=0x00cd9320, IPerlStdIO * ipStd=0x00cd9358, IPerlLIO * ipLIO=0x00cd93f4, IPerlDir * ipD=0x00cd945c, IPerlSock * ipS=0x00cd9488, IPerlProc * ipP=0x00cd9538) Line 13895 + 0x14 C
  perl519.dll!PerlProcFork(IPerlProc * piPerl=0x003677c0) Line 1832 + 0x65 C
  perl519.dll!Perl_pp_fork(interpreter * my_perl=0x00364824) Line 4021 + 0x16 C
  perl519.dll!Perl_runops_standard(interpreter * my_perl=0x00364824) Line 42 + 0xa C
  perl519.dll!S_run_body(interpreter * my_perl=0x00364824, long oldscope=1) Line 2449 + 0xd C
  perl519.dll!perl_run(interpreter * my_perl=0x00364824) Line 2368 C
  perl519.dll!RunPerl(int argc=2, char * * argv=0x00362c68, char * * env=0x003664f0) Line 259 + 0x9 C
  perl.exe!main(int argc=2, char * * argv=0x00362c68, char * * env=0x00363528) Line 23 + 0x12 C
  perl.exe!mainCRTStartup() Line 398 + 0xe C
  kernel32.dll!_BaseProcessStart@​4() + 0x23


Unhandled exception at 0x28062a1c (perl519.dll) in perl.exe​: 0xC0000005​: Access violation reading location 0xabababb3.


SV * sstr is 0xabababb3


/* duplicate an SV of any type (including AV, HV etc) */

static SV *
S_sv_dup_common(pTHX_ const SV *const sstr, CLONE_PARAMS *const param)
{
  dVAR;
  SV *dstr;

  PERL_ARGS_ASSERT_SV_DUP_COMMON;

  if (SvTYPE(sstr) == (svtype)SVTYPEMASK) {<<<<<<<<<<<<<<<CRASH
#ifdef DEBUG_LEAKING_SCALARS_ABORT
  abort();
#endif
  return NULL;
  }


attached pic of var dump of var context * ncx in Perl_cx_dup.

--
bulk88 ~ bulk88 at hotmail.com

@p5pRT
Copy link
Author

p5pRT commented Apr 23, 2014

From @bulk88

sharedforkcrash.PNG

@p5pRT
Copy link
Author

p5pRT commented Apr 23, 2014

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

@p5pRT
Copy link
Author

p5pRT commented Apr 23, 2014

From @bulk88

No idea why the patch works or if its appropriate but it stopped the crash. Without a rational of why these werent null before. Or why it didn't crash before. This shouldn't be applied. I got no crashed on AP 5.10 and VC 5.12 and SP Win32 strawberry-perl 5.18.0.1. It might be because the bug isn't there in older Perls, or by chance the uninit memory was filled with NULL so no crash.

--
bulk88 ~ bulk88 at hotmail.com

@p5pRT
Copy link
Author

p5pRT commented Apr 23, 2014

From @bulk88

0001-WIP-no-idea-why-it-works-or-if-its-correct.patch
From 5ef2f410578fbe4a6cfd9b8f8d22661224afad8f Mon Sep 17 00:00:00 2001
From: Daniel Dragan <bulk88@hotmail.com>
Date: Wed, 23 Apr 2014 19:21:04 -0400
Subject: [PATCH] WIP no idea why it works or if its correct

---
 pp_hot.c  |    5 ++++-
 pp_sort.c |    5 ++++-
 2 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/pp_hot.c b/pp_hot.c
index ac69bc7..61acdf5 100644
--- a/pp_hot.c
+++ b/pp_hot.c
@@ -2715,7 +2715,10 @@ try_autoload:
 		}
 		MARK++;
 	    }
-	}
+	} else {
+            cx->blk_sub.savearray = NULL;
+	    cx->blk_sub.argarray = NULL;
+        }
 	SAVETMPS;
 	if (UNLIKELY((cx->blk_u16 & OPpENTERSUB_LVAL_MASK) == OPpLVAL_INTRO &&
 	    !CvLVALUE(cv)))
diff --git a/pp_sort.c b/pp_sort.c
index 0fe0411..ff5f34d 100644
--- a/pp_sort.c
+++ b/pp_sort.c
@@ -1695,7 +1695,10 @@ PP(pp_sort)
 			GvAV(PL_defgv) = MUTABLE_AV(SvREFCNT_inc_simple(av));
 			CX_CURPAD_SAVE(cx->blk_sub);
 			cx->blk_sub.argarray = av;
-		    }
+		    } else {
+                        cx->blk_sub.savearray = NULL;
+                        cx->blk_sub.argarray = NULL;
+                    }
 
 		}
 	    }
-- 
1.7.9.msysgit.0

@p5pRT
Copy link
Author

p5pRT commented Apr 24, 2014

From @chorny

I've simplified this code, so it can be converted to test.

&main;
sub main {
  fork;
}

P.S. Is run_multiple_progs from test.pl documented anywhere?

--
Alexandr Ciornii, http​://chorny.net

@p5pRT
Copy link
Author

p5pRT commented Apr 24, 2014

From [Unknown Contact. See original ticket]

I've simplified this code, so it can be converted to test.

&main;
sub main {
  fork;
}

P.S. Is run_multiple_progs from test.pl documented anywhere?

--
Alexandr Ciornii, http​://chorny.net

@p5pRT
Copy link
Author

p5pRT commented Apr 24, 2014

From @iabyn

On Wed, Apr 23, 2014 at 04​:29​:48PM -0700, bulk88 via RT wrote​:

No idea why the patch works or if its appropriate but it stopped the
crash. Without a rational of why these werent null before. Or why it
didn't crash before. This shouldn't be applied. I got no crashed on AP
5.10 and VC 5.12 and SP Win32 strawberry-perl 5.18.0.1. It might be
because the bug isn't there in older Perls, or by chance the uninit
memory was filled with NULL so no crash.

It might be better to just skip duping savearray and argarray
unless CxHASARGS(cx) is true. In fact looking at Perl_cx_dup(), I see it
already does that check for argarray; I guess it just needs extending to
handle savearray too.

As to why it didn't previously fail, I don't know. New CX stacks have
been being poisoned for many years, so getting 0xababab.. is nothing new.
I guess someone with Windows access needs to run a debugger on 5.18.0 or
whatever and see what savearray is set to.

--
The crew of the Enterprise encounter an alien life form which is
surprisingly neither humanoid nor made from pure energy.
  -- Things That Never Happen in "Star Trek" #22

@p5pRT
Copy link
Author

p5pRT commented Apr 25, 2014

From @bulk88

On Wed Apr 23 17​:08​:50 2014, chorny wrote​:

I've simplified this code, so it can be converted to test.

&main;
sub main {
fork;
}

P.S. Is run_multiple_progs from test.pl documented anywhere?

Crashed on DEBUGGING VC 2003 32 bit with psuedofork 5.12.


  perl512.dll!Perl_sv_dup(interpreter * my_perl=0x00830eec, const sv * const sstr=0xabababab, clone_params * const param=0x0006fa48) Line 10966 + 0x3 C
  perl512.dll!Perl_cx_dup(interpreter * my_perl=0x00830eec, context * cxs=0x0039989c, long ix=1, long max=168, clone_params * param=0x0006fa48) Line 11340 + 0x14 C
  perl512.dll!Perl_si_dup(interpreter * my_perl=0x00830eec, stackinfo * si=0x00392564, clone_params * param=0x0006fa48) Line 11413 + 0x22 C
  perl512.dll!perl_clone_using(interpreter * proto_perl=0x00394004, unsigned long flags=1, IPerlMem * ipM=0x0028600c, IPerlMem * ipMS=0x00286028, IPerlMem * ipMP=0x00286044, IPerlEnv * ipE=0x00286060, IPerlStdIO * ipStd=0x00286098, IPerlLIO * ipLIO=0x00286134, IPerlDir * ipD=0x0028619c, IPerlSock * ipS=0x002861c8, IPerlProc * ipP=0x00286278) Line 12421 + 0x17 C
  perl512.dll!PerlProcFork(IPerlProc * piPerl=0x002858d8) Line 1859 + 0x65 C++
  perl512.dll!Perl_pp_fork(interpreter * my_perl=0x00394004) Line 4082 + 0x16 C
  perl512.dll!Perl_runops_debug(interpreter * my_perl=0x00394004) Line 2049 + 0xd C
  perl512.dll!S_run_body(interpreter * my_perl=0x00394004, long oldscope=1) Line 2308 + 0xd C
  perl512.dll!perl_run(interpreter * my_perl=0x00394004) Line 2233 + 0xd C
  perl512.dll!RunPerl(int argc=2, char * * argv=0x00283f88, char * * env=0x00282758) Line 270 + 0x9 C++
  perl.exe!main(int argc=2, char * * argv=0x00283f88, char * * env=0x00282d38) Line 23 + 0x12 C
  perl.exe!mainCRTStartup() Line 398 + 0xe C
  kernel32.dll!_BaseProcessStart@​4() + 0x23


No crash on AP 5.10, but that isn't proof the bug isn't in 5.10 since this is uninit mem bug.

--
bulk88 ~ bulk88 at hotmail.com

@p5pRT
Copy link
Author

p5pRT commented Apr 25, 2014

From @bulk88

On Thu Apr 24 08​:36​:45 2014, davem wrote​:

On Wed, Apr 23, 2014 at 04​:29​:48PM -0700, bulk88 via RT wrote​:

It might be better to just skip duping savearray and argarray
unless CxHASARGS(cx) is true. In fact looking at Perl_cx_dup(), I see it
already does that check for argarray; I guess it just needs extending to
handle savearray too.

As to why it didn't previously fail, I don't know. New CX stacks have
been being poisoned for many years, so getting 0xababab..

Why are we poisoning *anything*at*all* in a non-PERL_POISON or atleast a non-DEBUGGING build? (note DEBUGGING builds atleast on Win32 aren't PERL_POISON builds (why? (valgrind?)), I've used -DPERL_POISON a couple times in history).

The 2 scope.c mentioned in this patch, which is were I *think* (and I know as much about this area perl internals as a drunk bum) context structs are alloced, git blame to http​://perl5.git.perl.org/perl.git/commitdiff/7e337ee0bc836d3147f3b2579c7e35127637e377 and then to background-less, useless description, commit from 2002/ithreads beginnings era http​://perl5.git.perl.org/perl.git/commitdiff/9965345dfe11415fe4409828505acf6c7fe193b9 which sounds like debugging code that someone forgot to remove for a problem that is lost to time. Technically, I think, reverting that commit to zero the structs instead of poisoning and therefore the SV * dup code will return a NULL SV* in child thread when passes NULL SV * (designed behavior) from parent thread instead of duping SV* 0xabababab.

Some other questions to answer, since a memset is already done on the context structs, switching it to zero it, instead of poison, and NOT have else {} blocks in the sloppy patch above would be more efficient, or not? Or remove the memset, regardless if its NULLing or poisoning, and just use the else blocks?

Should there be asserts for segv readability of those extra members of a context struct?

Why don't we have variable length context structs if in some cases we dont ever set later members in it?

I guess someone with Windows access needs to run a debugger on 5.18.0 or
whatever and see what savearray is set to.

set to exactly where (I need a file and line number/C func name)?

Kentnl on #p5p wants this to be a 5.20 blocker, something about Catalyst he said. IDK when I'll have time to deal with this further, and I might not have any time before 5-20-14. TonyC/SteveH feel free to fix it if I dont get around to it.

--
bulk88 ~ bulk88 at hotmail.com

@p5pRT
Copy link
Author

p5pRT commented Apr 25, 2014

From @iabyn

On Fri, Apr 25, 2014 at 12​:56​:30AM -0700, bulk88 via RT wrote​:

On Thu Apr 24 08​:36​:45 2014, davem wrote​:

On Wed, Apr 23, 2014 at 04​:29​:48PM -0700, bulk88 via RT wrote​:

It might be better to just skip duping savearray and argarray
unless CxHASARGS(cx) is true. In fact looking at Perl_cx_dup(), I see it
already does that check for argarray; I guess it just needs extending to
handle savearray too.

As to why it didn't previously fail, I don't know. New CX stacks have
been being poisoned for many years, so getting 0xababab..

Why are we poisoning *anything*at*all* in a non-PERL_POISON or atleast a
non-DEBUGGING build? (note DEBUGGING builds atleast on Win32 aren't
PERL_POISON builds (why? (valgrind?)), I've used -DPERL_POISON a couple
times in history).

Well the comments in the code say​:

  /* Without any kind of initialising PUSHSUBST()
  * in pp_subst() will read uninitialised heap. */
  PoisonNew(si->si_cxstack, cxitems, PERL_CONTEXT);

Based on that and the commit history, it appears that for some reason
pp_subst required the newly allocated context stack to be initialised;
originally it was intialised to zero, then someone decided it would be
better to poison it instead, as that is more likely to flush out bugs.
Whether it still needs initialising, I don't know.

The 2 scope.c mentioned in this patch, which is were I *think* (and I
know as much about this area perl internals as a drunk bum) context
structs are alloced, git blame to
http​://perl5.git.perl.org/perl.git/commitdiff/7e337ee0bc836d3147f3b2579c7e35127637e377
and then to background-less, useless description, commit from
2002/ithreads beginnings era
http​://perl5.git.perl.org/perl.git/commitdiff/9965345dfe11415fe4409828505acf6c7fe193b9
which sounds like debugging code that someone forgot to remove for a
problem that is lost to time. Technically, I think, reverting that
commit to zero the structs instead of poisoning and therefore the SV *
dup code will return a NULL SV* in child thread when passes NULL SV *
(designed behavior) from parent thread instead of duping SV* 0xabababab.

Note that this poisoning is only done when the stack is first allocated,
not each time a ne context is pushed. We're only seeing the 0xabab...
becuase at the point we fork, there has never been a sub call with args
at the lowest level.

Reemoving the poisoning wont fix this bug, it just means that whatever is
left in the savearray slot from some previous context push will be used
as an address to dup.

Some other questions to answer, since a memset is already done on the
context structs, switching it to zero it, instead of poison, and NOT
have else {} blocks in the sloppy patch above would be more efficient,
or not? Or remove the memset, regardless if its NULLing or poisoning,
and just use the else blocks?

see above.

Should there be asserts for segv readability of those extra members of a
context struct?

Why don't we have variable length context structs if in some cases we
dont ever set later members in it?

Because that would complicate matters. The only time these fields aren't
set is in an argumentless function call, i.e.

  &foo;

(as oppposed to foo() or &foo()).

In this case the CxHASARGS() flag wont be set, and all the relevant code
knows to ignore these two fields - except for that bug in Perl_cx_dup().

So I still think the simple and correct fix for this is to test for
CxHASARGS() in Perl_cx_dup. You haven't commented on this suggestion yet.

I guess someone with Windows access needs to run a debugger on 5.18.0 or
whatever and see what savearray is set to.

set to exactly where (I need a file and line number/C func name)?

In Perl_cx_dup() at the point where it tries to dup() the 'bad' savearray;
i.e. sv.c line 12781. If it hasn't got the value 0xabab... at that point
in 5.18.0, while it does in blead, then we need to understand why.

--
"You're so sadly neglected, and often ignored.
A poor second to Belgium, When going abroad."
  -- Monty Python, "Finland"

@p5pRT
Copy link
Author

p5pRT commented Apr 26, 2014

From @bulk88

Crashed in same way on Perl 5.10.1 DEBUGGING.


C​:\Documents and Settings\Owner\Desktop>perl -V
Summary of my perl5 (revision 5 version 10 subversion 1 patch maint-5.10 2009-08
-22.22​:20​:57 5348deb perl-5.10.1) configuration
:
  Snapshot of​: 5348deb
  Platform​:
  osname=MSWin32, osvers=5.1, archname=MSWin32-x86-multi-thread


perl510.dll!Perl_sv_dup(interpreter * my_perl=0x01831d24, const sv * sstr=0xabababab, clone_params * param=0x0140fa48) Line 10539 + 0x3 C
  perl510.dll!Perl_cx_dup(interpreter * my_perl=0x01831d24, context * cxs=0x00349eb4, long ix=1, long max=126, clone_params * param=0x0140fa48) Line 10894 + 0x14 C
  perl510.dll!Perl_si_dup(interpreter * my_perl=0x01831d24, stackinfo * si=0x00348d44, clone_params * param=0x0140fa48) Line 10956 + 0x22 C
  perl510.dll!perl_clone_using(interpreter * proto_perl=0x003423b4, unsigned long flags=1, IPerlMem * ipM=0x0023700c, IPerlMem * ipMS=0x00237028, IPerlMem * ipMP=0x00237044, IPerlEnv * ipE=0x00237060, IPerlStdIO * ipStd=0x00237098, IPerlLIO * ipLIO=0x00237134, IPerlDir * ipD=0x0023719c, IPerlSock * ipS=0x002371c8, IPerlProc * ipP=0x00237278) Line 11996 + 0x17 C
  perl510.dll!PerlProcFork(IPerlProc * piPerl=0x00236ab8) Line 1846 + 0x65 C
  perl510.dll!Perl_pp_fork(interpreter * my_perl=0x003423b4) Line 3998 + 0x16 C
  perl510.dll!Perl_runops_debug(interpreter * my_perl=0x003423b4) Line 1968 + 0xd C
  perl510.dll!S_run_body(interpreter * my_perl=0x003423b4, long oldscope=1) Line 2431 + 0xd C
  perl510.dll!perl_run(interpreter * my_perl=0x003423b4) Line 2349 + 0xd C
  perl510.dll!RunPerl(int argc=2, char * * argv=0x00234c80, char * * env=0x00232b90) Line 270 + 0x9 C
  perl.exe!main(int argc=2, char * * argv=0x00234c80, char * * env=0x00233338) Line 23 + 0x12 C
  perl.exe!mainCRTStartup() Line 398 + 0xe C
  kernel32.dll!_BaseProcessStart@​4() + 0x23


but it doesn't crash on AP 5.10.0. I'll try building a debugging 5.10.0.

--
bulk88 ~ bulk88 at hotmail.com

@p5pRT
Copy link
Author

p5pRT commented Apr 27, 2014

From @bulk88

On Sat Apr 26 15​:14​:57 2014, bulk88 wrote​:

but it doesn't crash on AP 5.10.0. I'll try building a debugging
5.10.0.

DEBUGGING 5.10.0 crashes. The member offset of cx->blk_sub.savearray in context struct between my DEBUGGING 5.10.0 and my AP 5.10.0 are different asm wise. Still trying to figure out exactly why AP 5.10.0 isn't crashing.

--
bulk88 ~ bulk88 at hotmail.com

@p5pRT
Copy link
Author

p5pRT commented Apr 27, 2014

From @bulk88

On Sat Apr 26 20​:11​:20 2014, bulk88 wrote​:

On Sat Apr 26 15​:14​:57 2014, bulk88 wrote​:

but it doesn't crash on AP 5.10.0. I'll try building a debugging
5.10.0.

DEBUGGING 5.10.0 crashes. The member offset of cx->blk_sub.savearray
in context struct between my DEBUGGING 5.10.0 and my AP 5.10.0 are
different asm wise. Still trying to figure out exactly why AP 5.10.0
isn't crashing.

AP, -O1


10363​: ncx->blk_sub.savearray = av_dup_inc(cx->blk_sub.savearray, param);
2807ADA3 FF 75 18 push dword ptr [param]
2807ADA6 89 47 24 mov dword ptr [edi+24h],eax
2807ADA9 FF 76 18 push dword ptr [esi+18h]
2807ADAC 53 push ebx
2807ADAD E8 01 F4 FF FF call Perl_sv_dup (2807A1B3h)


DEBUGGING -Od


10363​: ncx->blk_sub.savearray = av_dup_inc(cx->blk_sub.savearray, param);
280711A6 8B 55 18 mov edx,dword ptr [param]
280711A9 52 push edx
280711AA 8B 45 F8 mov eax,dword ptr [cx]
280711AD 8B 48 24 mov ecx,dword ptr [eax+24h]
280711B0 51 push ecx
280711B1 8B 55 08 mov edx,dword ptr [my_perl]
280711B4 52 push edx
280711B5 E8 E6 77 FF FF call Perl_sv_dup (280689A0h)


Offsets are different because a compiler optimization keeps the context * at +0xC for the life of the C function instead of 0x0, and 0xC+0x18 add to 0x24. False alarm.

The context struct contents in Perl_cx_dup is different between AP 5.10.0 and my DEBUGGING 5.10.0 build. IDK why yet. See attached pics, check names of the files to know which is which.

--
bulk88 ~ bulk88 at hotmail.com

@p5pRT
Copy link
Author

p5pRT commented Apr 27, 2014

@p5pRT
Copy link
Author

p5pRT commented Apr 27, 2014

@p5pRT
Copy link
Author

p5pRT commented Apr 27, 2014

From @bulk88

On Sat Apr 26 21​:14​:33 2014, bulk88 wrote​:

The context struct contents in Perl_cx_dup is different between AP
5.10.0 and my DEBUGGING 5.10.0 build. IDK why yet. See attached pics,
check names of the files to know which is which.

Compiled a non-DEBUGGING 5.10.0, same crash as DEBUGGING with 0xabXXXXXX SV *. Which means the AP 5.10.0 probably has a patch that isn't in blead/p5p 5.10 or 5.12. *sigh*

--
bulk88 ~ bulk88 at hotmail.com

@p5pRT
Copy link
Author

p5pRT commented Apr 27, 2014

From @bulk88

On Sat Apr 26 21​:20​:31 2014, bulk88 wrote​:

On Sat Apr 26 21​:14​:33 2014, bulk88 wrote​:

The context struct contents in Perl_cx_dup is different between AP
5.10.0 and my DEBUGGING 5.10.0 build. IDK why yet. See attached pics,
check names of the files to know which is which.

Compiled a non-DEBUGGING 5.10.0, same crash as DEBUGGING with
0xabXXXXXX SV *. Which means the AP 5.10.0 probably has a patch that
isn't in blead/p5p 5.10 or 5.12. *sigh*

pp_entersub in the AP, var hasargs is 1. My VC Perl, hasargs is 0. So in the AP, later on, savearray is assigned to. This doesn't happen in my VC Perl. But in the AP, it looks like the OP struct is malformed.

Putting a breakpoint in entersub with callstack


  perl510.dll!Perl_pp_entersub(interpreter * my_perl=0x00343e84) Line 2636 C
  perl510.dll!Perl_runops_debug(interpreter * my_perl=0x00343e84) Line 1931 + 0xd C
  perl510.dll!S_run_body(interpreter * my_perl=0x00343e84, long oldscope=0x00000001) Line 2384 + 0xd C
  perl510.dll!perl_run(interpreter * my_perl=0x00343e84) Line 2302 + 0xd C
  perl510.dll!RunPerl(int argc=0x00000002, char * * argv=0x00233db0, char * * env=0x00234e10) Line 266 + 0x9 C
  perl.exe!main(int argc=0x00000002, char * * argv=0x00233db0, char * * env=0x00232ee0) Line 23 + 0x12 C
  perl.exe!mainCRTStartup() Line 398 + 0xe C
  kernel32.dll!_BaseProcessStart@​4() + 0x23


shows 2 different OP structs in PL_op, the AP one doesn't have OPf_STACKED (0x40) in its flags.
--
bulk88 ~ bulk88 at hotmail.com

@p5pRT
Copy link
Author

p5pRT commented Apr 27, 2014

From @bulk88

5100DBGING_op_dump.PNG

@p5pRT
Copy link
Author

p5pRT commented Apr 27, 2014

From @bulk88

AP510_op_dump.PNG

@p5pRT
Copy link
Author

p5pRT commented Apr 27, 2014

From @bulk88

On Sun Apr 27 10​:31​:55 2014, bulk88 wrote​:

shows 2 different OP structs in PL_op, the AP one doesn't have
OPf_STACKED (0x40) in its flags.

Correction, AP5100 has OPf_STACKED, my 5100DBG doesn't. Note the AP one has no pp_addr. I wrote a script (noargscrash.pl) to dump the optree, it now crashes AP5100 in a similar but different way as in 5100DBG. It is attached.

AP running noargscrash.pl


  perl510.dll!Perl_sv_dup(interpreter * my_perl=0x019437bc, const sv * sstr=0x0000004c, clone_params * param=0x0140fa70) Line 10012 + 0xb C
  perl510.dll!Perl_cx_dup(interpreter * my_perl=0x01a0d4cc, context * cxs=0x00000003, long ix=0x00000002, long max=0xfe82eb58, clone_params * param=0x0140fa70) Line 10363 + 0xf C
  perl510.dll!Perl_si_dup(interpreter * my_perl=0x019437bc, stackinfo * si=0x00235fb4, clone_params * param=0x0140fa70) Line 10436 C
  perl510.dll!perl_clone_using(interpreter * proto_perl=0x00233f8c, unsigned long flags=0x00000001, IPerlMem * ipM=0x018e75dc, IPerlMem * ipMS=0x00000000, IPerlMem * ipMP=0x018dfdbc, IPerlEnv * ipE=0x018dfdd8, IPerlStdIO * ipStd=0x018dfe10, IPerlLIO * ipLIO=0x018dfeac, IPerlDir * ipD=0x018dff14, IPerlSock * ipS=0x018dff40, IPerlProc * ipP=0x018dfff0) Line 11442 + 0x10 C
  perl510.dll!PerlProcFork(IPerlProc * piPerl=0x00235898) Line 1846 + 0x3e C++
  perl510.dll!Perl_pp_fork(interpreter * my_perl=0x00233f8c) Line 3988 + 0xa C
  perl510.dll!Perl_runops_standard(interpreter * my_perl=0x00233f8c) Line 36 + 0xc C
  perl510.dll!S_run_body(interpreter * my_perl=0x00233f8c, long oldscope=0x00000001) Line 2385 + 0x7 C
  perl510.dll!perl_run(interpreter * my_perl=0x00233f8c) Line 2303 + 0xa C
  perl510.dll!RunPerl(int argc=0x00000002, char * * argv=0x00233f40, char * * env=0x01232d28) Line 266 + 0x6 C++
  perl.exe!main(int argc=0x00000002, char * * argv=0x00233f40, char * * env=0x00232d28) Line 22 + 0x12 C
  perl.exe!_mainCRTStartup() + 0xe3
  kernel32.dll!_BaseProcessStart@​4() + 0x23


5100 no dbging


  perl510.dll!Perl_sv_dup(interpreter * my_perl=0x019425a4, const sv * sstr=0x0000004c, clone_params * param=0x0140fa50) Line 10012 + 0x9 C
  perl510.dll!Perl_cx_dup(interpreter * my_perl=0x019425a4, context * cxs=0x0034a934, long ix=0x00000002, long max=0x0000007e, clone_params * param=0x0140fa50) Line 10363 + 0x14 C
  perl510.dll!Perl_si_dup(interpreter * my_perl=0x019425a4, stackinfo * si=0x0034246c, clone_params * param=0x0140fa50) Line 10434 + 0x22 C
  perl510.dll!perl_clone_using(interpreter * proto_perl=0x00343f94, unsigned long flags=0x00000001, IPerlMem * ipM=0x0023600c, IPerlMem * ipMS=0x00236028, IPerlMem * ipMP=0x00236044, IPerlEnv * ipE=0x00236060, IPerlStdIO * ipStd=0x00236098, IPerlLIO * ipLIO=0x00236134, IPerlDir * ipD=0x0023619c, IPerlSock * ipS=0x002361c8, IPerlProc * ipP=0x00236278) Line 11442 + 0x17 C
  perl510.dll!PerlProcFork(IPerlProc * piPerl=0x00235aa0) Line 1846 + 0x65 C++
  perl510.dll!Perl_pp_fork(interpreter * my_perl=0x00343f94) Line 3988 + 0x16 C
  perl510.dll!Perl_runops_standard(interpreter * my_perl=0x00343f94) Line 38 + 0xd C
  perl510.dll!S_run_body(interpreter * my_perl=0x00343f94, long oldscope=0x00000001) Line 2384 + 0xd C
  perl510.dll!perl_run(interpreter * my_perl=0x00343f94) Line 2302 + 0xd C
  perl510.dll!RunPerl(int argc=0x00000002, char * * argv=0x00233ed0, char * * env=0x00232980) Line 266 + 0x9 C++
  perl.exe!main(int argc=0x00000002, char * * argv=0x00233ed0, char * * env=0x00232d00) Line 23 + 0x12 C
  perl.exe!mainCRTStartup() Line 398 + 0xe C
  kernel32.dll!_BaseProcessStart@​4() + 0x23


AP


C​:\Documents and Settings\Owner\Desktop>perl noargcrash.pl
B​::Concise​::compile(CODE(0x182a33c))
# 5​: &main;
1 <;> nextstate(main -8 noargcrash.pl​:5) v
2 <0> pushmark s
3 <#> gv[*main] s
4 <1> entersub[t2] K/TARG,AMPER,1
5 <1> leavesub[1 ref] K/REFC,1
**crash**
C​:\Documents and Settings\Owner\Desktop>perl -v

This is perl, v5.10.0 built for MSWin32-x86-multi-thread
(with 5 registered patches, see perl -V for more detail)

Copyright 1987-2007, Larry Wall

Binary build 1003 [285500] provided by ActiveState http​://www.ActiveState.com
Built May 13 2008 16​:52​:49

Perl may be copied only under the terms of either the Artistic License or the
GNU General Public License, which may be found in the Perl 5 source kit.

Complete documentation for Perl, including FAQ lists, should be found on
this system using "man perl" or "perldoc perl". If you have access to the
Internet, point your browser at http​://www.perl.org/, the Perl Home Page.

C​:\Documents and Settings\Owner\Desktop>


My 5100


C​:\Documents and Settings\Owner\Desktop>perl noargcrash.pl
B​::Concise​::compile(CODE(0x1827ed4))
# 5​: &main;
1 <;> nextstate(main -8 noargcrash.pl​:5) v
2 <0> pushmark s
3 <#> gv[*main] s
4 <1> entersub[t2] K/TARG,AMPER,1
5 <1> leavesub[1 ref] K/REFC,1
**crash**
C​:\Documents and Settings\Owner\Desktop>perl -v

This is perl, v5.10.0 built for MSWin32-x86-multi-thread

Copyright 1987-2007, Larry Wall

Perl may be copied only under the terms of either the Artistic License or the
GNU General Public License, which may be found in the Perl 5 source kit.

Complete documentation for Perl, including FAQ lists, should be found on
this system using "man perl" or "perldoc perl". If you have access to the
Internet, point your browser at http​://www.perl.org/, the Perl Home Page.

C​:\Documents and Settings\Owner\Desktop>


IDK how to dump the root psuedo CV with Concise, since if the "&main;" call is in a sub, a different bug/callstack crash happens, vs if "&main;" is in root psuedo sub.

--
bulk88 ~ bulk88 at hotmail.com

@p5pRT
Copy link
Author

p5pRT commented Apr 27, 2014

From @bulk88

noargcrash.pl

@p5pRT
Copy link
Author

p5pRT commented Apr 27, 2014

From @bulk88

noargcrash.pl does *NOT* crash on blead.


C​:\Documents and Settings\Owner\Desktop>perl noargcrash.pl
B​::Concise​::compile(CODE(0x8fb104))
# 5​: &main;
1 <;> nextstate(main -8 noargcrash.pl​:5) v
2 <0> pushmark s
3 <#> gv[*main] s
4 <1> entersub[t2] K/TARG,8
5 <1> leavesub[1 ref] K/REFC,1

C​:\Documents and Settings\Owner\Desktop>perl -v

This is perl 5, version 19, subversion 11 (v5.19.11) built for MSWin32-x86-multi
-thread
(with 1 registered patch, see perl -V for more detail)

Copyright 1987-2014, Larry Wall

Perl may be copied only under the terms of either the Artistic License or the
GNU General Public License, which may be found in the Perl 5 source kit.

Complete documentation for Perl, including FAQ lists, should be found on
this system using "man perl" or "perldoc perl". If you have access to the
Internet, point your browser at http​://www.perl.org/, the Perl Home Page.

C​:\Documents and Settings\Owner\Desktop>


--
bulk88 ~ bulk88 at hotmail.com

@p5pRT
Copy link
Author

p5pRT commented Apr 27, 2014

From @bulk88

On Sun Apr 27 11​:21​:58 2014, bulk88 wrote​:

noargcrash.pl does *NOT* crash on blead.

Because I patched blead and forgot to revert it. DOPE

--
bulk88 ~ bulk88 at hotmail.com

@p5pRT
Copy link
Author

p5pRT commented Apr 28, 2014

From @bulk88

On Sun Apr 27 13​:17​:24 2014, bulk88 wrote​:

On Sun Apr 27 11​:21​:58 2014, bulk88 wrote​:

noargcrash.pl does *NOT* crash on blead.

Because I patched blead and forgot to revert it. DOPE

noargcrash.pl (paramless main call in a sub) on blead and SP 5.18 and 5.12 doesn't crash. On 5.10 it crashes.

paramless main call in root crashes on 5.10, 5.12, 5.18, and blead

paramless main call in root is


&main;
sub main {
  fork;
}


--
bulk88 ~ bulk88 at hotmail.com

@p5pRT
Copy link
Author

p5pRT commented Apr 28, 2014

From @iabyn

On Sun, Apr 27, 2014 at 10​:40​:38PM -0700, bulk88 via RT wrote​:

On Sun Apr 27 13​:17​:24 2014, bulk88 wrote​:

On Sun Apr 27 11​:21​:58 2014, bulk88 wrote​:

noargcrash.pl does *NOT* crash on blead.

Because I patched blead and forgot to revert it. DOPE

noargcrash.pl (paramless main call in a sub) on blead and SP 5.18 and 5.12 doesn't crash. On 5.10 it crashes.

paramless main call in root crashes on 5.10, 5.12, 5.18, and blead

paramless main call in root is
------------------------
&main;
sub main {
fork;
}
------------------------

I think we can conclude from this that the bug has always been present,
and that therefore we no longer need to worry why it wasn't failing
earlier. So I've now pushed the following fix (untested on win32)​:

commit 9625867
Author​: David Mitchell <davem@​iabyn.com>
AuthorDate​: Mon Apr 28 11​:50​:20 2014 +0100
Commit​: David Mitchell <davem@​iabyn.com>
CommitDate​: Mon Apr 28 12​:06​:37 2014 +0100

  Pseudo-fork dups arg array on argless calls
 
  RT #121721.
 
  A subroutine call like &foo; pushes a SUB context with the savearray field
  unassigned, and with CxHASARGS() false. Most of the core knows not to use
  this field without CxHASARGS() being true​: except for Perl_cx_dup(),
  which was still trying to dup it. This could lead to SEGVs on a fresh CX
  stack, or possibly duping some other sub's @​_ on a reused stack entry.
 
  The fix is simple; don't dup this field unless CxHASARGS() is set.
  Note that a similar test is already in place for the argarray field.

--
Overhead, without any fuss, the stars were going out.
  -- Arthur C Clarke

@p5pRT
Copy link
Author

p5pRT commented Apr 28, 2014

@iabyn - Status changed from 'open' to 'resolved'

@p5pRT
Copy link
Author

p5pRT commented Apr 29, 2014

From @bulk88

This needs to be reopened until perldelta is written. There was none in http​://perl5.git.perl.org/perl.git/commit/96258673547f51dc588c290d9c8ff3d9b2b93397

--
bulk88 ~ bulk88 at hotmail.com

@p5pRT
Copy link
Author

p5pRT commented May 5, 2014

@tonycoz - Status changed from 'resolved' to 'open'

@p5pRT
Copy link
Author

p5pRT commented May 6, 2014

From @tonycoz

On Wed Apr 23 17​:08​:50 2014, chorny wrote​:

P.S. Is run_multiple_progs from test.pl documented anywhere?

The data format is documented from line 997 in t/test.pl.

Tony

@p5pRT
Copy link
Author

p5pRT commented May 6, 2014

From @rjbs

On Tue Apr 29 08​:51​:35 2014, bulk88 wrote​:

This needs to be reopened until perldelta is written. There was none
in
http​://perl5.git.perl.org/perl.git/commit/96258673547f51dc588c290d9c8ff3d9b2b93397

I suggest something along the lines of "a bug leading to stack corruption when calling a sub with ampersand in a pseudo-forking perl has been fixed," in the Selected Bug Fixes section. If you concur, I will apply it in my perldelta branch.

--
rjbs

@p5pRT
Copy link
Author

p5pRT commented May 7, 2014

From @tonycoz

On Tue Apr 29 08​:51​:35 2014, bulk88 wrote​:

This needs to be reopened until perldelta is written. There was none
in
http​://perl5.git.perl.org/perl.git/commit/96258673547f51dc588c290d9c8ff3d9b2b93397

Done as 32f39bf* in rjbs/perldelta.

Tony

* until the branch is rebased

@p5pRT
Copy link
Author

p5pRT commented May 7, 2014

@tonycoz - Status changed from 'open' to 'resolved'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant