caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* Heaps size problems with "caml_alloc_small" in foreign function interfaces
@ 2008-07-11  8:21 Sean Seefried
  2008-07-11  9:40 ` [Caml-list] " Richard Jones
  2008-07-11 14:11 ` Xavier Leroy
  0 siblings, 2 replies; 14+ messages in thread
From: Sean Seefried @ 2008-07-11  8:21 UTC (permalink / raw)
  To: caml-list

Hi,

I'm having a problem where sometimes a call to "caml_alloc_small" from  
C results in a segmentation fault. If I increase the size of the stack  
using OCAMLRUNPARAM=s=1000k then I don't get the crash anymore. It  
seems strange that I have to increase the size of the heap manually  
like this. Is this because I'm calling this function from C?

If I want to increase the size of the heap in C how do I do this?  
Could I write a "safe" caml_alloc_small which first checks to see if  
there is enough memory and then increases the heap size if not?

Sean


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [Caml-list] Heaps size problems with "caml_alloc_small" in foreign function interfaces
  2008-07-11  8:21 Heaps size problems with "caml_alloc_small" in foreign function interfaces Sean Seefried
@ 2008-07-11  9:40 ` Richard Jones
  2008-07-11  9:51   ` Richard Jones
  2008-07-11 10:21   ` Sean Seefried
  2008-07-11 14:11 ` Xavier Leroy
  1 sibling, 2 replies; 14+ messages in thread
From: Richard Jones @ 2008-07-11  9:40 UTC (permalink / raw)
  To: Sean Seefried; +Cc: caml-list

On Fri, Jul 11, 2008 at 06:21:51PM +1000, Sean Seefried wrote:
> I'm having a problem where sometimes a call to "caml_alloc_small" from  
> C results in a segmentation fault. If I increase the size of the stack  
> using OCAMLRUNPARAM=s=1000k then I don't get the crash anymore. It  
> seems strange that I have to increase the size of the heap manually  
> like this. Is this because I'm calling this function from C?

Seems like you have confusion over heap & stack.

First of all, caml_alloc_small is limited to small allocations, so
number of words allocated must be <= Max_young_wosize.  You don't post
any example code so we can't see whether that is true in your code.

Secondly (and much more likely to be the problem), the caml_alloc*
functions allocate uninitialised memory.  If the garbage collector
gets to run before you've properly initialized all the fields then the
GC will hit an uninitialised field and a segfault could be the result.

  eg: This is a fail:

  v = caml_alloc (2, 0);
  vv = caml_alloc (3, 0);  /* GC could run here */
  Store_field (v, 0, vv);

Changing the _stack_ size (or other tunables) probably just changes
something about when the garbage collector runs, and thus moves the
bug around.

> If I want to increase the size of the heap in C how do I do this?  
> Could I write a "safe" caml_alloc_small which first checks to see if  
> there is enough memory and then increases the heap size if not?

The "size of the heap in C" is (for most operating systems) extended
automatically by malloc.  What you're saying here isn't necessary -
you must have some other bug.

I suggest you post some code which exhibits the problem.

Rich.

