www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Bus error on 32bit OSX, not 64bit

reply Jacob Carlborg <doob me.com> writes:
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 store the return value of "fp" in "foo" in a temporary variable and 
then return it

DMD 2.062
Mac OS X 10.8.2

-- 
/Jacob Carlborg
Apr 14 2013
next sibling parent reply "Peter Alexander" <peter.alexander.au gmail.com> writes:
On Sunday, 14 April 2013 at 14:48:40 UTC, Jacob Carlborg wrote:
 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 store the return value of "fp" in "foo" in a temporary 
 variable and then return it

 DMD 2.062
 Mac OS X 10.8.2

http://d.puremagic.com/issues/enter_bug.cgi
Apr 14 2013
parent Jacob Carlborg <doob me.com> writes:
On 2013-04-14 17:13, Peter Alexander wrote:

 http://d.puremagic.com/issues/enter_bug.cgi

I was hoping someone would have an idea what's wrong so I can create a proper bugzilla entry. Filed an issue anyway: http://d.puremagic.com/issues/show_bug.cgi?id=9931 -- /Jacob Carlborg
Apr 14 2013
prev sibling next sibling parent reply "John Colvin" <john.loughran.colvin gmail.com> writes:
On Sunday, 14 April 2013 at 14:48:40 UTC, Jacob Carlborg wrote:
 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 store the return value of "fp" in "foo" in a temporary 
 variable and then return it

 DMD 2.062
 Mac OS X 10.8.2

Have you tried any debugging? Disassembly? It's quite hard for me (or anyone else for that matter) to diagnose when it's not a separately compilable example and there's no extra info.
Apr 14 2013
parent reply Jacob Carlborg <doob me.com> writes:
On 2013-04-14 19:12, John Colvin wrote:

 Have you tried any debugging? Disassembly? It's quite hard for me (or
 anyone else for that matter) to diagnose when it's not a separately
 compilable example and there's no extra info.

This is the dissassembly for the 64bit version: http://pastebin.com/L30u3tMu 32bit version: http://pastebin.com/tKVCTeZV This is what Clang produces for basically the same code: http://pastebin.com/JBcNupfs The C code looks like: http://pastebin.com/KS9QwB3A -- /Jacob Carlborg
Apr 14 2013
parent reply Jacob Carlborg <doob me.com> writes:
On 2013-04-14 23:55, John Colvin wrote:

 That's a start. The relative offsets are missing from the calls though
 (I think), which makes it rather hard to decipher. What are you using to
 disassemble? "objdump -M intel -dr file.o" will give you more info. It's
 the standard linux tool for the job, available from macports.

Ok, I used obj2asm.
 Also, it would be good if you ran it with gdb, when it bus errors type
 'disas' and post that. Then we'd be able to see what instruction it's
 occurring at (hopefully).

Ok, I'll do that. I just tried the same example on Mac OS X 10.6.3 and it runs fine. The assembly is basically the same. I wasn't able to install objdump, I'll try again tonight. This what otool gives: http://pastebin.com/N8hMiKDe This is the man page for otool, if there any particular flags you want me to use: http://developer.apple.com/library/mac/#documentation/Darwin/Reference/ManPages/man1/otool.1.html -- /Jacob Carlborg
Apr 15 2013
parent Jacob Carlborg <doob me.com> writes:
On 2013-04-15 16:34, John Colvin wrote:

 That otool output is missing foo. Other than that the flags you're using
 are fine.

Hmm, I don't know why it didn't output "foo". This is the output from the executable: http://pastebin.com/yJEpHaDH The previous ones were from the object file. -- /Jacob Carlborg
Apr 15 2013
prev sibling next sibling parent "John Colvin" <john.loughran.colvin gmail.com> writes:
On Sunday, 14 April 2013 at 18:50:52 UTC, Jacob Carlborg wrote:
 On 2013-04-14 19:12, John Colvin wrote:

 Have you tried any debugging? Disassembly? It's quite hard for 
 me (or
 anyone else for that matter) to diagnose when it's not a 
 separately
 compilable example and there's no extra info.

