www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Can't figure out segfault

reply rm <xenomorph64 gmail.com> writes:
I put together bindings for DevIL in D to use on a school assignment.  The
bindings (attached) work fine on Windows, but cause a segfault on Linux when I
call ilInit.

this can be demonstrated by a little test program

"
import graphics.bindings.devil;

public void main(string[] args)
{
   ilInit();
}
"
compiled with "dmd -L-ldl test.d devil.d" where test.d is the above program
and devil.d is attached.

When run, this program segfaults, but if lines 112,113,165,166 of devil.d are
commented out, the program works fine, and I can't figure out what the problem
with those lines is.  The fact that this works on Windows confuses me even more.

Any help would be appreciated.
Mar 01 2011
next sibling parent "Daniel Murphy" <yebblies nospamgmail.com> writes:
Assuming you've checked that dlopen isn't returning null, I can't find the 
source of the error in that code, sorry.

Unsolicited advice:

Is there any reason you're manually loading the dll rather than using an 
import library?

A couple of remarks about the rest of the code:

Generally in D the constants would all be:
enum uint IL_BLAH = BLAH;
rather than immutable.

You can specify attributes such as public and immutable in blocks

public immutable
{
   // lots of constants
}

Or if using enums, the following will have the same effect.

enum : uint
{
   constant1 = value,
   constant2 = value,
}


All of your function pointers are currently thread local, as are the static 
ctor/dtors.
To have them run once rather than once per thread, you should use 'shared 
static this()' and 'shared static ~this()' instead, and mark the function 
pointer variables as __gshared.

In all of the 'pointer = cast(function pointer)dlsym(...);' calls you're 
actually relying on a compiler bug, as you're assigning a 'extern(D) 
something function(args)' to a 'extern(System) something function(args)'.

For shorter, clearer and correct code you could instead use:
blah = cast(typeof(blah))dlsym(...);

You don't need to call std.string.toStringz on string literals, they're 
guaranteed to be null-terminated.

All the function signatures using immutable (void 
function(immutable(char)*), etc) are incorrect.  C or C++ function 
signatures should be using const instead (eg void function(const(char)*) ).

I really suggest using an import library if possible. 
Mar 02 2011
prev sibling parent Mike Wey <mike-wey example.com> writes:
On 03/02/2011 01:49 AM, rm wrote:
 I put together bindings for DevIL in D to use on a school assignment.  The
 bindings (attached) work fine on Windows, but cause a segfault on Linux when I
 call ilInit.

 this can be demonstrated by a little test program

 "
 import graphics.bindings.devil;

 public void main(string[] args)
 {
     ilInit();
 }
 "
 compiled with "dmd -L-ldl test.d devil.d" where test.d is the above program
 and devil.d is attached.

 When run, this program segfaults, but if lines 112,113,165,166 of devil.d are
 commented out, the program works fine, and I can't figure out what the problem
 with those lines is.  The fact that this works on Windows confuses me even
more.

 Any help would be appreciated.

On linux the linker is called with --export-dynamic by default and this tells the linker to export all the symbols pressent in your executable. So it is posible that dlsym is returning the address of the symbols in your execuable. Thunderbird is having some problems with your attachment so i'm not able to test, but renaming the functions should do the trick. -- Mike Wey
Mar 02 2011