-- 
Richard Jones
Red Hat


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [Caml-list] Heaps size problems with "caml_alloc_small" in foreign function interfaces
  2008-07-11  9:40 ` [Caml-list] " Richard Jones
@ 2008-07-11  9:51   ` Richard Jones
  2008-07-11 10:21   ` Sean Seefried
  1 sibling, 0 replies; 14+ messages in thread
From: Richard Jones @ 2008-07-11  9:51 UTC (permalink / raw)
  To: Sean Seefried; +Cc: caml-list

On Fri, Jul 11, 2008 at 10:40:50AM +0100, Richard Jones wrote:
>   v = caml_alloc (2, 0);
>   vv = caml_alloc (3, 0);  /* GC could run here */

Ick, actually caml_alloc is OK, it's only caml_alloc_small which
doesn't initialize.

Rich.

-- 
Richard Jones
Red Hat


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [Caml-list] Heaps size problems with "caml_alloc_small" in foreign function interfaces
  2008-07-11  9:40 ` [Caml-list] " Richard Jones
  2008-07-11  9:51   ` Richard Jones
@ 2008-07-11 10:21   ` Sean Seefried
  2008-07-11 15:56     ` Richard Jones
  1 sibling, 1 reply; 14+ messages in thread
From: Sean Seefried @ 2008-07-11 10:21 UTC (permalink / raw)
  To: Richard Jones; +Cc: caml-list


On 11/07/2008, at 7:40 PM, Richard Jones wrote:

> On Fri, Jul 11, 2008 at 06:21:51PM +1000, Sean Seefried wrote:
>> I'm having a problem where sometimes a call to "caml_alloc_small"  
>> from
>> C results in a segmentation fault. If I increase the size of the  
>> stack
>> using OCAMLRUNPARAM=s=1000k then I don't get the crash anymore. It
>> seems strange that I have to increase the size of the heap manually
>> like this. Is this because I'm calling this function from C?
>
> Seems like you have confusion over heap & stack.
>
> First of all, caml_alloc_small is limited to small allocations, so
> number of words allocated must be <= Max_young_wosize.  You don't post
> any example code so we can't see whether that is true in your code.
>

caml_alloc_small(32,0);

is what seemed to cause the problem. I'm shying away from posting more  
code since it is auto-generated from CamlIDL and is very verbose. I  
didn't write it myself.

> Secondly (and much more likely to be the problem), the caml_alloc*
> functions allocate uninitialised memory.  If the garbage collector

What do you mean by "uninitialised memory"?

> gets to run before you've properly initialized all the fields then the
> GC will hit an uninitialised field and a segfault could be the result.
>
>  eg: This is a fail:
>
>  v = caml_alloc (2, 0);
>  vv = caml_alloc (3, 0);  /* GC could run here */
>  Store_field (v, 0, vv);
>

What do you do about this? Is there a way to stop the GC from running  
for a period of time?

> Changing the _stack_ size (or other tunables) probably just changes
> something about when the garbage collector runs, and thus moves the
> bug around.
>
>> If I want to increase the size of the heap in C how do I do this?
>> Could I write a "safe" caml_alloc_small which first checks to see if
>> there is enough memory and then increases the heap size if not?
>
> The "size of the heap in C" is (for most operating systems) extended
> automatically by malloc.  What you're saying here isn't necessary -
> you must have some other bug.
>

I wasn't very clear but I meant changing the OCaml heap size using C  
functions.

Sean


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [Caml-list] Heaps size problems with "caml_alloc_small" in foreign function interfaces
  2008-07-11  8:21 Heaps size problems with "caml_alloc_small" in foreign function interfaces Sean Seefried
  2008-07-11  9:40 ` [Caml-list] " Richard Jones
@ 2008-07-11 14:11 ` Xavier Leroy
  2008-07-12  3:20   ` Sean Seefried
  2008-07-12  6:00   ` Sean Seefried
  1 sibling, 2 replies; 14+ messages in thread
From: Xavier Leroy @ 2008-07-11 14:11 UTC (permalink / raw)
  To: Sean Seefried; +Cc: caml-list

> I'm having a problem where sometimes a call to "caml_alloc_small" from C
> results in a segmentation fault. If I increase the size of the stack
> using OCAMLRUNPARAM=s=1000k then I don't get the crash anymore. It seems
> strange that I have to increase the size of the heap manually like this.

It's probably a root registration problem.  These are very sensitive
to the times when GC is triggered, which themselves are sensitive to
the heap sizes and memory behavior of your program.

> If I want to increase the size of the heap in C how do I do this? Could
> I write a "safe" caml_alloc_small which first checks to see if there is
> enough memory and then increases the heap size if not?

Don't try to hack around the real problem, but do make available a
repro case, no matter how large, on a Web site or as attachment to a
problem report on the bug tracking system, so that others can have a
look at it.

- Xavier Leroy


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [Caml-list] Heaps size problems with "caml_alloc_small" in foreign function interfaces
  2008-07-11 10:21   ` Sean Seefried
@ 2008-07-11 15:56     ` Richard Jones
  0 siblings, 0 replies; 14+ messages in thread
From: Richard Jones @ 2008-07-11 15:56 UTC (permalink / raw)
  To: Sean Seefried; +Cc: caml-list

On Fri, Jul 11, 2008 at 08:21:45PM +1000, Sean Seefried wrote:
> caml_alloc_small(32,0);
> 
> is what seemed to cause the problem. I'm shying away from posting more  
> code since it is auto-generated from CamlIDL and is very verbose. I  
> didn't write it myself.

You need to post a reproducer.

> >Secondly (and much more likely to be the problem), the caml_alloc*
> >functions allocate uninitialised memory.  If the garbage collector
> 
> What do you mean by "uninitialised memory"?

Memory which hasn't been explicitly initialized, and so contains
random stuff.  The GC attempts to interpret the random stuff and
fails.

[...]
> What do you do about this? Is there a way to stop the GC from running  
> for a period of time?

The GC could possibly run any time you call an allocation function.
So don't call allocation functions.

Anyhow, you really need to post some code at this point.

Rich.

-- 
Richard Jones
Red Hat


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [Caml-list] Heaps size problems with "caml_alloc_small" in foreign function interfaces
  2008-07-11 14:11 ` Xavier Leroy
