SIGSEGV in embedded NewLISP on 64bit Ubuntu

Machine-specific discussion
Unix, Linux, OS X, OS/2, Windows, ..?
Locked
pwhelan
Posts: 2
Joined: Fri Nov 13, 2009 9:15 pm

SIGSEGV in embedded NewLISP on 64bit Ubuntu

Post by pwhelan »

Hello there.

I am getting a SIGSEGV in the writeStreamStr() function on Ubuntu 64 (jaunty).

The stacktrace is as follows:

Code: Select all

(gdb) bt
#0  0x00007f3be166bfdd in writeStreamStr (stream=0xffffffffe1892e20, 
    buff=0x1abdb60 "(lambda ", length=8) at nl-string.c:828
#1  0x00007f3be1651ddf in varPrintf (device=18446744073198448160, 
    format=<value optimized out>) at newlisp.c:2263
#2  0x00007f3be165229e in printExpression (cell=0x1a8a100, 
    device=18446744073198448160) at newlisp.c:2464
#3  0x00007f3be165264b in printCell (cell=0x1a8a100, printFlag=1, 
    device=18446744073198448160) at newlisp.c:2358
#4  0x00007f3be165c218 in evaluateStream (stream=0x7fff07ab96b0, 
    outDevice=18446744073198448160, flag=0) at newlisp.c:1107
#5  0x00007f3be165c99a in executeCommandLine (
    command=0x400959 "(load \"helloworld.lsp\")", outDevice=28040032, 
    cmdStream=0x0) at newlisp.c:1051
#6  0x00007f3be1683927 in newlispEvalStr (
    cmd=0x400959 "(load \"helloworld.lsp\")") at unix-lib.c:97
#7  0x00000000004007f6 in main (argc=1, argv=0x7fff07ab9958)
    at interpreter.c:24
The crash ocurrs because the stream variable pointer is invalid:

Code: Select all

(gdb) fr 0
#0  0x00007f3be166bfdd in writeStreamStr (stream=0xffffffffe1892e20, 
    buff=0x1abdb60 "(lambda ", length=8) at nl-string.c:828
828	newPosition = stream->position + length;
(gdb) p/x stream
$4 = 0xffffffffe1892e20
(gdb) p/x *stream
Cannot access memory at address 0xffffffffe1892e20
I tracked down the problem to this little snippet:

Code: Select all

switch(device)
        {
        case OUT_NULL:
                return;
        case OUT_DEVICE:
                if(printDevice != 0)
                        {
                        if(write(printDevice, buffer, strlen(buffer)) < 0)
                                fatalError(ERR_IO_ERROR, 0, 0);
                        break;
                        }
        case OUT_CONSOLE:
#ifdef LIBRARY
                writeStreamStr(&libStrStream, buffer, 0);
                return;
#else
                if(IOchannel == stdin)
                        {
                        printf("%s", buffer);
                        if(!isTTY) fflush(NULL);
                        }
                else
                        {
                        if(IOchannel != NULL)
                                {
                                fprintf(IOchannel, "%s", buffer);
                                }
                        }
                break;
#endif
        case OUT_LOG:
                writeLog(buffer, 0);
                break;
        default:
                writeStreamStr((STREAM *)device, buffer, 0);
                break;
        }
I could see that the device parameter gets truncated from a 64 bit unsigned integer to a 32bit signed integer. Digging further I saw that this occurs in executeCommandline, due to it's device argument being defined as a simple 'int'.

Another problem that occurs on 64bit linux is a relocation error during linking. The solution to this is to create all objects with the '-fPIC' flag. I've also added this to the Makefile for the Linux 64bit library. To get both the interpreter and the embedable library in a single directory you will have to execute 'make clean' between them.

Here is a patch which should get the newlisp embedable library to work on 64 bit ubuntu linux (jaunty), with glibc and GCC.

Code: Select all

