Skip navigation.
 
mlRe: Use of Mac OS X 10.5 / Leopards Garbage Collection Considered Harmful
FROM : John Engelhart
DATE : Thu Feb 07 07:14:10 2008

On Feb 6, 2008, at 8:48 PM, Chris Suter wrote:

>
> On 07/02/2008, at 12:06 PM, John Engelhart wrote:
>

>> However, consider for a moment if it was a type attribute, and 
>> followed type attribute rules, and how this would effect the 
>> examples cited.  Off the top of my head, I think treating it as a 
>> type attribute would have prevent every single error I've pointed 
>> out.  Hypothetically, consider if UTF8String propagated the 
>> __strong type, and the assignment of its pointer to the ivar 'const 
>> char *'.
>>
>> The compiler would fail to compile the code, and generate an error.

>
> I don't think it should be a type qualifier. It would mean that you 
> wouldn't be able to do things like:
>
> puts ([myString UTF8String])
>
> without getting a compiler warning.


This is a pretty debatable point, with pros and cons on each side.  My 
opinion is that you should not be handing pointers which require write 
barriers for proper operation of the GC system to code that is not 
compiled with the proper support.  One could argue that the decision 
to require that "all frameworks must be GC compiled/capable" makes 
this policy a requirement.

Since the GC system considers everything on the stack to be a live 
pointer, this has the effect of catching 99.99% use of pointers in 
this fashion.  While I do not have a specific example to show here, I 
think you'll agree that there are occasionally times when calling a C 
library function will violate these principles.  Realistically, when 
you call a function, that pointer vanishes down a call stack that is 
surpassingly complex, and that pointer has a tendency of visiting 
places you would not think applies in a particular case.  If you've 
used Shark.app, I'm sure you've seen some functions which end up 
creating some surprisingly deep call-stacks that in turn are calling 
all sorts of seemingly unrelated functions.

I don't argue that it covers 99.99% of the cases.  It's that last tiny 
bit that I'm writing about.  I'm sure you'll agree that tracking down 
errors of this nature is, politely, frustrating.

There's an example someone once used to underscore how optimistic we 
can be and spectacularly misjudge the likelihood of these rare errors 
occurring.  It comes from the canonical example of multi-threaded/
multi-cpu programming:

x++;

I'll skip over the specifics, but the question is asked "How likely do 
you think the condition is for two threads to get into a race 
condition and incorrectly update 'x'?  A million to one?"

While a million to one odds seems like a lot, at two gigahertz, that's 
roughly 2000 times per second.  That's roughly a 500 microseconds mean 
time to failure rate.
>

>> Oddly, I had to add a second NSLog() in order to get some kind of 
>> lossage, but I think it's fair to chalk this up to the semi-random 
>> nature of allocations.

>
> I think that would have been because the pointer returned by 
> UTF8String was still on the stack or in a register.


Hard to say.  I think it does illustrate another point: the seemingly 
random nature in which you will get bitten by these kinds of bugs.

>

>> The above example is now perfectly legal by everyones definition of 
>> how things were under retain/release, and I correctly clear the 
>> pointer before it goes out of scope, and demonstrates that the GC 
>> system can, and does, reclaim live data out from under you.

>
> I think your example is contrived. Whilst it's legal in the retain/
> release world you wouldn't ever write anything like that.


Granted, my example is contrived, no two ways about it.  But is that 
not the point?  To create a compact example which replicates the 
problem?  I believe I have done all that is required: demonstrate that 
it is possible.  Once I've done that, the sheer volume of code under 
consideration essentially guarantees that this is taking place.  My 
practical, hands on experience suggests this (and by this, I don't 
mean this particular example per se, but the ease in which it's 
possible to get some of these subtle points wrong) is happening far 
more frequently then you would think.

>
> The solution to all of this is, as has already been stated, is to 
> understand the contract that UTF8String promises and to make your 
> own arrangements if you want to hang on to the value.


You're absolutely right.  But my point is that, in practice, this is 
not quite as clear cut as it seems.

Allow me to back way, way, way up.  For the purposes of this argument, 
let us not consider all the technical points that have been discussed 
so far, as it's easy to get lost arguing pedantic, nuanced details. 
Let's consider the GC system from a purely pragmatic point of view.

