[llvm-dev] Debugging an Objective-C metadata-emit problem, Bug #30413
Mehdi Amini via llvm-dev
llvm-dev at lists.llvm.org
Tue Jan 17 08:49:19 PST 2017
CC: cfe-dev (and tweak the title) ; this is really a frontend question.
—
Mehdi
> On Jan 17, 2017, at 7:31 AM, Lobron, David via llvm-dev <llvm-dev at lists.llvm.org> wrote:
>
> Hello llvm-dev,
>
> I opened bug report 30413 a while ago, and I'd like to request help from someone with better knowledge of clang. The bug occurs on Linux, where clang does not emit type metadata when compiling Objective-C programs, as it does on the Mac, and as gcc does on Linux. My program uses that metadata to do type introspection (see below for an example).
>
> From code inspection, it appears that the type metadata is written by code in clang's ASTContext class. I wrote a test program, copied below, which reproduces this bug. I ran clang under gdb, and set a breakpoint on all the methods in the clang::ASTContext:: namespace, but I found that none of these were called (at least, none of the 571 breakpoints was triggered). I confirmed that other gdb breakpoints (e.g., on ::main) did get triggered, so I know that my breakpoints in general were working.
>
> I was left with two questions:
>
> - Are the clang::ASTContext:: methods not called when compiling an ObjC program?
>
> - Is there some other part of the code where the metadata is emitted, if not from clang::ASTContext::? I looked for a quite a while, but I could not find a plausible candidate.
>
> Any help would be appreciated! Feel free to reply to me directly, or to the list, or to post suggestions in the bug report here:
>
> https://llvm.org/bugs/show_bug.cgi?id=30413
>
> Thanks!
>
> --David
>
> My test program code is below. On a Mac, compiled with clang, the runtime can correctly introspect the type of an NSString* instance variable. The output is:
>
> 2017-01-17 10:26:21.333 TestClassMetadata[13856:3607976] Ivar type _intIvar does not appear to be an object-valued class: type is i
> 2017-01-17 10:26:21.334 TestClassMetadata[13856:3607976] Ivar type _doubleVar does not appear to be an object-valued class: type is d
> 2017-01-17 10:26:21.334 TestClassMetadata[13856:3607976] Introspected class NSString for ivar name _stringIvar
>
> On Linux, compiled with clang, the NSString introspection does not work, because the metadata is not present. The output there is:
>
> 2017-01-17 15:27:15.641 TestClassMetadata[32308:32308] Ivar type _intIvar does not appear to be an object-valued class: type is i
> 2017-01-17 15:27:15.661 TestClassMetadata[32308:32308] Ivar type _doubleVar does not appear to be an object-valued class: type is d
> 2017-01-17 15:27:15.661 TestClassMetadata[32308:32308] Ivar type _stringIvar does not appear to be an object-valued class: type is @
>
> (Note the difference in the last lines).
>
> Program code:
>
> #import <Foundation/Foundation.h>
>
> #ifdef __APPLE__
> #import <objc/objc-runtime.h>
> #else
> #import <objc/runtime.h>
> #endif
>
> @interface TestClass : NSObject {
> @public
> int _intIvar;
> double _doubleVar;
> NSString *_stringIvar;
> }
> - (id)init;
> - (void)sayHello:(NSString *)txt;
> @end
>
> @implementation TestClass
>
> - (void)sayHello:(NSString *)txt
> {
> [_stringIvar release];
> _stringIvar = [txt retain];
> NSLog(@"%@", _stringIvar);
> }
>
> - (void)dealloc
> {
> [_stringIvar release];
> [super dealloc];
> }
>
> - (id)init {
> if ((self = [super init]) != nil) {
> unsigned i;
> Class c = [self class];
> NSAssert(c != 0, @"Could not get class object");
> unsigned ivarCount;
> Ivar *ivarList = class_copyIvarList(c, &ivarCount);
> for (i = 0; i < ivarCount; i++) {
> Ivar ivar = ivarList[i];
> const char *ivarCname = ivar_getName(ivar);
> if (ivarCname != 0) {
> NSString *ivarName = [NSString stringWithUTF8String:ivarCname];
> const char *ivarType = ivar_getTypeEncoding(ivar);
> if (ivarType[0] == '@' && ivarType[1] == '"') {
> NSString *className = [[[NSString alloc] initWithBytes: &ivarType[2]
> length: strlen(&ivarType[2])-1
> encoding: NSUTF8StringEncoding] autorelease];
> Class c = NSClassFromString(className);
> if (c == nil) {
> NSLog(@"WARNING: unknown class name \"%@\" in declaration of %@", className, [self class]);
> } else {
> NSLog(@"Introspected class %@ for ivar name %@",
> className, ivarName);
> }
> } else {
> NSLog(@"Ivar type %s does not appear to be an object-valued class: type is %s", ivarCname, ivarType);
> }
> }
> }
> if (ivarList)
> free(ivarList);
> }
>
> return self;
> }
>
> @end
>
> int main() {
> NSAutoreleasePool *pool = [NSAutoreleasePool new];
> TestClass *c = [[[TestClass alloc] init] autorelease];
> [pool release];
>
> return 0;
> }
> _______________________________________________
> LLVM Developers mailing list
> llvm-dev at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
More information about the llvm-dev
mailing list