[racket] MrEd-Designer crash with null ptr-ref

From: Kieron Hardy (kieron.hardy at gmail.com)
Date: Mon Jun 18 02:24:07 EDT 2012

Hi all,

On Windows Vista (64-bit on quad-core CPU), MrEd-Designer randomly crashes
when working on a large and somewhat complex UI. At the command prompt I
get a trace, and the last one included:

ptr-ref: contract violation
  expected: (and/c cpointer? (not/c (lambda (p) (pointer-equal? p #f))))
  given: #f
  argument position: 1st
  other arguments:
   #<ctype:scheme>
  context:
   ...\collects\mred\private\wx\win32\wndclass.rkt:43:0: set-hwnd-wx!
   ...\collects\racket\private\class-internal.rkt:3960:0:
continue-make-object
   ...\collects\mred\private\wx\win32\panel.rkt:16:2
   ...\collects\racket\private\class-internal.rkt:3960:0:
continue-make-object
   ...\collects\mred\private\wx\win32\panel.rkt:98:2
   ...\collects\racket\private\class-internal.rkt:3960:0:
continue-make-object
   ...\collects\mred\private\wxwindow.rkt:14:6
   ...\collects\racket\private\class-internal.rkt:3960:0:
continue-make-object
   ...\collects\mred\private\wxitem.rkt:34:6
   ...\collects\racket\private\class-internal.rkt:3960:0:
continue-make-object
   ...\collects\mred\private\wxpanel.rkt:69:4
   ...\collects\racket\private\class-internal.rkt:3960:0:
continue-make-object
   ...\collects\racket\private\class-internal.rkt:3960:0:
continue-make-object
   ...\collects\racket\private\class-internal.rkt:3960:0:
continue-make-object
   ...\collects\racket\private\class-internal.rkt:3960:0:
continue-make-object
   ...\collects\racket\private\class-internal.rkt:3960:0:
continue-make-object...

Where wndclass.rkt contains:

(define (set-hwnd-wx! hwnd wx)
  (let* ([c (GetWindowLongPtrW hwnd GWLP_USERDATA)]
         [v (ptr-ref c _racket)])
    (vector-set! v 0 (make-weak-box wx))))

and two functions that invoke SetWindowLongPtrW GWLP_USERDATA:

;; call in atomic mode:
(define (register-hwnd! hwnd)
  (hash-set! all-hwnds (cast hwnd _pointer _intptr) #t)
  (let ([c (malloc-immobile-cell (vector #f #f #f))])
    (void (SetWindowLongPtrW hwnd GWLP_USERDATA c))))

and:

;; call in atomic mode:
(define (unregister-hwnd! hwnd)
  (let ([c (GetWindowLongPtrW hwnd GWLP_USERDATA)])
    (when c
      (free-immobile-cell c)
      (SetWindowLongPtrW hwnd GWLP_USERDATA #f))
    (hash-remove! all-hwnds (cast hwnd _pointer _intptr))))

Since the crashes occur at random it seems likely that there is some sort
of race condition (perhaps caused by the register and/or unregister
functions not being called in 'atomic' mode), but my unfamiliarity with the
internals of both MrEd-Designer and the GUI components of Racket leave me
at a bit of a loss at how to proceed debugging this problem. Any hints or
tips would be very welcome.

Cheers,

Kieron.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.racket-lang.org/users/archive/attachments/20120618/dd770cbf/attachment.html>

Posted on the users mailing list.