I've been scratching my head solving a SIGSEGV on my machine when using futhark. I've reduced the problem to a self contained Nim and C files with no external nim packages involved, just plain C linkage.
The C program compiles and runs correctly, the Nim program goes SIGSEGV while calling C function, but they should be almost 1:1, can you help me track down the problem?
The program should link with -lclang. I've reproduced the problem on libclang-10, libclang-11, libclang-12, both gclib and musl, so the problem must be somewhere on the nim side.
You can find dockerfiles for reproducible builds and Makefile here: https://github.com/arkanoid87/futhest
futhest.c
#include "clang-c/Index.h"
int main (void) {
CXIndex Idx = clang_createIndex(0, 0);
const int args = 2;
const char *commandLineArgs[args];
commandLineArgs[0] = "-I/usr/lib/clang/10/include";
commandLineArgs[1] = "-I/usr/include";
CXTranslationUnit TU = clang_parseTranslationUnit(Idx,
"futhark-includes.h", commandLineArgs, args, 0, 0, 0);
CXCursor cursor = clang_getTranslationUnitCursor(TU);
clang_disposeTranslationUnit(TU);
}
futhest.nim
type
CXIndex = pointer
CXTranslationUnit = pointer
CXCursor = pointer
#[
CINDEX_LINKAGE CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
int displayDiagnostics);
]#
proc createIndex*(excludeDeclarationsFromPCH: cint; displayDiagnostics: cint): CXIndex {.
importc: "clang_createIndex", cdecl.}
#[
CINDEX_LINKAGE CXTranslationUnit
clang_parseTranslationUnit(CXIndex CIdx,
const char *source_filename,
const char *const *command_line_args,
int num_command_line_args,
struct CXUnsavedFile *unsaved_files,
unsigned num_unsaved_files,
unsigned options);
]#
proc parseTranslationUnit*(CIdx: CXIndex; source_filename: cstring;
command_line_args: cstringArray;
num_command_line_args: cint;
unsaved_files: pointer;
num_unsaved_files: cuint; options: cuint): CXTranslationUnit {.
importc: "clang_parseTranslationUnit", cdecl.}
#[
CINDEX_LINKAGE CXCursor clang_getTranslationUnitCursor(CXTranslationUnit);
]#
proc getTranslationUnitCursor*(a1: CXTranslationUnit): CXCursor {.
importc: "clang_getTranslationUnitCursor", cdecl.}
#[
CINDEX_LINKAGE void clang_disposeTranslationUnit(CXTranslationUnit);
]#
proc disposeTranslationUnit*(a1: CXTranslationUnit) {.importc: "clang_disposeTranslationUnit", cdecl.}
# ----------------------------------------------------------------------------
static:
# any content will fail, including empty file
writeFile("futhark-includes.h", """
#include "ldap.h"
""")
var
commandLineParams = @[
"-I/usr/lib/clang/10/include",
"-I/usr/include"]
index = createIndex(0, 0)
commandLineArgs = allocCStringArray(commandLineParams)
var unit = parseTranslationUnit(index,
"futhark-includes.h".cstring,
commandLineArgs, commandLineParams.len.cint, nil, 0, 0)
deallocCStringArray(commandLineArgs)
var cursor = getTranslationUnitCursor(unit) # SIGSEGV
disposeTranslationUnit(unit)
actually I did try this before, but I forgot to clean the cache after switching with choosenim