viralcode / address-sanitizer

Automatically exported from code.google.com/p/address-sanitizer
1 stars 0 forks source link

Some programs hang because of the replaced CFAllocator #10

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
=====================================================================
#import <Foundation/Foundation.h>
#import <WebKit/WebKit.h>

@interface WebKitDelegate : NSObject
@end

@implementation WebKitDelegate

- (void)webView:(WebView *)sender didFinishLoadForFrame:(WebFrame *)frame
{
    NSLog(@"didFinishLoadForFrame");
    [sender displayIfNeeded];
    if (frame == [sender mainFrame])
        exit(0);
}

- (NSURLRequest *)webView:(WebView *)sender resource:(id)identifier 
willSendRequest:(NSURLRequest *)request redirectResponse:(NSURLResponse 
*)redirectResponse fromDataSource:(WebDataSource *)dataSource;
{
    NSLog(@"Will send request %@ (redirect %@)",request,redirectResponse);
    return request;
}

- (void)webView:(WebView *)sender resource:(id)identifier 
didReceiveResponse:(NSURLResponse *)response fromDataSource:(WebDataSource 
*)dataSource
{
    NSLog(@"Got response %@",response);
}
@end

int main(int argc, char * const argv[])
{
    //// CFAllocatorSetDefault(kCFAllocatorMallocZone);
    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
    WebView *webView = [[WebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) frameName:nil groupName:@"org.webkit.parseWebKit"];
    WebKitDelegate* delegate = [[WebKitDelegate alloc] init];
    [webView setFrameLoadDelegate:delegate];
    [webView setResourceLoadDelegate:delegate];
    [[webView mainFrame] loadHTMLString:@"<html><body>test</body></html>" baseURL:nil];
    [[NSRunLoop currentRunLoop] run];
    [pool drain];
    return 0;
}
=====================================================================

The program above hangs under ASan. If the "CFAllocatorSetDefault" line is 
uncommented, the program hangs without ASan.

Original issue reported on code.google.com by gli...@chromium.org on 21 Nov 2011 at 9:12

GoogleCodeExporter commented 9 years ago
While the problem is caused by a subtle bug in CoreFoundation, this may make 
ASan unusable for some applications.
A temporary solution is add a flag to disable replacing the default CFAllocator:

  $ ASAN_OPTIONS="replace_cfallocator=0" asan/Release/parseWebKit

I haven't observed such problems with Chromium, thus replace_cfallocator is 1 
by default.

Original comment by gli...@chromium.org on 21 Nov 2011 at 9:17

GoogleCodeExporter commented 9 years ago
I've added the flag in r1084.

Original comment by ramosian.glider@gmail.com on 21 Nov 2011 at 9:33

GoogleCodeExporter commented 9 years ago

Original comment by mark@chromium.org on 19 Jan 2012 at 7:25

GoogleCodeExporter commented 9 years ago
Braden Thomas supposes that the problem may be caused by CFStringCreateCopy 
which normally does not copy constant strings, but does so if the allocator is 
replaced:
=================================================
$ cat t.mm
#import <Foundation/Foundation.h>
#include <stdio.h>

int main() {
#ifdef REPLACE
  CFAllocatorSetDefault(kCFAllocatorMallocZone);
#endif
  CFStringRef str = CFSTR("Hello world!\n");
  CFStringRef str2 = CFStringCreateCopy(0, str);
  fprintf(stderr, "str: %p\n", str);
  fprintf(stderr, "str2: %p\n", str2);
  return 0;
}

$ ../../../../build/Release+Asserts/bin/clang++   t.mm -framework Foundation -o 
t  && ./t
str: 0x100001060
str2: 0x100001060

$ ../../../../build/Release+Asserts/bin/clang++   t.mm -framework Foundation 
-DREPLACE -o t  && ./t
str: 0x100001070
str2: 0x1001099d8
=================================================

If so, we can try to intercept CFStringCreateCopy and make it leave constant 
strings as is

Original comment by ramosian.glider@gmail.com on 20 Jan 2012 at 3:35

GoogleCodeExporter commented 9 years ago
At least the initial WebKit example and the program from comment 4 behave 
correctly if I wrap CFStringCreateCopy() into a function that checks for the 
string constness before comparing the allocators.

