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);
    }
    
    
    
    Run

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)
    
    
    Run

Reply via email to