lua-users home
lua-l archive

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


On Mon, Aug 11, 2014 at 09:55:40PM -0400, Sean Conner wrote:
> It was thus said that the Great William Ahern once stated:
<snip>
> > >   Yeah, it's a bit of a round-about way of doing things, but it appears to
> > > tbe the safest way of handling signals in Lua.  I've done two
> > > implementations based on this method, on for ANSI-C only:
> > 
> > The safest way is to not handle signals asynchronously at all. 
> 
>   "The safest way is to not handle signals ------------- at all."
> 
>   Fixed that for you 8-P

sigtimedwait is both POSIX and completely safe. It clears the pending set
atomically. And even without without sigtimedwait you can emulate it. I had
a discussion about this in comp.unix.programmer a couple of years ago. There
are several ways to do it, and at least one technique is nearly ANSI
C-compatible (if you don't count use of nanosleep or sigset_t routines),
async-signal-safe, and uses no global state.

Another POSIX-compatible and safe way to handle signals is using the "pipe
trick", which has been used since the 1990s. With the pipe trick you set a
signal handler which writes the signal number to a pipe. It's a hack but
also safe. The only caveat is the case of too many signals (>PIPE_BUF, 4096
on Linux), so handling overflow is a headache, but can still be done safey.
In any event any such technique is still better than a method which is
unsafe even in a normal, non-malicous operating environments.

It's not practical to avoid dealing with signals in a Unix environment. It's
the normal way to communicate with a process in a generic fashion. You can't
do much process control, such as manage sub processes, without signals. You
can't safely shutdown your service unless you can handle SIGTERM, which is
what is sent to all processes during system shutdown.

> > But the problem with sigtimedwait is that you often want some sort of
> > concurrent execution of signal handlers without having to explicitly query
> > them. My cqueues library provides an API for kernel-based, event-oriented
> > signal management. Internally it uses signalfd on Linux and kqueue
> > EVFILT_SIGNAL on BSDs (including OS X). 
> 
>   I must be running a Linux kernel older than 20 minutes because I don't
> have signalfd on my system. [1]

signalfd added to kernel version 2.6.22, released July 2007. So it's over 7
years old.

AFAICT sigtimedwait was added to Linux with NPTL. glibc was using the
rt_sigtimedwait syscall no later than 2004.

> > 		local signo = sigfd:wait() -- doesn't block process
> > 
> > 		print(signo)
> > 	end
> 
>   But this won't handle the original problem:
> 
> 	coroutine.resume(coroutine.create(function() while true do end end))

Neither will using lua_sethook! IIRC this was discussed in another thread a
few weeks ago. Here's the relevant code in Lua (from 5.2 source code):

LUA_API int lua_sethook (lua_State *L, lua_Hook func, int mask, int count) {
  if (func == NULL || mask == 0) {  /* turn off hooks? */
    mask = 0;
    func = NULL;
  }
  if (isLua(L->ci))
    L->oldpc = L->ci->u.l.savedpc;
  L->hook = func;
  L->basehookcount = count;
  resethookcount(L);
  L->hookmask = cast_byte(mask);
  return 1;
}

Note that it only sets the hook for the currently running coroutine.

<snip>
> [1]	Not everybody updates their systems every ten minutes.  I don't do
> 	that, because I operate under the "if it ain't broke, don't fix it"
> 	mandate.  And because of that, I wasn't affected by Heartbleed.  Nor
> 	have I been bitten by updates borking my system.

The Linux kernel has exploits on a monthly basis. If you're running a kernel
from before 2007 then are many other things I'd be concerned about. No
kernel before 2.6.32 is actively maintained.[1] I understand using old
kernels. At work I was stuck supporting 2.4 kernels until roughly 2011. 2.4
was end-of-lifed in 2012, though. So such kernels are as relevant as SCO
UNIX when discussing portability. Obviously SCO UNIX and pre-2.6.22 kernels
are still used, but IMO there's no reasonable argument which can appeal to
their feature set when discussing new software, even in the context of
portability.

I run OpenBSD on most of my servers, so I'm not a bleeding edge kind of
user. I also maintain my unix and cqueues modules on NetBSD 5.2 and FreeBSD
9.0, which aren't exactly new. NetBSD 5.2 in particular requires lots of
stupid hacks because of bugs and poor POSIX support.

1. Source: https://www.kernel.org/releases.html