Found because 'stress-ng --memcpy ...' and other tests report segfaults:
An exception 0xc0000374 (STATUS_HEAP_CORRUPTION) occurs if a signal
arrives during a memmove() which copies backwards due to overlap.
The related snippet[s] from winsup/cygwin/x86_64/bcopy.S:
std
rep
movs[qb]
cld
The testcase below shows that a set DF arrives at the signal handler.
This violates the ABI, AFAIK. After return, the process aborts
regardless of a "cld" in the signal handler.
$ uname -r # also reproducible with 3.5.7-1
3.6.0-1.x86_64
$ cat dflagsig.c
#include <signal.h>
#include <unistd.h>
static volatile sig_atomic_t sigcnt;
static void sighandler(int sig)
{
(void)sig;
// asm volatile ("cld"); // <== does not prevent crash
if (__builtin_ia32_readeflags_u64() & 0x0400)
write(1, "[DF=1]\n", 7);
else
write(1, "[DF=0]\n", 7);
++sigcnt;
}
int main()
{
signal(SIGINT, sighandler);
int std = 0, cnt;
while ((cnt = sigcnt) < 5) {
if (cnt == 2 && !std) {
asm volatile ("std");
std = 1;
}
else if (cnt > 2 && std) {
asm volatile ("cld");
std = 0;
}
}
return 42;
}
$ gcc -o dflagsig dflagsig.c
$ ./dflagsig # ... and press 3x ^C
[DF=0]
[DF=0]
[DF=1]
$ echo $? # Hmm... "silent" crash!
0
$ strace ./dflagsig # ... and run 3x 'kill -INT 1288' from other window
...
48 14882485 [main] dflagsig 1288 set_signal_mask: setmask 2, newmask
0, mask_bits 2
863030 15745515 [sig] dflagsig 1288 sigpacket::process: signal 2 processing
...
55 15746773 [sig] dflagsig 1288 _cygtls::interrupt_setup: armed
signal_arrived 0x0, signal 2
70 15746843 [sig] dflagsig 1288 sigpacket::setup_handler: signal 2
delivered
--- Process 12736 (pid: 1288), exception c0000374 at 00007ffe342dcba9
...
--- Process 12736 exited with status 0xc0000374
--
Regards,
Christian
--
Problem reports: https://cygwin.com/problems.html
FAQ: https://cygwin.com/faq/
Documentation: https://cygwin.com/docs.html
Unsubscribe info: https://cygwin.com/ml/#unsubscribe-simple