SIGSEGV in embedded NewLISP on 64bit Ubuntu

Started by pwhelan, December 06, 2009, 05:49:46 PM

Previous topic - Next topic

pwhelan

Hello there.



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



The stacktrace is as follows:

(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:

(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:



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.



--- 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);

TedWalther

#1
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

#2
Quote from: "TedWalther"Thanks Phillip.  Who would have thought a simple int/UINT mixup would have such effects?

Certainly http://it.slashdot.org/comments.pl?sid=1448990&cid=30147842">not Google ;)

Lutz

#3
Thanks for catching this. The changes are merged here:



http://www.newlisp.org/downloads/development/latest/newlisp-10.1.9-dev.tgz">http://www.newlisp.org/downloads/develo ... .9-dev.tgz">http://www.newlisp.org/downloads/development/latest/newlisp-10.1.9-dev.tgz