[gambit-list] Obscurities with FFI and possible bug

Christian christian at pflanze.mine.nu
Thu Nov 30 11:03:00 EST 2006


Hello

I am sometimes getting segfaults with this code:

(c-declare "
typedef int MPI_Comm;
static MPI_Comm globalcomm=123;
")

(c-define-type MPI_Comm "MPI_Comm")

(define get-comm
  (c-lambda ()
	    MPI_Comm
	    "___result_voidstar=&globalcomm;"))


See below for a sequence of commands with which I can consistently get
a segfault. Strangely, a test function looping over about the same
sequence doesn't trigger it.

Am I doing things right? I don't want to just (c-define-type MPI_Comm
int), because that would breach encapsulation (I only found out that
MPI_Comm (I'm binding PETSc) was an int by looking at the gcc -E
output!).

Do I understand right that I am supposed to give a pointer to the
data? e.g. "___result_voidstar=&globalcomm;", not
"___result_voidstar=globalcomm;"? That should probably be made clear
in the documentation. I've also tried (c-define-type MPI_Comm (type
"MPI_Comm")) at first.

But probably I'm better of just doing this?:
(c-define-type MPI_Comm (pointer "MPI_Comm"))

Also: are
(c-define-type MPI_Comm "MPI_Comm")
and
(c-define-type MPI_Comm (type "MPI_Comm"))
really equivalent?

I'm confused:

- from reading the documentation, I thought that (type "MPI_Comm")
will create a copy of the "MPI_Comm" object (how?, by applying memcpy
to sizeof(MPI_Comm)?) and deallocate that again transparently upon
destruction of the foreign object.

- when seeing the ___release_rc calls under gdb (where the segfault
happens), I thought that this is the release function. But looking at
mem.c that rather looks like some management function for the scheme
heap?

- but seeing those
    #<foreign #2 0xB7FD630C>
    #<foreign #3 0xB7FD630C>
  I notice that they always carry the same address, so that would
contradict the expectation of a new malloc'ed copy every time.

BTW note that I'm still running the gambit beta 17.

Thanks
Christian.


The test loop which does *not* segfault:

; (define (test n)
;   (let lp ((i 0)
; 	   (c #f))
;     (if (< i n)
; 	(lp (+ i 1)
; 	    (get-comm)))))

; (time (test 1000000))
;     496 ms real time
;     488 ms cpu time (488 user, 0 system)
;     28 collections accounting for 324 ms real time (316 user, 0 system)
;     36000000 bytes allocated
;     no minor faults
;     no major faults
;??


An example of a segfault (using chjmodule):
(note: those 1's and 3's are just there to flush the old values from
my repl value cache patched into gambit)

> (use bug-MPI_Comm)
loading "~/schemedevelopment/gambit/Loader/gambit-interpreter-env-bindings.o1" into namespace ""...done.
import from "" to "gambit-interpreter-env#": 777 newly copied, 0 previously done.
loading "~/schemedevelopment/gambit/Loader/gambit-interpreter-env.o1" into namespace "gambit-interpreter-env#"...done.
import from "gambit-interpreter-env#" to "cj-env#": 785 newly copied, 0 previously done.
import from "gambit-interpreter-env#" to "oleg-env#": 785 newly copied, 0 previously done.
loading "~/schemedevelopment/gambit/mod/oleg-env.o1" into namespace "oleg-env#"...done.
import from "oleg-env#" to "cj-env#": 3 newly copied, 0 previously done.
loading "~/schemedevelopment/gambit/mod/cj-env.o13" into namespace "cj-env#"...done.
import from "cj-env#" to "": 45 newly copied, 0 previously done.
loading "./bug-MPI_Comm.o2" into namespace ""...done.
import from "" to "": 0 newly copied, 0 previously done.
> (get-comm)
#<foreign #2 0xB7FD630C>
> 1
1
> 1
1
> 1
1
> 1
1
> (##gc)
> (##gc)
> (##gc)
> (##gc)
> (get-comm)
#<foreign #3 0xB7FD630C>
> 3
3
> 3
3
> 3
3
> 3
3
> (##gc)
> (##gc)
> (##gc)
> (get-comm)
#<foreign #4 0xB7FD630C>
> (get-comm)
#<foreign #5 0xB7FD630C>
> 3
3
> 3
3
> 3
3
> 3
3
> (##gc)
> (##gc)
> (##gc)
> (##gc)
> (##gc)
> (get-comm)
#<foreign #6 0xB7FD630C>
> (get-comm)
#<foreign #7 0xB7FD630C>
> (get-comm)
#<foreign #8 0xB7FD630C>
> 3
3
> 3
3
> 3
3
> 3
3
> (##gc)

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread -1214533504 (LWP 22116)]
___release_rc (ptr=0x0) at mem.c:630
630	          next->prev = prev;

and a backtrace from another one:

> (##gc)

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread -1214578560 (LWP 23687)]
___release_rc (ptr=0x0) at mem.c:630
630	          next->prev = prev;
(gdb) bt
#0  ___release_rc (ptr=0x0) at mem.c:630
#1  0xb7fca829 in ___release_fn0 ()
   from /home/chris/schemedevelopment/gambit/work/./bug-MPI_Comm.o2
#2  0xb7fcb30c in _ () from /home/chris/schemedevelopment/gambit/work/./bug-MPI_Comm.o2
#3  0xb7ed5e91 in ___lbl_tbl () from /usr/local/Gambit-C/lib/libgambc.so
#4  0xb7fbc0e0 in __JCR_LIST__ () from /usr/local/Gambit-C/lib/libgambc.so
#5  0xb7d3cb1b in ___release_foreign (obj=59) at c_intf.c:1173
#6  0xb7d3a6e5 in free_unmarked_still_objs () at mem.c:2332
#7  0xb7d3b667 in ___garbage_collect (nonmovable_words_needed=0) at mem.c:3652
#8  0xb7d5434a in ___H__20___kernel (___ps=0xb7fc0320) at _kernel.c:7542
#9  0xb7d3830d in ___call (nargs=0, proc=-1209180911, stack_marker=136566237) at setup.c:1784
#10 0xb7d3927e in ___setup (setup_params=0x0) at setup.c:2909
#11 0xb7d369c8 in ___main (linker=0) at main.c:557
#12 0xb7d414a9 in ___main_char (argc=6, argv=0x0, linker=0, script_line=0x0) at os_base.c:240
#13 0x0816207f in main ()





More information about the Gambit-list mailing list