[Openmcl-devel] Missing header(s) for OpenGL FFI?

Gary Byers gb at clozure.com
Sat Aug 12 12:00:46 PDT 2006


Someone somewhere once said that "simple binary search" is never simple.
Or something like that.

The way that the bridge usually tries to determine whether or not a
random pointer is or is not an instance of some ObjC class is to
ask #_malloc for information about the memory region where the pointer
is allocated; if #_malloc knows about the pointer, then the bridge
looks to see if the first word in the pointer references an ObjC class.
(The #_malloc check is basically there to ensure that the pointer
points to mapped memory and that we won't segfault when trying to
look at its first word.)  The check's obviously a little slow, but
information about the results of the check are cached in bits in
the pointer object, so it's only done at most once per (EQ) unique
pointer.

Unfortunately, that isn't adequate to recognize all instances of
NSConstantString and related (CF) classes, which are often just
embedded in the data segments of libraries.  The bridge tries to keep
track of the memory regions associated with all known shared
libraries, and does a binary search through that list of regions to
see if a given pointer is contained within any of them.  (If so, it's
safe to indirect through the pointer and look at its first word, and
that first word -might- reference a class like NSConstantString, in
which case the pointer will be recognized as an instance of that class.)

(At one point a couple of years ago, the binary search was a linear
search and was naturally even slower.  There are a finite number
of NSConstantString instances in all loaded libraries at any given
time, and I think that it'd be possible to enumerate them by looking
at relocation information and make it much easier to recognize these
instances.)

Anyway, the short version is that there's a bug in that binary search
code that makes it impossible to determine the class of some pointers-to-
possible-ObjC-objects.  Presumably, the recursive error failure has something
to do with trying to print an object whose class can't be determined without
signalling an error.

It may be the case that there appears to be nothing different between
the environment where the error occurs and the environment where it
doesn't besides the set of interfaces in use, but I'd guess that (for
some reason) either a slightly different set of shared libraries is
loaded or (for some reason) they're mapped at slightly different addresses,
and one or the other of these differences is enough to trigger the fencepost
in the binary search routine (CCL::POINTER-IN-CFSTRING-SECTION-P).

I thought that I'd fixed the real (fencepost) problem at some point (and
I'm pretty sure that I remember that it was a fencepost problem in
that binary search routine, which is of course so simple that it's
impossible to get right ...), but if I remember that correctly it
doesn't look like I checked the fix in.

The runtime doesn't expect CLASS-OF to fail; that's a generally
reasonable assumption, but the fact that it is failing seems to
be what's causing the error death-spiral.


On Sat, 12 Aug 2006, Phil wrote:

