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

[BUG 5.005_03 and 5.005_61 mg.c] POPSTACK panic at line 1126 #485

Closed
p5pRT opened this issue Sep 7, 1999 · 7 comments
Closed

[BUG 5.005_03 and 5.005_61 mg.c] POPSTACK panic at line 1126 #485

p5pRT opened this issue Sep 7, 1999 · 7 comments

Comments

@p5pRT
Copy link

p5pRT commented Sep 7, 1999

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

Searchable as RT1327$

@p5pRT
Copy link
Author

p5pRT commented Sep 7, 1999

From @schwern

ok 274
panic​: POPSTACK at #1126, mg.c

In the Perl code, the panic occurs at a fairly mundane place​:
  push @​​::failed, $ok_count unless $_[0];

I dug into the code and found out its failing at the POPSTACK macro
call in mg.c at line 1126. Reason? PL_curstackinfo->si_prev is
empty. Not being very adept with gdb, I can't elaborate much further,
but I can provide a backtrace for what its worth​:

[This is immediately before POPSTACK is called]

#0 Perl_magic_wipepack (sv=0x818b0b0, mg=0x81e6b08) at mg.c​:1126
#1 0x80a10bb in Perl_mg_clear (sv=0x818b0b0) at mg.c​:219
#2 0x80a85c9 in Perl_hv_clear (hv=0x818b0b0) at hv.c​:956
#3 0x80ae959 in Perl_pp_aassign () at pp_hot.c​:680
#4 0x80abbee in Perl_runops_debug () at run.c​:57
#5 0x80e0df3 in S_docatch_body (args=0xbffff42c) at pp_ctl.c​:2418
#6 0x80d532e in Perl_vdefault_protect (excpt=0xbffff448,
  body=0x80e0de4 <S_docatch_body>, args=0xbffff414) at scope.c​:44
#7 0x80d5260 in Perl_default_protect (excpt=0xbffff448,
  body=0x80e0de4 <S_docatch_body>) at scope.c​:25
#8 0x80e0e5c in S_docatch (o=0x81a2f48) at pp_ctl.c​:2434
#9 0x80e3a54 in Perl_pp_entertry () at pp_ctl.c​:3167
#10 0x80abbee in Perl_runops_debug () at run.c​:57
#11 0x805cecd in S_call_xbody (myop=0xbffff518, is_eval=0) at perl.c​:1347
#12 0x805c87e in perl_call_sv (sv=0x819e3c8, flags=2) at perl.c​:1235
#13 0x805c67d in perl_call_method (methname=0x8116b38 "CLEAR", flags=2)
  at perl.c​:1182
#14 0x80a3806 in Perl_magic_wipepack (sv=0x818b0b0, mg=0x81e6b08) at mg.c​:1125
#15 0x80a10bb in Perl_mg_clear (sv=0x818b0b0) at mg.c​:219
#16 0x80a85c9 in Perl_hv_clear (hv=0x818b0b0) at hv.c​:956
#17 0x80ae959 in Perl_pp_aassign () at pp_hot.c​:680
#18 0x80abbee in Perl_runops_debug () at run.c​:57
#19 0x80e0df3 in S_docatch_body (args=0xbffff7dc) at pp_ctl.c​:2418
#20 0x80d532e in Perl_vdefault_protect (excpt=0xbffff7f8,
  body=0x80e0de4 <S_docatch_body>, args=0xbffff7c4) at scope.c​:44
#21 0x80d5260 in Perl_default_protect (excpt=0xbffff7f8,
  body=0x80e0de4 <S_docatch_body>) at scope.c​:25
