[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Chicken-users] #<invalid forwarded object> using FFI callback
From: |
.alyn.post. |
Subject: |
[Chicken-users] #<invalid forwarded object> using FFI callback |
Date: |
Sun, 8 Dec 2013 10:19:29 -0700 |
Greetings,
I'm encountering the following error message inside a callback using
Chicken's FFI interface:
Error: (cdr) bad argument type: #<invalid forwarded object>
Call history:
pwent.scm:100: loop
pwent.scm:56: ##sys#gc
pwent.scm:56: g42
pwent.scm:24: make-string
pwent.scm:24: make-string
pwent.scm:24: make-string
pwent.scm:24: make-string
pwent.scm:50: clist-append!
pwent.scm:100: loop
pwent.scm:56: ##sys#gc
pwent.scm:56: g42
pwent.scm:24: make-string
pwent.scm:24: make-string
pwent.scm:24: make-string
pwent.scm:24: make-string
pwent.scm:50: clist-append! <--
What seems to be happening is that I'm running out of (stack?) memory
while inside/around a C thunk. I cannot seem to avoid this message by
modifying the nursery, either from csc -nursery or from -:s.
I have only a topical grasp of Chicken's FFI, so I suspect I'm simply
doing something ill-advised, though I would appreciate advice on how
to approach my problem:
I'm trying to read /etc/passwd using getpwent(3) and store each
record returned in a scheme list. (My particular /etc/passwd file
contains <100 elements, the above error happens near the end of the
call.) I'm marshalling records using two callbacks: one to create the
memory for string data, and one to append each record to the list.
May I have feedback on the pattern I'm using here to marshall data?
And a suggestion on how to avoid invalid forward objects while
reading large but disjoint data from C? I'm at a loss as to why
exactly I'm getting the above message, and it well could be incorrect
code on my part. Do my multiple calls to _make_string from C,
below, cause the GC to loose track of my string pointers? Something
else?
<++> csc -o pwent pwent.scm && ./pwent
(use extras)
; a circular list (where we track the
; head and tail) with a dummy head.
;
(define (make-clist)
(let ((head (list #f)))
(cons head head)))
; O(1) list append.
;
(define (clist-append! d v)
(let ((l (list v)))
(set-cdr! (cdr d) l)
(set-cdr! d l)))
; return proper list
;
(define (clist->list d)
(cdr (car d)))
; allocate a scheme string available in C.
;
(define-external
(_make_string (size_t n)) scheme-object
(make-string n))
(declare (foreign-declare #<<EOF
#include <sys/types.h>
#include <string.h>
#include <pwd.h>
EOF
))
(define (getpwent)
; append! each pwent record to our record list.
;
(define-external
(_getpwent_cb (scheme-object clist)
(scheme-object user)
(scheme-object passwd)
(scheme-object uid)
(scheme-object gid)
(scheme-object home)
(scheme-object shell)) void
(let ((pwent `((user . ,user)
(passwd . ,passwd)
(uid . ,uid)
(gid . ,gid)
(home . ,home)
(shell . ,shell))))
(clist-append! clist pwent)))
; retrieve the next pwent record and marshall it
; in to scheme.
;
(define _getpwent
(foreign-safe-lambda* bool ((scheme-object clist)) #<<EOF
struct passwd *pw;
C_word shell, dir, passwd, name;
size_t n;
pw = getpwent();
if(!pw) {
endpwent();
C_return(0);
}
n = strlen(pw->pw_name);
name = _make_string(n);
C_memcpy(C_c_string(name), pw->pw_name, n);
n = strlen(pw->pw_passwd);
passwd = _make_string(n);
C_memcpy(C_c_string(passwd), pw->pw_passwd, n);
n = strlen(pw->pw_dir);
dir = _make_string(n);
C_memcpy(C_c_string(dir), pw->pw_dir, n);
n = strlen(pw->pw_shell);
shell = _make_string(n);
C_memcpy(C_c_string(shell), pw->pw_shell, n);
_getpwent_cb(clist,
name,
passwd,
C_fix(pw->pw_uid),
C_fix(pw->pw_gid),
dir,
shell);
C_return(1);
EOF
))
; loop ever every entry in pwent and append
; it to our list.
;
(let loop ((clist (make-clist)))
(if (_getpwent clist)
(loop clist)
(clist->list clist))))
(pretty-print (getpwent))
<-->
Thank you,
-a
$ csc -version
(c) 2008-2013, The Chicken Team
(c) 2000-2007, Felix L. Winkelmann
Version 4.8.0.5 (stability/4.8.0) (rev 5bd53ac)
openbsd-unix-gnu-x86 [ manyargs dload ptables ]
compiled 2013-10-03 on aeryn.xorinia.dim (Darwin)
--
my personal website: http://c0redump.org/
- [Chicken-users] #<invalid forwarded object> using FFI callback,
.alyn.post. <=