possible snprintf() regression in 3.3.2
Tony Cook
tony@develop-help.com
Wed Nov 17 00:37:18 GMT 2021
This came up from regression testing perl.
Regression testing of perl @4a1b9dd524007193213d3919d6a331109608b90c
used (from uname):
cygwin_nt-10.0 fv-az177-186 3.3.1(0.34153) 2021-10-28 20:52 x86_64 cygwin
this did not exhibit the problem. See https://github.com/Perl/perl5/runs/4084168038?check_suite_focus=true
Testing of perl @a85e04e2281234a61c051f8f3ff63bed7381902c, the next
commit, which is purely a documentation change did exhibit the bug, used:
cygwin_nt-10.0 fv-az177-290 3.3.2(0.34153) 2021-11-08 16:55 x86_64 cygwin
which did crash. See https://github.com/Perl/perl5/runs/4159124596?check_suite_focus=true
snprintf() appears to be crashing internally to ldtoa_r(), without
cygwin-debuginfo the backtrace is:
Thread 1 "perl" received signal SIGSEGV, Segmentation fault.
0x00007ffd26b21548 in ntdll!RtlVirtualUnwind ()
from /cygdrive/c/WINDOWS/SYSTEM32/ntdll.dll
(gdb) bt
#0 0x00007ffd26b21548 in ntdll!RtlVirtualUnwind ()
from /cygdrive/c/WINDOWS/SYSTEM32/ntdll.dll
#1 0x00007ffd26b21040 in ntdll!RtlVirtualUnwind ()
from /cygdrive/c/WINDOWS/SYSTEM32/ntdll.dll
#2 0x00007ffd26b20e7b in ntdll!RtlVirtualUnwind ()
from /cygdrive/c/WINDOWS/SYSTEM32/ntdll.dll
#3 0x00007ffd26b413a8 in ntdll!RtlRaiseException ()
from /cygdrive/c/WINDOWS/SYSTEM32/ntdll.dll
#4 0x00007ffd26b90bfe in ntdll!KiUserExceptionDispatcher ()
from /cygdrive/c/WINDOWS/SYSTEM32/ntdll.dll
#5 0x00000001801fec7c in eiremain () from /usr/bin/cygwin1.dll
#6 0x0000000180200319 in _ldtoa_r () from /usr/bin/cygwin1.dll
#7 0x00000001801cfca9 in _svfprintf_r () from /usr/bin/cygwin1.dll
#8 0x00000001801bf327 in snprintf () from /usr/bin/cygwin1.dll
#9 0x000000018018eb0b in _sigfe () from /usr/bin/cygwin1.dll
#10 0x0000000052162647 in Perl_sv_vcatpvfn_flags (my_perl=0x80004a3e0,
sv=0x800ca9e78, pat=0x523a3501 <regexp_core_intflags_names+4769> "%.9f",
patlen=4, args=0xffffc550, svargs=0x0, sv_count=0, maybe_tainted=0x0,
flags=0) at sv.c:13482
#11 0x000000005215e360 in Perl_sv_vsetpvfn (my_perl=0x80004a3e0,
sv=0x800ca9e78, pat=0x523a3501 <regexp_core_intflags_names+4769> "%.9f",
patlen=4, args=0xffffc550, svargs=0x0, sv_count=0, maybe_tainted=0x0)
at sv.c:11271
#12 0x000000005215dde9 in Perl_sv_vsetpvf (my_perl=0x80004a3e0,
sv=0x800ca9e78, pat=0x523a3501 <regexp_core_intflags_names+4769> "%.9f",
args=0xffffc550) at sv.c:11101
#13 0x000000005215dd6a in Perl_sv_setpvf (my_perl=0x80004a3e0, sv=0x800ca9e78,
pat=0x523a3501 <regexp_core_intflags_names+4769> "%.9f") at sv.c:11076
#14 0x000000005210aa74 in Perl_upg_version (my_perl=0x80004a3e0,
ver=0x800cacb00, qv=false) at /home/tony/dev/perl/git/perl/vutil.c:700
#15 0x00000000520440a4 in XS_universal_version (my_perl=0x80004a3e0,
cv=0x80004dfa0) at /home/tony/dev/perl/git/perl/vxs.inc:122
#16 0x0000000052142b10 in Perl_pp_entersub (my_perl=0x80004a3e0)
at pp_hot.c:5361
#17 0x00000000521318e7 in Perl_runops_standard (my_perl=0x80004a3e0)
at run.c:41
#18 0x00000000520376ff in S_run_body (my_perl=0x80004a3e0, oldscope=1)
at perl.c:2715
#19 0x0000000052037214 in perl_run (my_perl=0x80004a3e0) at perl.c:2643
#20 0x000000010040117c in main (argc=4, argv=0xffffcc00, env=0x8000281a0)
at perlmain.c:110
With cygwin-debuginfo installed the backtrace is:
Thread 1 "perl" received signal SIGSEGV, Segmentation fault.
0x00007ffd26b21548 in ntdll!RtlVirtualUnwind ()
from /cygdrive/c/WINDOWS/SYSTEM32/ntdll.dll
(gdb) bt
#0 0x00007ffd26b21548 in ntdll!RtlVirtualUnwind ()
from /cygdrive/c/WINDOWS/SYSTEM32/ntdll.dll
#1 0x00007ffd26b21040 in ntdll!RtlVirtualUnwind ()
from /cygdrive/c/WINDOWS/SYSTEM32/ntdll.dll
#2 0x00007ffd26b20e7b in ntdll!RtlVirtualUnwind ()
from /cygdrive/c/WINDOWS/SYSTEM32/ntdll.dll
#3 0x00007ffd26b413a8 in ntdll!RtlRaiseException ()
from /cygdrive/c/WINDOWS/SYSTEM32/ntdll.dll
#4 0x00007ffd26b90bfe in ntdll!KiUserExceptionDispatcher ()
from /cygdrive/c/WINDOWS/SYSTEM32/ntdll.dll
#5 0x00000001801fec7c in eiremain (den=0x1, num=0x0, ldp=0x5)
at /usr/src/debug/cygwin-3.3.2-1/newlib/libc/stdlib/ldtoa.c:3736
#6 0x00000001802bb0b0 in etens () from /usr/bin/cygwin1.dll
#7 0x00000000ffffbac2 in ?? ()
Backtrace stopped: previous frame inner to this frame (corrupt stack?)
The stack appears to be badly corrupted (etens isn't a function).
Unfortunately I haven't been able to make a simple pure C reproducer
for this.
To reproduce:
Fetch and build perl (needs make, gcc):
$ git clone https://github.com/Perl/perl5.git
$ cd perl5
$ ./Configure -des -Dusedevel -Doptimize=-O0\ -g
# adjust -j6 to the desired parallel jobs
$ make -j6 test-prep
reproducing the original failure:
$ cd t ; gdb --args ./perl -I.. -MTestInit ../cpan/version/t/01base.t
a simpler test case, with some debugging:
$ echo '$Foo::VERSION = 9.e99; eval { Foo->VERSION(9e99) }' >mytest.pl
$ gdb --args ./perl mytest.pl
...
Reading symbols from ./perl...
(gdb) b vutil.c:700
No source file named vutil.c.
Make breakpoint pending on future shared library load? (y or [n]) y
Breakpoint 1 (vutil.c:700) pending.
(gdb) r
Starting program: /home/tony/dev/perl/git/perl/perl mytest.pl
[New Thread 16120.0x3a54]
[New Thread 16120.0x3368]
[New Thread 16120.0x134]
[New Thread 16120.0x133c]
Thread 1 "perl" hit Breakpoint 1, Perl_upg_version (my_perl=0x80004a3b0,
ver=0x800090c98, qv=false) at /home/tony/dev/perl/git/perl/vutil.c:700
700 Perl_sv_setpvf(aTHX_ sv, "%.9" NVff, SvNVX(ver));
(gdb) b sv.c:13482
Breakpoint 2 at 0x521624f6: file sv.c, line 13482.
(gdb) c
Continuing.
Thread 1 "perl" hit Breakpoint 2, Perl_sv_vcatpvfn_flags (my_perl=0x80004a3b0,
sv=0x800090c80, pat=0x523a3501 <regexp_core_intflags_names+4769> "%.9f",
patlen=4, args=0xffffc580, svargs=0x0, sv_count=0, maybe_tainted=0x0,
flags=0) at sv.c:13482
13482 WITH_LC_NUMERIC_SET_TO_NEEDED_IN(in_lc_numeric,
(gdb) p my_perl->Iefloatbuf
$1 = 0x80009b540 ""
(gdb) p my_perl->Iefloatsize
$2 = 177
(gdb) p ptr
$3 = 0xffffc44a "%.9f"
(gdb) p fv
$4 = 8.99999999999999994886e+99
(gdb) c
Continuing.
[New Thread 16120.0x3a98]
[New Thread 16120.0x1c3c]
Thread 1 "perl" received signal SIGSEGV, Segmentation fault.
0x00007ffd26b21548 in ntdll!RtlVirtualUnwind ()
from /cygdrive/c/WINDOWS/SYSTEM32/ntdll.dll
The code at sv.c:13482 is 13482 is:
WITH_LC_NUMERIC_SET_TO_NEEDED_IN(in_lc_numeric,
elen = ((intsize == 'q')
? my_snprintf(PL_efloatbuf, PL_efloatsize, ptr, fv)
: my_snprintf(PL_efloatbuf, PL_efloatsize, ptr, (double)fv))
);
Given the macro definitions and value of intsize at this point, this
becomes a call to snprintf:
snprintf(my_perl->Iefloatbuf, my_perl->Iefloatsize, ptr, (double)fv)
I suspect
https://cygwin.com/git/?p=newlib-cygwin.git;a=commit;h=4d90e5335914551862831de3e02f6c102b78435b
but I'm not really setup to build and debug cygwin.
Tony
More information about the Cygwin
mailing list