There is a gc bug somewhere exhibited by this badly written program:

~/felix>cat ls.flx
include "std/posix/filesystem";

  fun regfilesin(dname:string): list[string] = {
println$ "regfilesin " + dname;
if dname == "." or dname == ".." do return Empty[string]; done
     return 
     match FileSystem::filesin(dname) with
     | None  => Empty[string]
     | Some ?files =>
       List::fold_left 
         (fun (acc:list[string]) (f:string) = { if f == "." or f == ".." do 
return Empty[string]; done 
println$ "Folding " + f ; return
            let ?d = Filename::join (dname,f) in
            let ?t = FileSystem::filetype d in
              match t with
              | REGULAR => acc + d
              | DIRECTORY => acc + regfilesin d
              | _ => acc
              endmatch
          ;})
          Empty[string]
          files
      endmatch
   ;
  }

var dir = FileSystem::getcwd();
println$ "Files in curdir " + dir + "=" + regfilesin dir;

////////////////

This is just a recursive listing of all the files in the current directory.

It works fine with this command (after compilation by flx -c --static ls):

FLX_DEBUG=1 FLX_MIN_MEM=1000  ./ls 2> tmp.tmp

although very slow (reason later). That's allocating 1000 Meg=1 Gig of ram
in the initial memory pool, before garbage collector is allowed to run.

With smaller values of FLX_MIN_MEM it crashes earlier. Note I'm doing an "ls"
of felix, which contains a lot of files. This severely hammers allocation and 
list
processing. The crash is a corruption (there is often a match failure in a case
that cannot actually fail).

A bug in the GC may explain why the website top level server is crashing.
The port 1116 one doesn't (because it isn't so visible).

I could use some help with code review. There are 3 possible sources of the bug:

1) The GC code (C++) is bugged

2) The compiler is generating wrong shape information (doubtful, the code is too
simple, there are only 2 types: list nodes and union constructors (_uctor_).

3) It's also possible the C++ "in place list reversal" code is wrong (in 
lib/std/list).
This code reverse a list in O(N) time "in place" so isn't safe for general use,
but it is fine for using inside library functions like "map" which build their 
result
backwards (since the result is only accessible privately there can't be any 
sharing).

Now: the reason the above code is bad is evident here:

            let ?t = FileSystem::filetype d in
              match t with
              | REGULAR => acc + d                     // tack element d on end 
of list
              | DIRECTORY => acc + regfilesin d // concatenate lists

These are expensive operations. To tack an element onto a list tail like this
is pointless (better to push on the head and reverse the result later).
[The function also isn't tail recursive however that doesn't matter because
we're only recursing down directory trees which are never very deep].

--
john skaller
skal...@users.sourceforge.net





------------------------------------------------------------------------------
Protect Your Site and Customers from Malware Attacks
Learn about various malware tactics and how to avoid them. Understand 
malware threats, the impact they can have on your business, and how you 
can protect your company and customers by using code signing.
http://p.sf.net/sfu/oracle-sfdevnl
_______________________________________________
Felix-language mailing list
Felix-language@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/felix-language

Reply via email to