Live data from Hacker News

How Not to Write a Signal Handler

741mhz.com

11–20 of 52 posts

Re: How Not to Write a Signal Handler

#11
post #2

I still don't understand how queueing signals works. For example, signalfd() is really cool, and you can indeed read() a signal from it, but only one of a kind. If you get, say, two SIGINT's you may as well just be able to read() one. I guess it's an implementation detail that some signals aren't queued while some others are, I guess. In practice it means that receiving a signal is an edge, and in signal handler you…

You don't check how many times the signal occured - you write your code so that it doesn't matter how many times the signal occured.

For example, when you're handling a SIGCHLD you don't assume exactly one child has exited - you loop around calling waitpid() with WNOHANG and handle every child that's exited.

Re: How Not to Write a Signal Handler

#12
post #6

Earlier quoted context omitted.

I don't see why it would be less secure, reliable, or performant. It might be that the new ideas, and new abstractions, make it harder to do things in insecure or unreliable ways.

It's just that new programs often have more bugs in them, and bugs can sometimes end opening up an exploit vector.

> It's just that new programs often have more bugs in them...

That sure is a broad brush that you are using.

Re: How Not to Write a Signal Handler

#13
post #9

I looked around but couldn't find a great answer on how to do this correctly in Python on Linux. I have a daemon that attempts to shut down cleanly when it gets a number of signals and it appears to be working correctly. But, it's written like the first example.

Python does the right thing under the hood for you. The signal handler you register in Python isn't run in the dangerous context. There's an internal signal handler which just tells the interpreter a signal happened and when control is returned back to the interpreter outside of the signal handler it knows what to do:

https://hg.python.org/cpython/file/c7d45da654ee/Modules/sign...

Re: How Not to Write a Signal Handler

#14
post #2

I still don't understand how queueing signals works. For example, signalfd() is really cool, and you can indeed read() a signal from it, but only one of a kind. If you get, say, two SIGINT's you may as well just be able to read() one. I guess it's an implementation detail that some signals aren't queued while some others are, I guess. In practice it means that receiving a signal is an edge, and in signal handler you…

What's a good use case for knowing how many times a signal was raised? Signal once raised has no more context than the signal itself.

Re: How Not to Write a Signal Handler

#15
post #6

Earlier quoted context omitted.

We wouldn't be better off, no. The newer OS would likely be less secure, less reliable, and probably less performant. It would also require all of the tools we take for granted to be ported to the new OS, which would be difficult since the above proposal is to change the API of the new OS. It doesn't seem like there's anything wrong with libraries.

I don't see why it would be less secure, reliable, or performant. It might be that the new ideas, and new abstractions, make it harder to do things in insecure or unreliable ways.

Reliability problems: You're going to be porting a lot of programs to this hypothetical OS. The porting process is going to be difficult and error-prone by definition, because the proposal was to make significant changes to the kernel API. This leads to...

Security problems: When you change the fundamental assumptions of a program, you open them up to security flaws. I am primarily referring to ported programs when I say "the new OS will have security problems."

Performance problems: The performance will be worse than existing OS's, because drivers that work for Linux probably won't work for this new OS. This means you're going to have to get by with slower video drivers, at least initially.

These three types of problems aren't impossible to overcome. I doubt 2,000 years from now that people will be using Linux, BSD, or Windows. But you will have to overcome them.

Re: How Not to Write a Signal Handler

#16
post #2

I still don't understand how queueing signals works. For example, signalfd() is really cool, and you can indeed read() a signal from it, but only one of a kind. If you get, say, two SIGINT's you may as well just be able to read() one. I guess it's an implementation detail that some signals aren't queued while some others are, I guess. In practice it means that receiving a signal is an edge, and in signal handler you…

What's a good use case for knowing how many times a signal was raised? Signal once raised has no more context than the signal itself.

If the signal is received more than once it means it is more important :p

"Oh shit!"

"^C^C^C^C^C^C~C^C"

Re: How Not to Write a Signal Handler

#17
post #4

They write: "It is the 2013th year in the Common Era at the moment of this writing and you might think that people should have came up with something better in terms of signal handling at this time. The truth is that they did. It is just not that well known yet due to a huge momentum of outdated information still overflowing the Internet." Then they talk about kqueue. The above paragraph emphasizes how much Unix prog…

