[gambit-list] Xlib

Marc Feeley feeley at iro.umontreal.ca
Fri Jan 14 21:30:57 EST 2011


On 2011-01-14, at 4:37 PM, David Bridgham wrote:

> On 01/14/2011 02:53 PM, Marc Feeley wrote:
> 
>>> However, while trying this from a different machine this morning I came
>>> across a rather strange effect.  If I'm running it to a remote X
>>> display, it doesn't crash. Only crashes if the bounce program is running
>>> on the same machine as my display
>>> 
>> Could it be that your Xlib is returning a pointer to a statically allocated Screen structure?  It is hard to tell from the Xlib documentation what is guaranteed to be a freshly allocated structure and what can be statically allocated.  Do you know?
>> 
> 
> Turns out it was not because of running it on a remote machine vs local,
> but whether I was running it from screen 0 or screen 1.  One of the two
> machines I've been using is dual-headed.
> 
> An array of screen structures is allocated and stashed away in the
> display structure.  If I run it on Screen 1, the screen pointer points
> into the middle of the allocated memory block and XFree crashes.  If I
> run it from screen 0, the screen pointer points to the beginning of the
> allocated memory and XFree "works", though I suspect it leaves a stale
> pointer in the display structure. 
> 
> I think it's safe to not free the screen structure explicitly as it will
> be free'd later when XCloseDisplay is called which calls
> _XFreeDisplayStructure.  At least that's what I see in the Xlib sources
> I have.
> 
> -Dave

That's a great analysis!  It means that XScreenOfDisplay does not return a pointer to a fresh Screen.  It is a pointer to a shared structure, whose deallocation is the responsibility of Xlib.  In other words, Xlib.scm should not say:

(define XScreenOfDisplay
  (c-lambda (Display*      ;; display
             int)          ;; screen_number
            Screen*/XFree
            "XScreenOfDisplay"))

it should say:

(define XScreenOfDisplay
  (c-lambda (Display*      ;; display
             int)          ;; screen_number
            Screen*
            "XScreenOfDisplay"))

That way the pointer to the Screen returned by XScreenOfDisplay will not be managed by the Gambit garbage collector (when the Scheme world drops the pointer to the Screen, it must not be passed to XFree).

Marc




More information about the Gambit-list mailing list