5 ms·
C has this problem too: see signal-safety(7). > * If a signal handler interrupts the execution of an unsafe function, and the handler terminates via a call to
by hun3 2y ago
C has this problem too: see signal-safety(7).
> * If a signal handler interrupts the execution of an unsafe function, and the handler terminates via a call to longjmp(3) or siglongjmp(3) and the program subsequently calls an unsafe function, then the behavior of the program is undefined.
Also note that pthread_cancel() provides a way to block asynchronous cancellations via pthread_setcancelstate().
- jandrese 2y agoAm I weird that I've been programming in C for decades and have never used longjmp? For the longest time I thought it was some legacy function that was only used on ancient segmented memory systems, but it instead turns out to be a complete program flow destroyer that I can't see a good use for. I have seen some libraries that do error handling via the user passing a callback for a longjmp, but even that seems ill advised. Fortunately it is always optional.
- jeff-davis 2y agoLongjmp is used by Postgres for transaction aborts. With C, there's not really a better option available.
- eqvinox 2y agoThat's not from within signal handlers, though. (i.e. it relates to this specific longjmp discussion but not the root post re. exceptions on other threads.)
- anarazel 2y agoIt unfortunately is used from within signal handlers, albeit only in specific cases (SIGFPE). There used to several more, but we luckily largely cleaned that up over the last few years.
- eqvinox 2y agoMeh. Well. Good to hear on the cleanup. Didn't know it used to be different :/ Re. SIGFPE, to be fair, it feels a bit like the "asynchronous vs. synchronous abort¹" thing on CPUs; synchronous aborts are reasonably doable while on asynchronous aborts you're pretty much left with torching things down far and wide. (SIGFPE should hopefully be synchronous; it's in fact closely connected to sync/async CPU aborts...) [¹ frequently also called exceptions, depending on the CPU architecture, but this post already uses "exception" for the language level concept]
- anarazel 2y ago> Meh. Well. Good to hear on the cleanup. Didn't know it used to be different :/ If you want to be scared: Until not too long ago postgres' supervisor process would start some types of subprocesses from within a signal handler... Not entirely surprisingly, that found bugs in various debugging tools (IIRC at least valgrind, rr, one of the sanitizer libs). > Re. SIGFPE, to be fair, it feels a bit like the "asynchronous vs. synchronous abort¹" thing on CPUs; synchronous aborts are reasonably doable while on asynchronous aborts you're pretty much left with torching things down far and wide. Agreed, I think it's quite reasonable to use signals + longjmp() for the FP error case. In fact, I think we should do so more widely - we loose a fair bit of performance due to all kinds of floating point error checking that we could set up to instead signal.
- chuckadams 2y agoLambdaMOO which dates from the early 90’s uses setjmp/longjmp to implement structured exceptions in C, which it throws on task timeouts (though not for anything else afaik). Even has try/throw/catch macros.
- eqvinox 2y agoTo qualify this a bit, the reference to longjmp() is kind of a red herring; in general the list of things you can do in a signal handler is very limited (as documented by signal-safety(7) that you reference.) longjmp() is just one prominent item on that list of things you can't (or shouldn't do.) None of the items on that list allow you to cleanly terminate the thread (you can send another signal to yourself or another thread, but that's only very conditionally helpful.) pthread_cancel() does the one and only sane thing - implement a flag mechanism that is checked in a bunch of well-specified places, and gated with an enable. Whether these well-specified places work for a particular application is definitely a tough question, but either way anything sane will be some type of "set flag and interrupt long-running (I/O) operations" combination.