I've got the following code:
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"))
when calling, I expect debug output 1 and 2, or at least the assert triggering, but I only get:
1
["endless" (i pressed ^C after about a minute) freeze]
when i finally got luajit to run in gdb, this is the backtrace when freezing:
(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 ()
so it seems to me that something is blocking the mutex, which is kinda strange, because, while there are two threads running, only one even touches physfs (the second thread doesn't even ffi.load "physfs"
)
what could/should I do?
I still don't really know what the hell is going on, but while trying to further debug the mutex in gdb I LD_PRELOAD
ed libpthread.so
to the gdb process, and suddenly it worked.
Then I tried just preloading it to luajit without gdb, also works.
Then I dug further into physfs and lualanes (which is a pthread ffi wrapper I'm using for threading), to find out they both try to load libpthread if not already loaded, but physfs from C and lualanes using the ffi, which somehow doesn't see the one loaded by physfs, and the process ends up with 2 copies of the library loaded.
so the fix is to explicitely do a ffi.load"pthread"
before ffi.load"physfs"
, because while lanes can't see the version loaded by physfs, physfs is just happy with the version loaded by us, and doesn't try to load it again, while the luajit ffi ignores further load tries made by lanes.