luajit/physicsfs 互斥死锁

luajit/physicsfs mutex deadlock

我有以下代码:

local M=ffi.load "physfs"
ffi.cdef [[ //basically the preprocessed content of physfs.h, see http://icculus.org/physfs/docs/html/physfs_8h.html ]]
M.PHYSFS_init(arg[0])
M.PHYSFS_setSaneConfig("a","b","zip",0,0)

function file2str(path)
  local cpath=ffi.cast("const char *",path)
  print(1) --debug
  if M.PHYSFS_exists(cpath)==0 then return nil,"file not found" end
  print(2) --debug
  -- some more magic
end
assert(file2str("someFile.txt"))

调用时,我希望调试输出 1 和 2,或者至少触发断言,但我只得到:

1
["endless" (i pressed ^C after about a minute) freeze]

当我终于在 gdb 中将 luajit 设置为 运行 时,这是冻结时的回溯:

(gdb) bt
#0  0x00007ffff37a5c40 in __pause_nocancel ()
    at ../sysdeps/unix/syscall-template.S:81
#1  0x00007ffff379bce6 in __pthread_mutex_lock_full (mutex=0x68cbf0)
    at ../nptl/pthread_mutex_lock.c:354
#2  0x00007ffff606951f in __PHYSFS_platformGrabMutex (mutex=0x68cbf0)
    at /home/kyra/YDist/src/physfs-2.0.3/platform/unix.c:403
#3  0x00007ffff606410d in PHYSFS_getWriteDir ()
    at /home/kyra/YDist/src/physfs-2.0.3/physfs.c:913
#4  0x000000000045482b in ?? ()
#5  0x000000000043a829 in ?? ()
#6  0x000000000043af17 in ?? ()
#7  0x00000000004526a6 in ?? ()
#8  0x0000000000446fb0 in lua_pcall ()
#9  0x00000000004047dc in _start ()

所以在我看来似乎有什么东西阻塞了互斥锁,这有点奇怪,因为虽然有两个线程 运行ning,但只有一个甚至触及 physfs(第二个线程甚至没有 ffi.load "physfs")

我做什么could/should?

我仍然不知道到底发生了什么,但是在尝试进一步调试 gdb 中的互斥锁时,我 LD_PRELOADed libpthread.so 到 gdb 进程,突然它起作用了.

然后我尝试在没有 gdb 的情况下将它预加载到 luajit,也可以。

然后我进一步研究了 physfs 和 lualanes(这是我用于线程的 pthread ffi 包装器),发现它们都尝试加载 libpthread(如果尚未加载),但来自 C 的 physfs 和 lualanes 使用ffi,它以某种方式看不到 physfs 加载的那个,并且该过程最终加载了库的 2 个副本。

所以解决方法是在 ffi.load"physfs" 之前明确地执行 ffi.load"pthread",因为虽然 lanes 看不到 physfs 加载的版本,但 physfs 对我们加载的版本很满意,并且不会尝试再次加载它,而 luajit ffi 会忽略 lanes 进行的进一步加载尝试。