NSInvocation has garbage return value, and even trashes target?

41 views
Skip to first unread message

andyvn22

unread,
Mar 28, 2012, 5:34:55 PM3/28/12
to cocotr...@googlegroups.com
It seems that any NSInvocation with a return value that's a struct gives a garbage return value. Furthermore, as demonstrated by the little test below, it seems to even mess up its target object when it is invoked. The logging of [vertex location] segfaults after the invocation, but works before. If I comment that out, thus allowing the code to log the return value, that prints incorrect x and y values.

Any idea what's going on here or at least where I could start debugging this?

Thank you!

@interface IRVertex : NSObject
{
    NSPoint location;
}
@property (nonatomic,assign) NSPoint location;
@end
@implementation IRVertex
@synthesize location;
@end
int main(int argc, char *argv[])
{
    NSAutoreleasePool* pool = [NSAutoreleasePool new];
    
    IRVertex* vertex = [[IRVertex new] autorelease];
    [vertex setLocation:NSMakePoint(4,2)];
    NSLog(@"Value before invocation:");
    NSLog(@"%@",NSStringFromPoint([vertex location]));
    
    SEL sel = @selector(location);
    id sig = [vertex methodSignatureForSelector:sel];
    id inv = [NSInvocation invocationWithMethodSignature:sig];
    [inv setSelector:sel];
    [inv invokeWithTarget:vertex];
    
    NSUInteger returnLength=[sig methodReturnLength];
    void *returnValue=__builtin_alloca(returnLength);
    [inv getReturnValue:returnValue];
    
    NSLog(@"Value after invocation:");
    NSLog(@"%@",NSStringFromPoint([vertex location]));
    NSLog(@"Invocation return value:");
    NSLog(@"%@",NSStringFromPoint(*(NSPoint*)returnValue));
    
    [pool drain];
    
    return NSApplicationMain(argc, (const char **) argv);
}

Elder William

unread,
Mar 28, 2012, 7:58:18 PM3/28/12
to cocotr...@googlegroups.com, cocotr...@googlegroups.com
Does   [inv getReturnValue:&returnValue]; work?
In my experience you have to pass the address of the variable using &... for both get and setReturnValue....(this is on apples implementation though)

Andre

iPadから送信
--
You received this message because you are subscribed to the Google Groups "Cocotron Developers" group.
To view this discussion on the web visit https://groups.google.com/d/msg/cocotron-dev/-/kv_pY4-kHi0J.
To post to this group, send email to cocotr...@googlegroups.com.
To unsubscribe from this group, send email to cocotron-dev...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/cocotron-dev?hl=en.

Christopher Lloyd

unread,
Mar 28, 2012, 9:29:53 PM3/28/12
to cocotr...@googlegroups.com
If 'target' is getting trashed I'd guess -methodReturnLength is returning the wrong value. In general NSInvocation could use some work especially for struct returns, although NSPoint should fall into the non-struct return category.

Start putting some logs in there :)

Chris

andyvn22

unread,
Mar 29, 2012, 8:13:24 PM3/29/12
to cocotr...@googlegroups.com
Hum, -methodReturnLength is a reasonable value according to NSGetSizeAndAlignment(@encode(NSPoint)...)--it also matches the Mac 32-bit value.

Through some logging, I tracked down the problem to NSInvocation.m:448:

else if (size <= sizeof(long long)) {
    long long (*function)() = msgSendv;
    NSLog(@"1: %@",NSStringFromPoint([[self target] location])); //Result: 1: {4, 2}
    long long value = function([self target], [self selector], _argumentFrameSize, _argumentFrame);
    NSLog(@"2: %@",NSStringFromPoint([[self target] location])); //Result: Segmentation fault
    [self setReturnValue:&value];
}

What does this mean? Possibly incorrect _argumentFrameSize? It seems to be 8, same as -methodReturnLength.

Thank you!

Christopher Lloyd

unread,
Mar 30, 2012, 7:29:51 PM3/30/12
to cocotr...@googlegroups.com
Ah, you need to call NSInitializeProcess(argc,argv) right after main. The runtime is not initialized properly.

Chris

andyvn22

unread,
Mar 31, 2012, 12:52:13 AM3/31/12
to cocotr...@googlegroups.com
Oh--thank you! I wasn't aware of that. Unfortunately, adding it did not change the behavior. Is there any other initialization that needs to be done?

Christopher Lloyd

unread,
Apr 1, 2012, 2:07:29 PM4/1/12
to cocotr...@googlegroups.com
Hm, I tried this out as-is in a small example (beginning of TextEditor example) and it seems fine, runs as expected.

Possibly something else is interacting here?

Chris

andyvn22

unread,
Apr 15, 2012, 12:25:11 AM4/15/12
to cocotr...@googlegroups.com
Perhaps it's a Linux-specific issue, then... I've no way to run Windows tests.
Reply all
Reply to author
Forward
0 new messages