[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Crashing in _Block_release

From: Jens Alfke
Subject: Re: Crashing in _Block_release
Date: Wed, 29 Feb 2012 17:34:14 -0800

On Feb 29, 2012, at 3:45 PM, David Chisnall wrote:

> This looks like a double-free.  Can you try running with valgrind or with 
> whatever memory debugging facilities your system malloc provides turned on?

I ran with valgrind and it reported nothing until the point where the program 
normally crashes; then it output:

==13971== Invalid read of size 4
==13971==    at 0x4A88075: _Block_object_dispose (blocks_runtime.m:206)
==13971==    by 0x47B0F28: __destroy_helper_block_ (MYBlockUtils.m:54)
==13971==    by 0x4A88334: _Block_release (blocks_runtime.m:299)
==13971==    by 0x414476B: _i_GSBlock__release (GSBlocks.m:81)
==13971==    by 0x41C6DC0: _i_NSAutoreleasePool__emptyPool 
==13971==    by 0x41C68E0: _i_NSAutoreleasePool__dealloc 
==13971==    by 0x41C674F: _i_NSAutoreleasePool__drain (NSAutoreleasePool.m:519)
==13971==    by 0x47B16C0: RunTestCase (Test.m:69)
==13971==    by 0x47B1074: RunTestCaseNamed (Test.m:83)
==13971==    by 0x47B1215: RunTestCases (Test.m:114)
==13971==    by 0x8048751: main (EmptyGNUstepApp.m:29)
==13971==  Address 0x748247c is 0 bytes after a block of size 20 alloc'd
==13971==    at 0x402732C: calloc (vg_replace_malloc.c:467)
==13971==    by 0x4A79075: alloc (gc_none.c:21)
==13971==    by 0x4A87C33: _Block_object_assign (blocks_runtime.m:127)
==13971==    by 0x47B0EDC: __copy_helper_block_ (MYBlockUtils.m:54)
==13971==    by 0x4A87F89: _Block_copy (blocks_runtime.m:265)
==13971==    by 0x41446EB: _i_GSBlock__copy (GSBlocks.m:71)
==13971==    by 0x47B089F: MYAfterDelay (MYBlockUtils.m:29)
==13971==    by 0x47B0BA1: Test_MYAfterDelay (MYBlockUtils.m:54)
==13971==    by 0x47B157C: RunTestCase (Test.m:46)
==13971==    by 0x47B1074: RunTestCaseNamed (Test.m:83)
==13971==    by 0x47B1215: RunTestCases (Test.m:114)
==13971==    by 0x8048751: main (EmptyGNUstepApp.m:29)

The “__destroy_helper_block_” function must be something auto-generated by the 
compiler; the source line (MYBlockUtils.m:54) is the line where the block 
literal appears in my code.

I’ll paste my code below, with minimal changes to replace some of my own 
testing and assertion macros with standard stuff. The crash is after the call 
to the test function, when the test harness drains the temporary autorelease 
pool. FYI, this code runs fine on Mac OS X 10.7 and iOS 5.


@interface NSObject (MYBlockUtils)
- (void) my_run_as_block;

/* This is sort of a kludge. This method only needs to be defined for blocks, 
but their class (NSBlock) isn't public, and the only public base class is 
NSObject. */
@implementation NSObject (MYBlockUtils)

- (void) my_run_as_block {
    ((void (^)())self)();


id MYAfterDelay( NSTimeInterval delay, void (^block)() ) {
    block = [[block copy] autorelease];
    [block performSelector: @selector(my_run_as_block)
                withObject: nil
                afterDelay: delay];
    return block;

void TestMYAfterDelay(void) {
    __block BOOL fired = NO;
    MYAfterDelay(0.5, ^{fired = YES; NSLog(@"Fired!");});
    while (!fired) {
        if (![[NSRunLoop currentRunLoop] runMode: NSDefaultRunLoopMode
                                      beforeDate: [NSDate 
dateWithTimeIntervalSinceNow: 0.5]])

reply via email to

[Prev in Thread] Current Thread [Next in Thread]