[Issue 19017] New: Calling objc method returning struct segfaults
d-bugmail at puremagic.com
d-bugmail at puremagic.com
Sat Jun 23 07:56:48 UTC 2018
https://issues.dlang.org/show_bug.cgi?id=19017
Issue ID: 19017
Summary: Calling objc method returning struct segfaults
Product: D
Version: D2
Hardware: x86_64
OS: Mac OS X
Status: NEW
Severity: critical
Priority: P1
Component: dmd
Assignee: nobody at puremagic.com
Reporter: doob at me.com
Calling an Objective-C method that returns a struct that is too big to fit in
registers will result in a segmentation fault when accessing fields of the
returned struct. Example:
// foo.m
#import <Foundation/Foundation.h>
typedef struct
{
int a, b, c, d, e;
} Bar;
@interface Foo : NSObject
-(Bar) getValue;
@end
@implementation Foo
-(Bar) getValue
{
Bar s = { 3, 3, 3, 3, 3 };
return s;
}
@end
// main.d
extern (C) int printf(in char*, ...);
struct Bar
{
int a, b, c, d, e;
}
extern (Objective-C)
interface Foo
{
static Foo alloc() @selector("alloc");
Foo init() @selector("init");
Bar getValue() @selector("getValue");
}
void main()
{
auto f = Foo.alloc.init;
auto b = f.getValue;
printf("%d\n", b.a);
}
Compile with:
clang foo.m -o foo.o
dmd main.d foo.o -L-framework -LFoundation
Running this in a debugger results in:
lldb main
(lldb) target create "main"
Current executable set to 'main' (x86_64).
(lldb) r
Process 84149 launched: 'main' (x86_64)
Process 84149 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS
(code=EXC_I386_GPFLT)
frame #0: 0x00007fff6ac2030a libdyld.dylib`stack_not_16_byte_aligned_error
libdyld.dylib`stack_not_16_byte_aligned_error:
-> 0x7fff6ac2030a <+0>: movdqa %xmm0, (%rsp)
0x7fff6ac2030f <+5>: int3
libdyld.dylib`_dyld_func_lookup:
0x7fff6ac20310 <+0>: pushq %rbp
0x7fff6ac20311 <+1>: movq %rsp, %rbp
Target 0: (main) stopped.
(lldb) bt
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS
(code=EXC_I386_GPFLT)
* frame #0: 0x00007fff6ac2030a libdyld.dylib`stack_not_16_byte_aligned_error
frame #1: 0x00007ffeefbff390
frame #2: 0x000000010001f4ac
main`_D2rt6dmain211_d_run_mainUiPPaPUAAaZiZ6runAllMFZ9__lambda1MFZv + 40
frame #3: 0x000000010001f33c
main`_D2rt6dmain211_d_run_mainUiPPaPUAAaZiZ7tryExecMFMDFZvZv + 32
frame #4: 0x000000010001f417
main`_D2rt6dmain211_d_run_mainUiPPaPUAAaZiZ6runAllMFZv + 139
frame #5: 0x000000010001f33c
main`_D2rt6dmain211_d_run_mainUiPPaPUAAaZiZ7tryExecMFMDFZvZv + 32
frame #6: 0x000000010001f2aa main`_d_run_main + 486
frame #7: 0x0000000100000cd0 main`main + 16
frame #8: 0x00007fff6ac20015 libdyld.dylib`start + 1
An Objective-C call like "f.getValue" is supposed to be lowered to this C call
[1]:
Bar tmp;
objc_msgSend_stret(&tmp, f, "getValue");
As far as I know this is the same ABI as a regular C function returning a
struct.
[1] For more details see the Objective-C ABI documentation:
https://github.com/dlang/dmd/blob/master/docs/objective-c_abi.md#returning-a-struct
--
More information about the Digitalmars-d-bugs
mailing list