Skip to content

Commit

Permalink
Follow-up fix for stack overflow handling cleanup.
Browse files Browse the repository at this point in the history
(cherry-picked from commit aa6b15c)

The stack overflow error is thrown in `lj_state_growstack` only
if the coroutine status is `OK`, however, stack overflow can
happen on a yielded coroutine too. This patch fixes the condition
for status, so now the error thrown on yielded coroutines too.

Maxim Kokryashkin:
* added the description and the test for the patch

Part of tarantool/tarantool#9145
  • Loading branch information
Mike Pall authored and mkokryashkin committed Nov 21, 2023
1 parent 69cfe31 commit f8d053c
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 1 deletion.
2 changes: 1 addition & 1 deletion src/lj_state.c
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ void LJ_FASTCALL lj_state_growstack(lua_State *L, MSize need)
if (L->stacksize > LJ_STACK_MAXEX)
lj_err_throw(L, LUA_ERRERR); /* Does not invoke an error handler. */
/* 1. We are _at_ the limit after the last growth. */
if (!L->status) { /* 2. Throw 'stack overflow'. */
if (L->status < LUA_ERRRUN) { /* 2. Throw 'stack overflow'. */
L->status = LUA_ERRRUN; /* Prevent ending here again for pushed msg. */
lj_err_msg(L, LJ_ERR_STKOV); /* May invoke an error handler. */
}
Expand Down
23 changes: 23 additions & 0 deletions test/tarantool-c-tests/lj-962-premature-stack-overflow.test.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,20 @@ static int fill_stack(lua_State *L)
return 0;
}

static int immediate_yield(lua_State *L)
{
return lua_yield(L, 0);
}

static int overflow_suspended_coro(lua_State *L)
{
lua_State *newL = lua_newthread(L);
lua_pushcfunction(newL, immediate_yield);
lua_resume(newL, 0);
fill_stack(newL);
return 0;
}

static int premature_stackoverflow(void *test_state)
{
lua_State *L = test_state;
Expand All @@ -29,11 +43,20 @@ static int premature_stackoverflow(void *test_state)
return TEST_EXIT_SUCCESS;
}

static int stackoverflow_on_suspended_coro(void *test_state)
{
lua_State *L = test_state;
int status = lua_cpcall(L, overflow_suspended_coro, NULL);
assert_true(status == LUA_ERRRUN);
return TEST_EXIT_SUCCESS;
}

int main(void)
{
lua_State *L = utils_lua_init();
const struct test_unit tgroup[] = {
test_unit_def(premature_stackoverflow),
test_unit_def(stackoverflow_on_suspended_coro),
};
const int test_result = test_run_group(tgroup, L);
utils_lua_close(L);
Expand Down

0 comments on commit f8d053c

Please sign in to comment.