#22 0x80e0e5c in S_docatch (o=0x81e7088) at pp_ctl.c​:2434
#23 0x80e2e25 in Perl_pp_require () at pp_ctl.c​:3007
#24 0x80abbee in Perl_runops_debug () at run.c​:57
#25 0x805cecd in S_call_xbody (myop=0xbffff938, is_eval=0) at perl.c​:1347
#26 0x805c87e in perl_call_sv (sv=0x819e17c, flags=2) at perl.c​:1235
#27 0x805c67d in perl_call_method (methname=0x8116b21 "STORE", flags=2)
  at perl.c​:1182
#28 0x80a2dae in S_magic_methcall (sv=0x81a25e8, mg=0x81e6bc8,
  meth=0x8116b21 "STORE", flags=2, n=3, val=0x81a25e8) at mg.c​:1046
#29 0x80a3208 in Perl_magic_setpack (sv=0x81a25e8, mg=0x81e6bc8) at mg.c​:1083
#30 0x80a0e50 in Perl_mg_set (sv=0x81a25e8) at mg.c​:140
#31 0x80ac390 in Perl_pp_sassign () at pp_hot.c​:124
#32 0x80abbee in Perl_runops_debug () at run.c​:57
#33 0x805c279 in S_run_body (args=0xbffffbf0) at perl.c​:1072
#34 0x80d532e in Perl_vdefault_protect (excpt=0xbffffc14,
  body=0x805c10c <S_run_body>, args=0xbffffbd4) at scope.c​:44
#35 0x80d5260 in Perl_default_protect (excpt=0xbffffc14,
  body=0x805c10c <S_run_body>) at scope.c​:25
#36 0x805bed7 in perl_run (my_perl=0x8128808) at perl.c​:1005
#37 0x8059735 in main (argc=3, argv=0xbffffcb4, env=0xbffffcc4)
  at perlmain.c​:53

*PL_curstackinfo is​:
{si_stack = 0x8129038, si_cxstack = 0x812b808, si_cxix = -1,
  si_cxmax = 105, si_type = 1, si_prev = 0x0, si_next = 0x8134208,
  si_markbase = 0x812d808}

The same result has been seen on Slackware (5.005_02, libc5), Debian
Potato (5.005_61 and 5.005_03, glibc2.1), Solaris 2.5.1 (5.005_03) and
Digital Unix (5.004_03).

[This is the perl -V for the Debian machine]
Summary of my perl5 (5.0 patchlevel 5 subversion 3) configuration​:
  Platform​:
  osname=linux, osvers=2.2.7, archname=i686-linux
  uname='linux athens 2.2.7 #2 smp mon may 10 23​:17​:01 edt 1999 i686 unknown '
  hint=recommended, useposix=true, d_sigaction=define
  usethreads=undef useperlio=undef d_sfio=undef
  Compiler​:
  cc='gcc', optimize='-O6', gccversion=egcs-2.91.66 19990314 (egcs-1.1.2 release)
  cppflags='-Dbool=char -DHAS_BOOL -I/usr/local/include'
  ccflags ='-Dbool=char -DHAS_BOOL -I/usr/local/include'
  stdchar='char', d_stdstdio=undef, usevfork=false
  intsize=4, longsize=4, ptrsize=4, doublesize=8
  d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=12
  alignbytes=4, usemymalloc=y, prototype=define
  Linker and Libraries​:
  ld='gcc', ldflags =' -L/usr/local/lib'
  libpth=/usr/local/lib /lib /usr/lib
  libs=-lnsl -lndbm -lgdbm -ldbm -ldb -ldl -lm -lc -lposix -lcrypt
  libc=, so=so, useshrplib=false, libperl=libperl.a
  Dynamic Linking​:
  dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-rdynamic'
  cccdlflags='-fpic', lddlflags='-shared -L/usr/local/lib'

Characteristics of this binary (from libperl)​:
  Built under linux
  Compiled at Jul 29 1999 00​:29​:00
  %ENV​:
  PERL5LIB="/home/schwern/lib/perl5/site_perl/5.005"
  @​INC​:
  /home/schwern/lib/perl5/site_perl/5.005/i686-linux
  /home/schwern/lib/perl5/site_perl/5.005
  /usr/lib/perl5/i686-linux
  /usr/lib/perl5
  /usr/lib/perl5/site_perl/5.005/i686-linux
  /usr/lib/perl5/site_perl/5.005
  .

