
On Monday 08 October 2007 11:45, Roberto Bagnara wrote:
Jan Wielemaker wrote:
The only thing you are allowed to do from the GMP allocation functions is stop the process.
This is not my understanding: where did you get this restriction from?
Quoting from the GMP manual (GMP 4.2.1, SuSE RPM):
There's currently no defined way for the allocation functions to recover from an error such as out of memory, they must terminate program execution. A `longjmp' or throwing a C++ exception will have undefined results. This may change in the future.
I see. Well, I think the situation is that they do not make promises (not now) but either they will need to do so if they want a decent C++ interface. My experience is that when you get an out of memory error from GMP it is perfectly safe to discard the GMP object involved and computation can continue: we are testing this all the time and it never ever failed.
My guess is you will have some memory loss and possibly inconsistency in GMP objects who's modification caused the overflow.
So, I wonder how you safely recover. Surely if you call Prolog, which calls a GMP function, which gets you using longjmp or a C++ exception back to the C++ program, you haven't made Prolog particulary happy. Seems from the rest that you are calling C++ from Prolog, which might make things a bit better ...
Yes, we are calling C++ from Prolog.
Anyway for the others, I added
PL_action(PL_GMP_SET_ALLOC_FUNCTIONS, TRUE)
if you want Prolog's GMP allocation initialised *now* (without initializing the rest of SWI-Prolog). or
PL_action(PL_GMP_SET_ALLOC_FUNCTIONS, FALSE)
If you want to stop Prolog from setting the allocation functions. Must be called before PL_initialise(), of course.
I see how to use that in the foreign-calls-Prolog case. How can I achieve that in the Prolog-calls-foreign case (which is the one I am mostly interested in)?
You mean you load a shared object into Prolog? Good!
No, I am having problems with libraries statically linked to the SWI-Prolog system. These libraries (written in C++) use several statically allocated GMP numbers. When the system starts, the statically allocated variables are initialized with the GMP's memory allocation function. Then SWI-Prolog is given control and the allocation functions are changed. Then the system exits and the statically allocated variables are destroyed with the wrong (i.e., SWI-Prolog's) allocation function: which results into a segmentation fault. This change you have made to SWI-Prolog is really breaking everything here.
I'm not getting it. I think there are two situations: you embed Prolog, so you call PL_initialise() and you can call the PL_action(PL_GMP_SET_ALLOC_FUNCTIONS, FALSE) before it or you keep the Prolog toplevel and you load your code as a .so file into Prolog. I think both work fine, even with global C++ initializers. What am I missing? Please describe how you link the two together and what is the main routine from C(++).
Cheers --- Jan