lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


> This is not what I experience using Lua 5.3.

I hope this is not Lua version dependent (at least for Lua 5.2, 5.3 and 5.4 - I can ignore 5.1 and I don't care about 5.0 or older)

> check the NDEBUG define in your toolchain.

Actually the code I posted before was a little simplified, to keep the mail short.
I do not (only) use assert, but some makros and several printf - but I can post the full code + build command line (see below).
It does not trigger any error on Ubuntu Linux.

Build command line:
clang luaexit.c  -llua -lm -ldl -O1 -g -fsanitize=address -fno-omit-frame-pointer -Wall

Full source code:
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
#include <setjmp.h>
#include <stdio.h>
#include <assert.h>


jmp_buf JUMP_TO_EXIT;

#define UNREACHABLE {printf("Reached unreachable code at %u\n", __LINE__); assert(0);}
#define check(val, exp) check_func(val, exp, __LINE__)


int my_exit(lua_State *L)
{
  int num = lua_tointeger(L, 1);
  lua_close(L);
  longjmp(JUMP_TO_EXIT, num);
  UNREACHABLE
  return 0; /* will not return */
}


int fail_continuation_function(lua_State *L, int status, lua_KContext ctx) {
  printf("FAIL @ %u\n", __LINE__);
  UNREACHABLE
}


int my_pcallk(lua_State *L)
{
  lua_pcallk(L, lua_gettop(L)-1, 0, 0, 0, fail_continuation_function);
  UNREACHABLE
  return 0;
}


int my_pcall(lua_State *L)
{
  lua_pcall(L, lua_gettop(L)-1, 0, 0);
  UNREACHABLE
  return 0;
}


int num_from_lua(const char *code)
{
  lua_State *L = luaL_newstate();  /* create state */
  luaL_openlibs(L);
  lua_pushcfunction(L, my_exit);
  lua_setglobal(L, "my_exit");
  lua_pushcfunction(L, my_pcallk);
  lua_setglobal(L, "my_pcallk");

  luaL_loadstring(L, code);
  int result = setjmp(JUMP_TO_EXIT);
  if (result) {
      return result;
  }
  int status = lua_pcall(L, 0, 1, 0);
  if (status) {
    printf("%s\n", lua_tostring(L, 1));
  } else {
    result = lua_tonumber(L, -1);
  }
  lua_close(L);
  return result;
}


void check_func(int is, int exp, unsigned line)
{
    if (is == exp) {
        printf("passed line %u\n", line);
    } else {
        printf("ERROR in line %u: is = %i, expected = %i\n", line, is, exp);
// assert(0);
    }
}


int main(int argc, char *argv[])
{
  (void) argc;
  (void) argv;
 
  int a;

  a = num_from_lua(
    "print(_VERSION); "
    "return 10;"
  );
  check(a, 10);

  a = num_from_lua(
    "pcall("
    "  function () "
    "    pcall(my_exit, 123) "
    "  end"
    "); "
    "return 45;"
  );
  check(a, 123);

  a = num_from_lua(
    "co = coroutine.create("
    "  function () "
    "    pcall(my_exit, 67) "
    "  end"
    "); "
    "coroutine.resume(co); "
    "return 89;"
  );
  check(a, 67);

  a = num_from_lua(
    "co = coroutine.create("
    "  function () "
    "    my_pcallk(my_exit, 98) "
    "  end"
    "); "
    "coroutine.resume(co); "
    "return 76;"
  );
  check(a, 98);

  a = num_from_lua(
    "co = coroutine.create("
    "  function () "
    "    my_pcallk(coroutine.yield) "
    "  end"
    "); "
    "coroutine.resume(co); "
    "return 54;"
  );
  check(a, 54);

  a = num_from_lua(
    "co = coroutine.create("
    "  function () "
    "    my_pcall(coroutine.yield) "
    "  end"
    "); "
    "coroutine.resume(co); "
    "print(coroutine.status(co)); "
    "return 32;"
  );
  check(a, 32);

  printf("Test the test!\n");
  a = 1;
  check(a, 2); /* 1 != 2 */
 
  //UNREACHABLE --> will cause assert + core dump

  return 0;
}






I can p





On Mon, Mar 1, 2021 at 9:44 AM Viacheslav Usov <via.usov@gmail.com> wrote:
On Sun, Feb 28, 2021 at 10:37 PM bel <bel2125@gmail.com> wrote:

> It seems I can create a simple Lua code that does not return after pcall:
>
> co = coroutine.create(function () my_pcall(coroutine.yield) end);
> coroutine.resume(co);
> print(coroutine.status(co)); -- dead ... but no exception or other issue
>
> Corresponding C code for "my_pcall" - I would not think this is "misbehaved":
>
> int my_pcall(lua_State *L)
> {
>   lua_pcall(L, lua_gettop(L)-1, 0, 0);
>   assert(0);
>   return 0;
> }
>
> Maybe Lua raised an error in coroutine.yield (where does this error go?).
> But it still did not continue after lua_pcall - the assert is not triggered.

This is not what I experience using Lua 5.3. What I get is error
"attempt to yield across a C-call boundary" pushed on stack by
lua_pcall(), exactly like the manual states. Whether assert() is
"triggered" is another matter, check the NDEBUG define in your
toolchain.

Cheers,
V.