--

Michael G Schwern schwern@​pobox.com
  http​://www.pobox.com/~schwern
  /(?​:(?​:(1)[.-]?)?\(?(\d{3})\)?[.-]?)?(\d{3})[.-]?(\d{4})(x\d+)?/i

@p5pRT
Copy link
Author

p5pRT commented Sep 7, 1999

From [Unknown Contact. See original ticket]

Michael G Schwern <schwern@​pobox.com> writes​:

While testing Tie​::SecureHash 1.02 I get a "panic​: POPSTACK" during testing​:

ok 274
panic​: POPSTACK at #1126, mg.c

You have my sympathy. It took ages to track down something similar
which was a side effect of $SIG{__DIE__} inside an implied eval {} of
a require. The snag in my case was that the stack switch for the
handler was undone by the unwind for the eval {}. And then eval longjmp()'ed
to somewhere that attempted the popstack. The snag in that case was
that the DIE handler was using perl_call_sv() which set the magic flag
which caused eval {} code to do a new setjmp() which was not really
appropriate. As 'magic' (=tie) handling also does this kind of thing
I suspect the fail mode is similar.

There is now (5.005_61) a G_NOCATCH flag to pass to perl_call_sv() which inhibits
the setjmp().

In may case the stack trace at the 'panic' was not that helpful
as code had reached that point via a longjmp().

The code fragment in wipepack​:

  PUSHSTACKi(PERLSI_MAGIC);
  PUSHMARK(SP);
  XPUSHs(SvTIED_obj(sv, mg));
  PUTBACK;
  call_method("CLEAR", G_SCALAR|G_DISCARD); # add G_NOCATCH ?????
  POPSTACK;

Looks very similar.

What ticked my case use use new lightweight of Carp in the __DIE__ handler
which introduced a require (=eval {}) into things.

In the Perl code, the panic occurs at a fairly mundane place​:
push @​​::failed, $ok_count unless $_[0];

I dug into the code and found out its failing at the POPSTACK macro
call in mg.c at line 1126. Reason? PL_curstackinfo->si_prev is
empty. Not being very adept with gdb, I can't elaborate much further,
but I can provide a backtrace for what its worth​:

[This is immediately before POPSTACK is called]

