gbatt
gbatt

Reputation: 63

CGo segfault when returning C.CString

I am trying to call a Go function from C code, but I encountered a issue which I can't really explain:

C:

char * ret; 
CheckDpkgInfo(&ret);
printf("%s", ret);

Go:

func CheckDpkgInfo(dpkg_c **C.char) { 
*dpkg_c = C.CString("whatever")
}

This works, but not when I simply return a c string from Go (segfault):

C:

char * ret = CheckDpkgInfo();
printf("%s", ret);

Go:

func CheckDpkgInfo() *C.char { 
return C.CString("whatever") 
}

If I understood the documentation correctly CString should call malloc, therefore I really don't get why the printf segfaults. Thanks!

Upvotes: 3

Views: 508

Answers (1)

peterSO
peterSO

Reputation: 166598

I am trying to call a Go function from C code.

What exactly is your issue?


For example, this works,

Output:

$ go version
go version devel +5e514b76e2 Tue Oct 1 00:02:11 2019 +0000 linux/amd64
$ gcc --version
gcc (Ubuntu 7.4.0-1ubuntu1~18.04.1) 7.4.0
$ go build -buildmode=c-archive -o cstr.a cstr.go
$ gcc -pthread -o cstr cstr.c cstr.a
$ ./cstr
ret = 0x5600ca344390
whatever
$ echo $?
0
$ 

cstr.go:

package main

/*
 */
import "C"

//export CheckDpkgInfo
func CheckDpkgInfo() *C.char {
    return C.CString("whatever")
}

func main() {}

cstr.c:

#include "cstr.h"
#include <stdlib.h>
#include <stdio.h>

int main() {
    char * ret = CheckDpkgInfo();
    printf("ret = %p\n", ret);
    if (!ret) {
        return 1;
    }
    printf("%s\n", ret);
    free(ret);
    return 0;
}

Reference: Command cgo


Solution:

Comment: Even the minimal example caused a segfault, but it was due to the fact that I build the application in a Docker container, while preparing the c-archive outside. So it came down to a compatibility issue. – gbatt

Upvotes: 2

Related Questions