> Below is the backtrace but please keep in mind, this and the previous error I 
> reported *only* occur with the new interfaces.  When I switch back to the 
> older interfaces, the exact same code compiles without error.  Re: redefining 
> something that the runtime needs... all of my code is in CL-USER (the only 
> exception being a modification to ccl::sletify to add rect-to-nsrect) and I 
> have not received any messages indicating that I'm redefining anything.  If 
> this information isn't helpful, let me know and I will work on isolating the 
> code which results in the error so that you can attempt to reproduce on your 
> end.
>
>> Error in process listener(1): Error reporting error
>> While executing: CCL::FUNCALL-WITH-ERROR-REENTRY-DETECTION
>> Type :GO to continue, :POP to abort.
>> If continued: Skip loading init file.
> Type :? for other options.
> 1 > (:b t)
> (F0134130) : 0 (FUNCALL-WITH-ERROR-REENTRY-DETECTION #<COMPILED- 
> LEXICAL-CLOSURE #x294146>) 112
>  0 CCL::THUNK: #<COMPILED-LEXICAL-CLOSURE #x294146> ("required")
>  1 : #<Recursive printing error  #x2941EE> ("saved SAVE0")
>  2 CCL::*ERROR-REENTRY-COUNT*: 1 (:SAVED-SPECIAL)
>
> (F0134150) : 2 (FUNCALL #'#<Anonymous Function #x810655E> [...]) 208
>  0 CCL::XP:  (:INHERITED)
>  1 CCL::FN: #<Compiled-function CCL::POINTER-IN-CFSTRING-SECTION-P 
> (Non-Global)  #x83BAFBE> (:INHERITED)
>  2 CCL::PC-OR-INDEX: #<A Mac Pointer #x28> (:INHERITED)
>  3 CCL::FN-REG: 16 (:INHERITED)
>  4 CCL::THE-TRAP: 2092832776 (:INHERITED)
>  5 CCL::FRAME-PTR: #<CCL::FAKE-STACK-FRAME #x29417E> ("optional")
>  6 #:G27089: #<COMPILED-LEXICAL-CLOSURE #x294146>
>
>> Error in process listener(1): Array index 54 out of bounds for 
> #<SIMPLE-VECTOR 54> .
>> While executing: CCL::POINTER-IN-CFSTRING-SECTION-P
>> Type :POP to abort.
> Type :? for other options.
> 2 >
>
>
> On Aug 12, 2006, at 1:09 PM, Gary Byers wrote:
>
>> The error message basically means that the last few attempts to signal
>> an error themselves resulted in errors.  There are a number of things
>> that can cause this (e.g.,  redefining some class/method/function that's
>> basic part of the lisp runtime); if there's enough of the error system
>> there for it to notice that it's not making progress, that -usually-
>> implies that thing aren't hosed at a deeper level.  Without seeing a
>> backtrace (if things are un-hosed enough to make that possible), I
>> can't really guess what the original error would have been or why
>> attempts to signal it generate further errors.
>> 
>> I would be surprised if any of this had anything to do with incompatibities
>> between the lisp and a set of interfaces.  The format of the information
>> in the .cdb files hasn't changed since before 1.0; the lisp runtime
>> depend on a fairly small subset of the stuff in the standard C library
>> (file I/O, exception context information, some math library functions, not
>> much else) and most of that stuff is pretty stable between OS releases
>> (since thousands of other programs depend on the same things.)  If there
>> -were- changes in those interfaces, they'd be more likely to cause
>> problems when the lisp itself was being compiled than at runtime.
>> 
>> I might be mistaken about some or all of this, but I think that the
>> first thing that needs to be done is to try to either see a backtrace
>> from the point where you get the "error reporting error" or, if that's
>> not possible, to see what I'd need to do to reproduce the problem.
>> 
>> 
>> On Sat, 12 Aug 2006, Phil wrote:
>> 
>>> Gary,
>>> 
>>> I attempted to switch back to the new interfaces and now have a new 
>>> problem compiling a new method (Error in process listener(1): Error 
>>> reporting error. While executing: CCL::FUNCALL-WITH-ERROR- 
>>> REENTRY-DETECTION) so I'm thinking that the problem might be a version 
>>> mismatch between the image (1.0) I'm using and interfaces downloaded.  If 
>>> this seems the likely source of my problems, which versions of the test 
>>> images and interfaces should I be downloading for PPC-32 for Tiger?
>>> 
>>> Thanks,
>>> Phil
>>> 
>>> On Jul 23, 2006, at 4:03 AM, Gary Byers wrote:
>>> 
>>>> I'll try to take a look at it; I'm skeptical that anything's actually
>>>> defined differently and there may be some other bug at play here.
>>>> On Sat, 22 Jul 2006, Phil wrote:
>>>>> Apologies for muddying the water with the NSString... I was mainly
>>>>> asking about NSAttributedString which does appear to be an issue
>>>>> since the Tiger Interfaces:
>>>>> ; New interfaces (060620 Darwin interfaces)
>>>>> (CCL::SLET ((TEST-SIZE
>>>>>   (CCL::SEND (CCL::MAKE-OBJC-INSTANCE
>>>>>                            'NS-ATTRIBUTED-STRING
>>>>>                            :INIT-WITH-STRING
>>>>>                            "testing")
>>>>>                           'SIZE))))
>>>>> NonSTRET SEND in (CCL::SEND (CCL::MAKE-OBJC-INSTANCE
>>>>> 'NS-ATTRIBUTED-STRING
>>>>> :INIT-WITH-STRING
>>>>> "testing")
>>>>> 'SIZE)
>>>>> [Condition of type SIMPLE-ERROR]
>>>>> (CCL::OBJC-MESSAGE-INFO-FLAGS
>>>>>   (CCL::GET-OBJC-MESSAGE-INFO
>>>>>     (CCL::PARSE-MESSAGE
>>>>>       (CDDR '(CCL::SEND (CCL::MAKE-OBJC-INSTANCE
>>>>>                                                'NS-ATTRIBUTED-STRING
>>>>>                                                :INIT-WITH-STRING
>>>>>                                                "testing")
>>>>>                                              'SIZE)))))
>>>>> (:AMBIGUOUS T)
>>>>> ; Old interfaces (Tiger Cocoa interfaces)
>>>>> (CCL::SLET ((TEST-SIZE
>>>>>   (CCL::SEND (CCL::MAKE-OBJC-INSTANCE
>>>>>                             'NS-ATTRIBUTED-STRING
>>>>>                             :INIT-WITH-STRING
>>>>>                             "testing")
>>>>>                            'SIZE))))
>>>>> NIL
>>>>> (CCL::OBJC-MESSAGE-INFO-FLAGS
>>>>>   (CCL::GET-OBJC-MESSAGE-INFO
>>>>>     (CCL::PARSE-MESSAGE
>>>>>       (CDDR '(CCL::SEND (CCL::MAKE-OBJC-INSTANCE
>>>>>                                               'NS-ATTRIBUTED-STRING
>>>>>                                               :INIT-WITH-STRING
>>>>>                                               "testing")
>>>>>                                              'SIZE)))))
>>>>> (:RETURNS-STRUCTURE T)
>>>>> On Jul 16, 2006, at 8:49 PM, Gary Byers wrote:
>>>>>> AFAIK, NString has never had or inherited a "size" method.
>>>>>> NSAttributedString defines such a method, as do a few other classes.
>>>>>> All of the size methods that're defined in the standard Cocoa headers
>>>>>> have the same type signature; this means that - with only those
>>>>>> headers
>>>>>> in effect - a SEND of a "size" message to any object will use that
>>>>>> common type signature (and arrange to "return" an NSSize.)  This
>>>>>> has to do with what SEND macroexpands into; sending a message to
>>>>>> an object that doesn't implement it generally results in a runtime
>>>>>> error.
>>>>>> ? (ccl::lookup-objc-message-info "size") #S(OBJC-MESSAGE-INFO ...)
>>>>>> with 3 methods (NSImage, INImageRep,
>>>>>> NSAttributedString).  If you look at the methods, you'll see that
>>>>>> they each return an NSSize.
>>>>>> If you introduce additional interfaces, it's possible that a new
>>>>>> "size" method with a different type signature will be declared in
>>>>>> those interfaces.  (This doesn't happen too often; when it does
>>>>>> happen, it tends to involve message with generic names like "size".)
>>>>>> When it happens, a warning is printed (since we'd been assuming that
>>>>>> "size" was unambiguous but now have information to the contrary.)
>>>>>> Note that this (the introduction of a method with a different type
>>>>>> signature) can only happen if the class on which that method is
>>>>>> defined is disjoint from all other classes which define the method.
>>>>>> If it doesn't have any additional information about the type of
>>>>>> the "receiver" object, SEND has to treat the message send as a
>>>>>> sort of TYPECASE.  If the class NSToaster defines "size" to
>>>>>> return an :int and NSAttributedString, NSImage, and NSImage all
>>>>>> define it to return an :<NSS>ize, then SEND may have to arrange
>>>>>> to test at runtime to determine which of these classes the instance
>>>>>> is a receiver of.  An NSString might fail all of these tests; even
>>>>>> if it didn't, the message send should generate a runtime "message not
>>>>>> understood" NSException.
>>>>>> I don't believe that there's any substantial difference in content
>>>>>> between what I packaged as the "Tiger Cocoa interfaces" and the
>>>>>> cocoa stuff in the "060620 Darwin interfaces", and I don't believe
>>>>>> that NSString has ever defined a "size" method (unless a string has
>>>>>> some attributes - like font and point size - it'd be a little hard
>>>>>> to tell how big it'd be when drawn ...)
>>>>>> On Sun, 16 Jul 2006, Phil wrote:
>>>>>>> Thanks for clarifying that point.  I dropped in the new interfaces
>>>>>>> (replacing the previous tiger interface update) and it resulted in
>>>>>>> one bit of breakage: sending an NSString or NSAttributedString a
>>>>>>> size message no longer works (nonSTRET SEND).  I did a little
>>>>>>> digging and found that in the previous interfaces this bit of code:
>>>>>>> (CCL::OBJC-MESSAGE-INFO-FLAGS
>>>>>>>  (CCL::GET-OBJC-MESSAGE-INFO
>>>>>>>    (CCL::PARSE-MESSAGE
>>>>>>>      (CDDR '(CCL::SEND (CCL::MAKE-OBJC-INSTANCE
>>>>>>>                                               'NS-STRING
>>>>>>>                                               :INIT-WITH-STRING
>>>>>>>                                               "testing")
>>>>>>>                                             'SIZE)))))
>>>>>>> which previously resulted in:
>>>>>>> (:returns-structure t)
>>>>>>> now returns:
>>>>>>> (:ambiguous t)
>>>>>>> On Jul 14, 2006, at 4:08 PM, Gary Byers wrote:
>>>>>>>> Sorry if I wasn't clear; the "060620" interfaces are all Tiger-based
>>>>>>>> (except for the CHUD stuff, which has been enough of a moving target
>>>>>>>> that I wanted to pick an arbitrary release and stick with it as long
>>>>>>>> as possible.)
>>>>>>>> On Fri, 14 Jul 2006, Phil wrote:
>>>>>>>>> Gary,
>>>>>>>>> Any chance of getting an updated version of the Tiger interfaces
>>>>>>>>> or it safe to mix and match? (i.e. should I just drop the darwin
>>>>>>>>> GL interfaces from darwin on top of the tiger version)
>>>>>>>>> Thanks,
>>>>>>>>> Phil
>>>>>>>>> On Jul 14, 2006, at 4:22 AM, Gary Byers wrote:
>>>>>>>>>> I think that it was probably an oversight.
>>>>>>>>>> I can't easily check at the moment (the machine that I used is
>>>>>>>>>> acting
>>>>>>>>>> up ...), but I think that the interfaces that were generated on
>>>>>>>>>> 6/20
>>>>>>>>>> (in <ftp://clozure.com/pub/testing/openmcl-darwin-
>>>>>>>>>> interfaces-060620.tar.gz>)
>>>>>>>>>> contain glext.h (by virtue of the fact that AGL/agl.h #includes
>>>>>>>>>> it.)
>>>>>>>>>> On Fri, 14 Jul 2006, Phil wrote:
>>>>>>>>>>> The GL extension constants and functions (i.e. glext.h) don't
>>>>>>>>>>> appear
>>>>>>>>>>> to be included and I was wondering if this was by design or
>>>>>>>>>>> just an
>>>>>>>>>>> oversight?
>>>>>>>>>>> Thanks,
>>>>>>>>>>> Phil
>>>>>>>>>>> _______________________________________________
>>>>>>>>>>> Openmcl-devel mailing list
>>>>>>>>>>> Openmcl-devel at clozure.com
>>>>>>>>>>> http://clozure.com/mailman/listinfo/openmcl-devel
>>>>> _______________________________________________
>>>>> Openmcl-devel mailing list
>>>>> Openmcl-devel at clozure.com
>>>>> http://clozure.com/mailman/listinfo/openmcl-devel
>>> 
>>> 
>
>



More information about the Openmcl-devel mailing list