Now, the precise specifics not withstanding, you will at some time get 
some small detail wrong.  You will have created a bug with regards to 
some GC detail.  The effect of this bug, which I think everyone will 
reasonably agree on, is likely to result in the collector reclaiming 
memory that you have in use when you clearly didn't want it to.

The hows and whys of your bug aren't really important, but you have 
done something wrong when you shouldn't have.  These things happen.

My experience with these bugs has been that they consume an 
EXTRAORDINARY amount of time to track down.  Because of the semi-
random nature that these bugs manifest themselves in, I have found 
that it's virtually impossible to find a solid set of conditions to 
tickle the condition.  I have found that unit tests are worthless in 
trying to track down these problems.  The complex interactions 
required to tickle these bugs are essentially impossible to create 
with unit tests.  All unit tests will pass, flawlessly, and in fact it 
some times may not be possible to recreate the right conditions to 
trigger the bug because essentially all your variables are sitting on 
the stack in the scope of the unit test.

The pragmatic effects of using Leopards GC system has been a MASSIVE 
increase in the amount of time I have spent debugging problems that 
have all the symptoms of "race condition" bugs, and consequently the 
huge uptick in effort required to find and eliminate these bugs.

This is my warning to you (you being all of the list, or archive 
reader).  Setting aside all the technical points discussed, you will 
eventually create a bug that in retrospect, you clearly shouldn't 
have.  The nature of these bugs means that it will take tremendous 
effort and time to track down and correct.  My experiences with the GC 
system have seen the time I spend debugging explode, and in fact 
dominate the time I spend developing.  What's worse is that these bugs 
rarely manifest themselves during development and are nearly 
impossible to catch with unit tests.  This means that the reliability 
of "shipped code" goes right through the floor, and replicating the 
bug often requires considerable interaction with an outside party and 
all the difficulties that that entails.

