Re: test if a pointer is pointing to a valid object or not? (Alastair J.Houghton)
Re: test if a pointer is pointing to a valid object or not? (Alastair J.Houghton)
- Subject: Re: test if a pointer is pointing to a valid object or not? (Alastair J.Houghton)
- From: p3consulting <email@hidden>
- Date: Wed, 29 Oct 2003 12:28:36 +0100
>
On Wednesday, October 29, 2003, at 08:50 am, p3consulting wrote:
>
>
>>> is there anyway to test if a pointer, that isn't NULL, is pointing
>
>>> to
>
>>> a valid object or not?
>
>
> It''s not possible that way because calling isKindOfClass
>
> assume the target is an object
>
> In other words the hypothesis has been used in the
>
> demonstration making it void.
>
>
>
> Theory of operation for a IsValidObjectPointer(void *ptr)
>
> function: (may I insist on the "theory" word here)
>
>
You can insist on the word "theory" if you like, but it doesn't make
>
your argument below correct.
>
>
> 1. if p is not a multiple of 4 it''s not a valid mallocated
>
> pointer: reject it
>
>
Fair enough. I think the restriction on alignment may actually be
>
more extreme than this on Mac OS X (8 or perhaps even 16 bytes), but I
>
don't have the inclination to check right now.
ok rewrite it as
1. if is not aligned as it should in the context of your app (4, 8 or
16) (16 is enforced in Altivec enabled code for sure) -
but if you don't want to complicate too much just check for alignement
on 4 bytes boundaries
>
> 2. check that p is in the memory space (some Unix/Mach/BSD
>
> calls should provide this kind of info) of your process and - if
>
> this is possible - check if it is in the malloc heap
>
>
OK, that's fair enough also.
>
in fact no OS calls are needed since
----------------------------------------------------------------
high address | command line args and env variables |
|--------------------------------------------------------------|
| stack |
| growing down |
| |
| |
| growing up |
| heap |
----------------------------------------------------------------
| uninitialized static data |
----------------------------------------------------------------
| initialized static data |
----------------------------------------------------------------
| program text |
low
address
----------------------------------------------------------------
>
> 3. if ok then dereferences it (it's now guaranted not to crash
>
> your code with a signal) to get the theorical isa and loop on
>
> that process
>
> (checking if the isa you now have is correctly aligned, in
>
> your memory space etc.)
>
> until you reach the top of the hierarchy that should be a
>
> [NSObject class]
>
>
But this is wrong, for three reasons:
>
1. malloc() and free() don't clear memory.
read my post until the end we should clear freed memory before trying
to write just a routine
and as you state in your own post this is controlled by malloc
environment variables (MallocScribble in this case)
still a problem ?
>
So you could have a pointer to an object that you have already
>
released, but that is in an area of memory that has since been given
>
to someone else by malloc(). It will pass tests 1 and 2, even if you
>
elaborate test 2 to ask whether it is in the allocated region of the
>
malloc() heap.
>
if MallocScribble is enabled free memory will be filled with 0x55 and
the isa will then be 0x55555555 : odd thus invalid pointer
>
2. You can't assume that some area of memory contains a valid object
>
just because the memory appears to contain a valid isa pointer,
>
stretching right back to an NSObject at the very top. Perhaps whoever
>
currently owns that block of memory has cleared or otherwise
>
initialised some of it, but has left the first four bytes alone for
>
the moment. Or perhaps the isa pointer was copied there from
>
somewhere else. You just don't know, and no amount of code is going
>
to tell you.
>
Well this left us with the problem :"a routine checking that an
ObjectiveC pointer belongs to an instance of class X" may return true
if the memory was freed then reallocated to another object of the same
class ? But then it's valid as far as the purpose of the routine is
concerned !
>
3. Even assuming that it does contain a valid object, you don't know
>
that it was the object you originally had a pointer to. The area of
>
memory may have been re-used by someone
of course such a routine should not be used to know if a pointer on an
object is still on the original one that's a totally different
debugging problem and is not what the original poster was asking
>
else for another, completely different object. Again, you don't know,
>
and no amount of code will tell you.
>
hence the word "theory" at the beginning: the postive answer of a
routine trying to check a pointer must be interpreted as "looks like
something valid", but the negative answer is more interesting because
it can be trusted: "for sure this is not a pointer on an Objective-C
object".
So the usefulness of such a routine will depend on the context of use
and the understanding by the developper of what it is really checking
>
There are some additional problems, including the fact that there can
>
be more than one malloc() heap on Mac OS X (corresponding to the
>
NSZone objects in Cocoa), so you'd have to check whether the block was
>
allocated in any of the currently active heaps. And the fact that not
>
all objects you might see actually inherit from NSObject (the proxy
>
objects for DO don't, for example).
>
More than a malloc heap is not a problem they are all in the same
memory area between the lowest address used by the stack and the top
most address used by unitialized data
We are not trying to know if the pointer is in the "right" heap, we are
trying to answer "is this a pointer on Objective-C object"
Not an object inheriting from NSObject ? then either in the spec of the
"checkpointer" routine it will be specified that incorrect response may
be returned for DO object, either you test for that situation in the
routine you should be able to know the root class of DO objects by
creating such an object and looking for the root class, isn't ?
(probably Object ?)
>
Plus, as you say, you'd have to detect cycles, including cycles of
>
more than length one.
>
Of course more than length one, that's why I draw attention on the
performance overhead impact
(especially if you want to be thread safe when writing such a routine)
>
So, as I said before, it won't work. You can't do this.
>
Too short as an answer,
my post was to attract attention on the fact that you can do SOME
testing on pointer validity but obviously the only answer you can trust
fully is the negative one ("this is not an objective-C object"), the
positive answer has to be interpreted as "looks like something valid"
and turning on the right malloc environment variables may increase the
"trust-ness" of this anwer
And as you stated looking at NSDebug.h may also give some idea of what
to turn on to help tracking down memory problem
And this may be enough to some developers really depend on what kind
of bug you are tracking down
Pascal Pochet
P3 Consulting
email@hidden
http://www.p3-consulting.net
_______________________________________________
cocoa-dev mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/cocoa-dev
Do not post admin requests to the list. They will be ignored.