Post Reply 
(Probably) New bug found in HP-71B (2CDCC and possibly others)
03-04-2018, 09:57 PM
Post: #1
(Probably) New bug found in HP-71B (2CDCC and possibly others)
      
Hi, all:

I've found what I believe to be a never-before-reported bug present in the most recent version of the HP-71B ROMs, namely the 2CDCC one. I found it while using an Emu71 instance with these installed ROM versions:

      >VER$
                  HP71:2CDCC MATH:1A JPC:F01 HPIL:1B STRU:A RCPY:E


The problem can be reproduced by following this minimal example:

(Note: To guarantee correct reproduction first execute END ALL and DESTROY ALL and enter these code snippets on an empty worfile. You might also want to execute DELAY 0.5 to see the output before it scrolls up out of view when running the 2nd and 3rd code snippets.

Caveat: Also, after finding and investigating this bug I've not experienced any problems like corrupted memory, corrupted file chain or system unstability so I deem it perfectly safe for you to run the following code snippets without experiencing any problems but, as usual, no guarantees).


1) Correct functionality (no user-defined function):

This code snippet displays the square root of integers in a FOR-NEXT loop and tries to catch the error when the integers become negative, in which case the error is trapped and displayed and the loop continues with the next integer till the loop is completed and the program outputs "Done" and terminates:

10 ON ERROR GOTO 40 @ FOR X=3 TO -2 STEP -1 @ DISP "X=";X;
20 Y=SQR(X) @ DISP ", Sqrt(";X;")=";Y
30 NEXT X @ DISP "Done" @ END
40 DISP ", Error";ERRN;"in line";ERRL @ GOTO 30

>RUN

X= 3 , Sqrt( 3 )= 1.73205080757
X= 2 , Sqrt( 2 )= 1.41421356237
X= 1 , Sqrt( 1 )= 1
X= 0 , Sqrt( 0 )= 0
X=-1 , Error 10 in line 20
X=-2 , Error 10 in line 20
Done


This is the expected correct behaviour. Note that when X=-1 the error is trapped and displayed instead of the numeric square root and the loop's execution continues with the next integer, namely X=-2, where the error is again trapped and displayed, and as there's no next element the loop ends and the program terminates normally. The reported error is of course:

      >MSG$(10)
                  SQR(neg)

2) Incorrect functionality (a single-statement UDF):

Now we replace the Y=SQR(X) at line 20 with a call to a single-statement user-defined function, i.e.: Y=FNF(X), which we define at line 1. The changed code is:

1 DEF FNF(N)=SQR(N)
10 ON ERROR GOTO 40 @ FOR X=3 TO -2 STEP -1 @ DISP "X=";X;
20 Y=FNF(X) @ DISP ", Sqrt(";X;")=";Y
30 NEXT X @ DISP "Done" @ END
40 DISP ", Error";ERRN;"in line";ERRL @ GOTO 30

>RUN

X= 3 , Sqrt( 3 )= 1.73205080757
X= 2 , Sqrt( 2 )= 1.41421356237
X= 1 , Sqrt( 1 )= 1
X= 0 , Sqrt( 0 )= 0
X=-1 , Error 10 in line 1
, Error 43 in line 30
, Error 43 in line 30
, Error 43 in line 30
... (continues indefinitely) ...

This is incorrect behaviour. When X=-1, the error is trapped and displayed as before, reported at line 1 (the UDF) when it tries to compute the square root of its argument, -1. So far so good.

But then, when the NEXT X at line 30 gets executed, a new error gets trapped and reported, and the NEXT X is executed again with the same result so the program never stops but is stuck into an infinite loop.

The first error is the same we saw before, namely:

      >MSG$(10)
                  SQR(neg)


But the new, wholly unexpected error is:

      >MSG$(43)
                  NEXT w/o FOR


So it seems that when the error occurs in the UDF, despite getting traped it nevertheless manages to disrupt the FOR-NEXT loop which gets unduly terminated or corrupted so that NEXT X fails, unlike what happened when we used SQR(X) instead of FNF(X).

This incorrect behaviour also happens when using a multi-statement user-defined function:

1 DEF FNF(N) @ FNF=SQR(N) @ END DEF
10 ON ERROR GOTO 40 @ FOR X=3 TO -2 STEP -1 @ DISP "X=";X;
20 Y=FNF(X) @ DISP ", Sqrt(";X;")=";Y
30 NEXT X @ DISP "Done" @ END
40 DISP ", Error";ERRN;"in line";ERRL @ GOTO 30

