Thread overview
SEGFAULT when converting C string to string
Mar 18, 2019
DFTW
Mar 18, 2019
H. S. Teoh
Mar 18, 2019
DFTW
March 18, 2019
I'm writing a shared library in C to be used from a C program, so I went to my small tests. That one failed give a SEGFAULT on the std.conv.to call.

This is the pice of D code/the library:

extern(C) int foo(const char *name, int age)
{
    import core.stdc.stdio : printf;
    import core.stdc.stdlib;
    import std.conv : to;
    printf("printf() got called! age = %d\n", age);
    printf("name = [%s]\n", name);
    //auto nm = to!string(name); // <-- everything works until I uncomment this line.
    return age * 2;
}

if matters, compiled with dub: "targetType" : "dynamicLibrary"
on 64-bit machine.

This is the piece of C code, foo.c:

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

int main(void)
{
  printf("+main();\n");
  const char* libpath = "mylib.so";
  void *lh = dlopen(libpath, RTLD_LAZY);
  if(!lh) {
    fprintf(stderr, "dlopen error: %s\n", dlerror());
    return EXIT_FAILURE;
  }

  int (*fn)(const char*, int) = dlsym(lh, "foo");
  char *err = dlerror();
  if(err) {
    fprintf(stderr, "dlsym error: %s\n", err);
    return EXIT_FAILURE;
  }
  const char *name = "jhon";
  int age = 18;
  int result = (*fn)(name, age);
  printf("unloading lib");
  dlclose(lh);
  printf("result = %d\n", result);
  printf("-main()\n");
  return 0;
}

compile as:

gcc foo.c -ldl

My OS is Ubuntu version 18

I'm assuming const char* both in C and D are raw pointers.

March 18, 2019
On Mon, Mar 18, 2019 at 10:20:35PM +0000, DFTW via Digitalmars-d-learn wrote:
> I'm writing a shared library in C to be used from a C program, so I went to my small tests. That one failed give a SEGFAULT on the std.conv.to call.
> 
> This is the pice of D code/the library:
> 
> extern(C) int foo(const char *name, int age)
> {
>     import core.stdc.stdio : printf;
>     import core.stdc.stdlib;
>     import std.conv : to;
>     printf("printf() got called! age = %d\n", age);
>     printf("name = [%s]\n", name);
>     //auto nm = to!string(name); // <-- everything works until I uncomment
> this line.
>     return age * 2;
> }
[...]

Most likely explanation: you failed to call rt_init() before using a language feature that requires druntime to be initialized. In this case, a GC allocation by std.conv.to!string.

Call rt_init() immediately after loading the library, and calling
rt_term() after you're done with it, should fix this problem.


T

-- 
Talk is cheap. Whining is actually free. -- Lars Wirzenius
March 18, 2019
On Monday, 18 March 2019 at 22:33:21 UTC, H. S. Teoh wrote:
> On Mon, Mar 18, 2019 at 10:20:35PM +0000, DFTW via Digitalmars-d-learn wrote:
>> [...]
> [...]
>
> Most likely explanation: you failed to call rt_init() before using a language feature that requires druntime to be initialized. In this case, a GC allocation by std.conv.to!string.
>
> Call rt_init() immediately after loading the library, and calling
> rt_term() after you're done with it, should fix this problem.
>
>
> T

That's right. From the small code samples I've seen, they had no rt_init() usage, so I wasn't aware I've had to call it.
Thanks!