--- newlisp-10.1.7/makefile_linuxLP64_lib       2009-11-24 06:38:53.000000000 -0800
+++ newlisp-10.1.7-embed64/makefile_linuxLP64_lib       2009-12-06 17:33:06.000000000 -0800
@@ -6,12 +6,12 @@
 OBJS = newlisp.o nl-symbol.o nl-math.o nl-list.o nl-liststr.o nl-string.o nl-filesys.o \
        nl-sock.o nl-import.o nl-xml.o nl-web.o nl-matrix.o nl-debug.o pcre.o unix-lib.o
 
-CFLAGS = -m64 -Wall -pedantic -Wno-uninitialized -Wno-strict-aliasing -Wno-long-long -c -O2 -g -DLINUX -DNEWLISP64
+CFLAGS = -fPIC -m64 -Wall -pedantic -Wno-uninitialized -Wno-strict-aliasing -Wno-long-long -c -O2 -ggdb -DLINUX -D
 
 CC = gcc
 
 default: $(OBJS)
-       $(CC) $(OBJS) -m64 -g -lm -ldl -shared -o newlisp.so
+       $(CC) $(OBJS) -fPIC -m64 -ggdb -lm -ldl -shared -o newlisp.so
        strip newlisp.so
  
 .c.o:
diff -ur newlisp-10.1.7/newlisp.c newlisp-10.1.7-embed64/newlisp.c
--- newlisp-10.1.7/newlisp.c    2009-11-24 06:38:53.000000000 -0800
+++ newlisp-10.1.7-embed64/newlisp.c    2009-12-06 17:41:17.000000000 -0800
@@ -978,7 +978,7 @@
 
 char * processCommandEvent(char * command);
 
-void executeCommandLine(char * command, int outDevice, STREAM * cmdStream)
+void executeCommandLine(char * command, UINT outDevice, STREAM * cmdStream)
 {
 STREAM stream;
 char buff[MAX_LINE];
diff -ur newlisp-10.1.7/protos.h newlisp-10.1.7-embed64/protos.h
--- newlisp-10.1.7/protos.h     2009-11-24 06:38:53.000000000 -0800
+++ newlisp-10.1.7-embed64/protos.h     2009-12-06 17:41:37.000000000 -0800
@@ -564,7 +564,7 @@
 void deleteList(CELL * cell);
 void deleteTagStack(void);
 void encryptPad(char * encrypted, char * data, char * key, size_t dataLen, size_t keyLen);
-void executeCommandLine(char * command, int outDevice, STREAM * cmdStream);
+void executeCommandLine(char * command, UINT outDevice, STREAM * cmdStream);
 void expandSymbol(CELL * cell, SYMBOL * sPtr);
 void errorMissingPar(STREAM * stream);
 void fatalError(int errorNumber, CELL * expr, int deleteFlag);
Last edited by pwhelan on Mon Dec 07, 2009 2:02 am, edited 1 time in total.

TedWalther
Posts: 608
Joined: Mon Feb 05, 2007 1:04 am
Location: Abbotsford, BC
Contact:

Re: SIGSEGV in embedded NewLISP on 64bit Ubuntu

Post by TedWalther »

Thanks Phillip. Who would have thought a simple int/UINT mixup would have such effects?

Ted
Cavemen in bearskins invaded the ivory towers of Artificial Intelligence. Nine months later, they left with a baby named newLISP. The women of the ivory towers wept and wailed. "Abomination!" they cried.

m35
Posts: 171
Joined: Wed Feb 14, 2007 12:54 pm
Location: Carifornia

Re: SIGSEGV in embedded NewLISP on 64bit Ubuntu

Post by m35 »

TedWalther wrote:Thanks Phillip. Who would have thought a simple int/UINT mixup would have such effects?
Certainly not Google ;)

Lutz
Posts: 5289
Joined: Thu Sep 26, 2002 4:45 pm
Location: Pasadena, California
Contact:

Re: SIGSEGV in embedded NewLISP on 64bit Ubuntu

Post by Lutz »

Thanks for catching this. The changes are merged here:

http://www.newlisp.org/downloads/develo ... .9-dev.tgz

Locked