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

Roberto Bagnara bagnara at cs.unipr.it
Mon Oct 8 14:23:42 CEST 2007


Jan Wielemaker wrote:
>>>>> 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?

Probably the fact that the constructors of global variables are all
run (in unspecified order) before main() is given control.
You can compile the following with

     g++ -W -Wall test.cc

and see.

#include <iostream>

class Foo {
  public:
   Foo() {
     std::cout << "Foo::Foo() called." << std::endl;
   }
};

Foo foo;

int main() {
   // Calling PL_action(PL_GMP_SET_ALLOC_FUNCTIONS, FALSE) here would not help.
   std::cout << "main() called." << std::endl;
}

Of course, in the real code we have mpz_class, mpq_class and so forth
instead of Foo.
All the best,

     Roberto

-- 
Prof. Roberto Bagnara
Computer Science Group
Department of Mathematics, University of Parma, Italy
http://www.cs.unipr.it/~bagnara/
mailto:bagnara at cs.unipr.it



More information about the PPL-devel mailing list