Thread overview
Can't figure out segfault
Mar 02, 2011
rm
Mar 02, 2011
Daniel Murphy
Mar 02, 2011
Mike Wey
March 02, 2011
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.
March 02, 2011
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.


March 02, 2011
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