Fix missing symbol errors and add a test (#14907)

Co-authored-by: Jarred Sumner <jarred@bun.sh>
This commit is contained in:
Jarred Sumner
2024-10-30 19:55:42 -07:00
committed by GitHub
parent 955cc6265b
commit eaa088ba55
6 changed files with 219 additions and 45 deletions

58
.vscode/launch.json generated vendored
View File

@@ -22,6 +22,8 @@
"BUN_GARBAGE_COLLECTOR_LEVEL": "1",
},
"console": "internalConsole",
// Don't pause when the GC runs while the debugger is open.
"postRunCommands": ["process handle -p true -s false -n false SIGUSR1"],
},
{
"type": "lldb",
@@ -37,6 +39,8 @@
"BUN_DEBUG_jest": "1",
},
"console": "internalConsole",
// Don't pause when the GC runs while the debugger is open.
"postRunCommands": ["process handle -p true -s false -n false SIGUSR1"],
},
{
"type": "lldb",
@@ -58,6 +62,8 @@
"BUN_GARBAGE_COLLECTOR_LEVEL": "0",
},
"console": "internalConsole",
// Don't pause when the GC runs while the debugger is open.
"postRunCommands": ["process handle -p true -s false -n false SIGUSR1"],
},
{
"type": "lldb",
@@ -73,6 +79,8 @@
"BUN_GARBAGE_COLLECTOR_LEVEL": "2",
},
"console": "internalConsole",
// Don't pause when the GC runs while the debugger is open.
"postRunCommands": ["process handle -p true -s false -n false SIGUSR1"],
},
{
"type": "lldb",
@@ -88,6 +96,8 @@
"BUN_GARBAGE_COLLECTOR_LEVEL": "2",
},
"console": "internalConsole",
// Don't pause when the GC runs while the debugger is open.
"postRunCommands": ["process handle -p true -s false -n false SIGUSR1"],
},
{
"type": "lldb",
@@ -103,6 +113,8 @@
"BUN_GARBAGE_COLLECTOR_LEVEL": "2",
},
"console": "internalConsole",
// Don't pause when the GC runs while the debugger is open.
"postRunCommands": ["process handle -p true -s false -n false SIGUSR1"],
},
{
"type": "lldb",
@@ -119,6 +131,8 @@
"BUN_INSPECT": "ws://localhost:0/?wait=1",
},
"console": "internalConsole",
// Don't pause when the GC runs while the debugger is open.
"postRunCommands": ["process handle -p true -s false -n false SIGUSR1"],
"serverReadyAction": {
"pattern": "https://debug.bun.sh/#localhost:([0-9]+)/",
"uriFormat": "https://debug.bun.sh/#ws://localhost:%s/",
@@ -140,6 +154,8 @@
"BUN_INSPECT": "ws://localhost:0/?break=1",
},
"console": "internalConsole",
// Don't pause when the GC runs while the debugger is open.
"postRunCommands": ["process handle -p true -s false -n false SIGUSR1"],
"serverReadyAction": {
"pattern": "https://debug.bun.sh/#localhost:([0-9]+)/",
"uriFormat": "https://debug.bun.sh/#ws://localhost:%s/",
@@ -160,6 +176,8 @@
"BUN_GARBAGE_COLLECTOR_LEVEL": "2",
},
"console": "internalConsole",
// Don't pause when the GC runs while the debugger is open.
"postRunCommands": ["process handle -p true -s false -n false SIGUSR1"],
},
{
"type": "lldb",
@@ -178,6 +196,8 @@
"GOMAXPROCS": "1",
},
"console": "internalConsole",
// Don't pause when the GC runs while the debugger is open.
"postRunCommands": ["process handle -p true -s false -n false SIGUSR1"],
},
{
"type": "lldb",
@@ -192,6 +212,8 @@
"BUN_GARBAGE_COLLECTOR_LEVEL": "2",
},
"console": "internalConsole",
// Don't pause when the GC runs while the debugger is open.
"postRunCommands": ["process handle -p true -s false -n false SIGUSR1"],
},
{
"type": "lldb",
@@ -206,6 +228,8 @@
"BUN_GARBAGE_COLLECTOR_LEVEL": "2",
},
"console": "internalConsole",
// Don't pause when the GC runs while the debugger is open.
"postRunCommands": ["process handle -p true -s false -n false SIGUSR1"],
},
{
"type": "lldb",
@@ -220,6 +244,8 @@
"BUN_GARBAGE_COLLECTOR_LEVEL": "2",
},
"console": "internalConsole",
// Don't pause when the GC runs while the debugger is open.
"postRunCommands": ["process handle -p true -s false -n false SIGUSR1"],
},
{
"type": "lldb",
@@ -235,6 +261,8 @@
"BUN_INSPECT": "ws://localhost:0/?wait=1",
},
"console": "internalConsole",
// Don't pause when the GC runs while the debugger is open.
"postRunCommands": ["process handle -p true -s false -n false SIGUSR1"],
"serverReadyAction": {
"pattern": "https://debug.bun.sh/#localhost:([0-9]+)/",
"uriFormat": "https://debug.bun.sh/#ws://localhost:%s/",
@@ -255,6 +283,8 @@
"BUN_INSPECT": "ws://localhost:0/?break=1",
},
"console": "internalConsole",
// Don't pause when the GC runs while the debugger is open.
"postRunCommands": ["process handle -p true -s false -n false SIGUSR1"],
"serverReadyAction": {
"pattern": "https://debug.bun.sh/#localhost:([0-9]+)/",
"uriFormat": "https://debug.bun.sh/#ws://localhost:%s/",
@@ -276,6 +306,8 @@
"BUN_GARBAGE_COLLECTOR_LEVEL": "2",
},
"console": "internalConsole",
// Don't pause when the GC runs while the debugger is open.
"postRunCommands": ["process handle -p true -s false -n false SIGUSR1"],
},
{
"type": "lldb",
@@ -291,6 +323,8 @@
"BUN_GARBAGE_COLLECTOR_LEVEL": "0",
},
"console": "internalConsole",
// Don't pause when the GC runs while the debugger is open.
"postRunCommands": ["process handle -p true -s false -n false SIGUSR1"],
},
{
"type": "lldb",
@@ -306,6 +340,8 @@
"BUN_GARBAGE_COLLECTOR_LEVEL": "2",
},
"console": "internalConsole",
// Don't pause when the GC runs while the debugger is open.
"postRunCommands": ["process handle -p true -s false -n false SIGUSR1"],
},
{
"type": "lldb",
@@ -321,6 +357,8 @@
"BUN_GARBAGE_COLLECTOR_LEVEL": "2",
},
"console": "internalConsole",
// Don't pause when the GC runs while the debugger is open.
"postRunCommands": ["process handle -p true -s false -n false SIGUSR1"],
},
{
"type": "lldb",
@@ -336,6 +374,8 @@
"BUN_GARBAGE_COLLECTOR_LEVEL": "2",
},
"console": "internalConsole",
// Don't pause when the GC runs while the debugger is open.
"postRunCommands": ["process handle -p true -s false -n false SIGUSR1"],
},
{
"type": "lldb",
@@ -352,6 +392,8 @@
"BUN_INSPECT": "ws://localhost:0/?wait=1",
},
"console": "internalConsole",
// Don't pause when the GC runs while the debugger is open.
"postRunCommands": ["process handle -p true -s false -n false SIGUSR1"],
"serverReadyAction": {
"pattern": "https://debug.bun.sh/#localhost:([0-9]+)/",
"uriFormat": "https://debug.bun.sh/#ws://localhost:%s/",
@@ -373,6 +415,8 @@
"BUN_INSPECT": "ws://localhost:0/?break=1",
},
"console": "internalConsole",
// Don't pause when the GC runs while the debugger is open.
"postRunCommands": ["process handle -p true -s false -n false SIGUSR1"],
"serverReadyAction": {
"pattern": "https://debug.bun.sh/#localhost:([0-9]+)/",
"uriFormat": "https://debug.bun.sh/#ws://localhost:%s/",
@@ -393,6 +437,8 @@
"BUN_GARBAGE_COLLECTOR_LEVEL": "2",
},
"console": "internalConsole",
// Don't pause when the GC runs while the debugger is open.
"postRunCommands": ["process handle -p true -s false -n false SIGUSR1"],
},
// bun test [*]
{
@@ -408,6 +454,8 @@
"BUN_GARBAGE_COLLECTOR_LEVEL": "2",
},
"console": "internalConsole",
// Don't pause when the GC runs while the debugger is open.
"postRunCommands": ["process handle -p true -s false -n false SIGUSR1"],
},
{
"type": "lldb",
@@ -422,6 +470,8 @@
"BUN_GARBAGE_COLLECTOR_LEVEL": "0",
},
"console": "internalConsole",
// Don't pause when the GC runs while the debugger is open.
"postRunCommands": ["process handle -p true -s false -n false SIGUSR1"],
},
{
"type": "lldb",
@@ -437,6 +487,8 @@
"BUN_INSPECT": "ws://localhost:0/",
},
"console": "internalConsole",
// Don't pause when the GC runs while the debugger is open.
"postRunCommands": ["process handle -p true -s false -n false SIGUSR1"],
"serverReadyAction": {
"pattern": "https://debug.bun.sh/#localhost:([0-9]+)/",
"uriFormat": "https://debug.bun.sh/#ws://localhost:%s/",
@@ -456,6 +508,8 @@
"BUN_GARBAGE_COLLECTOR_LEVEL": "2",
},
"console": "internalConsole",
// Don't pause when the GC runs while the debugger is open.
"postRunCommands": ["process handle -p true -s false -n false SIGUSR1"],
},
{
"type": "lldb",
@@ -470,6 +524,8 @@
"BUN_GARBAGE_COLLECTOR_LEVEL": "2",
},
"console": "internalConsole",
// Don't pause when the GC runs while the debugger is open.
"postRunCommands": ["process handle -p true -s false -n false SIGUSR1"],
},
// Windows: bun test [file]
{
@@ -1182,6 +1238,8 @@
},
],
"console": "internalConsole",
// Don't pause when the GC runs while the debugger is open.
"postRunCommands": ["process handle -p true -s false -n false SIGUSR1"],
},
],
"inputs": [

View File

@@ -482,13 +482,16 @@ endif()
set(BUN_ZIG_OUTPUT ${BUILD_PATH}/bun-zig.o)
if(CMAKE_SYSTEM_PROCESSOR MATCHES "arm|ARM|arm64|ARM64|aarch64|AARCH64")
set(IS_ARM64 ON)
if(APPLE)
set(ZIG_CPU "apple_m1")
else()
set(ZIG_CPU "native")
endif()
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64|X86_64|x64|X64|amd64|AMD64")
set(IS_X86_64 ON)
if(ENABLE_BASELINE)
set(ZIG_CPU "nehalem")
else()
@@ -846,6 +849,29 @@ else()
set(LLD_NAME lld-${LLVM_VERSION_MAJOR})
endif()
if (IS_ARM64)
set(ARCH_WRAP_FLAGS
-Wl,--wrap=fcntl64
-Wl,--wrap=statx
)
elseif(IS_X86_64)
set(ARCH_WRAP_FLAGS
-Wl,--wrap=fcntl
-Wl,--wrap=fcntl64
-Wl,--wrap=fstat
-Wl,--wrap=fstat64
-Wl,--wrap=fstatat
-Wl,--wrap=fstatat64
-Wl,--wrap=lstat
-Wl,--wrap=lstat64
-Wl,--wrap=mknod
-Wl,--wrap=mknodat
-Wl,--wrap=stat
-Wl,--wrap=stat64
-Wl,--wrap=statx
)
endif()
target_link_options(${bun} PUBLIC
-fuse-ld=${LLD_NAME}
-fno-pic
@@ -856,32 +882,21 @@ else()
-Wl,--as-needed
-Wl,--gc-sections
-Wl,-z,stack-size=12800000
${ARCH_WRAP_FLAGS}
-Wl,--wrap=cosf
-Wl,--wrap=exp
-Wl,--wrap=expf
-Wl,--wrap=fcntl
-Wl,--wrap=fcntl64
-Wl,--wrap=fmod
-Wl,--wrap=fmodf
-Wl,--wrap=fstat
-Wl,--wrap=fstat64
-Wl,--wrap=fstatat
-Wl,--wrap=fstatat64
-Wl,--wrap=log
-Wl,--wrap=log10f
-Wl,--wrap=log2
-Wl,--wrap=log2f
-Wl,--wrap=logf
-Wl,--wrap=lstat
-Wl,--wrap=lstat64
-Wl,--wrap=mknod
-Wl,--wrap=mknodat
-Wl,--wrap=pow
-Wl,--wrap=powf
-Wl,--wrap=sincosf
-Wl,--wrap=sinf
-Wl,--wrap=stat
-Wl,--wrap=stat64
-Wl,--wrap=statx
-Wl,--wrap=tanf
-Wl,--compress-debug-sections=zlib
-Wl,-z,lazy

View File

@@ -113,6 +113,9 @@ struct us_loop_t *us_timer_loop(struct us_timer_t *t) {
#if defined(LIBUS_USE_EPOLL)
#include <sys/syscall.h>
#include <signal.h>
#include <errno.h>
static int has_epoll_pwait2 = -1;
#ifndef SYS_epoll_pwait2
@@ -122,18 +125,21 @@ static int has_epoll_pwait2 = -1;
#define SYS_epoll_pwait2 441
#endif
static ssize_t sys_epoll_pwait2(int epfd, struct epoll_event *events, int maxevents, const struct timespec *timeout, const sigset_t *sigmask, size_t sigsetsize) {
return syscall(SYS_epoll_pwait2, epfd, events, maxevents, timeout, sigmask, sigsetsize);
}
extern ssize_t sys_epoll_pwait2(int epfd, struct epoll_event* events, int maxevents,
const struct timespec* timeout, const sigset_t* sigmask);
static int bun_epoll_pwait2(int epfd, struct epoll_event *events, int maxevents, const struct timespec *timeout) {
int ret;
sigset_t mask;
sigemptyset(&mask);
if (has_epoll_pwait2 != 0) {
do {
ret = sys_epoll_pwait2(epfd, events, maxevents, timeout, NULL, 0);
} while (IS_EINTR(ret));
ret = sys_epoll_pwait2(epfd, events, maxevents, timeout, &mask);
} while (ret == -EINTR);
if (LIKELY(ret != -1 || errno != ENOSYS)) {
if (LIKELY(ret != -ENOSYS && ret != -EPERM && ret != -EOPNOTSUPP)) {
return ret;
}
@@ -146,7 +152,7 @@ static int bun_epoll_pwait2(int epfd, struct epoll_event *events, int maxevents,
}
do {
ret = epoll_wait(epfd, events, maxevents, timeoutMs);
ret = epoll_pwait(epfd, events, maxevents, timeoutMs, &mask);
} while (IS_EINTR(ret));
return ret;

View File

@@ -87,6 +87,7 @@ __asm__(".symver log2,log2@GLIBC_2.2.5");
__asm__(".symver log2f,log2f@GLIBC_2.2.5");
__asm__(".symver logf,logf@GLIBC_2.2.5");
__asm__(".symver pow,pow@GLIBC_2.2.5");
__asm__(".symver powf,powf@GLIBC_2.2.5");
__asm__(".symver sincosf,sincosf@GLIBC_2.2.5");
__asm__(".symver sinf,sinf@GLIBC_2.2.5");
__asm__(".symver tanf,tanf@GLIBC_2.2.5");
@@ -94,7 +95,6 @@ __asm__(".symver tanf,tanf@GLIBC_2.2.5");
__asm__(".symver cosf,cosf@GLIBC_2.17");
__asm__(".symver exp,exp@GLIBC_2.17");
__asm__(".symver expf,expf@GLIBC_2.17");
__asm__(".symver fcntl,fcntl@GLIBC_2.17");
__asm__(".symver fmod,fmod@GLIBC_2.17");
__asm__(".symver fmodf,fmodf@GLIBC_2.17");
__asm__(".symver log,log@GLIBC_2.17");
@@ -103,6 +103,7 @@ __asm__(".symver log2,log2@GLIBC_2.17");
__asm__(".symver log2f,log2f@GLIBC_2.17");
__asm__(".symver logf,logf@GLIBC_2.17");
__asm__(".symver pow,pow@GLIBC_2.17");
__asm__(".symver powf,powf@GLIBC_2.17");
__asm__(".symver sincosf,sincosf@GLIBC_2.17");
__asm__(".symver sinf,sinf@GLIBC_2.17");
__asm__(".symver tanf,tanf@GLIBC_2.17");
@@ -134,6 +135,9 @@ void BUN_WRAP_GLIBC_SYMBOL(sincosf)(float, float*, float*);
}
extern "C" {
#if defined(__x86_64__) || defined(__aarch64__)
int __wrap_fcntl(int fd, int cmd, ...)
{
va_list args;
@@ -150,6 +154,10 @@ static void init_real_fcntl64()
{
if (!real_fcntl64) {
real_fcntl64 = (fcntl64_func)dlsym(RTLD_NEXT, "fcntl64");
if (!real_fcntl64) {
real_fcntl64 = (fcntl64_func)dlsym(RTLD_NEXT, "fcntl");
}
}
}
@@ -233,32 +241,10 @@ extern "C" int __wrap_fcntl64(int fd, int cmd, ...)
return -1;
}
}
double __wrap_exp(double x) { return exp(x); }
double __wrap_fmod(double x, double y) { return fmod(x, y); }
double __wrap_log(double x) { return log(x); }
double __wrap_log2(double x) { return log2(x); }
double __wrap_pow(double x, double y) { return pow(x, y); }
float __wrap_cosf(float x) { return cosf(x); }
float __wrap_expf(float x) { return expf(x); }
float __wrap_fmodf(float x, float y) { return fmodf(x, y); }
float __wrap_log10f(float x) { return log10f(x); }
float __wrap_log2f(float x) { return log2f(x); }
float __wrap_logf(float x) { return logf(x); }
float __wrap_sinf(float x) { return sinf(x); }
float __wrap_tanf(float x) { return tanf(x); }
void __wrap_sincosf(float x, float* sin_x, float* cos_x) { sincosf(x, sin_x, cos_x); }
}
// ban statx, for now
extern "C" int __wrap_statx(int fd, const char* path, int flags,
unsigned int mask, struct statx* buf)
{
errno = ENOSYS;
#ifdef BUN_DEBUG
abort();
#endif
return -1;
}
#if defined(__x86_64__)
#ifndef _MKNOD_VER
#define _MKNOD_VER 1
@@ -326,6 +312,36 @@ extern "C" int __wrap_mknodat(int dirfd, const char* path, __mode_t mode, __dev_
#endif
double __wrap_exp(double x) { return exp(x); }
double __wrap_fmod(double x, double y) { return fmod(x, y); }
double __wrap_log(double x) { return log(x); }
double __wrap_log2(double x) { return log2(x); }
double __wrap_pow(double x, double y) { return pow(x, y); }
float __wrap_powf(float x, float y) { return powf(x, y); }
float __wrap_cosf(float x) { return cosf(x); }
float __wrap_expf(float x) { return expf(x); }
float __wrap_fmodf(float x, float y) { return fmodf(x, y); }
float __wrap_log10f(float x) { return log10f(x); }
float __wrap_log2f(float x) { return log2f(x); }
float __wrap_logf(float x) { return logf(x); }
float __wrap_sinf(float x) { return sinf(x); }
float __wrap_tanf(float x) { return tanf(x); }
void __wrap_sincosf(float x, float* sin_x, float* cos_x) { sincosf(x, sin_x, cos_x); }
}
// ban statx, for now
extern "C" int __wrap_statx(int fd, const char* path, int flags,
unsigned int mask, struct statx* buf)
{
errno = ENOSYS;
#ifdef BUN_DEBUG
abort();
#endif
return -1;
}
#endif
// macOS
#if defined(__APPLE__)

View File

@@ -771,3 +771,17 @@ pub extern "C" fn memrchr(ptr: [*]const u8, val: c_int, len: usize) ?[*]const u8
pub const netdb = @cImport({
@cInclude("netdb.h");
});
export fn sys_epoll_pwait2(epfd: i32, events: ?[*]std.os.linux.epoll_event, maxevents: i32, timeout: ?*const std.os.linux.timespec, sigmask: ?*const std.os.linux.sigset_t) isize {
return @bitCast(
std.os.linux.syscall6(
.epoll_pwait2,
@bitCast(@as(isize, @intCast(epfd))),
@intFromPtr(events),
@bitCast(@as(isize, @intCast(maxevents))),
@intFromPtr(timeout),
@intFromPtr(sigmask),
8,
),
);
}

View File

@@ -0,0 +1,65 @@
import { test, expect } from "bun:test";
import { $ } from "bun";
import { bunExe } from "harness";
import { semver } from "bun";
const BUN_EXE = bunExe();
if (process.platform === "linux") {
test("objdump -T does not include symbols from glibc > 2.27", async () => {
const objdump = Bun.which("objdump") || Bun.which("llvm-objdump");
if (!objdump) {
throw new Error("objdump executable not found. Please install it.");
}
const output = await $`${objdump} -T ${BUN_EXE} | grep GLIBC_`.text();
const lines = output.split("\n");
const errors = [];
for (const line of lines) {
const match = line.match(/\(GLIBC_2(.*)\)\s/);
if (match?.[1]) {
let version = "2." + match[1];
if (version.startsWith("2..")) {
version = "2." + version.slice(3);
}
if (semver.order(version, "2.27.0") >= 0) {
errors.push({
symbol: line.slice(line.lastIndexOf(")") + 1).trim(),
"glibc version": version,
});
}
}
}
if (errors.length) {
throw new Error(`Found glibc symbols >= 2.27. This breaks Amazon Linux 2 and Vercel.
${Bun.inspect.table(errors, { colors: true })}
To fix this, add it to -Wl,-wrap=symbol in the linker flags and update workaround-missing-symbols.cpp.`);
}
});
test("libatomic.so is not linked", async () => {
const ldd = Bun.which("ldd");
if (!ldd) {
throw new Error("ldd executable not found. Please install it.");
}
const output = await $`${ldd} ${BUN_EXE}`.text();
const lines = output.split("\n");
const errors = [];
for (const line of lines) {
// libatomic
if (line.includes("libatomic")) {
errors.push(line);
}
}
if (errors.length) {
throw new Error(`libatomic.so is linked. This breaks Amazon Linux 2 and Vercel.
${errors.join("\n")}
To fix this, figure out which C math symbol is being used that causes it, and wrap it in workaround-missing-symbols.cpp.`);
}
});
}