@ 2008-07-12  3:20   ` Sean Seefried
  2008-07-12  6:00   ` Sean Seefried
  1 sibling, 0 replies; 14+ messages in thread
From: Sean Seefried @ 2008-07-12  3:20 UTC (permalink / raw)
  To: Xavier Leroy; +Cc: caml-list

Could you give me a pointer to information on root registration?

What frustrates me is that this is CamlIDL generated code. Shouldn't  
it just work?

Sean

On 12/07/2008, at 0:11, Xavier Leroy <Xavier.Leroy@inria.fr> wrote:

>> I'm having a problem where sometimes a call to "caml_alloc_small"  
>> from C
>> results in a segmentation fault. If I increase the size of the stack
>> using OCAMLRUNPARAM=s=1000k then I don't get the crash anymore. It  
>> seems
>> strange that I have to increase the size of the heap manually like  
>> this.
>
> It's probably a root registration problem.  These are very sensitive
> to the times when GC is triggered, which themselves are sensitive to
> the heap sizes and memory behavior of your program.
>
>> If I want to increase the size of the heap in C how do I do this?  
>> Could
>> I write a "safe" caml_alloc_small which first checks to see if  
>> there is
>> enough memory and then increases the heap size if not?
>
> Don't try to hack around the real problem, but do make available a
> repro case, no matter how large, on a Web site or as attachment to a
> problem report on the bug tracking system, so that others can have a
> look at it.
>
> - Xavier Leroy


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [Caml-list] Heaps size problems with "caml_alloc_small" in foreign function interfaces
  2008-07-11 14:11 ` Xavier Leroy
  2008-07-12  3:20   ` Sean Seefried
@ 2008-07-12  6:00   ` Sean Seefried
  1 sibling, 0 replies; 14+ messages in thread
From: Sean Seefried @ 2008-07-12  6:00 UTC (permalink / raw)
  To: Xavier Leroy; +Cc: caml-list

[-- Attachment #1: Type: text/plain, Size: 1219 bytes --]

>>

Hi Xavier,

Okay, here's some further clarification and this time I'm attaching a  
file. I've had to GZip it because it's so big.

The bug in question occurs on line 4078.

I should clarify. This file becomes part of a library that is linked  
into another OCaml program.  On one input file that this OCaml program  
takes as input it fails on line 4078.  On other files it fails on  
other lines. However, the code it fails at always seems to be of the  
form:

     _v2 = camlidl_alloc_small(18, 0);
     { mlsize_t _c8;
       for (_c8 = 0; _c8 < 18; _c8++) Field(_v2, _c8) = _v3[_c8];
     }

What's strange about this is that this is automatically generated code  
from CamlIDL (with a few extra debugging messages I threw in). Xavier,  
I'm using CamlDL to write a binding to a  C front-end which has an  
absolutely huge C data structure.  I've had to write several  
extensions to CamlIDL to make this a reality, but for the moment I'm  
keeping these in my own source control mainly because your coding  
style is very clean and many of my extensions could have been done a  
lot more elegantly.

However, the code that is being generated above was already generated  
by version 1.05 of CamlIDL.




Sean

[-- Attachment #2.1: Type: text/html, Size: 1972 bytes --]

[-- Attachment #2.2: test.c.gz --]
[-- Type: application/x-gzip, Size: 116331 bytes --]

[-- Attachment #2.3: Type: text/html, Size: 164 bytes --]

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [Caml-list] Heaps size problems with "caml_alloc_small" in foreign function interfaces
  2008-07-13 13:25   ` Sean Seefried
  2008-07-13 13:37     ` Gordon Henriksen
@ 2008-07-13 14:03     ` Thomas Crimi
  1 sibling, 0 replies; 14+ messages in thread
From: Thomas Crimi @ 2008-07-13 14:03 UTC (permalink / raw)
  To: Sean Seefried; +Cc: caml-list

On Jul 13, 2008, at 9:25 AM, Sean Seefried wrote:

>
> So now I have a question. Is there any way that I can find out what  
> address the garbage collector moves these values to? I need to  
> update the table when this happens.

  You have to register each of your pointers as global roots, but  
beware that doing so for a large number of objects can dramatically  
slow down the GC since all the roots must be scanned on each minor  
collection.  The main issue here is that the OCaml run-time can't tell  
if you're modifying root pointers behind its back;  pointing into the  
young generation, so each scan of the young generation needs to first  
check all root pointers.  It should be possible to better optimize  
this by having the C code promise not to do this without telling the  
GC, but such functions currently don't exist.

  A solution I've used in the past (surely obtained from this list) is  
