Thread overview | ||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
April 14, 2013 [Issue 9931] New: Bus error interfacing with C function returning structs with floats | ||||
---|---|---|---|---|
| ||||
http://d.puremagic.com/issues/show_bug.cgi?id=9931 Summary: Bus error interfacing with C function returning structs with floats Product: D Version: D2 Platform: x86 OS/Version: Mac OS X Status: NEW Severity: normal Priority: P2 Component: DMD AssignedTo: nobody@puremagic.com ReportedBy: doob@me.com --- Comment #0 from Jacob Carlborg <doob@me.com> 2013-04-14 09:25:06 PDT --- This code: http://pastebin.com/U5XdFfDq Will result in a bus error when compiled as 32bit. Three ways the bus error won't happen: * If I compile as 64bit everything works fine * If the function "foo" is moved inline in the "main" function everything works fine * If I store the return value of "fp" in "foo" in a temporary variable and then return it Mac OS X 10.8.2. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: ------- |
April 14, 2013 [Issue 9931] Bus error interfacing with C function returning structs with floats | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jacob Carlborg | http://d.puremagic.com/issues/show_bug.cgi?id=9931 Martin Nowak <code@dawg.eu> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|NEW |RESOLVED CC| |code@dawg.eu Resolution| |INVALID --- Comment #1 from Martin Nowak <code@dawg.eu> 2013-04-14 09:53:35 PDT --- You can't cast the "..." part o a C vararg function away. You also don't pass a pointer to the struct return to objc_msgSend_stret, which is the first parameter. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: ------- |
April 14, 2013 [Issue 9931] Bus error interfacing with C function returning structs with floats | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jacob Carlborg | http://d.puremagic.com/issues/show_bug.cgi?id=9931 Jacob Carlborg <doob@me.com> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|RESOLVED |REOPENED Resolution|INVALID | --- Comment #2 from Jacob Carlborg <doob@me.com> 2013-04-14 11:43:05 PDT --- You're supposed to invoke the functions like that. The objc_msgSend functions need to be casted to the correct signature. http://stackoverflow.com/questions/8405737/how-do-i-return-a-struct-value-from-a-runtime-defined-class-method-under-arc This works perfectly fine in C: http://pastebin.com/cTfn0PJS -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: ------- |
April 14, 2013 [Issue 9931] Bus error interfacing with C function returning structs with floats | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jacob Carlborg | http://d.puremagic.com/issues/show_bug.cgi?id=9931 --- Comment #3 from Martin Nowak <code@dawg.eu> 2013-04-14 16:56:04 PDT --- NSRect foo (id screen) { alias extern (C) NSRect function (id, SEL) frameFp; auto fp = cast(frameFp) &objc_msgSend_stret; return fp(screen, sel_registerName("visibleFrame".ptr)); } - You omit the pointer to the return value, that might accidently work on some ABIs because a hidden pointer to the return value is passed as first argument. What's the problem with this? NSRect foo(id screen) { NSRect res; objc_msgSend_stret(&res, screen, sel_registerName("visibleFrame")); return res; } -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: ------- |
April 15, 2013 [Issue 9931] Bus error interfacing with C function returning structs with floats | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jacob Carlborg | http://d.puremagic.com/issues/show_bug.cgi?id=9931 --- Comment #4 from Jacob Carlborg <doob@me.com> 2013-04-14 23:38:54 PDT --- (In reply to comment #3) > NSRect foo (id screen) > { > alias extern (C) NSRect function (id, SEL) frameFp; > auto fp = cast(frameFp) &objc_msgSend_stret; > return fp(screen, sel_registerName("visibleFrame".ptr)); > } > > - You omit the pointer to the return value, that might accidently work on some ABIs because a hidden pointer to the return value is passed as first argument. I don't know why it behaves like this but that's how you're supposed to invoke the function. This is the Objective-C runtime and it's kind of special. > What's the problem with this? > > NSRect foo(id screen) > { > NSRect res; > objc_msgSend_stret(&res, screen, sel_registerName("visibleFrame")); > return res; > } On Mac OS X 10.6.3 it segfaults. I haven't tried on 10.8.2 yet. It also segfaults if I cast it to: extern (C) void function (NSRect*, id, SEL). BTW, the original example doesn't _not_ cause a bus error on Mac OS X 10.6.3. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: ------- |
April 16, 2013 [Issue 9931] Bus error interfacing with C function returning structs with floats | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jacob Carlborg | http://d.puremagic.com/issues/show_bug.cgi?id=9931 --- Comment #5 from Jacob Carlborg <doob@me.com> 2013-04-16 00:10:33 PDT --- Here's one of my post from the discussion of this issue at the newsgroup: http://forum.dlang.org/thread/kkefk8$2663$1@digitalmars.com I've done some investigation about how the "objc_msgSend" family of functions work, including "objc_msgSend_stret". For those who don't know they're are part of the Objective-C runtime used for calling Objective-C methods. These functions are _not_ regular C functions, they're completely implemented using assembly. What they basically do is looking up the Objective-C method to call and just calls it (some caching is involved as well). What's special about this is that it won't mess with any resister or stack used for passing function arguments or sending back return values. What happens when it has found the correct Objective-C method is that it will just jump to the function. All registers and the stack are already correct, from the call to the objc_msgSend itself. I assume that is way the objc_msgSend method need to be cast to the correct signature before calling it. We don't want to use the ABI for variadic functions (as declared by objc_msgSend), we want the ABI used for the target function, that is, the Objective-C method. An Objective-C method is implement like a regular C function, following the ABI of the platform. It has to take at least these two parameters: void foo (id self, SEL _cmd); "self" would be the object we're calling the method on. "_cmd" is the selector (method) being called. Then what's objc_msgSend_stret used for. The objc_msgSend_stret function is used for returning structs that are too large to fit in the register. This is completely dependent on the platform ABI. I don't know if this helps. Some info about how objc_msgSend works: http://www.friday.com/bbum/2009/12/18/objc_msgsend-part-1-the-road-map/ Some info about why objc_msgSend_stret exists: http://www.sealiesoftware.com/blog/archive/2008/10/30/objc_explain_objc_msgSend_stret.html -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: ------- |
April 16, 2013 [Issue 9931] Bus error interfacing with C function returning structs with floats | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jacob Carlborg | http://d.puremagic.com/issues/show_bug.cgi?id=9931 --- Comment #6 from Jacob Carlborg <doob@me.com> 2013-04-16 12:28:13 PDT --- I think I found smaller test case for this problem, without the casts and Objective-C runtime functions: http://forum.dlang.org/thread/kkk8kh$2jsu$1@digitalmars.com -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: ------- |
April 17, 2013 [Issue 9931] Bus error interfacing with C function returning structs with floats | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jacob Carlborg | http://d.puremagic.com/issues/show_bug.cgi?id=9931 --- Comment #7 from Martin Nowak <code@dawg.eu> 2013-04-16 17:57:26 PDT --- Seems like OSX deviates from the SysV IA-32 ABI for memory struct returns. The callee does NOT return the hidden pointer in EAX. Instead the caller has to use the value passed as argument. 0x0000267c <D4test3barFZS4test3Foo+20>: call 0x26a0 <foo> 0x00002681 <D4test3barFZS4test3Foo+25>: add $0xc,%esp 0x00002684 <D4test3barFZS4test3Foo+28>: mov %eax,%esi // <- EAX is trashed 0x00002686 <D4test3barFZS4test3Foo+30>: mov -0x4(%ebp),%edi 0x00002689 <D4test3barFZS4test3Foo+33>: movsl %ds:(%esi),%es:(%edi) 0x0000268a <D4test3barFZS4test3Foo+34>: movsl %ds:(%esi),%es:(%edi) 0x0000268b <D4test3barFZS4test3Foo+35>: movsl %ds:(%esi),%es:(%edi) -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: ------- |
April 17, 2013 [Issue 9931] Bus error interfacing with C function returning structs with floats | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jacob Carlborg | http://d.puremagic.com/issues/show_bug.cgi?id=9931 --- Comment #8 from Jacob Carlborg <doob@me.com> 2013-04-16 23:38:53 PDT --- (In reply to comment #7) > Seems like OSX deviates from the SysV IA-32 ABI for memory struct returns. > The callee does NOT return the hidden pointer in EAX. > Instead the caller has to use the value passed as argument. I don't know if this is what you're but the the ABI documentation says: "When a function returns a structure or union larger than 8 bytes, the caller passes a pointer to appropriate storage as the first argument to the function." And: "The called function returns structures according to their aligned size. * Structures 1 or 2 bytes in size are placed in EAX. * Structures 4 or 8 bytes in size are placed in: EAX and EDX. * Structures of other sizes are placed at the address supplied by the caller. For example, the C++ language occasionally forces the compiler to return a value in memory when it would normally be returned in registers. See “Passing Arguments” for more information." http://developer.apple.com/library/mac/#documentation/DeveloperTools/Conceptual/LowLevelABI/130-IA-32_Function_Calling_Conventions/IA32.html#//apple_ref/doc/uid/TP40002492-SW4 -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: ------- |
April 17, 2013 [Issue 9931] Bus error interfacing with C function returning structs with floats | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jacob Carlborg | http://d.puremagic.com/issues/show_bug.cgi?id=9931 John Colvin <john.loughran.colvin@gmail.com> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |john.loughran.colvin@gmail. | |com --- Comment #9 from John Colvin <john.loughran.colvin@gmail.com> 2013-04-17 08:04:52 BST --- (In reply to comment #7) > 0x0000267c <D4test3barFZS4test3Foo+20>: call 0x26a0 <foo> > 0x00002681 <D4test3barFZS4test3Foo+25>: add $0xc,%esp > 0x00002684 <D4test3barFZS4test3Foo+28>: mov %eax,%esi // <- EAX is trashed > 0x00002686 <D4test3barFZS4test3Foo+30>: mov -0x4(%ebp),%edi > 0x00002689 <D4test3barFZS4test3Foo+33>: movsl %ds:(%esi),%es:(%edi) > 0x0000268a <D4test3barFZS4test3Foo+34>: movsl %ds:(%esi),%es:(%edi) > 0x0000268b <D4test3barFZS4test3Foo+35>: movsl %ds:(%esi),%es:(%edi) You're reading it the wrong way around, at&t is src,des -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: ------- |
Copyright © 1999-2021 by the D Language Foundation