segmentation fault using import on OSX

Started by pkoppstein, August 02, 2013, 10:47:20 AM

Previous topic - Next topic

pkoppstein

$ newlisp

newLISP v.10.5.3 64-bit on OSX IPv4/6 UTF-8, options: newlisp -h



> (import "libc.dylib" "printf")

printf@7FFF92EAD222

> (printf "%s %d" "hola" 123)    

hola 1238

> (printf "%s %d %cn" "hello" 999 65)

hello 999 A

12

> (printf "%g" 1.2)

4.35711e-31412

> (printf "%g %s %d %cn" 1.23 "hello" 999 65)

Segmentation fault: 11

$



# I couldn't find a better "Forum" in which to file this bug report.  Sorry.

Lutz

#1
from the manual entry for import "The simple import syntax":


QuoteTo use floating point numbers in a 64-bit environment use the extended import syntax.


like this:


newLISP v.10.5.3 64-bit on OSX IPv4/6 UTF-8 libffi, options: newlisp -h

>  (import "libc.dylib" "printf" "long" "char*" "double" "char*" "int" "char")
printf@7FFF865F0650
> (printf "%g %s %d %cn" 1.23 "hello" 999 65)
1.23 hello 999 A
17
>


the return value 17 is the number of characters printed.



Even better: use format for formatted printing.

rickyboy

#2
Quote from: "Lutz"Even better: use format for formatted printing.

Yup.  That's what it's there for: http://www.newlisp.org/downloads/newlisp_manual.html#format">http://www.newlisp.org/downloads/newlis ... tml#format">http://www.newlisp.org/downloads/newlisp_manual.html#format.
(λx. x x) (λx. x x)

pkoppstein

#3
Thank you for your responses, but please note:



1) using the "extended syntax" also does not work in the Mac environment I am using (see below);

2) even the fixed-signature "atof" does not work properly, as is illustrated below as well.



Anyway, since "printf" is "polymorphic", it would seem there is no possibility of importing it in all its generality. If that's the case, then it seems to me the documentation should mention this limitation rather than giving "printf" as an example.



# The documentation says that the return type should be specified first, so these examples do so,

# but I have also tried other variations.



$ newlisp

newLISP v.10.5.3 64-bit on OSX IPv4/6 UTF-8, options: newlisp -h



> (import "libc.dylib" "printf" "int" "double")

printf@7FFF92EAD222

> (printf "%gn" 1.23)

4.30659e-314

13

>



$ newlisp

newLISP v.10.5.3 64-bit on OSX IPv4/6 UTF-8, options: newlisp -h



> (import "libc.dylib" "printf" "int" "double" "char*" "int" "char")

printf@7FFF92EAD222

> (printf "%g %s %d %cn" 1.23 "hello" 999 65)

Segmentation fault: 11

$



$ newlisp

newLISP v.10.5.3 64-bit on OSX IPv4/6 UTF-8, options: newlisp -h



> (import "libc.dylib" "atof" "double" "char*")

atof@7FFF92E72C8C

> (atof "1.23")

3

>

Lutz

#4
You are not doing the import for printf as shown in my last post. The return value must be long, not int which is only 32 bit on 64-bit OSX. You also forgot the "char*" spec for the first argument of printf, which is the format string:


>  (import "libc.dylib" "printf" "long" "char*" "double" "char*" "int" "char")
printf@7FFF865F0650
> (printf "%g %s %d %cn" 1.23 "hello" 999 65)
1.23 hello 999 A
17
>


You are doing the import for atof correecty and it works well on my system:


> (import "libc.dylib" "atof" "double" "char*")
atof@7FFF865CB3F8
> (atof "1.234")
1.234
> (atof "1.23")
1.23
> (atof "-56.7890")
-56.789
>


I wonder what kind of binary/compile you are using? Mine is from the binary dsitribution on http://www.newlisp.org/">http://www.newlisp.org/ and I am using OSX 10.8.4 - Mointain Lion. I also checked on 10.6.8 (Snow Leopard) where its also runs fine.



Perhaps the following table can help you to pick the right types:

LP64 memory model on OSX and other UNIX
type      bytes
---------------
char        1
char *      8
void *      8
short int   2
int         4
long        8
long int    8
long long   8
float       4
double      8
long double 16
wchar_t     4


As a general rule: the import functions should only be used by newLISP users well familiar with C programming and memory models and type sizes. In the newlisp-x.x.x/util directory you can fiund a C program types.c. Compile it and run it, to see the default memory model of your platform. Or force 32bit or 64bit compile to see either model scheme.

rickyboy

#5
It works for me on my Mac, as Lutz outlined.


church:~ $ newlisp
newLISP v.10.5.3 64-bit on OSX IPv4/6 UTF-8 libffi, options: newlisp -h

> (import "libc.dylib" "printf" "int" "char*" "double" "char*" "int" "char")
printf@7FFF82BD3F3A
> (printf "%g %s %d %cn" 1.23 "hello" 999 65)
1.23 hello 999 A
17
>

I used "int" for the return type — instead of "long" which Lutz used —because that's what the printf prototype in /usr/include/stdio.h said.  (I may be looking at the wrong header file, but the basic idea is to find the header that corresponds to the library you're importing from and use that as a guide.)



BTW, I'm on OS X 10.6.8.
(λx. x x) (λx. x x)

Lutz

#6
you are right, the headerfile is what should be the guidance, or do a:


man 3 printf

at the prompt to get the printf(...) man page. On my OSX system too, both int and long work, but int would be the correct type to choose.



pkoppstein's problem then seems to be just the forgotten first char* parameter.

pkoppstein

#7
Some good news: after I switched from the "homebrew" version of newlisp to the "official" (newlisp.org) version, the unexplained problems went away.  Notice in particular the difference in banners:



homebrew: newLISP v.10.5.3 64-bit on OSX IPv4/6 UTF-8, options: newlisp -h

official: newLISP v.10.5.3 64-bit on OSX IPv4/6 UTF-8 libffi, options: newlisp -h



That is, the homebrew version is missing "libffi".



Interestingly, the "official" version is not so fussy about the difference between "long" and "int", e.g.



 $ /usr/bin/newlisp

newLISP v.10.5.3 64-bit on OSX IPv4/6 UTF-8 libffi, options: newlisp -h



> (import "libc.dylib" "printf" "int" "char*" "double" "char*" "int" "char")

printf@7FFF92EAD222

> (printf "%g %s %d %cn" 1.23 "hello" 999 65)

1.23 hello 999 A

17

>



In light of all these complications, it seems to me that the newlisp documentation about the C-interface could be improved by pointing out its limitations with respect to printf and portability. Perhaps the following statement in the documentation should also be clarified:



"Programs written with extended import API will run without change on 32-bit and 64-bit newLISP and libraries."



Thanks for your patience.

Lutz

#8
Thanks for figuring it out. I didn't realize the missing "libffi" in the newLISP banner of your post.



How strange, that the Homebrew people compile without libffi support. That library comes installed by default on OS X (and Windows). I added some clarification to the documentation.