Note that (a) the issue was with clearing the direction flag on signal handler entry, not saving it; and (b) it's since been fixed in the kernel to conform to the ABI (which GCC blindly trusted) [1]. And after reading that thread, I'm not as convinced as I was a few minutes ago that this was an obvious kernel issue. Yes, the kernel mismatched the published ABI, but callee-vs-caller save and setup is not always consis…
Why isn't memset() async-signal-safe?
31–40 of 98 posts
Re: Why isn't memset() async-signal-safe?
#32The post makes it a bit unclear, so for the record: there's no theoretical reason the direction flag should be a problem. Just like any other callee-saved register, the kernel needs to save it to the stack and restore it when returning from the signal handler; there's nothing about the direction flag that makes it harder to do so, even if a signal handler is interrupting another signal handler or whatnot. And before…
I don't know what historical architectures may have had a bug with this, but it's not true of x86. If memset isn't signal-safe on modern x86 linux, it's surely not because of EFLAGS state management.
Re: Why isn't memset() async-signal-safe?
#33Earlier quoted context omitted.
Oh wow. When did this change? I vaguely seem to remember that as recently as Windows 7 (or was it 8.0?) there was trouble with AVX2 or something, but I can't find the info anywhere at the moment.
An OS can still use xsave incorrectly, such as by hardcoding the expected size rather than detecting it at runtime, or by getting some aspect of the CPUID leaf 0xd enumeration wrong. I wouldn't find it surprising if an initial implementation got one of the details wrong, resulting in a bug that wouldn't manifest until the next time the xsave layout changed.
Re: Why isn't memset() async-signal-safe?
#34 while(n--)
*m++ = c;
With a call to the built in memset()Re: Why isn't memset() async-signal-safe?
#35(For a long time, I thought that literally the only thing that POSIX didn't fuck up is the way they don't have any analogue to MAXIMUM_WAIT_OBJECTS. But then, after I gained more experience with POSIX, I realised that even if I don't understand how, this too was probably also something they got wrong.)
Re: Why isn't memset() async-signal-safe?
#36Related: Unix signals are deemed "unfixable" by some: https://lwn.net/Articles/414618/
http://stackoverflow.com/questions/13341870/signals-and-inte...
I have the intuition knowing the HW/ASM & the code but ignoring how POSIX works (I read stevens, but I am not having all my answers) that unices reimplement in SW what the HW does with wires.
Maybe this could be fixable at the HW level? (and maybe I guess requiring kernel privileges)?
Re: Why isn't memset() async-signal-safe?
#37Tricky! Even writing your own memset would experience the same behavior, since the compiler will assume the direction flag is unset. I agree with colanderman; the kernel should be saving every register when the signal handler is entered.
But I won't restart a war that has ended the day x86 architecture won over 68K.
Re: Why isn't memset() async-signal-safe?
#38Re: Why isn't memset() async-signal-safe?
#39Seems like a good argument against an architecture having stateful flags that affect the execution of other instructions. Or, at least, against having such flags and not including them in the state saved and restored when switching contexts (including to signals).
Re: Why isn't memset() async-signal-safe?
#40Couple of things. First, I don't think that's true nowadays. The discussion points that this (not restoring DF on signal return) is a kernel bug and should be fixed: https://lkml.org/lkml/2008/3/5/531 Second, the kernel tries to avoid doing too much work in the signal return code. It tries hard do _avoid_ heavy XSAVE and just preserve only the needed registers. This is the job of sigreturn(2) syscall btw. http://man7…
I mean, kernel bug or no, if that's how it actually works, then it isn't actually safe to be handle signals while executing these functions. If people are still working to change the code and standards we hold the code to, then you can't push changes that rely on the new behavior without introducing some truly bizarre race conditions.
> The conclusion is that DF=1 in x86_64 64-bit code is extremely rare