SV: SV: SV: SV: SV: SV: SV: [elephant-devel] Memory error with Elephant

Ian Eslick eslick at csail.mit.edu
Tue Aug 22 18:36:19 UTC 2006


There are definitely some issues with string calculations.  I've had
some issues dealing
with allegro's unicode support.

Look in memutil.lisp:
The byte-length macro

Look in serializer.lisp:
(method serialize %serialize) the string case statements

Serialization of strings involves:
1) Serialize appropriate string tag based on Lisp character width for
string type
    In SBCL this is 1 byte or 4 bytes depending on Unicode support
2) Serialize the total string length (bytes * num chars).  The
byte-length macro
    is used for this
3) Serialize the array of characters using buffer-write-string

Hopefully that will help you figure out where the mismatch occurs.

Cheers,
Ian

Petter Egesund wrote:
> I am not sure, I have been looking for good documentation. I might exist
> somewhere, though? I am guessing int in FFI is closer connected to int
> as is defined by C and thereby the OS? Somebody can probably tell us...
>
> It seems also to be a problem computing the size of a buffer, as well,
> which causes problems for strings. I will take a closer look tomorrow,
> tonight I have to struggle with some deadlines...
>
> Petter
>
>
> -----Opprinnelig melding-----
> Fra: Ian Eslick [mailto:eslick at csail.mit.edu] 
> Sendt: 22. august 2006 15:43
> Til: Petter Egesund; eslick at media.mit.edu
> Kopi: Robert L. Read; Ian Eslick; elephant-devel at common-lisp.net
> Emne: RE: SV: SV: SV: SV: SV: SV: [elephant-devel] Memory error with
> Elephant
>
> I don't have internet at the moment, but what is the definition of int
> vs integer in the sb-alien foreign interface?  Just want to make sure we
> aren't asking for trouble in the future.  (i.e. is int signed or
> unsigned vs integer?  Is it 32bit for compatibility or whatever the clib
> it's linked to says it is?)
>
> Ian
>
> -----Original Message-----
> From: "Petter Egesund" <Petter.Egesund at kunnskapsforlaget.no>
> To: eslick at media.mit.edu
> Cc: "Robert L. Read" <read at robertlread.net>; "Ian Eslick"
> <ieslick at common-lisp.net>; elephant-devel at common-lisp.net
> Sent: 8/22/06 8:18 AM
> Subject: SV: SV: SV: SV: SV: SV: [elephant-devel] Memory error with
> Elephant
>
> Hi;
>
> I have done some debugging. It seems the problem of serializing integers
> is caused by mixing of the types int and integer in the foreign
> interface?
>
> I change the function read-int in the package memutil.lisp to:
>
> (defun pread-int (buf offset)
>   "Read a 32-bit signed integer from a foreign char buffer."
>   (declare (optimize speed (safety 1) (debug 1))
> 	   (type (alien (* char)) buf)
> 	   (type fixnum offset))
>   (print "Offset: ") (print offset)
>   (the (signed-byte 32)
>     (deref (cast (sap-alien (sap+ (alien-sap buf) offset) (* char))
> 		 (* int))))) ;; !!!!!!!!!!!!! Changed from (* integer)
>
>
> After this the integer-test runs fine. I will do some more testing.
>
> Cheers,
>
> Petter Egesund
>
>
>
>  
>
> -----Opprinnelig melding-----
> Fra: Ian Eslick [mailto:eslick at csail.mit.edu] 
> Sendt: 21. august 2006 16:11
> Til: Petter Egesund
> Kopi: Robert L. Read; eslick at media.mit.edu; Ian Eslick
> Emne: Re: SV: SV: SV: SV: SV: [elephant-devel] Memory error with
> Elephant
>
> Interesting.  That explains the source of our problem (serializing
> integers) but I still don't understand why.  Even if the 4 byte
> assumption in lisp keeps us from expanding the buffer streams
> appropriately the write should still write the first 8 bytes correctly
> and thus be able to read it correctly.  It almost looks like it is
> writing 4 bytes but reading 8.
>
> 1) Try replacing the #x45 with #x00 in my test code
>
> The other test is to see what is actually being put into the buffer
> stream.
>
> 2) replace #x45 with #x40302010 and add the following code instead of
> the buffer-read-int at the end:
>
> (loop for i from 0 upto 16 do
>     (format t "byte ~A: ~A~%" i (buffer-read-byte bs)))
>
> Ian
>
> Petter Egesund wrote:
>   
>>  
>>
>> ----------------------------------------------------------------------
>> --
>> *Fra:* Robert L. Read [mailto:read at robertlread.net]
>> *Sendt:* 19. august 2006 22:26
>> *Til:* Petter Egesund
>> *Kopi:* eslick at media.mit.edu; Ian Eslick
>> *Emne:* Re: SV: SV: SV: SV: [elephant-devel] Memory error with 
>> Elephant
>>
>> Personally, the fact that buffer-write-int in memutil.lisp assumes a 
>> 4-byte integer:
>> (defun buffer-write-int (i bs)
>>   "Write a 32-bit signed integer."
>>   (declare (optimize (speed 3) (safety 0))
>>    (type buffer-stream bs)
>>    (type (signed-byte 32) i))
>>   (with-struct-slots ((buf buffer-stream-buffer)
>>       (size buffer-stream-size)
>>       (len buffer-stream-length))
>>     bs      
>>     (let ((needed (+ size 4)))
>>       (when (> needed len)
>> (resize-buffer-stream bs needed))
>>       (write-int buf i size)
>>       (setf size needed)
>>       nil)))
>> While the c-code version of write-int in libmemutil.c uses the 
>> "sizeof(int)" paradigm seems fragile on a 64-bit architecture:
>>
>> void write_int(char *buf, int num, int offset) {
>>   memcpy(buf+offset, &num, sizeof(int)); }
>>
>> I would like to know if "sizeof(int)" is 8 or 4 as compiled.
>> A simple C program (or reading the f-ing manual) would answer that 
>> question.
>> An awful hack that would let us test things would be to hard-wire "4"
>> in place of
>> "sizeof(int)" in the libmemutil.c file;  I don't know enough about 
>> UFFI and sap-alien to know if that would work.
>>
>> A better solution is to expose a C-function that simply gives the size
>>     
>
>   
>> of an integer in bytes to LISP (it could be added to libmemutil.c 
>> file) and then have memutil.lisp use that in place of the assumption 
>> "4".)
>>
>> How this changes the typing in memutil.lisp, I'm not sure ---- can 
>> we/should we force the
>> AMD64 to use 32-bit integers, or should we rewrite memutil.lisp to 
>> determine based on its compilation environment the size of an integer?
>>     
>
>   
>> Either solution is better than what we have now.
>>
>>
>> On Sat, 2006-08-19 at 20:53 +0200, Petter Egesund wrote:
>>     
>>> It looks like below. Certainly not 35.
>>>
>>> Petter
>>>
>>> -------
>>>
>>> ELE> (defun fixnum-test ()
>>>      (with-buffer-streams (bs)
>>>        (buffer-write-int #x23 bs)
>>>        (buffer-write-int #x45 bs)
>>>        (reset-buffer-stream bs)
>>>        (buffer-read-int bs)))
>>> ; in: LAMBDA NIL
>>> ;     (ELEPHANT-MEMUTIL:BUFFER-WRITE-INT 69 ELEPHANT::BS)
>>> ; --> BLOCK ELEPHANT-MEMUTIL::WITH-STRUCT-SLOTS SYMBOL-MACROLET LET 
>>> WHEN ; --> COND IF PROGN ; ==>
>>> ;   (ELEPHANT-MEMUTIL:RESIZE-BUFFER-STREAM ELEPHANT-MEMUTIL::BS
>>> ;                                          ELEPHANT-MEMUTIL::NEEDED)
>>> ;
>>> ; note: doing signed word to integer coercion (cost 20)
>>>
>>> ;     (ELEPHANT-MEMUTIL:BUFFER-WRITE-INT 35 ELEPHANT::BS)
>>> ; --> BLOCK ELEPHANT-MEMUTIL::WITH-STRUCT-SLOTS SYMBOL-MACROLET LET 
>>> WHEN ; --> COND IF PROGN ; ==>
>>> ;   (ELEPHANT-MEMUTIL:RESIZE-BUFFER-STREAM ELEPHANT-MEMUTIL::BS
>>> ;                                          ELEPHANT-MEMUTIL::NEEDED)
>>> ;
>>> ; note: doing signed word to integer coercion (cost 20) ; ; 
>>> compilation unit finished
>>> ;   printed 2 notes
>>> FIXNUM-TEST
>>> ELE> (fixnum-test)
>>> 296352743459
>>> ELE> 
>>>
>>>
>>>
>>>
>>>  
>>>       
>
>   



More information about the elephant-devel mailing list