On Saturday 22 November 2025 14:33:22 Pali Rohár wrote:
> On Saturday 22 November 2025 20:34:06 LIU Hao wrote:
> > 在 2025-11-22 09:24, Pali Rohár 写道:
> > > I'm somehow not able to trigger this issue.
> > > 
> > > On 64-bit Windows 10 system I'm always getting this line which does not
> > > trigger Assertion failed:
> > > 
> > > pacific _localtime32(1112524200): sec=0 min=30 hour=3 mday=3 mon=3 
> > > year=105 wday=0 yday=92 isdst=1
> > > 
> > > This output is from 32-bit crtdll, msvcrt, ucrt and 64-bit msvcrt and 
> > > ucrt builds.
> > > 
> > > I also tested it on the clean evaluation Windows Server 2022
> > > installation and the output is same, the test is passing.
> > > 
> > > Any idea what I could have missed?
> > 
> > This issue can be reproduced with UCRT, so I can build it in Visual Studio,
> > linking against Microsoft debug CRT, and step into UCRT sources.
> > 
> > In C:\Program Files (x86)\Windows Kits\10\Source\10.0.26100.0\ucrt\time 
> > there's:
> > 
> >    int  daylight = 0;
> >    long dstbias  = 0;
> >    long timezone = 0;
> >    _ERRCHECK(_get_daylight(&daylight));
> >    _ERRCHECK(_get_dstbias (&dstbias ));   // <<==== gets DST bias into 
> > `dstbias`
> >    _ERRCHECK(_get_timezone(&timezone));
> > 
> > The offending invocation to `_localtime32()`, which reaches here indirectly,
> > receives a value of 0 in `dstbias`. It should be -3600.
> > 
> > 
> > And here's its implementation:
> > 
> >    extern "C" errno_t __cdecl _get_dstbias(long* result)
> >    {
> >        _VALIDATE_RETURN_ERRCODE(result != nullptr, EINVAL);
> > 
> >        // This variable is correctly inited at startup, so no need to check 
> > if
> >        // CRT init finished.
> >        *result = _dstbias.value();
> >        return 0;
> >    }
> > 
> > This comment is incorrect. It seems that the value is not initialized at
> > startup, but by the first call to `_localtime32()`. If all those calls to
> > `_localtime32()` and `_localtime64()` before the loop are removed, the
> > assertion will pass.
> > 
> > This might explain why it doesn't fail on your side; maybe you are in that
> > time zone, but otoh I'm not (we don't do DST whatsoever).
> > 
> > 
> > And the fact that `_dstbias` is a static object probably means that it's
> > impossible to change the time zone with `putenv("TZ=PST8PDT"); tzset();`
> > once a TZ-aware function has been called.
> > 
> > So the test could be split into three files.
> > 
> > 
> > -- 
> > Best regards,
> > LIU Hao
> 
> Thank you for debugging this. Now I think I see where is the bug.
> The hint with (system) timezone which does not have DST active helped
> there.
> 
> If I unset "Automatically adjust clock for daylight saving changes"
> option in Windows Date and Time system dialog then the test starts failing.
> 
> I played a bit with it and seems that the default _dstbias variable has
> value -3600. And first usage of mktime/localtime reinitialize timezone
> from TZ variable.
> 
> But It looks like that _dstbias variable is changed only when changing
> timezone to the system one, and in this case it is set to the system tz
> dst bias value. When changing timezone to the non-system timezone
> (e.g. TZ=PST8PDT) then the _dstbias variable is unchanged.
> 
> At the beginning of the test is used system timezone as TZ env is not
> set (which initialize _dstbias variable to the system value), then there
> is a switch to TZ=PST8PDT (which does not touch _dstbias variable) and
> so pacific tests starts failing if the system tz dst bias is not same as
> for PST8PDT zone.
> 
> For me it looks like a bug that _tzset does not change _dstbias to -3600
> when env TZ=PST8PDT is set, but rather let _dstbias to the old value.
> 
> Simple test case:
> 
>   #include <stdio.h>
>   #include <time.h>
> 
>   int main() {
> 
>     printf("_dstbias=%ld\n", _dstbias);
> 
>     printf("_tzset()\n");
>     _tzset();
> 
>     printf("_dstbias=%ld\n", _dstbias);
> 
>     printf("_putvenv(\"TZ=PST8PDT\")\n");
>     _putenv("TZ=PST8PDT");
> 
>     printf("_tzset()\n");
>     _tzset();
> 
>     printf("_dstbias=%ld\n", _dstbias);
> 
>     return 0;
> 
>   }
> 
> With "Automatically adjust clock for daylight saving changes" option
> enabled in system settings it prints:
> 
>   _dstbias=-3600
>   _tzset()
>   _dstbias=-3600
>   _putvenv("TZ=PST8PDT")
>   _tzset()
>   _dstbias=-3600
> 
> And when that option is unchecked it prints:
> 
>   _dstbias=-3600
>   _tzset()
>   _dstbias=0
>   _putvenv("TZ=PST8PDT")
>   _tzset()
>   _dstbias=0
> 
> If you think that this is a bug, could somebody with ms account report
> this UCRT issue?
> 
> 
> For our test case, I think that it splitting it into 3 different files
> and executables does not help. When using the PST8PDT timezone in the
> test we need to explicitly set _dstbias variable to -3600 after _tzset()
> call, as msvcrt and UCRT does not do it for us.

I would propose following fix for this failing test:

diff --git a/mingw-w64-crt/testcases/t_time.c b/mingw-w64-crt/testcases/t_time.c
index e65e89a4c0f4..be912b889834 100644
--- a/mingw-w64-crt/testcases/t_time.c
+++ b/mingw-w64-crt/testcases/t_time.c
@@ -142,6 +142,7 @@ int main()
 
   /* following tests are explicitly for Pacific Time Zone */
   putenv ("TZ=PST8PDT");
+  _dstbias = -3600; /* tzset() does not change _dstbias when TZ= env is 
nonempty */
   tzset ();
   const struct {
     __time64_t time;
@@ -249,7 +250,8 @@ int main()
   }
 
   /* ctime, localtime and mktime returns time string in local timezone, so set 
local timezone to UTC to have test timezone independent */
-  putenv ("TZ=UTC");
+  putenv ("TZ=UTC0");
+  _dstbias = 0; /* tzset() does not change _dstbias when TZ= env is nonempty */
   tzset ();
 
   t64 = 1ULL << 33;


Could you try it on your configuration if it works?


_______________________________________________
Mingw-w64-public mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public

Reply via email to