[gambit-list] Segfault on OSX using Gambit's C Interface

Adam adam.mlmb at gmail.com
Fri Dec 18 01:58:39 EST 2015


Ah ok.

But, was there a bug in the current code inlining behavior - in what Gambit
version was that bug introduced?


2015-12-17 8:11 GMT+08:00 Marc Feeley <feeley at iro.umontreal.ca>:

> It was added today in the latest commit.
>
> The problem with using ___result and ___result_voidstar is that the
> programmer needs to know when to use one or the other, and this is related
> to the implementation of the FFI.  Types such as int, double, char can use
> ___result directly, but “foreign data” such as structs, unions, opaque
> types, and pointers need to set ___result_voidstar.
>
> In the case of values that are structs, unions and opaque types, a block
> of memory must be allocated, then initialized to the value, and
> ___result_voidstar is set to point to this block of memory.  But how is the
> block of memory initialized with the value?  Using an assignment works fine
> for C, but is not ideal when using C++… it is better to use the copy
> constructor in case the assignment operator is overloaded.  This means that
> the allocation of the block of memory and its initialization needs to be
> combined in a single operation.  The ___return macro hides all of these
> details so that the same code base will work in C and C++.
>
> Marc
>
>
> > On Dec 16, 2015, at 6:27 PM, Adam <adam.mlmb at gmail.com> wrote:
> >
> > Neat!
> >
> > What was the problem with ___result ?
> >
> > And, in what commit did you introduce ___return ?
> >
> > 2015-12-17 7:00 GMT+08:00 Marc Feeley <feeley at iro.umontreal.ca>:
> > I have improved the FFI by introducing the ___return(val) macro which
> should be used from now on instead of ___result=val and
> ___result_voidstar=val.  So your *->My function can be coded like this:
> >
> > (define *->My (c-lambda (My*/nonnull) My "___return(*___arg1);"))
> >
> > This will hide the implementation of the FFI and the use of ___result
> and ___result_voidstar, which was confusing.
> >
> > Check the updated Gambit manual for details.
> >
> > Marc
> >
> > > On Dec 14, 2015, at 2:46 PM, Paolo Carlesi <pcarlesi at gmail.com> wrote:
> > >
> > > Thank you for the workaround!
> > >
> > > What is the best way to generate a foreign c-type object ?
> > >
> > > This seems to me the best approach (sorry if it's obvious to everybody
> but me):
> > >
> > > (define make-My (c-lambda () My "___result_voidstar =
> ___EXT(___alloc_rc)(sizeof(struct My));"))
> > > (define My->* (c-lambda (My) My*/nonnull "___result_voidstar =
> &___arg1;"))
> > >
> > > has the advantage of not wasting time / space creating a new foreign
> object and a copy, like *->My below does.
> > > It also doesn't trigger the c-lambda bug, not that I have verified
> carefully yet.
> > > Members can easily be set up with a syntax like (My-x-set! (My->*
> xoxo) #xdeadbeef) .
> > > Is this approach correct?
> > >
> > > Thanks Again
> > >
> > > Paolo
> > >
> > > Il giorno 14/dic/2015, alle ore 18:02, Marc Feeley <
> feeley at iro.umontreal.ca> ha scritto:
> > >
> > >> There appears to be a bug in the FFI when using a c-lambda with
> inline code that returns a foreign object.  So for now you will have to
> define a C function that does the work and use the name of that function in
> the c-lambda.  In other words:
> > >>
> > >> (c-declare #<<c-declare-end
> > >>
> > >> My indirect_My_star(My *ptr) { return *ptr; }
> > >>
> > >> c-declare-end
> > >> )
> > >>
> > >> (define *->My (c-lambda (My*/nonnull) My "indirect_My_star"))
> > >>
> > >> Marc
> > >>
> > >>
> > >>> On Dec 14, 2015, at 4:55 AM, Paolo Carlesi <pcarlesi at gmail.com>
> wrote:
> > >>>
> > >>> Hello,
> > >>>
> > >>> I'm experiencing regular segfaults on OSX 10.9.5, with the sample
> code shown below.
> > >>> Tested with Gambit 4.8.1 + GCC 4.9  and with packaged Gambit 4.7.3 +
> LLVM.
> > >>> No issue at all on Linux, GCC 4.8, with both Gambit 4.2.8 and Gambit
> 4.8.2.
> > >>> Of course I may be doing something silly.
> > >>>
> > >>> A simple struct, "My" is generated inside a c procedure, then passed
> multiple times to another c-lambda procedure (*->My).
> > >>> It's a simplified model of the code produced by a FFI SDL2 Library
> I'm using.
> > >>> The doc says that the foreign object (xoxo in the example) should
> not be released while the scheme code is still referencing it.
> > >>> I am seeing the refcount going wildly in the negative, one for each
> call to *->My
> > >>> The only way -- clumsy -- I have found to avoid this is to increment
> the reference count with ___addref_rc ( not shown here ).
> > >>>
> > >>> What's wrong here?
> > >>> Thanks!
> > >>>
> > >>>
> > >>> LLDB output:
> > >>>
> > >>> Process 48149 launched: '/Users/paolo/scheme/spazz/fromlin' (x86_64)
> > >>> Process 48149 stopped
> > >>> * thread #1: tid = 0x40e3c9, 0x000000010000770c
> fromlin`___release_rc + 28, queue = 'com.apple.main-thread', stop reason =
> EXC_BAD_ACCESS (code=EXC_I386_GPFLT)
> > >>>  frame #0: 0x000000010000770c fromlin`___release_rc + 28
> > >>> fromlin`___release_rc + 28:
> > >>> -> 0x10000770c:  movq   %rax, (%rdx)
> > >>> 0x10000770f:  movq   %rdx, 0x8(%rax)
> > >>> 0x100007713:  jmp    0x100010240               ; ___free_mem
> > >>> 0x100007718:  nopl   (%rax,%rax)
> > >>>
> > >>> stack trace:
> > >>>
> > >>> (lldb) bt
> > >>> * thread #1: tid = 0x40e3c9, 0x000000010000770c
> fromlin`___release_rc + 28, queue = 'com.apple.main-thread', stop reason =
> EXC_BAD_ACCESS (code=EXC_I386_GPFLT)
> > >>> * frame #0: 0x000000010000770c fromlin`___release_rc + 28
> > >>>  frame #1: 0x0000000100002579 fromlin`___release_fn0 + 9
> > >>>  frame #2: 0x0000000100009009 fromlin`___garbage_collect + 3497
> > >>>  frame #3: 0x00000001000091bf fromlin`___alloc_scmobj + 255
> > >>>  frame #4: 0x000000010000d4eb fromlin`___POINTER_to_SCMOBJ + 43
> > >>>  frame #5: 0x000000010000d5e4 fromlin`___STRUCT_to_SCMOBJ + 20
> > >>>  frame #6: 0x0000000100002112 fromlin`___H__20_fromlin + 3378
> > >>>  frame #7: 0x0000000100004aa4 fromlin`___call + 372
> > >>>  frame #8: 0x0000000100004bc6 fromlin`___setup_pstate + 262
> > >>>  frame #9: 0x00000001000063be fromlin`___setup + 3950
> > >>> (lldb)
> > >>>
> > >>>
> > >>> ;; SAMPLE CODE
> > >>>
> > >>> (c-declare #<<c-declare-end
> > >>>
> > >>> typedef struct My {
> > >>> int r;
> > >>> } My;
> > >>>
> > >>> c-declare-end
> > >>> )
> > >>>
> > >>> (begin
> > >>> (c-define-type My (struct "My"))
> > >>> (c-define-type My* (pointer My (My*)))
> > >>> (c-define-type My*/nonnull (nonnull-pointer My (My*)))
> > >>> (c-define-type My*/release-rc (nonnull-pointer My (My*)
> "___release_My")))
> > >>>
> > >>>
> > >>> (begin
> > >>>  (c-declare #<<c-declare-end
> > >>> static ___SCMOBJ ___release_My( void* ptr ) {
> > >>>  ___EXT(___release_rc)( ptr );
> > >>>  return ___FIX(___NO_ERR);
> > >>> }
> > >>> c-declare-end
> > >>>  )
> > >>>
> > >>>  (define alloc-My (c-lambda () My*/release-rc "___result_voidstar =
> ___EXT(___alloc_rc)( sizeof( struct My ));"))
> > >>>  (define *->My (c-lambda (My*/nonnull) My "___result_voidstar =
> (My*)___arg1;"))
> > >>>  (define My-r (c-lambda (My*/nonnull) unsigned-int8 "___result =
> ___arg1->r;"))
> > >>>  (define My-r-set! (c-lambda (My*/nonnull unsigned-int8) void
> "___arg1->r = ___arg2;")))
> > >>>
> > >>> (define (evil)
> > >>> (let ((xoxo (alloc-My)))
> > >>>    (My-r-set! xoxo #xff)
> > >>>    (let loop ((c 1))
> > >>>        (begin
> > >>>            (if (= 0 (remainder c 10000))
> > >>>                (begin (display c) (newline)))
> > >>>            (*->My xoxo)
> > >>>            (loop (+ 1 c))))))
> > >>>
> > >>> (evil)
> > >>>
> > >>> ;;END CODE
> > >>>
> > >>>
> > >>>
> > >>>
> > >>> _______________________________________________
> > >>> Gambit-list mailing list
> > >>> Gambit-list at iro.umontreal.ca
> > >>> https://webmail.iro.umontreal.ca/mailman/listinfo/gambit-list
> > >>
> > >
> >
> > _______________________________________________
> > Gambit-list mailing list
> > Gambit-list at iro.umontreal.ca
> > https://webmail.iro.umontreal.ca/mailman/listinfo/gambit-list
> >
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.iro.umontreal.ca/pipermail/gambit-list/attachments/20151218/7f2d473d/attachment.htm>


More information about the Gambit-list mailing list