Thread overview
Segfault in shared object when writeln
Jun 04, 2014
Harpo
Jun 04, 2014
ed
Jun 04, 2014
ed
Jun 04, 2014
Harpo
June 04, 2014
Hello I am having the following problem. I am trying to turn a program I have written into a shared object. I have ran into some problems however. When I use writeln instead of printf my program segfaults. I have edited the code to just the parts causing the problem.

=================main.d the so========================

import std.stdio;
import core.stdc.stdio;

extern (C) void main(){
 	writeln("Does it work?");
	printf("Works");
}

==============main.c the main executable======================

#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>

int main() {
  printf("+main()\n");

  void *lh = dlopen("THE PATH EDITED FOR MY SECURITY", RTLD_LAZY);
  if (!lh) {
    fprintf(stderr, "dlopen error: %s\n", dlerror());
    exit(1);
  }
  printf("libdll.so is loaded\n");

  void (*fn)() = dlsym(lh, "main");
  char *error = dlerror();
  if (error) {
    fprintf(stderr, "dlsym error: %s\n", error);
    exit(1);
  }
  printf("dll() function is found\n");
  (*fn)();

  printf("unloading libdll.so\n");
  dlclose(lh);

  printf("-main()\n");
  return 0;
}

========================The compile script===============

dmd -c main.d -fPIC

dmd -oflibdll.so main.o -shared -defaultlib=libphobos2.so -L-rpath=/usr/lib/x86_64-linux-gnu -L-ldl -gc

gcc -c main.c
gcc -rdynamic main.o -o main -ldl

=====================================================================
When I have just printf is works. When I have writeln it segfaults.

This fails

import std.stdio;

extern (C) void main(){
 	writeln("Does it work?");
}

This works

import core.stdc.stdio;

extern (C) void main(){
	printf("Works");
}

===========================================================================

Any one know whats up? Thanks!
-Harpo


June 04, 2014
On Wednesday, 4 June 2014 at 03:49:25 UTC, Harpo wrote:
> Hello I am having the following problem. I am trying to turn a program I have written into a shared object. I have ran into some problems however. When I use writeln instead of printf my program segfaults. I have edited the code to just the parts causing the problem.
>
> =================main.d the so========================
>
> import std.stdio;
> import core.stdc.stdio;
>
> extern (C) void main(){
>  	writeln("Does it work?");
> 	printf("Works");
> }
>
> ==============main.c the main executable======================
>
> #include <stdio.h>
> #include <stdlib.h>
> #include <dlfcn.h>
>
> int main() {
>   printf("+main()\n");
>
>   void *lh = dlopen("THE PATH EDITED FOR MY SECURITY", RTLD_LAZY);
>   if (!lh) {
>     fprintf(stderr, "dlopen error: %s\n", dlerror());
>     exit(1);
>   }
>   printf("libdll.so is loaded\n");
>
>   void (*fn)() = dlsym(lh, "main");
>   char *error = dlerror();
>   if (error) {
>     fprintf(stderr, "dlsym error: %s\n", error);
>     exit(1);
>   }
>   printf("dll() function is found\n");
>   (*fn)();
>
>   printf("unloading libdll.so\n");
>   dlclose(lh);
>
>   printf("-main()\n");
>   return 0;
> }
>
> ========================The compile script===============
>
> dmd -c main.d -fPIC
>
> dmd -oflibdll.so main.o -shared -defaultlib=libphobos2.so -L-rpath=/usr/lib/x86_64-linux-gnu -L-ldl -gc
>
> gcc -c main.c
> gcc -rdynamic main.o -o main -ldl
>
> =====================================================================
> When I have just printf is works. When I have writeln it segfaults.
>
> This fails
>
> import std.stdio;
>
> extern (C) void main(){
>  	writeln("Does it work?");
> }
>
> This works
>
> import core.stdc.stdio;
>
> extern (C) void main(){
> 	printf("Works");
> }
>
> ===========================================================================
>
> Any one know whats up? Thanks!
> -Harpo

I believe you need to initialise the D runtime in your D code before using Phobos or druntime itself in this manner. The printf call just wraps the C runtime but writeln requires the D runtime to be initialised.

Check out
http://dlang.org/phobos/core_runtime.html#.Runtime.initialize
http://dlang.org/phobos/core_runtime.html#.Runtime.terminate

Cheers,
ed



Cheers,
ed
June 04, 2014
On Wednesday, 4 June 2014 at 04:46:59 UTC, ed wrote:
> On Wednesday, 4 June 2014 at 03:49:25 UTC, Harpo wrote:
>> Hello I am having the following problem. I am trying to turn a program I have written into a shared object. I have ran into some problems however. When I use writeln instead of printf my program segfaults. I have edited the code to just the parts causing the problem.
>>
>> =================main.d the so========================
>>
>> import std.stdio;
>> import core.stdc.stdio;
>>
>> extern (C) void main(){
>> 	writeln("Does it work?");
>> 	printf("Works");
>> }
>>
>> ==============main.c the main executable======================
>>
>> #include <stdio.h>
>> #include <stdlib.h>
>> #include <dlfcn.h>
>>
>> int main() {
>>  printf("+main()\n");
>>
>>  void *lh = dlopen("THE PATH EDITED FOR MY SECURITY", RTLD_LAZY);
>>  if (!lh) {
>>    fprintf(stderr, "dlopen error: %s\n", dlerror());
>>    exit(1);
>>  }
>>  printf("libdll.so is loaded\n");
>>
>>  void (*fn)() = dlsym(lh, "main");
>>  char *error = dlerror();
>>  if (error) {
>>    fprintf(stderr, "dlsym error: %s\n", error);
>>    exit(1);
>>  }
>>  printf("dll() function is found\n");
>>  (*fn)();
>>
>>  printf("unloading libdll.so\n");
>>  dlclose(lh);
>>
>>  printf("-main()\n");
>>  return 0;
>> }
>>
>> ========================The compile script===============
>>
>> dmd -c main.d -fPIC
>>
>> dmd -oflibdll.so main.o -shared -defaultlib=libphobos2.so -L-rpath=/usr/lib/x86_64-linux-gnu -L-ldl -gc
>>
>> gcc -c main.c
>> gcc -rdynamic main.o -o main -ldl
>>
>> =====================================================================
>> When I have just printf is works. When I have writeln it segfaults.
>>
>> This fails
>>
>> import std.stdio;
>>
>> extern (C) void main(){
>> 	writeln("Does it work?");
>> }
>>
>> This works
>>
>> import core.stdc.stdio;
>>
>> extern (C) void main(){
>> 	printf("Works");
>> }
>>
>> ===========================================================================
>>
>> Any one know whats up? Thanks!
>> -Harpo
>
> I believe you need to initialise the D runtime in your D code before using Phobos or druntime itself in this manner. The printf call just wraps the C runtime but writeln requires the D runtime to be initialised.
>
> Check out
> http://dlang.org/phobos/core_runtime.html#.Runtime.initialize
> http://dlang.org/phobos/core_runtime.html#.Runtime.terminate
>
> Cheers,
> ed
>
>
>
> Cheers,
> ed

I just remembered you can do this on the C side, which is easier to manage

http://dlang.org/phobos/core_runtime.html#.rt_init
http://dlang.org/phobos/core_runtime.html#.rt_term

Cheers,
ed
June 04, 2014
Thanks! that was perfect.
-Harpo