digitalmars.D.bugs - [Issue 19017] New: Calling objc method returning struct segfaults
- d-bugmail puremagic.com (96/96) Jun 23 2018 https://issues.dlang.org/show_bug.cgi?id=19017
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 puremagic.com Reporter: doob 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 (code=EXC_I386_GPFLT) 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 (code=EXC_I386_GPFLT) main`_D2rt6dmain211_d_run_mainUiPPaPUAAaZiZ6runAllMFZ9__lambda1MFZv + 40 main`_D2rt6dmain211_d_run_mainUiPPaPUAAaZiZ7tryExecMFMDFZvZv + 32 main`_D2rt6dmain211_d_run_mainUiPPaPUAAaZiZ6runAllMFZv + 139 main`_D2rt6dmain211_d_run_mainUiPPaPUAAaZiZ7tryExecMFMDFZvZv + 32 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 --
Jun 23 2018