Discussion:
Ctrl-C handling and xpcall (with jit off)
Tudor Bosman
2014-07-15 05:24:08 UTC
Permalink
No, it's not the same "Ctrl-C won't raise a Lua error from compiled code"
issue again :)

If I catch Ctrl-C in an xpcall, any subsequent Ctrl-C will kill my program
unless LuaJIT gets back to top level (REPL).

Attaching an example (loop.lua). The program prints '1'; type Ctrl-C and
the error gets caught, and the program prints '2'; type Ctrl-C again and
the program exits. This doesn't happen if you call xpcall(loop, handler)
from the command line instead of from a script.

Thanks,
-Tudor.
Tudor Bosman
2014-07-15 13:38:42 UTC
Permalink
This post might be inappropriate. Click to display it.
Tudor Bosman
2014-07-15 13:55:47 UTC
Permalink
Attaching a patch that fixes this issue. It's against the LuaJIT 2.0.2
source code, but that piece of luajit.c hasn't changed since 2.0.2.

Thanks,
-Tudor.
Post by Tudor Bosman
No, it's not the same "Ctrl-C won't raise a Lua error from compiled code"
issue again :)
If I catch Ctrl-C in an xpcall, any subsequent Ctrl-C will kill my program
unless LuaJIT gets back to top level (REPL).
Attaching an example (loop.lua). The program prints '1'; type Ctrl-C and
the error gets caught, and the program prints '2'; type Ctrl-C again and
the program exits. This doesn't happen if you call xpcall(loop, handler)
from the command line instead of from a script.
Thanks,
-Tudor.
Mike Pall
2014-07-15 13:56:52 UTC
Permalink
Post by Tudor Bosman
If I catch Ctrl-C in an xpcall, any subsequent Ctrl-C will kill my program
unless LuaJIT gets back to top level (REPL).
The Ctrl-C handling of the LuaJIT command line program is the same
as for Lua. It's pretty rudimentary and only intended to give a
backtrace (well, most of the time) when you really want to abort
the program.

The SIGINT handler resets itself after the first trigger and then
the default behavior sets in (process kill). This is intentional,
because that's the only way to abort the process if it gets stuck
in some C code (which will never invoke the debug hook).

I'm not sure what you want to achieve, but here are my
suggestions:

1. Use C code in your own app to get the desired behavior. You
probably want to use POSIX sigaction() and not the (old) ANSI C
signal() handling. That allows you to retain the signal handler.

2. Disable the REPL signal handler via the FFI: signal(SIGINT, SIG_DFL).
This always kills the process on Ctrl-C.

3. If you're on Linux and want to do anything more complicated
with signals, like mixing them with other sync/async input
sources, then have a look at signalfd(). Interoperates nicely with
poll/epoll. Unlike signal handlers, this is easy to use with the
FFI, too.

--Mike
Tudor Bosman
2014-07-15 14:07:18 UTC
Permalink
Post by Mike Pall
The SIGINT handler resets itself after the first trigger and then
the default behavior sets in (process kill). This is intentional,
because that's the only way to abort the process if it gets stuck
in some C code (which will never invoke the debug hook).
Yes, I understand (and it makes sense). The bug is that the handler is
reset only when LuaJIT gets back to top level, while it could be reset
earlier (as soon as the debug hook is invoked).
Post by Mike Pall
I'm not sure what you want to achieve, but here are my
I'm using a custom REPL interactively, and the REPL relies on xpcall to
catch all errors, report them, and then issue a new prompt and wait for the
next command. (It's a slightly modified version of
https://github.com/torch/trepl). Ctrl-C works most of the time (except in
compiled code, but while running interactively it's usually okay to turn
off the jit, or in some C code -- if you have C code that hangs, well,
tough.)

-Tudor.
Mike Pall
2014-07-15 14:31:33 UTC
Permalink
Post by Tudor Bosman
Yes, I understand (and it makes sense). The bug is that the handler is
reset only when LuaJIT gets back to top level, while it could be reset
earlier (as soon as the debug hook is invoked).
This is not a bug, this is intentional. Otherwise a Lua program
could capture Ctrl-C indefinitely. I'm not going to change the
behavior of the REPL relative to what Lua implements.

--Mike

Loading...