[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