Hi there, since we have decided that PPL 0.4 must be shipped with a reasonably complete YAP interface, we have investigated a bit more the problems we are experiencing. These can be split in two: the first one has to do with the fact that PPL uses GMP and YAP also uses, by default, GMP. That results in a segmentation fault at the very first memory allocation of a GMP object that the PPL performs. But let us proceed with order. The machines we use are Athlon machines running RedHat GNU/Linux 7.2 and 7.3 with all the updates applied. We use GCC 3.0.4. $ uname -a Linux xyzzy 2.4.18 #2 Thu Feb 28 07:12:54 CET 2002 i686 unknown $ gcc -v Reading specs from /usr/local/lib/gcc-lib/i686-pc-linux-gnu/3.0.4/specs Configured with: ../gcc-3.0.4/configure --prefix=/usr/local Thread model: single gcc version 3.0.4 $ We use a CVS version of yap that is up-to-date at the time of writing. This has been configured with --enable-debug-yap --prefix=/usr/local With this configuration we cannot even load the PPL-YAP interface due to a segmentation fault in AllocBigNumSpace (size=4) at C/bignum.c:96. The complete log of a gdb session is below the signature (I am sure Vitor will immediately see where the problem is). To expose the other problems we have (I will do that in a following message) we must therefore add --disable-gmp to the configuration options of YAP. Will be back later Roberto -- Prof. Roberto Bagnara Computer Science Group Department of Mathematics, University of Parma, Italy http://www.cs.unipr.it/~bagnara/ mailto:bagnara@cs.unipr.it $ gdb yap GNU gdb Red Hat Linux (5.1-1) Copyright 2001 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type "show copying" to see the conditions. There is absolutely no warranty for GDB. Type "show warranty" for details. This GDB was configured as "i386-redhat-linux"... (gdb) r Starting program: /usr/local/bin/yap [ Restoring file startup ] [ YAP version Yap-4.3.23 ] ?- load_foreign_files(['ppl_yap'],[],init). Program received signal SIGSEGV, Segmentation fault. AllocBigNumSpace (size=4) at C/bignum.c:96 96 alloc_ptr[0] = size; (gdb) info stack #0 AllocBigNumSpace (size=4) at C/bignum.c:96 #1 0x400272a4 in __gmpz_init (x=0x80e1198) at ../../gmp-4.0.1/mpz/init.c:29 #2 0x4020b7cb in Parma_Polyhedra_Library::Init::Init() (this=0x4000cba0) at ../../../../ppl/ppl/src/Init.inlines.hh:36 #3 0x40203f11 in __static_initialization_and_destruction_0(int, int) ( __initialize_p=1, __priority=65535) at ../../../../ppl/ppl/src/initializer.hh:29 #4 0x40204845 in _GLOBAL__I__Z23Prolog_atom_from_stringPKc () at /usr/local/include/g++-v3/bits/locale_facets.h:97 #5 0x402048e7 in __do_global_ctors_aux () at /usr/local/include/g++-v3/bits/locale_facets.h:97 #6 0x401f05c6 in _init () from /home/roberto/dtppl/interfaces/Prolog/YAP/.libs/ppl_yap.so #7 0x4000d111 in _dl_init (main_map=0x80e1198, argc=1, argv=0xbffff904, env=0xbffff90c) at dl-init.c:70 #8 0x401ad3e1 in dl_open_worker (a=0xbffff4f0) at dl-open.c:361 #9 0x4000ce55 in _dl_catch_error (objname=0xbffff4e8, errstring=0xbffff4ec, operate=0x401ad14c <dl_open_worker>, args=0xbffff4f0) at dl-error.c:152 #10 0x401ad756 in _dl_open ( file=0x80dd7e0 "/home/roberto/dtppl/interfaces/Prolog/YAP/.libs/ppl_yap.so", mode=-2147483391, caller=0x809f01a) at dl-open.c:407 #11 0x40080363 in dlopen_doit (a=0xbffff650) at dlopen.c:39 #12 0x4000ce55 in _dl_catch_error (objname=0x400820e4, errstring=0x400820e8, ---Type <return> to continue, or q <return> to quit--- operate=0x40080338 <dlopen_doit>, args=0xbffff650) at dl-error.c:152 #13 0x400806b6 in _dlerror_run (operate=0x40080338 <dlopen_doit>, args=0xbffff650) at dlerror.c:130 #14 0x40080323 in __dlopen_check ( file=0x80dd7e0 "/home/roberto/dtppl/interfaces/Prolog/YAP/.libs/ppl_yap.so", mode=257) at dlopen.c:53 #15 0x0809f01a in LoadForeign (ofiles=0x90cbba8, libs=0x0, proc_name=0x90cba3c "init", init_proc=0xbffff6b8) at C/load_dl.c:60 #16 0x0809edff in p_load_foreign () at C/load_foreign.c:86 #17 0x080a932a in absmi (inp=0) at C/absmi.c:5659 #18 0x0806d988 in exec_absmi (top=1) at C/exec.c:881 #19 0x0806db82 in do_goal (CodeAdr=0x901a460 "ðV\n\bôÿÿÿØ£\001\t", arity=0, pt=0x0, args_to_save=0, top=1) at C/exec.c:934 #20 0x0806e1b4 in RunTopGoal (t=214482) at C/exec.c:1118 #21 0x08050f07 in YapRunGoal (t=214482) at C/c_interface.c:698 #22 0x0804f581 in do_top_goal (Goal=214482) at console/yap.c:122 #23 0x0804fd21 in exec_top_level (BootMode=1, filename=0x0) at console/yap.c:460 #24 0x0804fd9f in main (argc=1, argv=0xbffff904) at console/yap.c:486 #25 0x400b6316 in __libc_start_main (main=0x804fd50 <main>, argc=1, ubp_av=0xbffff904, init=0x804e974 <_init>, fini=0x80c8690 <_fini>, rtld_fini=0x4000d2fc <_dl_fini>, stack_end=0xbffff8fc) at ../sysdeps/generic/libc-start.c:129 (gdb) frame 0 #0 AllocBigNumSpace (size=4) at C/bignum.c:96 96 alloc_ptr[0] = size; (gdb) print alloc_ptr $1 = (CELL *) 0x0 (gdb) The following output may also be of interest: $ ldd /usr/local/bin/yap libgmp.so.3 => /usr/local/lib/libgmp.so.3 (0x40017000) libm.so.6 => /lib/libm.so.6 (0x4005d000) libdl.so.2 => /lib/libdl.so.2 (0x4007f000) libnsl.so.1 => /lib/libnsl.so.1 (0x40083000) libc.so.6 => /lib/libc.so.6 (0x4009a000) libgcc_s.so.1 => /usr/local/lib/libgcc_s.so.1 (0x401d1000) /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000) $ ldd ppl_yap.so libppl.so.0 => /home/roberto/dtppl/src/.libs/libppl.so.0 (0x4004f000) libgmp.so.3 => /usr/local/lib/libgmp.so.3 (0x400ed000) libgmpxx.so.3 => /usr/local/lib/libgmpxx.so.3 (0x40126000) libgcc_s.so.1 => /usr/local/lib/libgcc_s.so.1 (0x40132000) libc.so.6 => /lib/libc.so.6 (0x40148000) libstdc++.so.3 => /usr/local/lib/libstdc++.so.3 (0x4027e000) libm.so.6 => /lib/libm.so.6 (0x40315000) /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x80000000)
The problem seems to be that Yap defines its own allocation functions for gmp objects: #ifdef USE_GMP /* YAP style memory allocation */ mp_set_memory_functions( AllocBigNumSpace, ReAllocBigNumSpace, FreeBigNumSpace); #endif This allows Yap to work with such objects in its own stacks. Unfortunately, these functions require for another function, PreAllocBigNum to have been called before. In general, using them is a bit dangerous, because they assume they have control over the global stack. I suppose Yap is polluting the application space, so the correct solution would be for Yap to reset these functions before entering user code. But this would make the interface slower for any application that doesn't use GMP. A compromise might be for me to provide two interface functions (YapResetGMPFunctions() and YapSet GMPFunctions()) and for you to call them before you started manipulating GMP objects. Cheers, Vitor
Vitor Santos Costa wrote:
The problem seems to be that Yap defines its own allocation functions for gmp objects:
#ifdef USE_GMP /* YAP style memory allocation */ mp_set_memory_functions( AllocBigNumSpace, ReAllocBigNumSpace, FreeBigNumSpace); #endif
This allows Yap to work with such objects in its own stacks. Unfortunately, these functions require for another function, PreAllocBigNum to have been called before. In general, using them is a bit dangerous, because they assume they have control over the global stack.
I suppose Yap is polluting the application space, so the correct solution would be for Yap to reset these functions before entering user code. But this would make the interface slower for any application that doesn't use GMP.
A compromise might be for me to provide two interface functions (YapResetGMPFunctions() and YapSet GMPFunctions()) and for you to call them before you started manipulating GMP objects.
Why is not Yap calling PreAllocBigNum first? I mean, initializing things so that AllocBigNumSpace and friends work correctly would seem something to be done in the first lines of Yap's main function. Wouldn't this solve all the problems? The PPL does not really care where GMP takes the memory from: if it comes from Yap's stacks that is fine. In other words, PPL just uses the GMP's entry point without making any further assumption. 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@cs.unipr.it
Vitor Santos Costa wrote:
The problem seems to be that Yap defines its own allocation functions for gmp objects:
#ifdef USE_GMP /* YAP style memory allocation */ mp_set_memory_functions( AllocBigNumSpace, ReAllocBigNumSpace, FreeBigNumSpace); #endif
This allows Yap to work with such objects in its own stacks. Unfortunately, these functions require for another function, PreAllocBigNum to have been called before. In general, using them is a bit dangerous, because they assume they have control over the global stack.
I suppose Yap is polluting the application space, so the correct solution would be for Yap to reset these functions before entering user code. But this would make the interface slower for any application that doesn't use GMP.
A compromise might be for me to provide two interface functions (YapResetGMPFunctions() and YapSet GMPFunctions()) and for you to call them before you started manipulating GMP objects.
Hi Vitor, I believe that calling mp_set_memory_functions repeatedly would mean that we must abandon all the guarantees provided by GMP's interface. In fact, the following paragraph is taken from GMP's manual: @strong{Be sure to call @code{mp_set_memory_functions} only when there are no active GMP objects allocated using the previous memory functions! Usually that means calling it before any other GMP function.} Ciao Roberto -- Prof. Roberto Bagnara Computer Science Group Department of Mathematics, University of Parma, Italy http://www.cs.unipr.it/~bagnara/ mailto:bagnara@cs.unipr.it
Hi Roberto,
I believe that calling mp_set_memory_functions repeatedly would mean that we must abandon all the guarantees provided by GMP's interface. In fact, the following paragraph is taken from GMP's manual:
@strong{Be sure to call @code{mp_set_memory_functions} only when there are no active GMP objects allocated using the previous memory functions! Usually that means calling it before any other GMP function.}
I have to think a bit about this. The functions are really not ok to be exported right now. On the other hand what you want to do is quite legitimate. It's a bit of the minefield, let me consider the best alternative. Cheers Vitor
Hi Vitor,
I believe that calling mp_set_memory_functions repeatedly would mean that we must abandon all the guarantees provided by GMP's interface. In fact, the following paragraph is taken from GMP's manual:
@strong{Be sure to call @code{mp_set_memory_functions} only when there are no active GMP objects allocated using the previous memory functions! Usually that means calling it before any other GMP function.}
Ciao
Roberto
Hi Roberto, I changed the Yap GMP allocation routines to fall back to malloc/realloc/free if outside context. I think that is the best solution for two reasons: - It is the most general: external processes might not want their objects to disappear during backtracking. - It avoids nasty interactions with the garbage collector: even I disallow gc of these objects, is application is not prepared for the gc barging in and shifting objects around? I haven't actually tested it outside Yap, do you mind trying it and telling me it works? Thanks Vitor
Vitor Santos Costa wrote:
I changed the Yap GMP allocation routines to fall back to malloc/realloc/free if outside context. I think that is the best solution for two reasons:
- It is the most general: external processes might not want their objects to disappear during backtracking. - It avoids nasty interactions with the garbage collector: even I disallow gc of these objects, is application is not prepared for the gc barging in and shifting objects around?
I haven't actually tested it outside Yap, do you mind trying it and telling me it works?
Hi Vitor, I can confirm I am no longer observing the problem we had with GLP. (I am observing other problems, but more debugging work is needed to properly identify them.) Thanks a lot Roberto -- Prof. Roberto Bagnara Computer Science Group Department of Mathematics, University of Parma, Italy http://www.cs.unipr.it/~bagnara/ mailto:bagnara@cs.unipr.it
Vitor Santos Costa wrote:
I changed the Yap GMP allocation routines to fall back to malloc/realloc/free if outside context. I think that is the best solution for two reasons:
- It is the most general: external processes might not want their objects to disappear during backtracking. - It avoids nasty interactions with the garbage collector: even I disallow gc of these objects, is application is not prepared for the gc barging in and shifting objects around?
I haven't actually tested it outside Yap, do you mind trying it and telling me it works?
Dear Vitor, with your change I have succeeded, after fixing a couple of bugs on my part, at producing a working YAP interface for the Parma Polyhedra Library. This will be part of the next PPL release. BTW, finding these bugs has been exceptionally difficult due to the fact that Term, Functor and Atom are all typedef'd to be CELL: this means you can do all sorts of mistakes without any help from the C compiler. Thanks again for you help. 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@cs.unipr.it
Hi Roberto,
with your change I have succeeded, after fixing a couple of bugs on my part, at producing a working YAP interface for the Parma Polyhedra Library. This will be part of the next PPL release.
Great.
BTW, finding these bugs has been exceptionally difficult due to the fact that Term, Functor and Atom are all typedef'd to be CELL: this means you can do all sorts of mistakes without any help from the C compiler.
Yes, actually it is possible to have them being different types.
Thanks again for you help.
Thanks for your work, great news! Cheers, Vitor
Dear Roberto,
with your change I have succeeded, after fixing a couple of bugs on my part, at producing a working YAP interface for the Parma Polyhedra Library. This will be part of the next PPL release. BTW, finding these bugs has been exceptionally difficult due to the fact that Term, Functor and Atom are all typedef'd to be CELL: this means you can do all sorts of mistakes without any help from the C compiler.
That is quite a reasonable complaint, they actually have different types in Yap itself. I fixed it. Cheers, Vitor
participants (2)
-
Roberto Bagnara -
Vitor Santos Costa