>RUN

X= 3 , Sqrt( 3 )= 1.73205080757
X= 2 , Sqrt( 2 )= 1.41421356237
X= 1 , Sqrt( 1 )= 1
X= 0 , Sqrt( 0 )= 0
X=-1 , Error 10 in line 1
, Error 43 in line 30
, Error 43 in line 30
, Error 43 in line 30
... (continues indefinitely).



To wit: simply replacing Y=SQR(X) with Y=FNF(X) and trying to catch the "SQR(neg)" error within a FOR-NEXT loop causes the loop to be terminated early (and/or corrupted) and the program to get stuck into an infinite loop.

I've been looking at the documents J-F Garnier kindly published and mentioned in his Emu71 web site, namely "HP-71B Known Bugs February 6, 1985" (34 pages) and this particular bug doesn't seem to be mentioned there. The closest I've found there reads like this:

      "1072-8 (Rank 4) Outer FOR...NEXT loop is corrupted when inner FOR statement errors
       at execution. (Only a problem is you do keyboard GOTO after the FOR
       statement error)"


As you may see there's no mention of UDFs at all in bug 1072-8 and the description and commentary doesn't seem to apply to my minimal example so I'm pretty sure my newly found bug is different from the old 1072-8 reported there.

If this is indeed the case I think that it would be proper to include it in the list of known HP-71B bugs (it's probably present in all ROM versions up to and including 2CDCC) as well as any relevant comments (does it corrupt other things as well ?) and any workarounds which might be concocted.

Regards.
V.
      
Find all posts by this user
Quote this message in a reply
03-05-2018, 04:15 AM
Post: #2
RE: (Probably) New bug found in HP-71B (2CDCC and possibly others)
Confirmed using real 2CDCC hardware.
71:2CDCC FTH:1A EDT:A KBD:B MATH:1A JPC:F03 HPIL:1B FMT:A RCPY:E STR:A
Find all posts by this user
Quote this message in a reply
03-05-2018, 04:46 PM (This post was last modified: 03-05-2018 05:46 PM by J-F Garnier.)
Post: #3
RE: (Probably) New bug found in HP-71B (2CDCC and possibly others)
This is an interesting test case.

I agree it is no directly related to the bug 1072.
The bug 1072 is related to an error in the FOR statement itself, not in the statements between FOR and NEXT. For instance:
10 ! bug 1072-8
20 ON ERROR GOTO 60
30 FOR J=1 TO 3
40 FOR I=1 TO SQRT(-9)
50 NEXT I
60 PRINT I;J
70 NEXT J
80 END

On the HP71 1BBBB, the outer loop (J) doesn't run well and the program falls into an endless loop :
1 1
1 1
1 1
...


On the HP71 2CDCC, the program just runs fine:
1 1
1 2
1 3


The problem Valentin highlighted seems to be more related to the GOTO jumping out of DEF FN, as can be demonstrated with this small piece of code:
10 ! GOTO jumping out of DEF FN
20 DEF FNF(N)
30 GOTO 70
40 END DEF
50 FOR I=1 TO 3
60 X=FNF(1)
70 DISP I
80 NEXT I
90 END

An error 43 "NEXT w/o FOR" is generated at line 80.
This is consistent with the fact that User-Defined Functions (UDF) have their own FOR-NEXT environment as described in the user manual.

Is it a bug, or just a limitation of the implementation of ON ERROR GOTO ?
I'm not sure, but the HP75 (and probably series 80 as well) have a similar limitation. The generated error is different, but the root cause is the same: it is not allowed to jump out of a DEF FN with a GOTO, either explicitly with a GOTO or implicitly with a ON ERROR GOTO.

A workaround:
Use a ON ERROR GOSUB instead, pointing to a simple RETURN (or setting a global variable to flag the error). The effect will be to ignore errors:
X= 3 , Sqrt( 3 )= 1.73205080757
X= 2 , Sqrt( 2 )= 1.41421356237
X= 1 , Sqrt( 1 )= 1
X= 0 , Sqrt( 0 )= 0
X=-1 , Sqrt(-1 )= 0
X=-2 , Sqrt(-2 )= 0
Done.


J-F
Visit this user's website Find all posts by this user
Quote this message in a reply
Post Reply 




User(s) browsing this thread: 1 Guest(s)