[PPL-devel] [SWIPL] Re: GMP memory allocation problem in SWI-Prolog 5.6.38 and following versions

Jan Wielemaker wielemak at science.uva.nl
Mon Oct 8 13:43:29 CEST 2007


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




More information about the PPL-devel mailing list