I don't understand your point; kqueue is a comparatively new idea.

Do you want signals written as messages across ZeroMQ? In that case, look at Mac OS X's use of Mach ports for exception handling, which is an even older idea than kqueue.

Re: How Not to Write a Signal Handler

#18
post #7

I think it's a shame (and painful) how the major Unices have all significantly diverged on things like event handling, I/O multiplexing and file system watching. I find the BSD kqueue(2) interface to be much more elegant than any of Linux's *fd() functions or epoll(7). On the other hand, Linux's inotify(7) is, I find, cleaner to use for file system event notifications than kqueue(2). But then there's also fanotify(7)…

I think the kqueue interface is a lot worse than the Linux way. With kqueue everything is forced through one interface. In Linux it's just file descriptors and epoll to deal with them. It is a nice extension of the "everything is a file" mechanism and it embodies the "do one thing and do it right". This becomes apparent when you look at fs notifications. You've already mentioned how inotify is superior to kqueue. I m…

There's been talk (at BSDCam) of implementing inotify which is needed for the Linuxulator and exposing it in the FreeBSD API too. So your wish isn't so far fetched but I'm not sure anyone is actively working on it. Patches welcome :)

Re: How Not to Write a Signal Handler

#19
post #7

I think it's a shame (and painful) how the major Unices have all significantly diverged on things like event handling, I/O multiplexing and file system watching. I find the BSD kqueue(2) interface to be much more elegant than any of Linux's *fd() functions or epoll(7). On the other hand, Linux's inotify(7) is, I find, cleaner to use for file system event notifications than kqueue(2). But then there's also fanotify(7)…

I think the kqueue interface is a lot worse than the Linux way. With kqueue everything is forced through one interface. In Linux it's just file descriptors and epoll to deal with them. It is a nice extension of the "everything is a file" mechanism and it embodies the "do one thing and do it right". This becomes apparent when you look at fs notifications. You've already mentioned how inotify is superior to kqueue. I m…

Bah. This is complete nonsense.

EVFILT_VNODE is not complicated to use for the cases for which it was actually designed — monitoring a file descriptor. For more general file system monitoring, a new kqueue filter type would be ideal, but adding that does not require breaking or deprecating kqueue API; the whole point of kqueue is to provide a generic extensible event mechanism.

Adding a recursive path monitoring filter is as simple as:

- Defining a new `EVFILT_DIR` filter type.

- Accepting a file path or st_dev/ino_t pair via the generic `uinptr_t ident` kevent identifier.

- Providing extended data via the existing filter-controlled `intptr_t data` value.

Boom. Done. Using the nice, generic, well-designed kqueue() API that can also monitor file descriptors, processes, AIO events, signals, timers, and user-defined events.

I wish Linux — like Mac OS X, and all the BSDs — had adopted kqueue, or at least participated in the conversation. Instead, Linux went through 2-3 different mechanisms before finally settling on the odd-duck single-purpose inotify interface, despite kqueue's design having been published (http://people.freebsd.org/~jlemon/papers/kqueue.pdf) and released as part of FreeBSD 5 years earlier.

While Jon Lemon published a detailed paper covering kqueue's design, implementation, and performance benchmarking, the inotify developer published a 30 line README with erudite gems such as "Rumor is that the "d" in "dnotify" does not stand for "directory" but for "suck.": https://www.kernel.org/pub/linux/kernel/people/rml/inotify/R...

Re: How Not to Write a Signal Handler

#20
post #7

I think it's a shame (and painful) how the major Unices have all significantly diverged on things like event handling, I/O multiplexing and file system watching. I find the BSD kqueue(2) interface to be much more elegant than any of Linux's *fd() functions or epoll(7). On the other hand, Linux's inotify(7) is, I find, cleaner to use for file system event notifications than kqueue(2). But then there's also fanotify(7)…

I think the kqueue interface is a lot worse than the Linux way. With kqueue everything is forced through one interface. In Linux it's just file descriptors and epoll to deal with them. It is a nice extension of the "everything is a file" mechanism and it embodies the "do one thing and do it right". This becomes apparent when you look at fs notifications. You've already mentioned how inotify is superior to kqueue. I m…

[deleted]
Post reply on HN