Original CFStringCreateCopy() implementation from 
http://opensource.apple.com/source/CF/CF-476.19/CFString.c :
===========================================
CFStringRef CFStringCreateWithSubstring(CFAllocatorRef alloc, CFStringRef str, 
CFRange range) {
//      CF_OBJC_FUNCDISPATCH1(__kCFStringTypeID, CFStringRef , str, 
"_createSubstringWithRange:", CFRangeMake(range.location, range.length));

    __CFAssertIsString(str);
    __CFAssertRangeIsInStringBounds(str, range.location, range.length);

    if ((range.location == 0) && (range.length == __CFStrLength(str))) {    /* The substring is the whole string... */
    return (CFStringRef)CFStringCreateCopy(alloc, str);
    } else if (__CFStrIsEightBit(str)) {
    const uint8_t *contents = (const uint8_t *)__CFStrContents(str);
        return __CFStringCreateImmutableFunnel3(alloc, contents + range.location + __CFStrSkipAnyLengthByte(str), range.length, __CFStringGetEightBitStringEncoding(), false, false, false, false, false, ALLOCATORSFREEFUNC, 0);
    } else {
    const UniChar *contents = (UniChar *)__CFStrContents(str);
        return __CFStringCreateImmutableFunnel3(alloc, contents + range.location, range.length * sizeof(UniChar), kCFStringEncodingUnicode, false, true, false, false, false, ALLOCATORSFREEFUNC, 0);
    }
}
===========================================

My wrapper:

545 extern "C"
546 CFStringRef WRAP(CFStringCreateCopy)(CFAllocatorRef alloc, CFStringRef str) 
{
547   if (__CFStrIsConstant(str)) {
548     return str;
549   } else {
550     return real_CFStringCreateCopy(alloc, str);
551   }
552 }

Original comment by ramosian.glider@gmail.com on 20 Jan 2012 at 4:12

GoogleCodeExporter commented 9 years ago
BookmarkAllTabsControllerTest.BookmarkAllTabs 
(http://code.google.com/p/chromium/issues/detail?id=110589) does not fail 
anymore with this fix, neither does any of the unit_tests.
Moreover, the problem with blank omnibox in Chromium built with ASan disappears 
too.

I'm going to land the wrapper and propose an upstream fix for 
CFStringCreateCopy.

Original comment by ramosian.glider@gmail.com on 23 Jan 2012 at 8:58

GoogleCodeExporter commented 9 years ago
FTR, this is how omnibox used to behave for me:

> One of the problems I'm facing is that the Omnibox in my build is
> broken: it remains empty while I type in the address (my query appears
> in the drop-down list of suggestions). When I hit enter, the text
> appears, but it is gray instead of black.

Original comment by ramosian.glider@gmail.com on 23 Jan 2012 at 9:09

GoogleCodeExporter commented 9 years ago
As of r148696 the problem does not occur anymore.
I'm going to close the bug after I remove the replace_cfallocator flag, which 
will happen after the Apple folks confirm everything is correct.

Original comment by ramosian.glider@gmail.com on 23 Jan 2012 at 10:51

GoogleCodeExporter commented 9 years ago
can this be closed? 

Original comment by konstant...@gmail.com on 24 Feb 2012 at 10:57

GoogleCodeExporter commented 9 years ago
I haven't received any feedback from Apple about this, so let's keep it for 
some time, ok? We need to remove the flag once we're sure everything is all 
right.

Original comment by ramosian.glider@gmail.com on 28 Feb 2012 at 11:01

GoogleCodeExporter commented 9 years ago

Original comment by konstant...@gmail.com on 22 May 2012 at 8:39

GoogleCodeExporter commented 9 years ago
We've decided to keep this flag for now, since there are problems with 
CFAllocator on other OS X versions.

Original comment by ramosian.glider@gmail.com on 22 May 2012 at 8:45

GoogleCodeExporter commented 9 years ago
This has been fixed by the recent switch to the dynamic runtime, which does not 
replace CFAllocator.
I've removed the replace_cfallocator flag.

Original comment by ramosian.glider@gmail.com on 7 Feb 2013 at 4:00