JIT resolves CRT symbols from msvcrt.dll instead of ucrtbase on MS-Windows #803
Issue DescriptionOn Windows, jank's JIT resolves C standard library symbols ( This is caused by an issue in LLVM's DynamicLibrary symbol resolution, I just reported at llvm/llvm-project#200554. Some background: Windows has two C runtimes - msvcrt (legacy, used internally by system DLLs like advapi32) and ucrtbase (modern, what MSYS2 CLANG64 binaries link against). Their internal structures (e.g. This doesn't currently manifest in jank because no existing core function passes a Reproduction StepsSave as (cpp/raw "
#include <windows.h>
#include <cstdio>
namespace crt_cross {
using fwrite_fn = size_t (*)(const void*, size_t, size_t, FILE*);
// Returns the binary's fwrite (ucrtbase), not the JIT's (msvcrt)
fwrite_fn get_binary_fwrite() {
HMODULE exe = GetModuleHandleA(nullptr);
auto fn = (fwrite_fn)GetProcAddress(exe, \"fwrite\");
if (!fn) {
HMODULE ucrt = GetModuleHandleA(\"ucrtbase.dll\");
fn = (fwrite_fn)GetProcAddress(ucrt, \"fwrite\");
}
return fn;
}
// Creates a FILE* via JIT-resolved tmpfile (resolves from msvcrt)
FILE* jit_tmpfile() { return tmpfile(); }
// Writes using JIT-resolved fwrite (same CRT as tmpfile - msvcrt)
int jit_write(FILE* f) { return (int)fwrite(\"hello\", 1, 5, f); }
// Writes using the binary's fwrite (ucrtbase) - crashes on msvcrt FILE*
int binary_write(FILE* f) {
auto fn = get_binary_fwrite();
if (!fn) return -1;
return (int)fn(\"hello\", 1, 5, f);
}
void jit_close(FILE* f) { if (f) fclose(f); }
}
")
;; PASS: JIT FILE* + JIT fwrite (same CRT, works)
(let [^cpp/FILE* f (cpp/crt_cross.jit_tmpfile)]
(let [n (cpp/crt_cross.jit_write f)]
(cpp/crt_cross.jit_close f)
(println (str "same-CRT write: " n " bytes"))))
;; This crashes: JIT FILE* + binary fwrite (cross CRT)
(println "cross-CRT write...")
(let [^cpp/FILE* f (cpp/crt_cross.jit_tmpfile)]
(let [n (cpp/crt_cross.binary_write f)]
(cpp/crt_cross.jit_close f)
(println (str "cross-CRT write: " n " bytes"))))The same CRT write passes (both msvcrt.dll is always present because the MinGW/CLANG64 linker links Possible options I can think of:
My preference is option 1, since we don't know how long it might take for the LLVM issue to gain traction, let alone be fixed. jank health checkStack traceOS Version InformationMS-Windows 11 I acknowledge that:
|
Replies: 1 comment 1 reply
|
Opened jank-lang/CppInterOp#4 to address the issue. |
Updated jank to pickup CppInterOp change with #810.