This is the dissassembly for the 64bit version: http://pastebin.com/L30u3tMu 32bit version: http://pastebin.com/tKVCTeZV This is what Clang produces for basically the same code: http://pastebin.com/JBcNupfs The C code looks like: http://pastebin.com/KS9QwB3A

That's a start. The relative offsets are missing from the calls though (I think), which makes it rather hard to decipher. What are you using to disassemble? "objdump -M intel -dr file.o" will give you more info. It's the standard linux tool for the job, available from macports. Also, it would be good if you ran it with gdb, when it bus errors type 'disas' and post that. Then we'd be able to see what instruction it's occurring at (hopefully).
Apr 14 2013
prev sibling next sibling parent "John Colvin" <john.loughran.colvin gmail.com> writes:
On Monday, 15 April 2013 at 07:22:08 UTC, Jacob Carlborg wrote:
 On 2013-04-14 23:55, John Colvin wrote:

 That's a start. The relative offsets are missing from the 
 calls though
 (I think), which makes it rather hard to decipher. What are 
 you using to
 disassemble? "objdump -M intel -dr file.o" will give you more 
 info. It's
 the standard linux tool for the job, available from macports.

Ok, I used obj2asm.
 Also, it would be good if you ran it with gdb, when it bus 
 errors type
 'disas' and post that. Then we'd be able to see what 
 instruction it's
 occurring at (hopefully).

Ok, I'll do that. I just tried the same example on Mac OS X 10.6.3 and it runs fine. The assembly is basically the same. I wasn't able to install objdump, I'll try again tonight. This what otool gives: http://pastebin.com/N8hMiKDe This is the man page for otool, if there any particular flags you want me to use: http://developer.apple.com/library/mac/#documentation/Darwin/Reference/ManPages/man1/otool.1.html

That otool output is missing foo. Other than that the flags you're using are fine.
Apr 15 2013
prev sibling next sibling parent reply "John Colvin" <john.loughran.colvin gmail.com> writes:
On Sunday, 14 April 2013 at 14:48:40 UTC, Jacob Carlborg wrote:
 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 store the return value of "fp" in "foo" in a temporary 
 variable and then return it

 DMD 2.062
 Mac OS X 10.8.2

Casting a function that returns void to a function that returns something seems bound to cause trouble. While it may be allowed in C It seems a bit of a leap to assume that it would work properly in D.
Apr 15 2013
next sibling parent Jacob Carlborg <doob me.com> writes:
On 2013-04-15 19:56, John Colvin wrote:

 Casting a function that returns void to a function that returns
 something seems bound to cause trouble. While it may be allowed in C It
 seems a bit of a leap to assume that it would work properly in D.

I don't know what to say, this is how you're supposed to call these "objc_msgSend" functions. They part of the Objective-C runtime. In C, if I call it like it's declare, returning void, I get a segfault: NSRect foo (id screen) { NSRect rect; ((void (*)(NSRect*, id, SEL))objc_msgSend_stret)(&rect, screen, sel_registerName("visibleFrame")); return rect; } Don't ask me why it works like this. -- /Jacob Carlborg
Apr 15 2013
prev sibling parent Jacob Carlborg <doob me.com> writes:
On 2013-04-15 19:56, John Colvin wrote:

 Casting a function that returns void to a function that returns
 something seems bound to cause trouble. While it may be allowed in C It
 seems a bit of a leap to assume that it would work properly in D.

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 -- /Jacob Carlborg
Apr 16 2013
prev sibling parent Jacob Carlborg <doob me.com> writes:
On 2013-04-14 16:48, Jacob Carlborg wrote:
 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 store the return value of "fp" in "foo" in a temporary variable and
 then return it

 DMD 2.062
 Mac OS X 10.8.2

I think this problem is the same: http://forum.dlang.org/thread/kkk8kh$2jsu$1 digitalmars.com This is without all the casts and Objective-C runtime functions. -- /Jacob Carlborg
Apr 16 2013