to keep the Hashtable in OCaml, and register some functions that the C  
code can use to access it.  The C code can refer to objects long-term  
by integer ID which can be used for fast lookups.

  When you need the object, look it up by integer id to get the  
pointer.  Then, of course, register the pointer as a global root.   
Once your done with the object pointer you release the global root  
again (or just keep a single always-registered global root around and  
re-point it to each object you need).

   This keeps the number of global roots to a minimum but still allows  
fast access to the pointers.

   Generally in my code I've created C++ wrapper classes to wrap a  
'val' and provide C++-object-like access.  It's very easy to have a  
base class that properly manages root allocation / release and then  
never have to think about it again.  GC errors like this are insidious  
since your program can run for weeks without issue then one particular  
data-set causes a GC at the inopportune time and you have a mysterious  
crash.

   I'm not familiar with CamlIDL, so I'm not sure how amenable these  
tricks are.

  Regards,
   Tom


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [Caml-list] Heaps size problems with "caml_alloc_small" in foreign function interfaces
  2008-07-13 13:25   ` Sean Seefried
@ 2008-07-13 13:37     ` Gordon Henriksen
  2008-07-13 14:03     ` Thomas Crimi
  1 sibling, 0 replies; 14+ messages in thread
From: Gordon Henriksen @ 2008-07-13 13:37 UTC (permalink / raw)
  To: Caml List

On 2008-07-13, at 09:25, Sean Seefried wrote:

> After a weekend's worth of ruminating I have finally found the bug  
> in my code. It didn't turn out to be a root registration problem [...]
>
> So now I have a question. Is there any way that I can find out what  
> address the garbage collector moves these values to? I need to  
> update the table when this happens.


You need to register them as roots and the collector will update them  
for you.

— Gordon


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [Caml-list] Heaps size problems with "caml_alloc_small" in foreign function interfaces
  2008-07-12  8:50 ` Richard Jones
@ 2008-07-13 13:25   ` Sean Seefried
  2008-07-13 13:37     ` Gordon Henriksen
  2008-07-13 14:03     ` Thomas Crimi
  0 siblings, 2 replies; 14+ messages in thread
From: Sean Seefried @ 2008-07-13 13:25 UTC (permalink / raw)
  To: Xavier Leroy; +Cc: caml-list

[-- Attachment #1: Type: text/plain, Size: 1598 bytes --]

After a weekend's worth of ruminating I have finally found the bug in  
my code. It didn't turn out to be a root registration problem but your  
pointer to this possible cause led me to read a lot of interesting  
things about the garbage collector which, indirectly, helped me find  
the problem.

Xavier, I ran into a problem with CamlIDL when translating C data  
structures to OCaml ones. The problem was that I was translating a  
really large data structure with a lot of sharing. Most structs had  
next, prev, and parent pointers which meant that many, many recursive  
calls were made. This eventually blew the stack.

So what I decided to do was create a hashtable.  Whenever I  
encountered a C pointer type I first allocated memory for the OCaml  
value filled it's fields with dummy values and then associated the  
address of the C structure (the key) with the address of the OCaml  
value (the value).  This was great because whenever I came across the  
same C pointer again I would just look up the value and use that.

However, I failed to think about garbage collection!

Naturally, whenever garbage collection is done the OCaml values are  
moved in memory, but the addresses of the OCaml data structures in my  
hash table stay the same.  This is no good since those very same  
addresses become available again to be allocated by  
camlidl_alloc_small. This can lead to all sorts of unpleasantness!

So now I have a question. Is there any way that I can find out what  
address the garbage collector moves these values to? I need to update  
the table when this happens.

Sean

[-- Attachment #2: Type: text/html, Size: 1936 bytes --]

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [Caml-list] Heaps size problems with "caml_alloc_small" in foreign function interfaces
  2008-07-12  6:07 Sean Seefried
  2008-07-12  6:09 ` Sean Seefried
@ 2008-07-12  8:50 ` Richard Jones
  2008-07-13 13:25   ` Sean Seefried
  1 sibling, 1 reply; 14+ messages in thread
From: Richard Jones @ 2008-07-12  8:50 UTC (permalink / raw)
  To: Sean Seefried; +Cc: caml-list

On Sat, Jul 12, 2008 at 04:07:48PM +1000, Sean Seefried wrote:
> However, the code that is being generated above was already generated  
> by version 1.05 of CamlIDL.
> 
> The file can be found at: 
> http://howe.textdrive.com/~sseefried/files/test.c.gz

