[Openmcl-devel] Another linux86-32: signed doubleword parameters.

Gary Byers gb at clozure.com
Wed Oct 15 18:17:42 PDT 2008

On Wed, 15 Oct 2008, David Brown wrote:

> On Wed, Oct 15, 2008 at 01:08:20AM -0600, Gary Byers wrote:
>>> The only thing I haven't done is try running this code on another
>>> 32-bit system.  I'll need to build sbcl on the 32-bit machine to see
>>> if I can figure out what this might show.
>> If the bug was in your code, that might show something.
> Ok. I've gotten SBCL 32-bit installed, and the tests run without any
> evidence of problems.  I can think of two possibilities:
>  - The problem is somewhere inside of ccl, whether the kernel or
>    somewhere in a library somewhere.
>  - SBCL on 32-bit uses a conservative garbage collector, so it isn't
>    going to be moving things around, so I could have a bug that
>    doesn't show up.
> But, given that ccl 32-bit is the only platform I see the problem on,
> It's my suspicion.  It's just getting to be difficult to reproduce
> consistently enough.
> One question, if I do end up getting a breakpoint on a bogus object,
> how can I inspect or evaluate the things in the stack frames (or even
> refer to them)?

In the regular repl (not sure about SLIME),

? (defun make-things-bad ()
   (ccl:gc) ; make memory allocation more predictable
   (let* ((a (make-string 3 :initial-element #\a))
          (b (make-array 3 :element-type 'double-float)))
     (declare (optimize (speed 3) (safety 0)))
     (setf (aref b 3) pi) ; clobber A
? (length (make-things-bad))
> Error: value #<BOGUS object @ #x14A2AB6E> is not of the expected type SEQUENCE.
> While executing: SEQUENCE-TYPE, in process listener(1).
> Type :POP to abort, :R for a list of available restarts.
> Type :? for other options.
1 > :f 0
  (555D88) : 0 (SEQUENCE-TYPE #<BOGUS object @ #x14A2AB6E>) 95
    X: #<BOGUS object @ #x14A2AB6E>

;;; Return (and set CL:* to) the value of the argument named X in frame #0.
;;; There's also a :local break loop command with similar syntax.
1 > :arg 'x 0
#<BOGUS object @ #x14A2AB6E>

;;; Enter the kernel debugger, with that value in %ebx:
1 > (ccl::dbg *)
Lisp Breakpoint
? for help
[3816] OpenMCL kernel debugger: r
%eax = 0x0000003a
%ecx = 0x1405583e
%edx = 0x00000004
%ebx = 0x14a2ab6e               ; <<<<
%esp = 0x00555af0
%ebp = 0x00555af4
%esi = 0x14a2ab6e
%edi = 0x140557c6
%eip = 0x140557e0
%eflags = 0x00010202
[3816] OpenMCL kernel debugger:

If you attach gdb to the process (pid 3816 in this case),

(gdb) x/x 0x14a2ab68  ; strip off the low 3 tag bits from 0x14a2ab6e
0x14a2ab68:	0x54442d18  ;; low word of PI
0x14a2ab6c:	0x400921fb  ;; I assume that this is the high word
0x14a2ab70:	0x00000061  ;; #\a
0x14a2ab74:	0x00000061  ;; #\a

So (no surprise) we clobbered the header word and the first (0th ...) 
element of the string.

If things are hosed worse than they are in this example, backtrace
may choke trying to print things.  If you see something printing
as a #<BOGUS object @ some-hex-addres>, you can skip the middle-man
(:arg, ccl::dbg) and so on)

A thread allocates memory by grabbing a "chunk" (currently 64K on
32-bit CCLs, though it could be a little bigger sometimes) from the
runtime and allocating things from the high end (greater address) of
the chunk towards the low end, so in my example B was allocated after
A, and storing past the end of B clobbered A.

When the GC runs, it compacts live objects (regardless of what thread
allocated them) towards 0.  Things that were allocated in the same
chunk (in the same thread) at around the same time will usually wind
up near each other, but things near each other might have been allocated
in different threads.

> David

More information about the Openmcl-devel mailing list