exaloop / codon

A high-performance, zero-overhead, extensible Python compiler using LLVM
https://docs.exaloop.io/codon
Other
15.01k stars 517 forks source link

Shared Library dlopen() SIGSEGV #452

Open Kasuax opened 1 year ago

Kasuax commented 1 year ago

[OL8 Red Hat Enterprise Linux release 8.6] [GCC 8.5.0] [Codon Prebuild 0.16.3]

I am able to link my libfoo.so into my application if I wire it up during compile with gcc and provide the appropriate extern "C" prototype; however, I'm unable to properly dynamically load my codon foo librarie on Centos7 or Oracle Linux 8. Just focusing on OL8 for now because I get the same error.

Garbage collector freaks out during debug dlopen() call => SIGSEGV. If I run release it crashes calling the function.

The following is what I'm working with. Please let me know if I'm being short sighted somewhere.

foo.codon

@export
def foo(n: int):
    for i in range(n):
        print(i * i)
    return n * n

main.cpp

#include <stdint.h>
#include <stdio.h>
#include <dlfcn.h>
#include <iostream>

typedef int64_t (*FunctionType)(int64_t);

//extern "C" int64_t foo(int64_t);

int main() {

    //std::cout << "Running SL Function! " << (void*)&foo << "\n";

    //foo(10);

    void* libraryHandle = dlopen("libfoo.so", RTLD_LAZY);

    if (!libraryHandle) {
        std::cout << "Error loading library: " << dlerror() << std::endl;
        return 1;
    }

    void* funcHandle = dlsym(libraryHandle, "foo");

    if (!funcHandle) {
        std::cout << "Error loading function: " << dlerror() << std::endl;
        dlclose(libraryHandle);
        return 1;
    }

    std::cout << "Running DL Function! " << funcHandle << "\n";

    FunctionType* f = reinterpret_cast<FunctionType*>(funcHandle);

    (*f)(10);

    dlclose(libraryHandle);

    return 0;
}

build.sh

#!/bin/bash

LD_LIBRARY_PATH=$(pwd):~/.codon/lib/codon:$LD_LIBRARY_PATH

codon build --relocation-model=pic --lib --debug --debug-entry-values --debugger-tune=gdb -o libfoo.so foo.codon

#gcc -o foo -L. -ldl -lfoo -lstdc++ main.cpp -Wl,-rpath=$(pwd)
gcc -g -o foo -ldl -lstdc++ main.cpp

./foo

Stack Trace

1  GC_find_limit_with_bound               0x7ffff68d7712 
2  GC_init_linux_data_start               0x7ffff68d7530 
3  GC_init                                0x7ffff68d571d 
4  GC_generic_malloc_inner                0x7ffff68e1bc5 
5  GC_generic_malloc                      0x7ffff68e1f4d 
6  GC_malloc_kind_global                  0x7ffff68e21b1 
7  .main.unclash                          0x7ffff6cd1420 
8  .main.ctor                             0x7ffff6cd14aa 
9  call_init                dl-init.c 72  0x7ffff7de3e1a 
10 call_init                dl-init.c 30  0x7ffff7de3f1a 
11 _dl_init                 dl-init.c 119 0x7ffff7de3f1a 
12 _dl_catch_exception                    0x7ffff75db1ec 
13 dl_open_worker           dl-open.c 819 0x7ffff7de7b3e 
14 dl_open_worker           dl-open.c 782 0x7ffff7de7b3e 
15 _dl_catch_exception                    0x7ffff75db194 
16 _dl_open                 dl-open.c 900 0x7ffff7de7d21 
17 dlopen_doit                            0x7ffff7bcc1ea 
18 _dl_catch_exception                    0x7ffff75db194 
19 _dl_catch_error                        0x7ffff75db253 
20 _dlerror_run                           0x7ffff7bcc969 
21 dlopen * *GLIBC_2.2.5                  0x7ffff7bcc28a 
22 main                                   0x4009ce

ldd

[dev@localhost codon_test]$ ldd libfoo.so 
    linux-vdso.so.1 (0x00007f543de2e000)
    libcodonrt.so => /home/dev/.codon/lib/codon/libcodonrt.so (0x00007f543d518000)
    libomp.so => /home/dev/.codon/lib/codon/libomp.so (0x00007f543dd3f000)
    libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f543d2f8000)
    libdl.so.2 => /lib64/libdl.so.2 (0x00007f543d0f4000)
    libz.so.1 => /lib64/libz.so.1 (0x00007f543cedc000)
    libstdc++.so.6 => /lib64/libstdc++.so.6 (0x00007f543cb47000)
    libm.so.6 => /lib64/libm.so.6 (0x00007f543c7c5000)
    libc.so.6 => /lib64/libc.so.6 (0x00007f543c400000)
    libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007f543c1e7000)
    librt.so.1 => /lib64/librt.so.1 (0x00007f543bfdf000)
    /lib64/ld-linux-x86-64.so.2 (0x00007f543dc03000)

objdump libfoo.so -T | grep foo

0000000000005290 g    DF .text  000000000000007c  Base        foo

gdb debug

[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".
Core was generated by `./foo'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0  0x0000000000400ab2 in main () at main.cpp:35
35      (*f)(10);
[Current thread is 1 (Thread 0x7fb0694b2740 (LWP 133352))]
arshajii commented 1 year ago

Hi @Kasuax -- out of curiosity, does this work if you link it directly instead of using dlopen()? Want to see if it's an issue with dynamic loading...

Kasuax commented 1 year ago

You are correct! If I link the library during compile with gcc by specifying -L and -lfoo then manually define the extern "C" it all works as advertised.

SovereignSteve commented 3 weeks ago

Out of curiosity, has there been any resolution yet with this? Thank you!