www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Segfault in shared object when writeln

reply "Harpo" <roederharpo hushmail.com> writes:
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
Jun 03 2014
parent reply "ed" <gmail gmail.com> writes:
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 Cheers, ed Cheers, ed
Jun 03 2014
parent reply "ed" <gmail gmail.com> writes:
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 Cheers, ed Cheers, ed
I just remembered you can do this on the C side, which is easier to manage Cheers, ed
Jun 03 2014
parent "Harpo" <roederharpo hushmail.com> writes:
Thanks! that was perfect.
-Harpo
Jun 03 2014