www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 19017] New: Calling objc method returning struct segfaults

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