develooper Front page | perl.perl5.porters | Postings from June 2018

Re: [perl #133239] Very misleading line number for warnings in somecases

Thread Previous | Thread Next
From:
Rocky Bernstein
Date:
June 20, 2018 10:15
Subject:
Re: [perl #133239] Very misleading line number for warnings in somecases
Message ID:
CANCp2gZx6C5DeMONOEuQqPpsFcpWEAwck2M_3aHvB+AqZ9H92Q@mail.gmail.com
Apparently, I wasn't clear in describing what I was proposing. There were
two parts to what I wrote:


   1. A suggstion to add some sort of mechanism whereby a user can write a
   custom error/warning handler, and then
   2. a suggestiion on how to use this to provide a better error location
   indication

Let me elaborate a little on 1.

Currently Perl has an END block which is close, but has a couple of
problems here. First, there was a warning, so execution continues and we
don't trap on the END immediately. If you were to change the code so that
it produces an error that terminates, such as changing the condition to a
divide by 0,  then END does get called, and caller()  gives a line number
of where it thinks it was called*,* but I am not sure how to get the OP
address which is needed for deparsing.  Devel::Callsite fails here. And
interestingly Devel::Caller reports: "was expecting a pushmark or a
padrange, not a[sic] enterloop" which is promising.

But if this were fixed, how would we get the "Illegal division by zero"
message? It isn't contained in $!.

On Tue, Jun 19, 2018 at 5:20 PM, Rocky Bernstein <rocky.bernstein@gmail.com>
wrote:

>
> On Tue, Jun 19, 2018 at 4:36 AM, Dave Mitchell <davem@iabyn.com> wrote:
>
>> On Fri, Jun 01, 2018 at 03:22:18PM -0700, Stephen E. Dewey (via RT) wrote:
>> > I have provided a full description of the bug on StackOverflow
>> > at https://stackoverflow.com/q/50651331/783314. I will keep that
>> > question up-to-date in case I come across anything new.
>> >
>> > For convenience, here is what I wrote there:
>> > I have isolated a case where Perl provides a very misleading line
>> number in a warning message. I tested the below in Strawberry Perl 5.16.3.
>> >
>> > use strict;
>> > use warnings;
>> >
>> > my $choice = 0;
>> >
>> > while ($choice == 0){
>> >
>> >     #Pretend the user provided this via STDIN
>> >     $choice = '5,6,7';
>> >
>> >     if ($choice eq '-4'){
>> >         print "This isn't going to happen\n";
>> >     }
>> > }
>> >
>> > When you run this, you will get the warning message Argument "5,6,7"
>> isn't numeric in numeric eq (==) at example.pl line 11. But line 11
>> corresponds to the line if ($choice eq '-4'){ which cannot possibly cause
>> this warning message because it does not contain a numeric comparison.
>> >
>> > It seems what's actually happening is that Perl advances to the next
>> comparison, while ($choice == 0){, but the line counter used for the
>> warning message does not advance.
>> >
>> > What makes this particular case worse is that, since the "bad"
>> comparison is the loop condition, it is actually far away from the provided
>> line. In my (pre-simplification) script, it was hundreds of lines away from
>> the provided line number.
>> >
>> > Is this a bug or just an unfortunate limitation of the parser?
>>
>> It's a well-known limitation that needs to be addressed at some point.
>>
>
> The fact that it is a well-known limitation that has existed since, is it
> 5.008 (for 16 years!?) suggests that fixing this might be non trivial and
> disruptive.
>
> There is perhaps another, possibly less intrusive way, that this might be
> addressed (or at least ameliorated) - As we say in Perl: there is more than
> one way to do things.
>
> At the point of error Perl knows what instruction it was working on.
> Suppose you could register an error handler hook to get called with that op
> address...
>
> I have been working on a deparser that will show you at runtime where you
> are when given that OP address. Right now I have this hooked into the
> Devel::Trepan <https://metacpan.org/pod/Devel::Trepan> debugger, so I'll
> show how it works there.
>
> trepan.pl /tmp/bug.pl
> -- main::(/tmp/bug.pl:4 @0x1c69f78)
> my $choice = 0;
> set auto eval is on.
> (trepanpl): disasm
> Package Main
> ------------
>     #4: my $choice = 0;
>         COP (0x1c69ed0) dbstate
>         BINOP (0x1c69f30) sassign
> =>          SVOP (0x1c69f78) const  IV (0x1c63740) 0
>             OP (0x1c69fb8) padsv [1]
>     #6: while ($choice == 0){
>         COP (0x3f68280) dbstate
>         BINOP (0x3f682e0) leaveloop
>             LOOP (0x3f68328) enterloop
>             UNOP (0x3f68388) null
>                 LOGOP (0x3f683c8) and
>                     BINOP (0x1c6a670) eq   <<< this is the instruction
> that errors
>                         OP (0x1c69e20) padsv [1]
>                         SVOP (0x1c6a6b8) const  IV (0x1c63788) 0
>                     LISTOP (0x1c6a508) lineseq
>     #9:      $choice = '5,6,7';
>     ...
> (trepanpl): deparse 0x1c6a670
> binary operator ==, eq
> while ($choice == 0)  {
>        ------------
> (trepanpl):
>
> Notice that you not only get the text of the line but also where in the
> line there was a problem. If the code had been
>
>
> while ($choice == 0 && $i_feel_pretty == 3)  {
>
> the deparsing would indicate *which *of the two conditions had the
> problem, even though they are both on the same line.
>
>
>
>
>> The current implementation only records the line number of the start of
>> each statement. At runtime, each time the interpreter is about to start
>> executing a statement, it records the line number associated with that
>> statement. In warnings and error messages, the last recorded line number
>> is used.
>>
>> --
>> "I do not resent criticism, even when, for the sake of emphasis,
>> it parts for the time with reality".
>>     -- Winston Churchill, House of Commons, 22nd Jan 1941.
>>
>
>

Thread Previous | Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About