Hail, brothers and sisters in Scheme.
I've been working with Gambit's FFI recently, trying to create bindings for libxml2. Currently I'm trying to use libxml2 to parse a file, and produce structures representing the XML nodes. Reading Gambit's lib/os.c for some examples of how to produce such things (I started with service-info and worked down from there) I developed some code that pretty much works. But there are problems with memory corruption that result in "odd" looking results (for example, a list that should have some 95,000 items is instead two large fixnums consed together) or segfaults. Finally I teased out an XML file that fails pretty reliably, at least on my desktop.
First, the code is on Bitbucket --- https://bitbucket.org/taylor_venable/gambit-xml/. The default Makefile target will build xml.o1 - you will probably have to invoke it as "make GSC=gsc" (the Makefile uses "GSC=gambitc" by default, which is the name used by the Gambit compiler on Arch Linux since the "gsc" program is from Ghostscript).
Second, the test XML file is on my website --- http://metasyntax.net/test.xml.gz --- warning about clicking that in your browser, it's 141 MB uncompressed.
Here's how I'm using things:
$ make gcc -c -o os_xml.o -I/usr/include/libxml2 -g -O0 -Wall -Wno-unused -fPIC os_xml.c gambitc -debug -link -flat -o xml.o1.c xml.scm *** WARNING -- "##direct-structure-ref" is not defined, *** referenced in: ("/home/taylor/Repos/gambit-xml/xml.c") *** WARNING -- "##direct-structure-set!" is not defined, *** referenced in: ("/home/taylor/Repos/gambit-xml/xml.c") *** WARNING -- "##structure" is not defined, *** referenced in: ("/home/taylor/Repos/gambit-xml/xml.c") *** WARNING -- "##structure-instance-of?" is not defined, *** referenced in: ("/home/taylor/Repos/gambit-xml/xml.c") *** WARNING -- "##structure-type-set!" is not defined, *** referenced in: ("/home/taylor/Repos/gambit-xml/xml.c") *** WARNING -- "##subtype-set!" is not defined, *** referenced in: ("/home/taylor/Repos/gambit-xml/xml.c") *** WARNING -- "error" is not defined, *** referenced in: ("/home/taylor/Repos/gambit-xml/xml.c") *** WARNING -- "fx=" is not defined, *** referenced in: ("/home/taylor/Repos/gambit-xml/xml.c") *** WARNING -- "map" is not defined, *** referenced in: ("/home/taylor/Repos/gambit-xml/xml.c") *** WARNING -- "vector-ref" is not defined, *** referenced in: ("/home/taylor/Repos/gambit-xml/xml.c") gcc -c -o xml.o -I/usr/include/libxml2 -D___DYNAMIC -g -O0 -Wall -Wno-unused -fPIC xml.c gcc -c -o xml.o1.o -I/usr/include/libxml2 -D___DYNAMIC -g -O0 -Wall -Wno-unused -fPIC xml.o1.c gcc -shared -o xml.o1 -lxml2 os_xml.o xml.o xml.o1.o $ gsi Gambit v4.6.3
(load "xml")
"/home/taylor/Repos/gambit-xml/xml.o1"
(define xml (read-xml "./test.xml")) (length (xml-element-children (xml-document-root xml)))
Segmentation fault
Sometimes I can do this:
$ gsi Gambit v4.6.3
(load "xml")
"/home/taylor/Repos/gambit-xml/xml.o1"
(define xml (read-xml "./test.xml")) (length (xml-element-children (xml-document-root xml)))
*** ERROR IN (console)@4.9 -- (Argument 1) Instance of #<type #2 xml-element> expected (xml-element-children '#<gc-hash-table #3>) 1>
xml
#<xml-document #4 location: "./test.xml" root: #<gc-hash-table #3>>
Or this:
$ gsi Gambit v4.6.3
(load "xml")
"/home/taylor/Repos/gambit-xml/xml.o1"
(define xml (read-xml "/home/taylor/sis-conv-input.xml")) (length (xml-element-children (xml-document-root xml)))
*** ERROR IN (console)@3.1 -- (Argument 1) LIST expected (length '(23220778 . 22958618)) 1> xml #<xml-document #2 location: "/home/taylor/sis-conv-input.xml" root: #<xml-element #3 name: "enterprise" attrs: () children: (23220778 . 22958618)>>
It varies. Sometimes I get the error because children is a something like '(23220778 . 22958618), then when I print out the xml value, the root is printed as #<gc-hash-table #3>. So it looks to me like a memory corruption problem, but I don't know why. When I use gdb to look for a cause:
$ gdb gsi GNU gdb (GDB) 7.4 Copyright (C) 2012 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later http://gnu.org/licenses/gpl.html This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "x86_64-unknown-linux-gnu". For bug reporting instructions, please see: http://www.gnu.org/software/gdb/bugs/... Reading symbols from /usr/bin/gsi...(no debugging symbols found)...done. (gdb) run Starting program: /usr/bin/gsi Gambit v4.6.3
(load "xml")
"/home/taylor/Repos/gambit-xml/xml.o1"
(define xml (read-xml "./test.xml")) (length (xml-element-children (xml-document-root xml)))
Program received signal SIGSEGV, Segmentation fault. 0x00007ffff702b064 in ___H_xml_2d_element_2d_children (___ps=0xa4ce20) at xml.c:6232 6232 ___IF(___STRUCTUREDIOP(___R1,___R2)) (gdb) bt #0 0x00007ffff702b064 in ___H_xml_2d_element_2d_children (___ps=0xa4ce20) at xml.c:6232 #1 0x00000000004ad51f in ___call () #2 0x00000000004af14f in ___setup () #3 0x00000000004c3ef2 in ___main () #4 0x00000000004b8436 in ___main_char () #5 0x00000000004ac6a9 in main () (gdb) print ___ps->r $1 = {10259873, 11115697, 140737339703681, 11115697, 140737339703681}
The problem manifests in code generated by Gambit, but I doubt that's where the problem originates. I don't know enough about the Gambit internals to make it any further on my own. I hope somebody can help guide me in debugging what's wrong, and hopefully point out whether my memory handling in the os_xml.c file is correct or not. There are a few places where I have doubts about whether I should use ___release_scmobj() or not.
All of these problems happen fairly regularly on my desktop, which is an Intel Core i7-870 with 8GB of memory running Arch Linux x86_64 kernel 3.2.4 --- but I haven't yet had them on my laptop, which is an Intel Core 2 Duo P8800 with 4GB of memory running the same kernel.
Mighty thanks for any assistance!