tarantool / tarantool/tarantool

Tarantool hangs on exit after `tnt_tx_push` is used

Open
#12,763 4 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug
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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.