I think there are two bugs at play here - first, that CLX makes no attempt to avoid reusing IDs that are still in use once the count wraps around, and second that in this instance mcclim creates millions of gcontexts without freeing them.
I've hacked resourcealloc in CLX to check against the id cache, skipping IDs which are still in use, but this runs into the problem that not all types (in particular, graphics contexts) are stored in the cache. There's some comment about this not being useful and wasting space in depdefs.lisp next to defconstant +clx-cached-types+, and without considering the performance implications I've worked around it by setting the hash table entry to T at the point the ID is allocated, so that (I hope) every allocated resource is now there. To do this correctly also requirse that the deallocate-resource-id be changed to unconditionally invoke deallocate-resource-id-internal (thereby making the macro useless), which I've neglected to do. With that in mind, here's a version of resourcealloc with the changes described:
(defun resourcealloc (display) ;; Allocate a resource-id for in DISPLAY (declare (type display display)) (declare (clx-values resource-id))
(loop for next-count upfrom (1+ (display-resource-id-count display)) repeat (1+ (display-resource-id-mask display)) as id = (dpb next-count (display-resource-id-byte display) (display-resource-id-base display)) do (when (nth-value 1 (gethash id (display-resource-id-map display))) #+NIL (format *trace-output* "~&Skipping ~X (~A)~%" id (gethash id (display-resource-id-map display)))) (when (zerop (random 10000)) (format *trace-output* "~&~X~%" id)) (unless (nth-value 1 (gethash id (display-resource-id-map display))) (setf (display-resource-id-count display) next-count) #+NIL (format *trace-output* "~&Allocating ~X (~A IDs in use)~%" id (hash-table-count (display-resource-id-map display))) (setf (gethash id (display-resource-id-map display)) t) (when (= id #x2A00027) (break "Hi there.")) (return-from resourcealloc id))) (assert (= (hash-table-count (display-resource-id-map display)) (1+ (display-resource-id-mask display)))) (error "Available X resource IDs have been exhausted."))
Fixing this allocation issue doesn't solve the underlying problem that this test causes mcclim to exhaust the available space of resource-ids by never freeing these gcontexts.