1. Strange machine-level exception

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

new topic     » topic index » view message » categorize

2. 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

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

new topic     » goto parent     » topic index » view message » categorize

3. 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.


> 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

new topic     » goto parent     » topic index » view message » categorize

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.

new topic     » goto parent     » topic index » view message » categorize

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

new topic     » goto parent     » topic index » view message » categorize

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

new topic     » goto parent     » topic index » view message » categorize

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

new topic     » goto parent     » topic index » view message » categorize

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

new topic     » goto parent     » topic index » view message » categorize

9. Re: Strange machine-level exception

Hello Doni,

thanks for looking into it, and for your additional information.

Regards,
   Juergen

new topic     » goto parent     » topic index » view message » categorize

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

new topic     » goto parent     » topic index » view message » categorize

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

new topic     » goto parent     » topic index » view message » categorize

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

new topic     » goto parent     » topic index » view message » categorize

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

new topic     » goto parent     » topic index » view message » categorize

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

new topic     » goto parent     » topic index » view message » categorize

15. Re: Strange machine-level exception

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

new topic     » goto parent     » topic index » view message » categorize

16. Re: Strange machine-level exception

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

new topic     » goto parent     » topic index » view message » categorize

17. Re: Strange machine-level exception

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

new topic     » goto parent     » topic index » view message » categorize

18. Re: Strange machine-level exception

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

new topic     » goto parent     » topic index » view message » categorize

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

new topic     » goto parent     » topic index » view message » categorize

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

new topic     » goto parent     » topic index » view message » categorize

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

new topic     » goto parent     » topic index » view message » categorize

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

new topic     » goto parent     » topic index » view message » categorize

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

new topic     » goto parent     » topic index » view message » categorize

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.

new topic     » goto parent     » topic index » view message » categorize

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

new topic     » goto parent     » topic index » view message » categorize

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?

new topic     » goto parent     » topic index » view message » categorize

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

new topic     » goto parent     » topic index » view message » categorize

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

new topic     » goto parent     » topic index » view message » categorize

Search



Quick Links

User menu

Not signed in.

Misc Menu