#0 Perl_magic_wipepack (sv=0x818b0b0, mg=0x81e6b08) at mg.c​:1126
#1 0x80a10bb in Perl_mg_clear (sv=0x818b0b0) at mg.c​:219
#2 0x80a85c9 in Perl_hv_clear (hv=0x818b0b0) at hv.c​:956
#3 0x80ae959 in Perl_pp_aassign () at pp_hot.c​:680
#4 0x80abbee in Perl_runops_debug () at run.c​:57
#5 0x80e0df3 in S_docatch_body (args=0xbffff42c) at pp_ctl.c​:2418
#6 0x80d532e in Perl_vdefault_protect (excpt=0xbffff448,
body=0x80e0de4 <S_docatch_body>, args=0xbffff414) at scope.c​:44
#7 0x80d5260 in Perl_default_protect (excpt=0xbffff448,
body=0x80e0de4 <S_docatch_body>) at scope.c​:25
#8 0x80e0e5c in S_docatch (o=0x81a2f48) at pp_ctl.c​:2434
#9 0x80e3a54 in Perl_pp_entertry () at pp_ctl.c​:3167
#10 0x80abbee in Perl_runops_debug () at run.c​:57
#11 0x805cecd in S_call_xbody (myop=0xbffff518, is_eval=0) at perl.c​:1347
#12 0x805c87e in perl_call_sv (sv=0x819e3c8, flags=2) at perl.c​:1235
#13 0x805c67d in perl_call_method (methname=0x8116b38 "CLEAR", flags=2)
at perl.c​:1182
#14 0x80a3806 in Perl_magic_wipepack (sv=0x818b0b0, mg=0x81e6b08) at mg.c​:1125
#15 0x80a10bb in Perl_mg_clear (sv=0x818b0b0) at mg.c​:219
#16 0x80a85c9 in Perl_hv_clear (hv=0x818b0b0) at hv.c​:956
#17 0x80ae959 in Perl_pp_aassign () at pp_hot.c​:680
#18 0x80abbee in Perl_runops_debug () at run.c​:57
#19 0x80e0df3 in S_docatch_body (args=0xbffff7dc) at pp_ctl.c​:2418
#20 0x80d532e in Perl_vdefault_protect (excpt=0xbffff7f8,
body=0x80e0de4 <S_docatch_body>, args=0xbffff7c4) at scope.c​:44
#21 0x80d5260 in Perl_default_protect (excpt=0xbffff7f8,
body=0x80e0de4 <S_docatch_body>) at scope.c​:25
#22 0x80e0e5c in S_docatch (o=0x81e7088) at pp_ctl.c​:2434
#23 0x80e2e25 in Perl_pp_require () at pp_ctl.c​:3007
#24 0x80abbee in Perl_runops_debug () at run.c​:57
#25 0x805cecd in S_call_xbody (myop=0xbffff938, is_eval=0) at perl.c​:1347
#26 0x805c87e in perl_call_sv (sv=0x819e17c, flags=2) at perl.c​:1235
#27 0x805c67d in perl_call_method (methname=0x8116b21 "STORE", flags=2)
at perl.c​:1182
#28 0x80a2dae in S_magic_methcall (sv=0x81a25e8, mg=0x81e6bc8,
meth=0x8116b21 "STORE", flags=2, n=3, val=0x81a25e8) at mg.c​:1046
#29 0x80a3208 in Perl_magic_setpack (sv=0x81a25e8, mg=0x81e6bc8) at mg.c​:1083
#30 0x80a0e50 in Perl_mg_set (sv=0x81a25e8) at mg.c​:140
#31 0x80ac390 in Perl_pp_sassign () at pp_hot.c​:124
#32 0x80abbee in Perl_runops_debug () at run.c​:57
#33 0x805c279 in S_run_body (args=0xbffffbf0) at perl.c​:1072
#34 0x80d532e in Perl_vdefault_protect (excpt=0xbffffc14,
body=0x805c10c <S_run_body>, args=0xbffffbd4) at scope.c​:44
#35 0x80d5260 in Perl_default_protect (excpt=0xbffffc14,
body=0x805c10c <S_run_body>) at scope.c​:25
#36 0x805bed7 in perl_run (my_perl=0x8128808) at perl.c​:1005
#37 0x8059735 in main (argc=3, argv=0xbffffcb4, env=0xbffffcc4)
at perlmain.c​:53

*PL_curstackinfo is​:
{si_stack = 0x8129038, si_cxstack = 0x812b808, si_cxix = -1,
si_cxmax = 105, si_type = 1, si_prev = 0x0, si_next = 0x8134208,
si_markbase = 0x812d808}

The same result has been seen on Slackware (5.005_02, libc5), Debian
Potato (5.005_61 and 5.005_03, glibc2.1), Solaris 2.5.1 (5.005_03) and
Digital Unix (5.004_03).

