[Openmcl-devel] Debugging Cocoa (was: programmatic file chooser? thanks!)

Gary Byers gb at clozure.com
Tue Sep 2 18:19:20 PDT 2008

On Thu, 28 Aug 2008, Rainer Joswig wrote:

> Am 28.08.2008 um 21:34 schrieb Alexander Repenning:
>> Thanks Gary for the detailed response. I have just spent some time
>> to write some basic GUI code based on Cocoa in LispWorks and Clozure
>> CL. I could go on about the philosophical differences between LW and
>> CCL wrt Cocoa but that is perhaps left best for some other time. At
>> the end of the day both approaches work.
>> CCL gets high scores for having defined interfaces, based on reading
>> the header files I presume. LW includes no such information. As
>> developer I have to define my own function/method/constant
>> definitions for Cocoa and other APIs in LW. Not very practical for
>> large APIs.
>> The main problem, we found with CCL and Cocoa, especially vis-a-vis
>> LW, is debugging. Specifically, CCL makes it hard to debug Cocoa
>> call backs. Example: Say I have a window (NSWindow containing
>> NSView) with a buggy event handler.
>> (defmethod VIEW-LEFT-MOUSE-DOWN-EVENT-HANDLER ((Self event-test-
>> Window) X Y)
>>   (format t "click: x=~A, y=~A~%"  x y)
>>   (setf (x self) x)
>>   (setf (y self) y)
>>   (/ x 0) ;; division-by-zero!!!
>>   (print *Current-process*)
>>   (view-draw-contents Self))

I couldn't reproduce this (e.g., I got a DIVISION-BY-ZERO error
and a backtrace on standard output.)

In what lisp version does this happen ?

>> 1) output to OS X console does not work as interactive debugging
>> tool. There is too much lag. The print/format statements, if you
>> start CCL 1.2 by double clicking the OS X app will produce output in
>> the OS X console with great lag time.
> Probably not related to this, but I'll mention it anyway, since I have
> seen this in other debugging contexts:
> Sometimes the output streams are buffered (and the display gets
> updated sometime later) and one needs to
> call FINISH-OUTPUT or FORCE-OUTPUT after printing something to see any
> debug information immediately.
> Please ignore above if it does not apply here...

I think that what actually happens is something like:

- the main event thread gets an error in its event loop and writes
a bunch of stuff to file descriptor 1 (or 2), which is open on
a pipe (or something similar; I don't remember.)

- a background thread reads the other side of that connection and
packages up the incoming data, then "posts a notification" to the
event thread (the data is an attribute of the notification object.)

- the event thread is supposed to receive that notification (the next
time its in its event loop), extract the data from the notification
object and insert it in the console window.  This part would work a
lot better if the event thread wasn't too busy pumping out data to
listen for notifications of incoming data (e.g., the same thread is
trying to produce and consume the data at the same time.)

It's tempting to say that the right solution here is to simply cut out
the middle man (to write directly to the console window or a
listener-like window that "belongs to" the event thread.)  I'm sure
that that'd be better, but you basically want the event thread to be
responsive to events (and time spent generating large amounts of
output is time not spent being responsive to events.)  Generating a
large text backtrace from the event thread is never likely to
be blindingly fast (or at least there's always going to be some
latency between the time that output is generated and the time
that redisplay occurs and the output is visible.)  Fortunately,
dumping a large amount of text output to a console window or
listener isn't really an ideal response to debugging an error
in the event thread

Of course, as Alex's message suggested, a more nearly ideal response
to an error in the event thread is to have access to a break loop,
backtrace dialog, etc. in the (dynamic) context in which the error
occurred.  That dynamic context is typically in an event handler
(or a #/drawRect: method, or something similar), and supporting
event-driven interaction (typing into that listener, mousing
around in the backtrace dialog) in that context basically involves
running a recursive event loop.  There are some subtle issues there
and some work obviously needs to be done to address them.

> ...
> Rainer Joswig, Hamburg, Germany
> http://lispm.dyndns.org/
> mailto:joswig at lisp.de
> _______________________________________________
> Openmcl-devel mailing list
> Openmcl-devel at clozure.com
> http://clozure.com/mailman/listinfo/openmcl-devel

More information about the Openmcl-devel mailing list