What's the _original_ code though?  This is just some generated code,
apparently from camlidl, with your modifications.  If this is a bug in
camlidl, we need to see everything which generates this.

Rich.

-- 
Richard Jones
Red Hat


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [Caml-list] Heaps size problems with "caml_alloc_small" in foreign function interfaces
  2008-07-12  6:07 Sean Seefried
@ 2008-07-12  6:09 ` Sean Seefried
  2008-07-12  8:50 ` Richard Jones
  1 sibling, 0 replies; 14+ messages in thread
From: Sean Seefried @ 2008-07-12  6:09 UTC (permalink / raw)
  To: Xavier Leroy; +Cc: caml-list

[-- Attachment #1: Type: text/plain, Size: 1295 bytes --]

Hi Xavier,

Okay, here's some further clarification and this time I'm attaching a  
file. I've had to GZip it because it's so big.

The bug in question occurs on line 4078.

I should clarify. This file becomes part of a library that is linked  
into another OCaml program.  On one input file that this OCaml program  
takes as input it fails on line 4078.  On other files it fails on  
other lines. However, the code it fails at always seems to be of the  
form:

     _v2 = camlidl_alloc_small(18, 0);
     { mlsize_t _c8;
       for (_c8 = 0; _c8 < 18; _c8++) Field(_v2, _c8) = _v3[_c8];
     }

What's strange about this is that this is automatically generated code  
from CamlIDL (with a few extra debugging messages I threw in). Xavier,  
I'm using CamlDL to write a binding to a  C front-end which has an  
absolutely huge C data structure.  I've had to write several  
extensions to CamlIDL to make this a reality, but for the moment I'm  
keeping these in my own source control mainly because your coding  
style is very clean and many of my extensions could have been done a  
lot more elegantly.

However, the code that is being generated above was already generated  
by version 1.05 of CamlIDL.


The file can be found at: http://howe.textdrive.com/~sseefried/files/test.c.gz

Sean


[-- Attachment #2: Type: text/html, Size: 3388 bytes --]

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [Caml-list] Heaps size problems with "caml_alloc_small" in foreign function interfaces
@ 2008-07-12  6:07 Sean Seefried
  2008-07-12  6:09 ` Sean Seefried
  2008-07-12  8:50 ` Richard Jones
  0 siblings, 2 replies; 14+ messages in thread
From: Sean Seefried @ 2008-07-12  6:07 UTC (permalink / raw)
  To: Xavier Leroy; +Cc: caml-list

[-- Attachment #1: Type: text/plain, Size: 1293 bytes --]

Hi Xavier,

Okay, here's some further clarification and this time I'm attaching a  
file. I've had to GZip it because it's so big.

The bug in question occurs on line 4078.

I should clarify. This file becomes part of a library that is linked  
into another OCaml program.  On one input file that this OCaml program  
takes as input it fails on line 4078.  On other files it fails on  
other lines. However, the code it fails at always seems to be of the  
form:

     _v2 = camlidl_alloc_small(18, 0);
     { mlsize_t _c8;
       for (_c8 = 0; _c8 < 18; _c8++) Field(_v2, _c8) = _v3[_c8];
     }

What's strange about this is that this is automatically generated code  
from CamlIDL (with a few extra debugging messages I threw in). Xavier,  
I'm using CamlDL to write a binding to a  C front-end which has an  
absolutely huge C data structure.  I've had to write several  
extensions to CamlIDL to make this a reality, but for the moment I'm  
keeping these in my own source control mainly because your coding  
style is very clean and many of my extensions could have been done a  
lot more elegantly.

However, the code that is being generated above was already generated  
by version 1.05 of CamlIDL.


The file can be found at: http://howe.textdrive.com/~sseefried/files/test.c.gz

Sean

[-- Attachment #2: Type: text/html, Size: 2043 bytes --]

^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2008-07-13 14:03 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-07-11  8:21 Heaps size problems with "caml_alloc_small" in foreign function interfaces Sean Seefried
2008-07-11  9:40 ` [Caml-list] " Richard Jones
2008-07-11  9:51   ` Richard Jones
2008-07-11 10:21   ` Sean Seefried
2008-07-11 15:56     ` Richard Jones
2008-07-11 14:11 ` Xavier Leroy
2008-07-12  3:20   ` Sean Seefried
2008-07-12  6:00   ` Sean Seefried
2008-07-12  6:07 Sean Seefried
2008-07-12  6:09 ` Sean Seefried
2008-07-12  8:50 ` Richard Jones
2008-07-13 13:25   ` Sean Seefried
2008-07-13 13:37     ` Gordon Henriksen
2008-07-13 14:03     ` Thomas Crimi

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).