[This is the perl -V for the Debian machine]
Summary of my perl5 (5.0 patchlevel 5 subversion 3) configuration​:
Platform​:
osname=linux, osvers=2.2.7, archname=i686-linux
uname='linux athens 2.2.7 #2 smp mon may 10 23​:17​:01 edt 1999 i686 unknown '
hint=recommended, useposix=true, d_sigaction=define
usethreads=undef useperlio=undef d_sfio=undef
Compiler​:
cc='gcc', optimize='-O6', gccversion=egcs-2.91.66 19990314 (egcs-1.1.2 release)
cppflags='-Dbool=char -DHAS_BOOL -I/usr/local/include'
ccflags ='-Dbool=char -DHAS_BOOL -I/usr/local/include'
stdchar='char', d_stdstdio=undef, usevfork=false
intsize=4, longsize=4, ptrsize=4, doublesize=8
d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=12
alignbytes=4, usemymalloc=y, prototype=define
Linker and Libraries​:
ld='gcc', ldflags =' -L/usr/local/lib'
libpth=/usr/local/lib /lib /usr/lib
libs=-lnsl -lndbm -lgdbm -ldbm -ldb -ldl -lm -lc -lposix -lcrypt
libc=, so=so, useshrplib=false, libperl=libperl.a
Dynamic Linking​:
dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-rdynamic'
cccdlflags='-fpic', lddlflags='-shared -L/usr/local/lib'

Characteristics of this binary (from libperl)​:
Built under linux
Compiled at Jul 29 1999 00​:29​:00
%ENV​:
PERL5LIB="/home/schwern/lib/perl5/site_perl/5.005"
@​INC​:
/home/schwern/lib/perl5/site_perl/5.005/i686-linux
/home/schwern/lib/perl5/site_perl/5.005
/usr/lib/perl5/i686-linux
/usr/lib/perl5
/usr/lib/perl5/site_perl/5.005/i686-linux
/usr/lib/perl5/site_perl/5.005
.

--

Michael G Schwern schwern@​pobox.com
http​://www.pobox.com/~schwern
/(?​:(?​:(1)[.-]?)?\(?(\d{3})\)?[.-]?)?(\d{3})[.-]?(\d{4})(x\d+)?/i
--
Nick Ing-Simmons <nik@​tiuk.ti.com>
Via, but not speaking for​: Texas Instruments Ltd.

@p5pRT
Copy link
Author

p5pRT commented Sep 7, 1999

From [Unknown Contact. See original ticket]

On Tue, 7 Sep 1999 12​:44​:41 +0100 (BST)
  Nick Ing-Simmons <nik@​tiuk.ti.com> wrote
  using tkmail-0.011/Perl5 Mail​::Internet v1.32
  in <199909071144.MAA25198@​tiuk.ti.com>​:

You have my sympathy. It took ages to track down something similar
which was a side effect of $SIG{__DIE__} inside an implied eval {} of
a require.

There's been serious talk of deprecating $SIG{__DIE__}. People who aren't
using it for its original purpose of being something of a UNIVERSAL​::END,
but rather to cause strange action at a distance in other people's
unrelated modules, are just making life difficult for innocents.

--tom

@p5pRT
Copy link
Author

p5pRT commented Sep 7, 1999

From [Unknown Contact. See original ticket]

Tom Christiansen <tchrist@​jhereg.perl.com> writes​:

On Tue, 7 Sep 1999 12​:44​:41 +0100 (BST)
Nick Ing-Simmons <nik@​tiuk.ti.com> wrote
using tkmail-0.011/Perl5 Mail​::Internet v1.32
in <199909071144.MAA25198@​tiuk.ti.com>​:

You have my sympathy. It took ages to track down something similar
which was a side effect of $SIG{__DIE__} inside an implied eval {} of
a require.

There's been serious talk of deprecating $SIG{__DIE__}. People who aren't
using it for its original purpose of being something of a UNIVERSAL​::END,

The case that caused the problem was the debugging code

$SIG{__DIE__} = \&Carp​::confess;

Which is exactly in inline with the original purpose.

but rather to cause strange action at a distance in other people's
unrelated modules, are just making life difficult for innocents.

All too true - and personally I agree - but this particular case
is not one of those. Rather it is how new-ish stack-switching stuff
interacts with callbacks and eval. $SIG{__DIE__} just happened
to be the "callback" that was involved. Apparently "tie" callbacks are
also vulnerable.

