On Tue, Oct 07, 2014 at 05:02:41PM -0400, Andrew Piskorski wrote:

> And yet it still fails in exactly the same way, with EINVAL = 22.
> This makes me think there is nothing wrong with the tlsPtr code or
> data, rather something is seriously broken in my build.

I think my analysis above was entirely wrong.  I now see evidence that
the time_t value going into ns_localtime() is incorrect after all,
likely due to some sort of type mismatch.

And, after a very small amount of testing, it looks like simply
changing the Ns_Time.sec (in nsthread.h) to be time_t rather than long
fixes nearly everything.  Those changs are here:

  https://bitbucket.org/apiskors/naviserver/commits/all

Since I'd already written it earlier when I was more confused, here's
the slow, convoluted path I took to reach that conclusion:

I was stuck, so in a stand-alone C program, I confirmed that with a
64-bit time_t (which is the default), by casting to long long I can
correctly display the integer Unix time regardless of its particular
value, like so:

  time_t clock;
  //time(&clock);  /* Now */
  //clock = 1412722229; /* Oct 2014 */
  clock = 2174774400;  /* Nov 2038*/
  printf("clock lld:  %lld\n", (long long)clock);

Note that Nov. 2038 requires a 64-bit time_t, it is too big for
32-bit.

With both those integers above, printf() displays the same value I
hard-coded into my code.  If I use other format specifiers with
printf, the displayed integer can change completely depending on the
itns value, but by casting to long long and using %lld I seem to
always get the same output as my input.

Next, I changed ns_localtime() to use the same constant, hard-coded
time_t *clock value of 2174774400.  That worked!  The EINVAL failure
went away, and I was able to start up and shut down Naviserver normally!

Or if Inside ns_localtime() I completely ignore the incoming clock
pointer and instead just call time() to get the current time myself,
that works too!

Finally, I restored ns_localtime to its normal behavior, but left in a
debugging printf, like this:

  errNum = localtime_s(&tlsPtr->ltbuf, clock);
  printf("\nDebug:atp: ns_localtime: errNum from localtime_s:  %d", errNum);
  printf("\n  clock lld:  %lld", (long long)*clock);
  printf("\n  clock  ld:  %ld" , (long)*clock);
  printf("\n  clock   d:  %d\n", (int)*clock);

And here's the corresponding output from starting up the server twice,
which immediately aborts:

Debug:atp: ns_localtime: errNum from localtime_s:  22
  clock lld:  2996724649205424
  clock  ld:  1412734640
  clock   d:  1412734640
[3280.d64][-main-] Notice: nsmain: NaviServer/4.99 starting
[3280.d64][-main-] Fatal: nsthreads: localtime_s failed in ns_localtime: win32 
err: 22

Debug:atp: ns_localtime: errNum from localtime_s:  22
  clock lld:  435292053216956
  clock  ld:  1412734652
  clock   d:  1412734652
[2892.58c][-main-] Notice: nsmain: NaviServer/4.99 starting
[2892.58c][-main-] Fatal: nsthreads: localtime_s failed in ns_localtime: win32 
err: 22

$ tclsh8.5
% clock format 435292053216956
Sat Dec 29 13:55:56 EST 2036604
% clock format 1412734640 
Tue Oct 07 22:17:20 EDT 2014

Those huge 15-digits integers are VERY far in the future, and they
change seemingly arbitrarily each time I run nsd.  But their shorter
integer representation is the correct time!  Thus my earlier
confusion, because I was calling printf with %i or %d, and only seeing
the seemingly-correct short value.

Now, Tcl can process the year 2,036,604 just fine, so I'm not sure why
the Windows localtime_s() is throwing EINVAL on those inputs.  But
those Unix time values sure seem suspect...  And that lead me to the
definition of Ns_Time.  (Which I now recall wondering about days or
weeks ago, but then forgot about.  Ugh.)

-- 
Andrew Piskorski <a...@piskorski.com>

------------------------------------------------------------------------------
Meet PCI DSS 3.0 Compliance Requirements with EventLog Analyzer
Achieve PCI DSS 3.0 Compliant Status with Out-of-the-box PCI DSS Reports
Are you Audit-Ready for PCI DSS 3.0 Compliance? Download White paper
Comply to PCI DSS 3.0 Requirement 10 and 11.5 with EventLog Analyzer
http://pubads.g.doubleclick.net/gampad/clk?id=154622311&iu=/4140/ostg.clktrk
_______________________________________________
naviserver-devel mailing list
naviserver-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/naviserver-devel

Reply via email to