Euphoria
Ticket #749:
4.0 crashing badly with some while loops
-
Reported by
SDPringle
Feb 16, 2012
The 4.0 interpreter crashes while running the translator when a while loop with entry tries to use an uninitiated variable. No ex.err file is generated.
This was discovered by accident while working in another branch but it is a 4.0 problem. Examples are commented below.
Details
1. Comment by mattlewis
Feb 16, 2012
I think that it's fair (though sometimes annoying ) to require the last release to be able to build the next release.
2. Comment by jimcbrown
Feb 16, 2012
Even so, a low level crash so bad that we don't even have an ex.err suggests that an underlying bug in 4.0 has been exposed. (Do we have a core dump?)
This underlying bug might appear with other, legitimate 4.0 code.
3. Comment by mattlewis
Feb 16, 2012
I tried this on Linux. I built a debug version of the tip of 4.0, and used that as my eubin. Then I got:
source/fwdref.e:431 in function find_next_literal_match_record()
A machine-level exception occurred during execution of this statement (signal 11)
... called from /home/matt/eu/oe/source/fwdref.e:502 in procedure patch_forward_variable()
... called from /home/matt/eu/oe/source/fwdref.e:980 in function resolve_file()
... called from /home/matt/eu/oe/source/fwdref.e:1052 in procedure Resolve_forward_references()
... called from /home/matt/eu/oe/source/scanner.e:933 in function IncludePop()
... called from /home/matt/eu/oe/source/parser.e:5176 in procedure real_parser()
... called from /home/matt/eu/oe/source/parser.e:5308 in procedure parser()
... called from /home/matt/eu/oe/source/main.e:201 in procedure main()
... called from /home/matt/eu/oe/source/main.e:228
--> See ex.err
This line seems pretty innocuous, so more in depth analysis is clearly needed.
4. Comment by SDPringle
Feb 16, 2012
I put this line in be_execute.c in the L_INTEGER_CHECK case of the execution loop in the 4.0 tip.
if (top == NOVALUE)
RTFatal("Uninitialized value passed to L_INTEGER_CHECK");
Then I built the 4.0 interpreter with that change.
After that, I went back to the directory with the alternative literals branch. I ran 'wmake source' and I got:
C:\Users\Shawn\Documents\development\hg\4.0\build\watcom\d\eui.exe -d E32 -i C:\Users\Shawn\Document
s\development\hg\ticket657\include C:\Users\Shawn\Documents\development\hg\ticket657\source\ec.ex
-nobuild -wat -plat WINDOWS -D EU_MANAGED_MEM -i C:\Users\Shawn\Documents\development\hg\ticket65
7\include -c C:\Users\Shawn\Documents\development\hg\ticket657\build\watcom\o\eu.cfg C:\Users\Shawn\
Documents\development\hg\ticket657\source\int.ex C:\Users\Shawn\Documents\development\hg\ticket657\b
uild\watcom\o\eu.lib
C:\Users\Shawn\Documents\development\hg\ticket657\include\std\dll.e:378 in function define_c_func()
Uninitialized value passed to L_INTEGER_CHECK
... called from C:\Users\Shawn\Documents\development\hg\ticket657\include\std\filesys.e:830
--> See ex.err
5. Comment by mattlewis
Feb 16, 2012
gdb tells me this:
Program received signal SIGSEGV, Segmentation fault.
0x082d1359 in DoubleToInt (d=-1073741825) at be_runtime.c:1639
warning: Source file is more recent than executable.
1639
(gdb) bt
#0 0x082d1359 in DoubleToInt (d=-1073741825) at be_runtime.c:1639
#1 0x082be9de in do_exec (start_pc=0x9f76004) at be_execute.c:2388
#2 0x082bd9a7 in Execute (start_index=0x9f76004) at be_execute.c:1516
#3 0x082ca6ec in start_backend (x=-2127879185) at be_machine.c:2595
#4 0x082cab77 in machine (opcode=65, x=-2127879185) at be_machine.c:2896
#5 0x08056d84 in _68BackEnd (_il_file_62546=0) at /home/matt/eu/oe/4.0/intobj/backend.c:4268
#6 0x081f7eed in _2BackEnd (_x_182=0) at /home/matt/eu/oe/4.0/intobj/mode.c:204
#7 0x081e854d in _69main () at /home/matt/eu/oe/4.0/intobj/main.c:958
#8 0x081e74bc in main (argc=12, argv=0xffffd1b4) at /home/matt/eu/oe/4.0/intobj/main-.c:16363
6. Comment by SDPringle
Feb 16, 2012
This debug trace is the same when using Watcom.
7. Comment by mattlewis
Feb 16, 2012
We're trying to use t here before it's initialized. I think that the 'entry' in the while loop is confusing things, so we don't emit an init check, because it looks like it has been initialized (or at least checked). Should be easy to make a test for this.
8. Comment by mattlewis
Feb 16, 2012
This only seems to be a problem with private init checks. The following code has the same bug as fwdref.e, and demonstrates the lack of init checking:
function foo( integer baz )
return baz - 1
end function
procedure main()
integer t
while 1 with entry do
printf(1, "hello t\n", t )
exit
entry
t = foo( t )
end while
end procedure
main()
9. Comment by SDPringle
Feb 17, 2012
See: hg:euphoria/rev/1820c56e4431
changeset: 5501:1820c56e4431 branch: 4.0 tag: tip user: Shawn Pringle <shawn.pringle@gmail.com> date: Fri Feb 17 14:09:06 2012 -0300 files: tests/t_749.e description:
- added a test for ticket749
- ticket 749
10. Comment by SDPringle
Feb 17, 2012
See: hg:euphoria/rev/020d5a6df7e2
changeset: 5502:020d5a6df7e2 branch: 4.0 user: Shawn Pringle <shawn.pringle@gmail.com> date: Fri Feb 17 15:23:48 2012 -0300 files: source/Makefile.wat tests/t_749.e tests/t_c_749.d/control.err tests/t_c_749.e description:
- changed t_749.e to a counter test.
- ticket 749
11. Comment by mattlewis
Feb 24, 2012
A similar case:
procedure goto_init( integer y )
integer x
if y then
goto "x not initialized"
end if
x = 5
label "x not initialized"
x = foo( x )
end procedure
12. Comment by SDPringle
Mar 06, 2012
editing subject and content fields to reflect the essence of the problem.
13. Comment by DerekParnell
Mar 10, 2012
Can someone point me to the offending source code? I can't see it from the posts here.
14. Comment by mattlewis
Mar 10, 2012
Comments 8 and 11 show some code that crashes with this bug.
The problem is (more or less) in parser.e:InitCheck.
15. Comment by DerekParnell
Mar 10, 2012
Yes I see your example code that demonstrates the issue but from Shawn's original post, I got the impression that there was some existing code that does that sort of thing. Especially since Shawn explicitly mentions "with entry" as the initial cause of his error. I have been trawling through the source directory and std library to find Shawn's failing code and can't see it.
16. Comment by mattlewis
Mar 10, 2012
Oh, sorry. Shawn originally found the problem in some code in the alternative_literals branch in fwdref.e. See changesethg:euphoria/fb4246c41a66. The problematic code starts at line 491 of fwdref.e, pasted below. Note that integer t is declared and then used in the "entry block" before it ever gets a value.
integer t
while t entry do
sequence fix_this = forward_references[refs[ri]][FR_DATA][t]
if find(-ref,fix_this) then
fix_this[find(-ref,fix_this)] = tok[T_SYM]
end if
if sequence(fix_this[2]) and -ref = fix_this[2][3] then
fix_this[2][3] = tok[T_SYM]
end if
forward_references[refs[ri]][FR_DATA][t] = fix_this
entry
t = find_next_literal_match_record(refs[ri], t)
end while
17. Comment by mattlewis
Apr 12, 2012
See: hg:euphoria/rev/944742d83bdb
changeset: 5540:944742d83bdb branch: 4.0 parent: 5538:930a8e2dc4a0 user: Matt Lewis date: Thu Apr 12 05:42:27 2012 -0400 files: docs/manual.af docs/release/4.0.5.txt source/eutest.ex source/parser.e source/reswords.e tests/t_c_749_goto.d/control.err tests/t_c_749_goto.e description:
- save and restore private uninitialized information for while-entry and goto
- fixes ticket 749
18. Comment by mattlewis
Apr 12, 2012
See: hg:euphoria/rev/f4c256900ff0
changeset: 5542:f4c256900ff0 branch: 4.0 parent: 5540:944742d83bdb user: Matt Lewis date: Thu Apr 12 08:00:25 2012 -0400 files: source/parser.e description:
- fix loop-entry for ticket 749