--
Nick Ing-Simmons <nik@​tiuk.ti.com>
Via, but not speaking for​: Texas Instruments Ltd.

@p5pRT
Copy link
Author

p5pRT commented Sep 7, 1999

From @gsar

On Tue, 07 Sep 1999 12​:44​:41 BST, Nick Ing-Simmons wrote​:

Michael G Schwern <schwern@​pobox.com> writes​:

While testing Tie​::SecureHash 1.02 I get a "panic​: POPSTACK" during testing​:

ok 274
panic​: POPSTACK at #1126, mg.c

You have my sympathy. It took ages to track down something similar
which was a side effect of $SIG{__DIE__} inside an implied eval {} of
a require. The snag in my case was that the stack switch for the
handler was undone by the unwind for the eval {}. And then eval longjmp()'ed
to somewhere that attempted the popstack. The snag in that case was
that the DIE handler was using perl_call_sv() which set the magic flag
which caused eval {} code to do a new setjmp() which was not really
appropriate. As 'magic' (=tie) handling also does this kind of thing
I suspect the fail mode is similar.

There is now (5.005_61) a G_NOCATCH flag to pass to perl_call_sv() which inhib
its
the setjmp().

This, as we discussed during the conference, will have other undesirable
side effects in the general case (such as exceptions caused within an
eval in a callback ending up in the wrong "runlevel"). Most locations
that dispatch callbacks expect them to return, and G_NOCATCH will
prevent that, because it allows a longjmp() out of there. G_NOCATCH
looks appropriate for the __DIE__ case because of the "unusual"
circumstances.

This has come up several times before now. I'll see about working
out a proper fix.

Sarathy
gsar@​activestate.com

@p5pRT
Copy link
Author

p5pRT commented Sep 7, 1999

From [Unknown Contact. See original ticket]

Gurusamy Sarathy <gsar@​activestate.com> writes​:

On Tue, 07 Sep 1999 12​:44​:41 BST, Nick Ing-Simmons wrote​:

panic​: POPSTACK at #1126, mg.c

You have my sympathy.

...

There is now (5.005_61) a G_NOCATCH flag to pass to perl_call_sv() which inhib
its
the setjmp().

This, as we discussed during the conference, will have other undesirable
side effects in the general case (such as exceptions caused within an
eval in a callback ending up in the wrong "runlevel").

I did not mean to imply that it was a correct fix in this case.
Most of the problem is (as we discussed during the conference) insufficient
documentation on what a "runlevel" actually _is_.

The sequence

  PUSHSTACK;
  perl_call_sv();
  POPSTACK;

Seems to be fatally flawed as-now if the callback contains an eval.

Without NOCATCH (or G_EVAL) then call_sv forces a eval to add new setjmp(),
when eval's unwind occurs the popstack is done, and then longjmp() returns
from the call_sv and POPSTACK is done _again_.

There are two "obvious" fixes besides the NOCATCH hack​:
1. Stop unwind doing the POPSTACK.
2. Make the POPSTACK; part of the LEAVE processing

The 3rd alternative (since 5.000) which Tk has had to use is
"always use G_EVAL for callbacks" - but that is significant extra
overhead that should not be needed.

Most locations
that dispatch callbacks expect them to return, and G_NOCATCH will
prevent that, because it allows a longjmp() out of there. G_NOCATCH
looks appropriate for the __DIE__ case because of the "unusual"
circumstances.

Agreed.

This has come up several times before now. I'll see about working
out a proper fix.

Sarathy
gsar@​activestate.com
--
Nick Ing-Simmons <nik@​tiuk.ti.com>
Via, but not speaking for​: Texas Instruments Ltd.

@p5pRT
Copy link
Author

p5pRT commented Mar 8, 2001

From The RT System itself

appears to have been fixed in 5.005_61

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