Mailing List Archive

G_KEEPERR and debugger
Well, the newer debugger still coredumps on 5.001n, but at least now
it goes "almost there". If you remember, yesterday I got hit by pad_sv
panic (it may be related to NETaa14683, but happens in a short file).

Today I ran it in gdb, and after a lot of experiments found an error
in my script: It happens that not only ENDs, but also BEGINs may also
mask the error report.

For curious, try to run
eval 'sub x {$a();&b[]} BEGIN {OK}'; die $@
from a command line, or from a required file. Below is the tentative
patch for the problem. It fixes the situation when called from the
command line, but prints the message twice when run from a required
file. It happens like this: do_eval calls DIE with $@ as argument, die
calls die_where which appends $@ to the argument of DIE.

I'm not very fluent in Perl error processing, so did not try to fix
duplicate message. From my point of view one should never do $@="" if
in_eval is true, but I did not try to fix this too.

Note that this patch does not fix
panic pad_sv po
it just makes it possible to see the previous error.

Best,
Ilya

*** perl.c~ Tue Nov 07 03:28:58 1995
--- perl.c Wed Nov 08 22:39:02 1995
***************
*** 1743,1752 ****
switch (setjmp(top_env)) {
case 0: {
SV* atsv = GvSV(errgv);
PUSHMARK(stack_sp);
! perl_call_sv((SV*)cv, G_EVAL|G_DISCARD);
(void)SvPV(atsv, len);
! if (len) {
Copy(oldtop, top_env, 1, jmp_buf);
curcop = &compiling;
curcop->cop_line = oldline;
--- 1743,1754 ----
switch (setjmp(top_env)) {
case 0: {
SV* atsv = GvSV(errgv);
+ STRLEN oldlen = 0;
PUSHMARK(stack_sp);
! if (in_eval) (void)SvPV(atsv, oldlen);
! perl_call_sv((SV*)cv, G_EVAL|G_DISCARD|(in_eval ? G_KEEPERR : 0));
(void)SvPV(atsv, len);
! if (len > oldlen) {
Copy(oldtop, top_env, 1, jmp_buf);
curcop = &compiling;
curcop->cop_line = oldline;
Re: G_KEEPERR and debugger [ In reply to ]
On Thu, 09 Nov 1995 02:54:13 EST, Ilya Zakharevich wrote:
>
>For curious, try to run
> eval 'sub x {$a();&b[]} BEGIN {OK}'; die $@
>from a command line, or from a required file. Below is the tentative
>patch for the problem. It fixes the situation when called from the
>command line, but prints the message twice when run from a required
>file. It happens like this: do_eval calls DIE with $@ as argument, die
>calls die_where which appends $@ to the argument of DIE.
>

No time to apply and test with your patch, but I think the

if (optype == OP_REQUIRE)
DIE("%s", SvPVx(GvSV(errgv), na));

construct in die_where() needs to have an additional check to fix
any duplicate message.

>I'm not very fluent in Perl error processing, so did not try to fix
>duplicate message. From my point of view one should never do $@="" if
>in_eval is true, but I did not try to fix this too.
>
>Note that this patch does not fix
> panic pad_sv po
>it just makes it possible to see the previous error.
>
>Best,
>Ilya
>
>*** perl.c~ Tue Nov 07 03:28:58 1995
>--- perl.c Wed Nov 08 22:39:02 1995
>***************
>*** 1743,1752 ****
> switch (setjmp(top_env)) {
> case 0: {
> SV* atsv = GvSV(errgv);
> PUSHMARK(stack_sp);
>! perl_call_sv((SV*)cv, G_EVAL|G_DISCARD);
> (void)SvPV(atsv, len);
>! if (len) {
> Copy(oldtop, top_env, 1, jmp_buf);
> curcop = &compiling;
> curcop->cop_line = oldline;
>--- 1743,1754 ----
> switch (setjmp(top_env)) {
> case 0: {
> SV* atsv = GvSV(errgv);
>+ STRLEN oldlen = 0;
> PUSHMARK(stack_sp);
>! if (in_eval) (void)SvPV(atsv, oldlen);
>! perl_call_sv((SV*)cv, G_EVAL|G_DISCARD|(in_eval ? G_KEEPERR : 0));
> (void)SvPV(atsv, len);
>! if (len > oldlen) {

I think this has a subtle inadequacy. Imagine what happens when
in_eval is not true, and the perl_call_sv() ends up with a _shorter_
error message than the original error. The failure of BEGIN/END
blocks will not be trapped in such a case. I think a better
implementation would be to unconditionally use G_KEEPERR in
the perl_call_sv() call. len is then guaranteed to be not less than
oldlen in that case.

> Copy(oldtop, top_env, 1, jmp_buf);
> curcop = &compiling;
> curcop->cop_line = oldline;
>

- Sarathy.
gsar@engin.umich.edu
Re: G_KEEPERR and debugger [ In reply to ]
Gurusamy Sarathy writes:
> >***************
> >*** 1743,1752 ****
> > switch (setjmp(top_env)) {
> > case 0: {
> > SV* atsv = GvSV(errgv);
> > PUSHMARK(stack_sp);
> >! perl_call_sv((SV*)cv, G_EVAL|G_DISCARD);
> > (void)SvPV(atsv, len);
> >! if (len) {
> > Copy(oldtop, top_env, 1, jmp_buf);
> > curcop = &compiling;
> > curcop->cop_line = oldline;
> >--- 1743,1754 ----
> > switch (setjmp(top_env)) {
> > case 0: {
> > SV* atsv = GvSV(errgv);
> >+ STRLEN oldlen = 0;
> > PUSHMARK(stack_sp);
> >! if (in_eval) (void)SvPV(atsv, oldlen);
> >! perl_call_sv((SV*)cv, G_EVAL|G_DISCARD|(in_eval ? G_KEEPERR : 0));
> > (void)SvPV(atsv, len);
> >! if (len > oldlen) {
>
> I think this has a subtle inadequacy. Imagine what happens when
> in_eval is not true, and the perl_call_sv() ends up with a _shorter_
> error message than the original error.

It is very hard to be shorter than 0, what is oldlen in the case
in_eval==0.

Btw, Larry, I had a case when die was called like
die("%s", "");
before the patch (since the error count was positive, but $@ was wiped
out). Note that mess() reads before the start of
the string:

*s++ = SvPVX(tmpstr)[SvCUR(tmpstr)-1];


Ilya
Re: G_KEEPERR and debugger [ In reply to ]
> From: Ilya Zakharevich <ilya@math.ohio-state.edu>
>
> Btw, Larry, I had a case when die was called like
> die("%s", "");
> before the patch (since the error count was positive, but $@ was wiped out).

I've seen very occasional die's with no message where I've got a file bar.pl
with a line

use Foo; (or require?)

and I say

$ perl bar.pl
at bar.pl line X

where line X is the use line.

Saying perl -c Foo.pm usually shows up a syntax error. What's odd is
that syntax errors are usually correctly reported. I've never had time to
look into this (such as trying to characterise what types of syntax errors
cause these symptoms) since it's always happened at crunch times.

Hopefully the die and $@ patches will help. If I see it in any later
versions I'll try to look a little deeper.

Tim.
Re: G_KEEPERR and debugger [ In reply to ]
On Thu, 09 Nov 1995 16:09:12 EST, Ilya Zakharevich wrote:
>>
>> I think this has a subtle inadequacy. Imagine what happens when
>> in_eval is not true, and the perl_call_sv() ends up with a _shorter_
>> error message than the original error.
>
>It is very hard to be shorter than 0, what is oldlen in the case
>in_eval==0.

Awesome stupidity, eh? :-/

>
>Btw, Larry, I had a case when die was called like
> die("%s", "");
>before the patch (since the error count was positive, but $@ was wiped
>out). Note that mess() reads before the start of
>the string:
>
> *s++ = SvPVX(tmpstr)[SvCUR(tmpstr)-1];

Can you show me the test case where this happens?

- Sarathy.
gsar@engin.umich.edu
Re: G_KEEPERR and debugger [ In reply to ]
Gurusamy Sarathy writes:
>
> On Thu, 09 Nov 1995 16:09:12 EST, Ilya Zakharevich wrote:
> >>
> >> I think this has a subtle inadequacy. Imagine what happens when
> >> in_eval is not true, and the perl_call_sv() ends up with a _shorter_
> >> error message than the original error.
> >
> >It is very hard to be shorter than 0, what is oldlen in the case
> >in_eval==0.
>
> Awesome stupidity, eh? :-/
>

The (modern) Russian proverb may be transliterated as

The mighty hurrican took everything into account ;-).

> >
> >Btw, Larry, I had a case when die was called like
> > die("%s", "");
> >before the patch (since the error count was positive, but $@ was wiped
> >out). Note that mess() reads before the start of
> >the string:
> >
> > *s++ = SvPVX(tmpstr)[SvCUR(tmpstr)-1];
>
> Can you show me the test case where this happens?
>

Just a small modification of my panic: pad_sv po test: require a file
with
$a(); BEGIN{}

Ilya