[Openmcl-devel] PDFKit crashes
Ron Garret
ron at awun.net
Wed May 27 23:06:08 PDT 2009
Thanks! It actually turns out that it's the pdf-view that needed to
be initialized.
It turns out that I've been forgetting to #/init things all over the
place but things still mostly work for me. Am I just getting lucky?
Should #/init always be called when #/alloc is called? If not, how do
you know when you need to call #/init? (Feel free to treat those as
rhetorical questions. I'm sure there's a Cocoa memory management
primer somewhere that I can go read.)
Just for the record, SCE is supposed to be P1. The document I was
using to test with originally was called sce.pdf (because it was a
scanned electricity bill from Southern California Edison). I intended
to rename it to be more generic to avoid confusion and ended up
creating more confusion. Sorry about that.
Also for the record, I think calling #/description for printing is
fine despite the potential fragility. The extra functionality is very
useful, and the right way IMO to make it less fragile is with a
wrapper layer that handles all the initialization and memory management.
rg
On May 27, 2009, at 8:13 PM, Gary Byers wrote:
> T
>
> On Wed, 27 May 2009, Ron Garret wrote:
>
>>
>> On May 27, 2009, at 4:19 PM, Ron Garret wrote:
>>
>>> Trying to open and display a PDF file crashes CCL in various ways.
>>>
>>> Using this code:
>>>
>>> (in-package "CL-USER")
>>>
>>> (require :cocoa)
>>> (objc:load-framework "Quartz" :quartz)
>>> (defun nsstr (s) (make-instance 'gui::ns-lisp-string :string s))
>>>
>>> (defun pdf-from-file (filename)
>>> (#/initWithData: (#/alloc ns:pdf-document)
>>> (#/dataWithContentsOfFile: ns:ns-data filename)))
>>>
>>> (defun pdf-from-url (url)
>>> (#/initWithUrl: (#/alloc ns:pdf-document)
>>> (#/URLWithString: ns:ns-url url)))
>>>
>>
>> So it turns out that this problem is due to misspelling initWithURL
>> as
>> initWithUrl. Still, it would be good if the result of this were
>> not a
>> hard crash.
>
> An ObjC message named #/description is applicable to all NSObjects; it
> returns an NSString which ... um, describes the object:
>
> ? (#/description (#/init (#/alloc ns:ns-object)))
> #<NS-MUTABLE-STRING "<NSObject: 0x12994200>" (#x12943380)>
>
> There isn't too much to say about a direct instance of NS:NS-OBJECT,
> but
> for instances of other classes there's often quite a bit of
> information
> in the #/description string. The default PRINT-OBJECT method for
> NS:NS-OBJECTs
> invokes #/description, obtains a lisp string from the ns-string, and
> uses
> the resulting string (all of it ...) in its output. (As I was typing
> this, I saw a message suggesting that this output observe *PRINT-
> LENGTH*;
> that isn't relevant to the printing of strings, but truncating the
> string to some reasonable length would probably be reasonable.)
>
> In most cases, the existing #/description methods are remarkably
> robust,
> but in at least some cases - most of which seem to involve objects
> that
> have been allocated but not yet initialized - they leap before looking
> and try to print uninitialized slots in the object:
>
> ? (#/description (#/alloc ns::pdf-document))
> Unhandled exception 10 at 0x1451647a, context->regs at #xb029b970
> Exception occurred while executing foreign code
> at .objc_category_name_NSColor_PDFColorUtilities + 99450
>
>
>
> which looks kind of familiar. So yes, you should have gotten a
> runtime
> when trying to call a misspelled ObjC method name (which was warned
> about)
> and in fact you did. The system started to enter a break loop (the
> good
> news: on the event thread in the context in which the error
> occurred; the
> bad news: using AltConsole, until something better comes along) but
> crashed
> trying to print the (uninitialized) NS:NS-PDF-DOCUMENT object by
> printing
> the string returned by its #/description method. (Look at the
> backtrace.)
>
> I don't know how to tell in general whether or not it's safe to call a
> #/description method on an arbitrary NSObject (it certainly seems to
> be in the vast majority of cases, but it may be hard to recover from
> the cases where it isn't.) Until this point, I'd been fairly
> impressed at how robust #/description methods are, but that enthusiasm
> is certainly tempered by cases like this. At the very least, in cases
> where the output is unsolicited (error messages), it'd likely be wiser
> to not call #/description when printing an NSObject unless we're more
> sure than we can be in general that that won't sail off into the
> ozone.
>
>
>>
>> Still puzzling over the second problem.
>
> Both your earlier email message and the bug report seem to contain
> references to something named "sce", which doesn't seem to be defined
> anywhere.
>
> In the code that I can see, you seem to be calling #/setDocument: on
> an NS:PDF-VIEW that's been allocated but not initialized.
>
> Doing
>
> ? (allocate-instance 'some-standard-clos-class)
>
> returns (in the general case) an instance of the specified class where
> all of the instance's slots are unbound; that's likely not to be as
> useful an object as the result of MAKE-INSTANCE would have been.
>
> Similarly, the NSObject returned by a call to #/alloc on its class
> isn't yet initialized and is unlikely to behave itself; you generally
> don't want to do anything with the result of a call to #/alloc but
> immediately call some flavor of #/init... on it.) ObjC's #/alloc
> and #/init are similar to ALLOCATE-INSTANCE and INITIALIZE-INSTANCE,
> but differ in some subtle ways (an #/init method may deallocate its
> argument and return some other instance.) It's often saner to
> avoid this gunk and simply use MAKE-INSTANCE:
>
> (make-instance some-objc-class)
>
> is equivalent to
>
> (#/init (#/alloc some-objc-class)) ; all NSObjects respond to #/init
>
> and
>
> (make-instance some-objc-class :with-x x :and-y y)
>
> is equivalent to
>
> (#/initWithX:andY: (#/alloc some-objc-class) x y)
>
> but may be less error-prone.
>
>>
>> rg
>>
>> _______________________________________________
>> Openmcl-devel mailing list
>> Openmcl-devel at clozure.com
>> http://clozure.com/mailman/listinfo/openmcl-devel
>>
>>
More information about the Openmcl-devel
mailing list