The Boston Diaries

The ongoing saga of a programmer who doesn't live in Boston, nor does he even like Boston, but yet named his weblog/journal “The Boston Diaries.”

Go figure.

Monday, October 22, 2007

Oh yeah … that other place

Least you think I forgot about the other place, I just added a new entry about greylisting there, since it was a request from Smirk.


Friends don't let friends write signal handlers

Mark has a bit more to say about signal handlers:

From
Mark Grosberg <XXXXXXXXXXXXXXXXX>
To
sean@conman.org
Subject
Signal handlers.
Date
Mon, 22 Oct 2007 14:36:05 -0400 (EDT)

You know, now that I think about it even the write() system call is not totally safe in signal handlers. Why? Because lets say the write system call fails. Furthermore lets say that the signal was delivered somewhere in the return path of some other function, like, oh, I dunno, a socket I/O call.

So the socket I/O call has been performed and we are in the midst of unwinding through the various layers of libc and have set errno to some important value (like say HOST-NOT-REACHABLE) and then our signal handler attempts to write … poof our important errno value gets corrupted!

Amusingly from the man page for signal on my system:

Additionally, inside the signal handler it is also considered more safe to make a copy of the global variable errno and restore it before returning from the signal handler.

Too bad if you are in a threaded program “errno” is actually #defined as something like (*__pthreads_get_errno_location()). Hahah! You're so double-XXXXXX with this its not funny. Assuming that getting the errno location is atomic, is loading/storing errno? What if you have some goofy architecture where writes to errno are not atomic and require multiple instructions. That's why sig_atomic_t is so special … it's guaranteed atomic.

The fact that errno is a global variable is a consequence of the C language and it's rather poor support for multiple return values (it can—it's just that you have to pass in additional pointers). At the time, it was the easiest thing that could possibly work (I swear—at times, it feels like if it wasn't in Unix V7, then it doesn't really work that well under modern versions of Unix, like threads), not the best thing that could possibly work (like writing a systems language that supported multiple return values).

And the whole (*__pthreads_get_errno_location()) is telling—the C Standard requires that errno “expands to a modifiable lvalue”—in other words, it could be a pointer to a location which can be changed.

In fact, the C Standard on errno only covers half a page, and P. J. Plauger states in his book The Standard C Library:

If I had to identify one part of the C Standard that is uniformly disliked, I would not have to look far. Nobody likes errno or the machinery that it implies. I can't recall anybody defending this approach to error reporting, not in two dozen or more meetings of X3J11 [The ANSI working committee on standardizing C in the late 80s. —Editor], the committee that developed the C Standard. Several alternatives were proposed over the years. At least one faction favored simply discarding errno. Yet it endures.

The C Standard has even added to the existing machinery. The header <errno.h> is an invention of the committee. We wanted to have every function and data object in the library declared in some standard header. We gave errno its own standard header mostly to ghettoize it. We even added some words in the hope of clarifying a notoriously murky corner of the C language.

A continuing topic among groups working to extend and improve C is how to tame errno. Or how to get rid of it. The fact that no clear answer has emerged to date should tell you something. There are no easy answers when it comes to reporting and handling errors.

It's a rather depressing chapter to read, and P. J. Plauger is right—reporting and handling of errors is difficult reguardless of language.

But errno isn't the only problematic area with signals, so too might be pthreads, making a three-for-one clusterXXXX of your code.

Sigh.

Obligatory Picture

An abstract representation of where you're coming from]

Obligatory Contact Info

Obligatory Feeds

Obligatory Links

Obligatory Miscellaneous

Obligatory AI Disclaimer

No AI was used in the making of this site, unless otherwise noted.

You have my permission to link freely to any entry here. Go ahead, I won't bite. I promise.

The dates are the permanent links to that day's entries (or entry, if there is only one entry). The titles are the permanent links to that entry only. The format for the links are simple: Start with the base link for this site: https://boston.conman.org/, then add the date you are interested in, say 2000/08/01, so that would make the final URL:

https://boston.conman.org/2000/08/01

You can also specify the entire month by leaving off the day portion. You can even select an arbitrary portion of time.

You may also note subtle shading of the links and that's intentional: the “closer” the link is (relative to the page) the “brighter” it appears. It's an experiment in using color shading to denote the distance a link is from here. If you don't notice it, don't worry; it's not all that important.

It is assumed that every brand name, slogan, corporate name, symbol, design element, et cetera mentioned in these pages is a protected and/or trademarked entity, the sole property of its owner(s), and acknowledgement of this status is implied.

Copyright © 1999-2024 by Sean Conner. All Rights Reserved.