ocaml / flexdll

a dlopen-like API for Windows
Other
97 stars 30 forks source link

Fail to find a function in the executable (pg_query) #132

Open F-Loyer opened 5 months ago

F-Loyer commented 5 months ago

When compiling pg_query on Windows (patched to make it compiled), I have a pg_check command which fails:

Fatal error: exception Dl.DL_error("dlsym: no such symbol: \"pg_query_parse\"")

However, the pg_query_parse symbol is available:

$nm /cygdrive/c/Users/frede/AppData/Local/opam/default/bin/pg_check|grep pg_query_parse
00000001400c61c0 T pg_query_parse
00000001400c6250 T pg_query_parse_opts
00000001400c62e0 T pg_query_parse_protobuf
00000001400c6350 T pg_query_parse_protobuf_opts

Note, the pg_query library is based on ctypes.foreign. Then the issue may appear in other libraries.

F-Loyer commented 5 months ago

I have found the objdump -tT which find many symbols including the needed pg_query_parse, but none exported in the dynamic table.

dra27 commented 4 months ago

Lack of time I'm afraid means that FlexDLL issues can be very long-burning - please do try to include full reproductions with issues (i.e. concrete links to branches and instructions to build them) so that when we do get spare minutes to have a look, they're not all spent just trying to reproduce the issue!

This is possibly a shot in the dark, but this is ringing a bell with symbols not being properly available because they're not being referenced - @jonahbeckford, does this look like a familiar type of failure?

dra27 commented 4 months ago

Ah - https://github.com/ocaml/ocaml/issues/12412 was what I was thinking of, but that's MSVC and I don't think should be applying here (assuming you're using mingw-w64).

jonahbeckford commented 4 months ago

As David asked, are you compiling with MSVC or GCC?

Either way, pasting in the first 10 lines of ocamlobjinfo pg_check.cmxa may help. (Or .cma if you created a bytecode executable)

F-Loyer commented 4 months ago

I am trying with Cygwin/MinGW. (On MSVC, even a simple (run %{make} build) is troublesome: not found) Instead of the whole pg_query, I propose this tiny project which spots the actual issue.

https://github.com/F-Loyer/ctype_error

On Windows, there are 2 symbol tables the (normal) SYMBOL TABLE and the DYNAMIC SYMBOL TABLE. By default the linker put symbols only in the SYMBOL TABLE, the DYNAMIC SYMBOL TABLE remains empty. However, the ffi library searches symbols in this latest table. Then, this can't work.

See https://github.com/F-Loyer/ctype_error/blob/main/main_objdump.txt#L10406 The function my_function is present, but not in the right table and FFI can't see it.

I have managed to solve the issue with the executable link flags of dune (the commented line in the project), with:

(link_flags -cclib -Wl,-Wl,--export-all-symbols)

I guess the default configuration should work without this tweak. (Note, I had to double the -Wl... perhaps one is eaten by gcc, the other by FlexDll or something like this).

Note: the ffi-7.dll I use comes from a Gtk installation from sources. I don't know if there is an official version I should prefer. EDIT: Same issue with a ffi-8.dll from vcpkg.

(Since pg_check and my project are executable - not libraries - no cmxa, but the issue is not there I think)

Note, the external __my_function__ : unit -> unit = "my_function" is to for the given function to be linked... the linker links all .o, but select from an .a what seems to be (statically) used.