LuaLanes / lanes

Lanes is a lightweight, native, lazy evaluating multithreading library for Lua 5.1 to 5.4.
Other
436 stars 93 forks source link

luajit+lualanes,Program crashed in ARM32 #217

Closed SeaAndSand closed 9 months ago

SeaAndSand commented 10 months ago

local lanes = require("lanes").configure({nb_keepers = 10, with_timers = false, on_state_create = registercfunc})

local createThread = lanes.gen("*", function(func, ...) local ok, msg = xpcall(func, debug.traceback, ...) if not ok then log:error(msg) end end)

I created 10 threads, and the program occasionally crashes,Stack corruption.

Luajit-2.1+lualanes3.16.0,I've also tested the latest LuaJIT, and I have a related question as well.

warning: Unable to find libthread_db matching inferior's thread library, thread debugging will not be available. Core was generated by `./armtest.out'. Program terminated with signal SIGSEGV, Segmentation fault.

0 0x76e1e022 in ?? () from /usr/lib/libluajit-5.1.so.2

(gdb) bt

0 0x76e1e022 in ?? () from /usr/lib/libluajit-5.1.so.2

1 0x6d8c7bb4 in protected_lua_Alloc ()

from ./lualocal/lanes/lib/lanes/core.so Backtrace stopped: Cannot access memory at address 0xc0000024

benoit-germain commented 10 months ago

I don't know about ARM platforms, but LuaJIT's memory allocator is not threadsafe and can cause this kind of crashes. Try to play with the "allocator" configuration setting to see if it helps.

SeaAndSand commented 9 months ago

It doesn't work. In fact, the default value of allocator is protected.

-- LuaJIT provides a thread-unsafe allocator by default, so we need to protect it when used in parallel lanes
allocator = (package.loaded.jit and jit.version) and "protected" or nil

From the crash information, it can be observed that protected_lua_Alloc() was indeed called.

SeaAndSand commented 9 months ago
// after all, it looks like we can use the state allocator for our own usage when running LuaJIT, as long as we mutex-protect it
#define USE_LUA_STATE_ALLOCATOR 1 // (LUAJIT_FLAVOR==0)

change this 0, no crash

benoit-germain commented 9 months ago

Hmm. It would seem then that LuaJIT's allocator behavior is not the same on ARM32 and (at least) windows. (That or I missed something). If the LuaJIT allocator assumes that no code besides LuaJIT itself can make use of it, and uses this information to do stuff such as relocating memory, it may invalidate pointers grabbed the way I do. But then, if LuaJIT supports the Lua API, then it should support acquiring the allocator from a state and making use of it. The other possibility is that the allocator obtained that way is for some reason the original (unprotected) one, and this causes concurrent accesses resulting in corruptions.

benoit-germain commented 9 months ago

I don't really want to remove the ability altogether. However I think I can make it a runtime configuration.

benoit-germain commented 9 months ago

Hopefully v3.16.1 should enable you to solve this issue.