tarantool / tarantool/tarantool
Tarantool hangs on exit after `tnt_tx_push` is used
Nobody has claimed this yet.
- Dominant language
- Lua
- Stars
- 3.7k
- Forks
- 419
- Avg merge
- 1d 23h
- Merged PRs (30d)
- 88
Description
Calling tnt_tx_push() from a coio_call() worker thread makes the process hang on graceful shutdown (os.exit(0) / SIGTERM) — it never exits and has to be killed with SIGKILL. A single tnt_tx_push is enough to trigger it; the worker function returns normally and coio_call completes, yet the subsequent graceful shutdown wedges. Without the tnt_tx_push call the same worker shuts down cleanly. Not specific to macOS.
* OS: macOS
* OS Version: macOS 15 (Darwin 25.4.0)
* Architecture: arm64
Tarantool 3.8.0-entrypoint-49-g97a3b38040
Target: Darwin-arm64-Release
* OS: Linux
* OS Version: Arch Linux (rolling), kernel 7.0.7-arch1-1
* Architecture: amd64 (x86_64)
Tarantool 3.8.0-entrypoint-49-g97a3b38040
Target: Linux-x86_64-RelWithDebInfo
Build options: cmake . -DCMAKE_INSTALL_PREFIX=/usr/local -DENABLE_BACKTRACE=TRUE
Compiler: GNU-16.1.1
Steps to reproduce
tnt_tx_push is a C API with no Lua binding, so the reproducer is a tiny C module plus a Lua driver.
txpush_bug.c:
#include <module.h>
#include <lua.h>
#include <lauxlib.h>
static void noop(void *arg) { (void) arg; }
static ssize_t
worker(va_list ap)
{
(void) ap;
tnt_tx_push(noop, NULL);
tnt_tx_flush();
return 0;
}
static int
lua_run(lua_State *L)
{
coio_call(worker);
return 0;
}
LUA_API int
luaopen_txpush_bug(lua_State *L)
{
static const struct luaL_Reg lib[] = { {"run", lua_run}, {NULL, NULL} };
luaL_register(L, "txpush_bug", lib);
return 1;
}
test.lua:
package.cpath = './?.so;' .. package.cpath
local fio = require('fio')
box.cfg{ memtx_dir = fio.tempdir(), wal_dir = fio.tempdir() }
require('txpush_bug').run()
print('worker returned; calling os.exit(0)')
os.exit(0)
How to run:
# adjust the include path to where module.h lives in your install
gcc -O2 -fPIC -bundle -undefined dynamic_lookup \
-I/path/to/tarantool/include/tarantool \
-o txpush_bug.so txpush_bug.c
timeout 10 tarantool test.lua
echo "exit: $?"
Actual behavior
worker returned; calling os.exit(0) is printed, then the process hangs indefinitely and is only terminated by the timeout wrapper / SIGKILL (exit 124 or 137). With a clean shutdown path this should not happen.
Expected behavior
The process exits cleanly with code 0 immediately after os.exit(0), the same as it does when the tnt_tx_push/tnt_tx_flush lines are removed from worker().
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by building the txpush_bug.c module and running test.lua with the supplied timeout command to reproduce the shutdown hang. Trace the tnt_tx_push/tnt_tx_flush path invoked from coio_call and the graceful shutdown path, then add or update a regression test using this reproducer. Done means the process exits cleanly with status 0 after os.exit(0), including on the reported platforms.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- c, lua
- Domain
- backend, databases
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100