1. Strange machine-level exception
- Posted by Juergen Luethje <j.lue at gmx.de>
Jun 17, 2007
-
Last edited Jun 18, 2007
Hi all,
I've changed my private create_set() function a little, in order to take
advantage of find_from(). Then I encountered a strange machine-level
exception.
I've tested it on Windows XP Pro and Euphoria 3.1. The following code runs
fine when interpreted by EX.exe, EXW.exe and EXWC.exe. When I uncomment
the denoted line near the end, the program still runs fine with EX.exe but
crashes reliably with EXW.exe and EXWC.exe. Renaming "safe.e" to "machine.e"
and including it in the program didn't provide any hints.
function create_set (sequence s)
-- create a set (= remove duplicate entries)
integer p
if length(s) < 2 then
return s
end if
p = length(s)
for i = length(s)-1 to 1 by -1 do
if find_from(s[i], s, i+1) = 0 then -- Machine-level exception here ...
p -= 1
s[p] = s[i]
end if
end for
return s[p..$]
end function
sequence freq, result, unique
integer n, player
n = 1000
result = {}
for i = 1 to n do
freq = repeat(0, 3)
for card = 1 to 4 do
player = rand(3)
-- freq[player] += 1 -- ... after uncommenting this line!
end for
result = append(result, freq)
end for
unique = create_set(result)
? unique
if getc(0) then end if
Can someone please confirm the problem?
Regards,
Juergen
2. Re: Strange machine-level exception
- Posted by CChris <christian.cuvier at agriculture.gouv.fr>
Jun 17, 2007
-
Last edited Jun 18, 2007
Juergen Luethje wrote:
>
> Hi all,
>
> I've changed my private create_set() function a little, in order to take
> advantage of find_from(). Then I encountered a strange machine-level
> exception.
>
> I've tested it on Windows XP Pro and Euphoria 3.1. The following code runs
> fine when interpreted by EX.exe, EXW.exe and EXWC.exe. When I uncomment
> the denoted line near the end, the program still runs fine with EX.exe but
> crashes reliably with EXW.exe and EXWC.exe. Renaming "safe.e" to "machine.e"
> and including it in the program didn't provide any hints.
> }}}
<eucode>
> function create_set (sequence s)
> -- create a set (= remove duplicate entries)
> integer p
>
> if length(s) < 2 then
> return s
> end if
>
> p = length(s)
> for i = length(s)-1 to 1 by -1 do
> if find_from(s[i], s, i+1) = 0 then -- Machine-level exception here ...
> p -= 1
> s[p] = s[i]
> end if
> end for
> return s[p..$]
> end function
>
>
> sequence freq, result, unique
> integer n, player
>
> n = 1000
>
> result = {}
> for i = 1 to n do
> freq = repeat(0, 3)
> for card = 1 to 4 do
> player = rand(3)
> -- freq[player] += 1 -- ... after uncommenting this
> line!
> end for
> result = append(result, freq)
> end for
>
> unique = create_set(result)
> ? unique
> if getc(0) then end if
> </eucode>
{{{
> Can someone please confirm the problem?
>
> Regards,
> Juergen
I just ran the above code as is. Under ex.exe, exw.exw and exwc.exe, the same
result is obtained:
{
{0,0,0}
}
This was under XP Home SP2, P4 Intel 3.0GHz, 1Go RAM
I just downloaded and executed e31setup.exe.
CChris
3. Re: Strange machine-level exception
- Posted by Derek Parnell <ddparnell at bigpond.com>
Jun 17, 2007
-
Last edited Jun 18, 2007
Juergen Luethje wrote:
>
> Hi all,
>
> I've changed my private create_set() function a little, in order to take
> advantage of find_from(). Then I encountered a strange machine-level
> exception.
>
> I've tested it on Windows XP Pro and Euphoria 3.1. The following code runs
> fine when interpreted by EX.exe, EXW.exe and EXWC.exe. When I uncomment
> the denoted line near the end, the program still runs fine with EX.exe but
> crashes reliably with EXW.exe and EXWC.exe. Renaming "safe.e" to "machine.e"
> and including it in the program didn't provide any hints.
> Can someone please confirm the problem?
Yes I can confirm it. There does appear to be a problem with find_from(). I
tried to get around it by not assigning back to the 's' sequence and that worked
for small sequence size but it failed for large ones. If you don't use
find_from() it works ...
eg.
function create_set (sequence s)
-- create a set (= remove duplicate entries)
sequence t
object x
if length(s) < 2 then
return s
end if
t = {s[1]}
for i = 2 to length(s) - 1 do
x = s[i]
if find(x, t) = 0 then
t = append(t,x)
end if
end for
return t
end function
--
Derek Parnell
Melbourne, Australia
Skype name: derek.j.parnell
4. Re: Strange machine-level exception
Hi Juergen.
I did not try your program, but apart from this, I have a suggestion to
improve its speed.
From the point of view of computational complexity, your code is
O(n*n).
This can be improved by first sorting the sequence, which is O(log(n)*n),
and then examining it linearly eliminating the equal elements, which is
O(n), giving a joint complexity O(log(n)*n).
This improvement will be more noticeable as the sequence length increases.
Regards.
5. Re: Strange machine-level exception
Ricardo Forno wrote:
>
> Hi Juergen.
> I did not try your program, but apart from this, I have a suggestion to
> improve its speed.
> From the point of view of computational complexity, your code is
> O(n*n).
> This can be improved by first sorting the sequence, which is O(log(n)*n),
> and then examining it linearly eliminating the equal elements, which is
> O(n), giving a joint complexity O(log(n)*n).
> This improvement will be more noticeable as the sequence length increases.
Actually, I tried that too because it sounds sensible. However when I did that,
pre-sorting it makes it run about 3X slower and causes the resulting set to be
ordered differently from the input set, which might be significant to some
applications.
include sort.e
function create2_set (sequence s)
-- create a set (= remove duplicate entries)
integer p
if length(s) < 2 then
return s
end if
s = sort(s)
p = 1
for i = 2 to length(s) do
if not equal(s[p], s[i]) then
p += 1
if p != i then
s[p] = s[i]
end if
end if
end for
return s[1..p]
end function
--
Derek Parnell
Melbourne, Australia
Skype name: derek.j.parnell
6. Re: Strange machine-level exception
Hmmm, it's very strange.
I got same error in my Windows 2K box, then I copied your code into my Linux
environment and it's run smoothly.
It seems the additional routine code was designed originally for Linux and
freebsd???
I found a strange message too when I'm trying to run a script with non-existing
filename in my Windows box.
For example:
exw xxxx
This message will appear:
Can't open xxxx.exu
Press Enter.
The default extension is pointing to exu in Window environment(???)
It's totally different with our older Euphoria which would give us a message
like this:
Can't open xxxx.exw
Press Enter.
Hope this information is usefull.
Regards,
Doni
7. Re: Strange machine-level exception
Derek Parnell wrote:
> Juergen Luethje wrote:
>>
>> Hi all,
>>
>> I've changed my private create_set() function a little, in order to take
>> advantage of find_from(). Then I encountered a strange machine-level
>> exception.
>>
>> I've tested it on Windows XP Pro and Euphoria 3.1. The following code runs
>> fine when interpreted by EX.exe, EXW.exe and EXWC.exe. When I uncomment
>> the denoted line near the end, the program still runs fine with EX.exe but
>> crashes reliably with EXW.exe and EXWC.exe. Renaming "safe.e" to "machine.e"
>> and including it in the program didn't provide any hints.
>
>
>> Can someone please confirm the problem?
>
> Yes I can confirm it.
Thanks, Derek.
> There does appear to be a problem with find_from(). I
> tried to get around it by not assigning back to the 's' sequence and that
> worked
> for small sequence size but it failed for large ones.
A strange point IMHO is, that the problem does not only depend on the size
of s but also on its content. With s = repeat(1000, {0,0,0}) there is no
problem, with other content (when the line at the end of the program is
uncommented) the program crashes.
> If you don't use find_from()
> it works ...
>
> eg.
>
> function create_set (sequence s)
> -- create a set (= remove duplicate entries)
> sequence t
> object x
>
> if length(s) < 2 then
> return s
> end if
>
> t = {s[1]}
> for i = 2 to length(s) - 1 do
> x = s[i]
> if find(x, t) = 0 then
> t = append(t,x)
> end if
> end for
> return t
> end function
Yep.
Regards,
Juergen
8. Re: Strange machine-level exception
CChris wrote:
> Juergen Luethje wrote:
<snip>
>> -- freq[player] += 1 -- ... after uncommenting this
>> line!
>> end for
>> result = append(result, freq)
>> end for
>>
>> unique = create_set(result)
>> ? unique
>> if getc(0) then end if
>> </eucode>
{{{
>> Can someone please confirm the problem?
>>
>> Regards,
>> Juergen
>
> I just ran the above code as is. Under ex.exe, exw.exw and exwc.exe, the same
> result is obtained:
> {
> {0,0,0}
> }
>
> This was under XP Home SP2, P4 Intel 3.0GHz, 1Go RAM
> I just downloaded and executed e31setup.exe.
>
> CChris
Thanks for testing. Now what happens on your system, after you have
uncommented the above denoted line?
Regards,
Juergen
9. Re: Strange machine-level exception
Hello Doni,
thanks for looking into it, and for your additional information.
Regards,
Juergen
10. Re: Strange machine-level exception
Juergen Luethje wrote:
>
> CChris wrote:
>
> > Juergen Luethje wrote:
>
> <snip>
>
> >> -- freq[player] += 1 -- ... after uncommenting this
> >> line!
> >> end for
> >> result = append(result, freq)
> >> end for
> >>
> >> unique = create_set(result)
> >> ? unique
> >> if getc(0) then end if
> >> </eucode>
{{{
> >> Can someone please confirm the problem?
> >>
> >> Regards,
> >> Juergen
> >
> > I just ran the above code as is. Under ex.exe, exw.exw and exwc.exe, the
> > same
> > result is obtained:
> > {
> > {0,0,0}
> > }
> >
> > This was under XP Home SP2, P4 Intel 3.0GHz, 1Go RAM
> > I just downloaded and executed e31setup.exe.
> >
> > CChris
>
> Thanks for testing. Now what happens on your system, after you have
> uncommented the above denoted line?
>
> Regards,
> Juergen
Uncommenting the line causes indeed a machine elevel exception at the line
containing the find_from() statement. At least using exw.exe and exwc.exe.
ex.exe handles the code correctly and displays a 7 or 8 element long sequence.
CChris
11. Re: Strange machine-level exception
Juergen Luethje wrote:
>
> Hi all,
>
> I've changed my private create_set() function a little, in order to take
> advantage of find_from(). Then I encountered a strange machine-level
> exception.
>
> I've tested it on Windows XP Pro and Euphoria 3.1. The following code runs
> fine when interpreted by EX.exe, EXW.exe and EXWC.exe. When I uncomment
> the denoted line near the end, the program still runs fine with EX.exe but
> crashes reliably with EXW.exe and EXWC.exe. Renaming "safe.e" to "machine.e"
> and including it in the program didn't provide any hints.
> }}}
<eucode>
> function create_set (sequence s)
> -- create a set (= remove duplicate entries)
> integer p
>
> if length(s) < 2 then
> return s
> end if
>
> p = length(s)
> for i = length(s)-1 to 1 by -1 do
> if find_from(s[i], s, i+1) = 0 then -- Machine-level exception here ...
> p -= 1
> s[p] = s[i]
> end if
> end for
> return s[p..$]
> end function
>
>
> sequence freq, result, unique
> integer n, player
>
> n = 1000
>
> result = {}
> for i = 1 to n do
> freq = repeat(0, 3)
> for card = 1 to 4 do
> player = rand(3)
> -- freq[player] += 1 -- ... after uncommenting this
> line!
> end for
> result = append(result, freq)
> end for
>
> unique = create_set(result)
> ? unique
> if getc(0) then end if
> </eucode>
{{{
> Can someone please confirm the problem?
>
> Regards,
> Juergen
Juergen:
Could the problem be caused by variations in the RAND() function ?
The rand() may be compiled different for each compiler or different
on each OS. The reason I say this is because the rand() occurs before
the line that is commented out.
Bernie
My files in archive:
WMOTOR, XMOTOR, W32ENGIN, MIXEDLIB, EU_ENGIN, WIN32ERU, WIN32API
Can be downloaded here:
http://www.rapideuphoria.com/cgi-bin/asearch.exu?dos=on&win=on&lnx=on&gen=on&keywords=bernie+ryan
12. Re: Strange machine-level exception
Bernie Ryan wrote:
>
> Juergen Luethje wrote:
> >
> > Hi all,
> >
> > I've changed my private create_set() function a little, in order to take
> > advantage of find_from(). Then I encountered a strange machine-level
> > exception.
> >
> > I've tested it on Windows XP Pro and Euphoria 3.1. The following code runs
> > fine when interpreted by EX.exe, EXW.exe and EXWC.exe. When I uncomment
> > the denoted line near the end, the program still runs fine with EX.exe but
> > crashes reliably with EXW.exe and EXWC.exe. Renaming "safe.e" to "machine.e"
> > and including it in the program didn't provide any hints.
> > }}}
<eucode>
> > function create_set (sequence s)
> > -- create a set (= remove duplicate entries)
> > integer p
> >
> > if length(s) < 2 then
> > return s
> > end if
> >
> > p = length(s)
> > for i = length(s)-1 to 1 by -1 do
> > if find_from(s[i], s, i+1) = 0 then -- Machine-level exception here
> > ...
> > p -= 1
> > s[p] = s[i]
> > end if
> > end for
> > return s[p..$]
> > end function
> >
> >
> > sequence freq, result, unique
> > integer n, player
> >
> > n = 1000
> >
> > result = {}
> > for i = 1 to n do
> > freq = repeat(0, 3)
> > for card = 1 to 4 do
> > player = rand(3)
> > -- freq[player] += 1 -- ... after uncommenting this
> > line!
> > end for
> > result = append(result, freq)
> > end for
> >
> > unique = create_set(result)
> > ? unique
> > if getc(0) then end if
> > </eucode>
{{{
> > Can someone please confirm the problem?
> >
> > Regards,
> > Juergen
>
> Juergen:
> Could the problem be caused by variations in the RAND() function ?
> The rand() may be compiled different for each compiler or different
> on each OS. The reason I say this is because the rand() occurs before
> the line that is commented out.
> Bernie
>
> My files in archive:
> WMOTOR, XMOTOR, W32ENGIN, MIXEDLIB, EU_ENGIN, WIN32ERU, WIN32API
>
> Can be downloaded here:
> <a
> href="http://www.rapideuphoria.com/cgi-bin/asearch.exu?dos=on&win=on&lnx=on&gen=on&keywords=bernie+ryan">http://www.rapideuphoria.com/cgi-bin/asearch.exu?dos=on&win=on&lnx=on&gen=on&keywords=bernie+ryan</a>
I just made a few tests from office (WinXP Pro). Same problems.
The exception occurs at random iterations in create_set(), but always during the
call to find_from(). 1000 calls to rand() are made before create_set() is run,
and no exception occurs during that stage.
So, if it is not a find_from() Windows implementation bug, it means that the
implementation of rand() interferes with the one of find_from() under Windows.
Still a possibility, but less likely.
The exception occcurs after 1 to 6 calls to find_from(), irrespective of the
last result being 0, 1000, i+1 or anything else.
CChris
13. Re: Strange machine-level exception
I just peeked at the code in be_runtime.c. I haven't coded in C for a couple
years, yet something looks wrong to me - but again, *I* might be quite wrong just
as well.
Line 4654 says: "bv = *(++bp);", assuming ++bp can be read always. If the end of
the sequence is being reached, one would expect *(++bp) to be NOVALUE. Aren't
there cases (under Windows) where this might not be true, resulting in a bad read
ptr error? Or perhaps it is Windows that catches the error and DOS/Linux don't
care.
Additionally, I wondered, reading lines 4633-4638, whether
else if (bv == NOVALUE) {
break;
}
else if (compare(a, bv) == 0) { /* not INT-INT case */
return bp - (object_ptr)b->base;
}
shouldn't read
else {
if (bv == NOVALUE)
break;
else if (compare(a, bv) == 0) /* not INT-INT case */
return bp - (object_ptr)b->base;
}
instead. Perhaps the two are equivalent, but at least the logic is clearer in
the second form.
CChris
14. Re: Strange machine-level exception
CChris wrote:
>
> I just peeked at the code in be_runtime.c. I haven't coded in C
Ditto, and I must have been reading be_runtime.c exact same time as you.
Mostly, I queried the setting of length, as used in the
do {
} while (--length > 1);
Should there be summat like length-=c-1 next to the bp+=c-1 ?
Regards,
Pete
15. Re: Strange machine-level exception
- Posted by Juergen Luethje <j.lue at gmx.de>
Jun 18, 2007
-
Last edited Jun 19, 2007
Bernie Ryan wrote:
<snip>
> Juergen:
> Could the problem be caused by variations in the RAND() function ?
> The rand() may be compiled different for each compiler or different
> on each OS. The reason I say this is because the rand() occurs before
> the line that is commented out.
> Bernie
I also had a similar suspicion. But now I found that the program still
crashes, when
player = rand(3)
is replaced with
player = remainder(i,3) + 1
function create_set (sequence s)
-- create a set (= remove duplicate entries)
integer p
if length(s) < 2 then
return s
end if
p = length(s)
for i = length(s)-1 to 1 by -1 do
if find_from(s[i], s, i+1) = 0 then -- Machine-level exception here
p -= 1
s[p] = s[i]
end if
end for
return s[p..$]
end function
sequence freq, result, unique
integer n, player
n = 1000
result = {}
for i = 1 to n do
freq = repeat(0, 3)
for card = 1 to 4 do
-- player = rand(3) -- old
player = remainder(i,3) + 1 -- new --> program still crashes
freq[player] += 1
end for
result = append(result, freq)
end for
unique = create_set(result)
? unique
if getc(0) then end if
Regards,
Juergen
16. Re: Strange machine-level exception
- Posted by Bernie Ryan <xotron at bluefrog.com>
Jun 18, 2007
-
Last edited Jun 19, 2007
Juergen Luethje wrote:
>
> Bernie Ryan wrote:
>
> <snip>
>
> > Juergen:
> > Could the problem be caused by variations in the RAND() function ?
> > The rand() may be compiled different for each compiler or different
> > on each OS. The reason I say this is because the rand() occurs before
> > the line that is commented out.
> > Bernie
>
> I also had a similar suspicion. But now I found that the program still
> crashes, when
> player = rand(3)
> is replaced with
> player = remainder(i,3) + 1
>
> }}}
<eucode>
> function create_set (sequence s)
> -- create a set (= remove duplicate entries)
> integer p
>
> if length(s) < 2 then
> return s
> end if
>
> p = length(s)
> for i = length(s)-1 to 1 by -1 do
> if find_from(s[i], s, i+1) = 0 then -- Machine-level exception here
> p -= 1
> s[p] = s[i]
> end if
> end for
> return s[p..$]
> end function
>
>
> sequence freq, result, unique
> integer n, player
>
> n = 1000
>
> result = {}
> for i = 1 to n do
> freq = repeat(0, 3)
> for card = 1 to 4 do
> -- player = rand(3) -- old
> player = remainder(i,3) + 1 -- new --> program still crashes
> freq[player] += 1
> end for
> result = append(result, freq)
> end for
>
> unique = create_set(result)
> ? unique
> if getc(0) then end if
> </eucode>
{{{
Juergen:
I think the result of remainder can be a float and player is an integer
Bernie
My files in archive:
WMOTOR, XMOTOR, W32ENGIN, MIXEDLIB, EU_ENGIN, WIN32ERU, WIN32API
Can be downloaded here:
http://www.rapideuphoria.com/cgi-bin/asearch.exu?dos=on&win=on&lnx=on&gen=on&keywords=bernie+ryan
17. Re: Strange machine-level exception
- Posted by Juergen Luethje <j.lue at gmx.de>
Jun 18, 2007
-
Last edited Jun 19, 2007
Bernie Ryan wrote:
> Juergen Luethje wrote:
> >
> > Bernie Ryan wrote:
> >
> > <snip>
> >
> > > Juergen:
> > > Could the problem be caused by variations in the RAND() function ?
> > > The rand() may be compiled different for each compiler or different
> > > on each OS. The reason I say this is because the rand() occurs before
> > > the line that is commented out.
> > > Bernie
> >
> > I also had a similar suspicion. But now I found that the program still
> > crashes, when
> > player = rand(3)
> > is replaced with
> > player = remainder(i,3) + 1
> >
> > }}}
<eucode>
> > function create_set (sequence s)
> > -- create a set (= remove duplicate entries)
> > integer p
> >
> > if length(s) < 2 then
> > return s
> > end if
> >
> > p = length(s)
> > for i = length(s)-1 to 1 by -1 do
> > if find_from(s[i], s, i+1) = 0 then -- Machine-level exception here
> > p -= 1
> > s[p] = s[i]
> > end if
> > end for
> > return s[p..$]
> > end function
> >
> >
> > sequence freq, result, unique
> > integer n, player
> >
> > n = 1000
> >
> > result = {}
> > for i = 1 to n do
> > freq = repeat(0, 3)
> > for card = 1 to 4 do
> > -- player = rand(3) -- old
> > player = remainder(i,3) + 1 -- new --> program still crashes
> > freq[player] += 1
> > end for
> > result = append(result, freq)
> > end for
> >
> > unique = create_set(result)
> > ? unique
> > if getc(0) then end if
> > </eucode>
{{{
>
> Juergen:
>
> I think the result of remainder can be a float and player is an integer
I don't think that that is a problem, because the program does not crash
on the line:
player = remainder(i,3) + 1
but as before, it crashes on the line:
if find_from(s[i], s, i+1) = 0 then
Regards,
Juergen
18. Re: Strange machine-level exception
- Posted by Juergen Luethje <j.lue at gmx.de>
Jun 18, 2007
-
Last edited Jun 19, 2007
Now I've mamaged to write somewhat simpler code that still crashes:
integer n
n = 1000
procedure process (sequence s)
for i = n-1 to n-5 by -1 do
if find_from(s[2], s, i+1) = 0 then -- Machine-level exception here
s[1] = "x"
end if
end for
end procedure
sequence r, s
s = {}
for i = 1 to n do
r = repeat(0, 3)
for k = 1 to 4 do
r[remainder(i,3)+1] += 1
end for
s = append(s, r)
end for
process(s)
puts(1, "Finished.")
if getc(0) then end if
Regards,
Juergen
19. Re: Strange machine-level exception
I've again simplified the code that shows the crash:
integer n
n = 1000
procedure process (sequence s)
for i = n-1 to n-5 by -1 do
if find_from(s[2], s, i+1) = 0 then -- Machine-level exception here
s[1] = {}
end if
end for
end procedure
sequence s
integer r
s = repeat({}, n)
for i = 1 to n do
r = remainder(i, 3)
s[i] = {r}
end for
process(s)
puts(1, "If you see this message, there was no crash.")
if getc(0) then end if
Regards,
Juergen
20. Re: Strange machine-level exception
Juergen Luethje wrote:
>
> I've again simplified the code that shows the crash:
I even get a crash with just this, and a causeway error on ex.exe as well:
constant n=399
sequence s
integer r
s = repeat(0, n)
s[2] = {2}
r=find_from(s[2], s, n-1) -- Machine-level exception here
puts(1, "If you see this message, there was no crash.")
if getc(0) then end if
Regards,
Pete
21. Re: Strange machine-level exception
Pete Lomax wrote:
> Juergen Luethje wrote:
> >
> > I've again simplified the code that shows the crash:
>
> I even get a crash with just this, and a causeway error on ex.exe as well:
> }}}
<eucode>
> constant n=399
>
> sequence s
> integer r
>
> s = repeat(0, n)
> s[2] = {2}
> r=find_from(s[2], s, n-1) -- Machine-level exception here
>
> puts(1, "If you see this message, there was no crash.")
> if getc(0) then end if
> </eucode>
{{{
Wow! I wasn't even able to get rid of the procedure.
It looks as if the bug is surrounded now.
Regards,
Juergen
22. Re: Strange machine-level exception
Looking at the source in be_runtime.c for find_from.
It seems that the code is testing for the value of the length for
the full sequence instead of the length of the sequence from the
starting point of the find to the end of the sequence.
Maybe I'am wrong ?
Bernie
My files in archive:
WMOTOR, XMOTOR, W32ENGIN, MIXEDLIB, EU_ENGIN, WIN32ERU, WIN32API
Can be downloaded here:
http://www.rapideuphoria.com/cgi-bin/asearch.exu?dos=on&win=on&lnx=on&gen=on&keywords=bernie+ryan
23. Re: Strange machine-level exception
Bernie Ryan wrote:
>
>
> Looking at the source in be_runtime.c for find_from.
>
> It seems that the code is testing for the value of the length for
>
> the full sequence instead of the length of the sequence from the
>
> starting point of the find to the end of the sequence.
>
> Maybe I'am wrong ?
That's what I thought too. A further test confirms this beyond any remaining
doubt:
sequence x
x={1,2,3,4,{5}}
x=x[1..3]
?find_from({5},x,3)
and it prints 5 which is obvious nonsense as length(x) is now 3.
Regards,
Pete
24. Re: Strange machine-level exception
Pete Lomax wrote:
>
> Bernie Ryan wrote:
> >
> >
> > Looking at the source in be_runtime.c for find_from.
> >
> > It seems that the code is testing for the value of the length for
> >
> > the full sequence instead of the length of the sequence from the
> >
> > starting point of the find to the end of the sequence.
> >
> > Maybe I'am wrong ?
>
> That's what I thought too. A further test confirms this beyond any remaining
> doubt:
> }}}
<eucode>
> sequence x
> x={1,2,3,4,{5}}
> x=x[1..3]
> ?find_from({5},x,3)
> </eucode>
{{{
> and it prints 5 which is obvious nonsense as length(x) is now 3.
>
> Regards,
> Pete
I agree the routine is searching memory beyond the end of the sequence.
There is another problem with both find_from and match_from. Neither
routine performs lower bounds checking on the third argument. If a negative
value is passed to the routines, they will search memory before the beginning
of the sequence which may also crash the interpreter. I also think the routines
should return -1 for an out of bounds condition instead of 0. The current
behavior makes a return value of 0 ambiguous.
25. Re: Strange machine-level exception
Daryl Border wrote:
> I also think the routines
> should return -1 for an out of bounds condition instead of 0. The current
> behavior makes a return value of 0 ambiguous.
Maybe, but that is likely to break a lot of code that does this sort of thing
...
if find_from(a,b,c) = 0 then
doNotFound()
end if
Anyhow, below is my version of what the code in be_runtime.c should be doing ...
long find_from(object a, s1_ptr b, object c)
/* find object a as an element of sequence b starting from c*/
{
register object_ptr bp;
register object_ptr b_end;
register object bv;
if (!IS_SEQUENCE(b))
RTFatal("second argument of find_from() must be a sequence");
if (!IS_ATOM_INT(c))
RTFatal("third argument of find_from() must be an integer");
b = SEQ_PTR(b);
if (b->length == 0)
return 0;
if (b->length < c) // should this be an error instead?
return 0;
if (0 >= c) // should this be an error instead?
return 0;
bp = b->base; // Point to start of 'b'
bp += c - 1; // Point to start of scan within 'b'
b_end = b->base + length - 1; // Point to last element in 'b'
if (IS_ATOM_INT(a)) {
while (bp <= b_end) {
bv = *bp;
bp++;
if (IS_ATOM_INT(bv)) {
if (a == bv)
return bp - (object_ptr)b->base;
}
else if (bv == NOVALUE) {
return 0;
}
else if (compare(a, bv) == 0) { /* not INT-INT case */
return bp - (object_ptr)b->base;
}
}
}
else if (IS_SEQUENCE(a)) {
long a_len;
a_len = SEQ_PTR(a)->length;
if (a_len > 0) {
while(bp <= b_end) {
bv = *bp;
bp++;
if (IS_SEQUENCE(bv)) {
if (a_len == SEQ_PTR(bv)->length) {
/* a is SEQUENCE => not INT-INT case */
if (compare(a, bv) == 0)
return bp - (object_ptr)b->base;
}
}
}
}
}
else {
while (bp <= b_end) {
bv = *bp;
bp++;
if ( !IS_SEQUENCE(bv)) {
if (compare(a, bv) == 0) {
return bp - (object_ptr)b->base;
}
}
}
}
return(0);
}
--
Derek Parnell
Melbourne, Australia
Skype name: derek.j.parnell
26. Re: Strange machine-level exception
Derek Parnell wrote:
>
> Daryl Border wrote:
>
> > I also think the routines
> > should return -1 for an out of bounds condition instead of 0. The current
> > behavior makes a return value of 0 ambiguous.
>
> Maybe, but that is likely to break a lot of code that does this sort of thing
> ...
>
> if find_from(a,b,c) = 0 then
> doNotFound()
> end if
>
>
<snipped/>
Another possibility would be to return {} in case of an error. This way:
* "if find_from(...) " will succeed when there is no anomaly, and branch to
found or not found case as find() is doing currently.
* Code like "if find_from(...) " or "p=find_from(...)" will crash on an anomaly
condition because of type check failure, and the coder must decide whether this
is a bug in defining the starting point or an extra step like we use with gets()
is in order.
By the way, I find it a little short sighted not to include an extra argument
for the upper bound. Let's do it now, while the code base using find_from() is
nil. Since Eu doesn't support defaulted arguments contrary to C (sigh), it will
be much tougher to extend it later - that's why we are saddled with a find() and
a find_from() in the first place -. At the same time, if lower_bound >
upper_bound, this will enable reverse find(), something Eu is missing too.
Some special value for the upper bound could be reserved to stand for
"length(target)". For consistency with the current semantics of the $ symbol, I
suggest to use nonpositive numbers to denote offsets from end of sequence.
For example:
p=find_from(x,s,3,-2)
would be an exact equivalent of
object p
if 3<=0 or 3>length(s) then p={}
elsif 3<=length(s)-2 then -- forward find
p=find(x,s[3..$-2])
if p then p+= 3-1 end if
else -- reverse find
p=0
for i=length(s)-2 to 3 by -1 do
if equal(s[i],x) then
p=i
exit
end if
end for
end if
but way faster.
CChris
PS: Derek, by the way, do you check your email these days?
27. Re: Strange machine-level exception
CChris wrote:
> PS: Derek, by the way, do you check your email these days?
Yes.
--
Derek Parnell
Melbourne, Australia
Skype name: derek.j.parnell
28. Re: Strange machine-level exception
Derek Parnell wrote:
>
> CChris wrote:
>
> > PS: Derek, by the way, do you check your email these days?
>
> Yes.
>
> --
> Derek Parnell
> Melbourne, Australia
> Skype name: derek.j.parnell
Good, because I have some questions. And more that I didn't ask yet, concerned
with the following general topic: should win32lib strive to cater for the Eu2.3/4
interpreter? The advent of crash_routine(), as well as safe.e being around for a
while, made a couple sections in the current w32support.e redundant, since the
functionality is in the language now. But I think it is your decision, not mine.
CChris