On Mon, 24 Mar 2025 11:59:58 +0100 Christian Franke wrote: > Takashi Yano wrote: > > x86_64 ABI requires the direction flag in CPU flags register cleared. > > https://learn.microsoft.com/en-us/cpp/build/x64-software-conventions > > However, currently that flag is not maintained in signal handler. > > Therefore, if the signal handler is called when that flag is set, it > > destroys the data and may crash if rep instruction is used in the > > signal handler. With this patch, the direction flag is cleared in > > sigdelayed() by adding cld instruction. > > > > Addresses: https://cygwin.com/pipermail/cygwin/2025-March/257704.html > > Fixes: 1fd5e000ace5 ("import winsup-2000-02-17 snapshot") > > Reported-by: Christian Franke <christian.fra...@t-online.de> > > Reviewed-by: > > Signed-off-by: Takashi Yano <takashi.y...@nifty.ne.jp> > > --- > > winsup/cygwin/scripts/gendef | 1 + > > 1 file changed, 1 insertion(+) > > > > diff --git a/winsup/cygwin/scripts/gendef b/winsup/cygwin/scripts/gendef > > index a2f0392bc..861a2405b 100755 > > --- a/winsup/cygwin/scripts/gendef > > +++ b/winsup/cygwin/scripts/gendef > > @@ -179,6 +179,7 @@ sigdelayed: > > movq %rsp,%rbp > > pushf > > .seh_pushreg %rax # fake, there's no .seh_pushreg > > for the flags > > + cld # x86_64 ABI requires direction > > flag cleared > > # stack is aligned or unaligned on entry! > > # make sure it is aligned from here on > > # We could be called from an interrupted thread which doesn't know > > Works as expected: > - the testcase no longer aborts. > > - a version with modified main loop does not detect DF modification by > the signal: > > while ((cnt = sigcnt) < 1000) { > if (!(__builtin_ia32_readeflags_u64() & 0x0400) != !std) > return 13; > if ((cnt & 1) && !std) { > asm volatile ("std"); > std = 1; > } > else if (!(cnt & 1) && std) { > asm volatile ("cld"); > std = 0; > } > } > > - The related stress-ng testcases no longer report segfaults: > > $ n=0 > $ while > stress-ng --parallel 2 --with memcpy,tree --memcpy-method libc > --tree-method btree -t 2; > do echo OK $((++n)); done > ... > OK 500 > ...
Thanks for testing! -- Takashi Yano <takashi.y...@nifty.ne.jp>