Related mailsAuthorDate
mlUse of Mac OS X 10.5 / Leopards Garbage Collection Considered Harmful John Engelhart Feb 4, 02:57
mlRe: Use of Mac OS X 10.5 / Leopards Garbage Collection Considered Harmful Quincey Morris Feb 4, 05:09
mlRe: Use of Mac OS X 10.5 / Leopards Garbage Collection Considered Harmful j o a r Feb 4, 08:18
mlre: Use of Mac OS X 10.5 / Leopards Garbage Collection Considered Harmful Ben Trumbull Feb 4, 10:19
mlRe: Use of Mac OS X 10.5 / Leopards Garbage Collection Considered Harmful Alastair Houghton Feb 4, 14:11
mlRe: Use of Mac OS X 10.5 / Leopards Garbage Collection Considered Harmful Greg Titus Feb 4, 16:39
mlRe: Use of Mac OS X 10.5 / Leopards Garbage Collection Considered Harmful Sean McBride Feb 4, 22:40
mlRe: Use of Mac OS X 10.5 / Leopards Garbage Collection Considered Harmful John Engelhart Feb 5, 01:14
mlRe: Use of Mac OS X 10.5 / Leopards Garbage Collection Considered Harmful Chris Hanson Feb 5, 02:21
mlRe: Use of Mac OS X 10.5 / Leopards Garbage Collection Considered Harmful Jonathon Mah Feb 5, 08:47
mlRe: Use of Mac OS X 10.5 / Leopards Garbage Collection Considered Harmful Alastair Houghton Feb 5, 13:40
mlRe: Use of Mac OS X 10.5 / Leopards Garbage Collection Considered Harmful John Engelhart Feb 6, 10:39
mlRe: Use of Mac OS X 10.5 / Leopards Garbage Collection Considered Harmful Alastair Houghton Feb 6, 12:15
mlRe: Use of Mac OS X 10.5 / Leopards Garbage Collection Considered Harmful John Engelhart Feb 6, 15:59
mlRe: Use of Mac OS X 10.5 / Leopards Garbage Collection Considered Harmful Michael Tsai Feb 6, 16:12
mlRe: Use of Mac OS X 10.5 / Leopards Garbage Collection Considered Harmful glenn andreas Feb 6, 16:45
mlBug in CF/NSString's no-copy constructors (was Re: Use of Mac OS X 10.5 / Leopards Garbage Collection Considered Harmful) Alastair Houghton Feb 6, 16:55
mlRe: Bug in CF/NSString's no-copy constructors (was Re: Use of Mac OS X 10.5 / Leopards Garbage Collection Considered Harmful) Michael Tsai Feb 6, 17:46
mlRe: Use of Mac OS X 10.5 / Leopards Garbage Collection Considered Harmful Clark Cox Feb 6, 17:47
mlRe: Use of Mac OS X 10.5 / Leopards Garbage Collection Considered Harmful Jean-Daniel Dupas Feb 6, 18:05
mlRe: Bug in CF/NSString's no-copy constructors Alastair Houghton Feb 6, 18:46
ml[Moderator] Re: Use of Mac OS X 10.5 / Leopards Garbage Collection Considered Harmful Scott Anguish Feb 6, 18:46
mlRe: Use of Mac OS X 10.5 / Leopards Garbage Collection Considered Harmful Hamish Allan Feb 6, 18:52
mlRe: Bug in CF/NSString's no-copy constructors Michael Tsai Feb 6, 19:29
mlRe: Use of Mac OS X 10.5 / Leopards Garbage Collection Considered Harmful Hamish Allan Feb 6, 19:36
mlRe: Use of Mac OS X 10.5 / Leopards Garbage Collection Considered Harmful Alastair Houghton Feb 6, 20:12
mlRe: Use of Mac OS X 10.5 / Leopards Garbage Collection Considered Harmful glenn andreas Feb 6, 21:23
mlRe: Use of Mac OS X 10.5 / Leopards Garbage Collection Considered Harmful Sean McBride Feb 6, 21:47
mlRe: Use of Mac OS X 10.5 / Leopards Garbage Collection Considered Harmful Michael Ash Feb 6, 22:38
mlRe: Use of Mac OS X 10.5 / Leopards Garbage Collection Considered Harmful Hamish Allan Feb 6, 23:49
mlRe: Use of Mac OS X 10.5 / Leopards Garbage Collection Considered Harmful John Engelhart Feb 7, 02:06
mlRe: Use of Mac OS X 10.5 / Leopards Garbage Collection Considered Harmful Hamish Allan Feb 7, 02:40
mlRe: Use of Mac OS X 10.5 / Leopards Garbage Collection Considered Harmful Chris Suter Feb 7, 02:48
mlRe: Use of Mac OS X 10.5 / Leopards Garbage Collection Considered Harmful John Engelhart Feb 7, 02:48
mlRe: Use of Mac OS X 10.5 / Leopards Garbage Collection Considered Harmful Clark Cox Feb 7, 03:52
mlRe: Use of Mac OS X 10.5 / Leopards Garbage Collection Considered Harmful glenn andreas Feb 7, 04:01
mlRe: Use of Mac OS X 10.5 / Leopards Garbage Collection Considered Harmful Timothy Reaves Feb 7, 04:08
mlRe: Use of Mac OS X 10.5 / Leopards Garbage Collection Considered Harmful Brady Duga Feb 7, 04:22
mlRe: Use of Mac OS X 10.5 / Leopards Garbage Collection Considered Harmful John Engelhart Feb 7, 07:14
mlRe: Use of Mac OS X 10.5 / Leopards Garbage Collection Considered Harmful John Engelhart Feb 7, 07:14
mlRe: Use of Mac OS X 10.5 / Leopards Garbage Collection Considered Harmful Michael Ash Feb 7, 23:58
mlRe: Bug in CF/NSString's no-copy constructors John Engelhart Feb 8, 03:31
mlRe: Use of Mac OS X 10.5 / Leopards Garbage Collection Considered Harmful John Engelhart Feb 8, 05:23
mlRe: Use of Mac OS X 10.5 / Leopards Garbage Collection Considered Harmful Greg Parker Feb 8, 05:30
mlRe: Use of Mac OS X 10.5 / Leopards Garbage Collection Considered Harmful Michael Tsai Feb 8, 05:56
mlRe: Use of Mac OS X 10.5 / Leopards Garbage Collection Considered Harmful Hamish Allan Feb 8, 18:35
ml[Moderator] Re: Use of Mac OS X 10.5 / Leopards Garbage Collection Considered Harmful Scott Anguish Feb 8, 22:17