Bug 12507 – SysTime.init.toString should not segfault

Status
RESOLVED
Resolution
FIXED
Severity
normal
Priority
P2
Component
phobos
Product
D
Version
D2
Platform
All
OS
All
Creation time
2014-04-02T20:26:34Z
Last change time
2018-06-26T11:33:57Z
Assigned to
No Owner
Creator
Vladimir Panteleev
Depends on
12624

Comments

Comment #0 by dlang-bugzilla — 2014-04-02T20:26:34Z
SysTime.init.toString unconditionally dereferences the timezone field (indirectly - it calls adjTime which does so), which will be null for SysTime.init. This needlessly complicates debugging - writeln(t) will segfault if t has not been set. Question: what should be returned? null? "null" the string literal (like what printf does for null pointers)? The time sans timezone ("0001-Jan-01 00:00:00")?
Comment #1 by issues.dlang — 2014-04-02T21:55:08Z
SysTime.init is supposed to be equivalent to SysTime(0, LocalTime()) - which would be 0001-Jan-01T00:00:00. The problem is that the timezone can't be initialized with LocalTime at compile time, so SysTime.init can't have a valid timezone. I believe that this limitation is documented. The only way to work around it would be to check for the timezone for null on every operation that uses it, which would then incur constant overhead for all SysTime objects just to try and make it so that SysTime.init is valid. I concluded that that wasn't worth it and instead opted for documenting the behavior. toString is just one of SysTime's functions which is affected by the problem. I suppose that we could add a check specifically for toString and let the operations still segfault for SysTime.init, but that seems rather inconsistent to me. My take on it is generally that you just shouldn't be doing much of anything with SysTime.init except using it as a default-initialized value that gets reassigned before you actually do anything with the object. I'm not super-enthused with the situation, but as far as I can see, there is no solution that results in SysTime.init being valid without adding extra overhead.
Comment #2 by issues.dlang — 2014-04-02T22:08:36Z
Actually, on further reflection, I think that it might be possible to make SysTime.init equivalent to SysTime(0, UTC()) and have it have a valid timezone. Around dconf last year, someone made it so that immutable classes could be created at compile time and continue on to runtime - so if a struct's member is an immutable class, it can be initialized at compile time. At the time, I tried to make that work with SysTime but ran into two problems: 1. SysTime uses a Rebindable!(immutable TimeZone), and the Rebindable couldn't be assigned at compile time (a limitation with unions during CTFE IIRC). 2. Because LocalTime needs to call tzset when it's initialized, even if the issue with Rebindable was fixed, SysTime.init's timezone field couldn't be initialized with LocalTime. However, UTC doesn't have that problem. So, if the issue with Rebindable has been fixed (IIRC, I opened a bug on it, but I'd have to track it down), then we could make SysTime.init use UTC. That's not quite idea IMHO, since SysTime normally defaults to using LocalTime as its timezone, but it _would_ allow us to make it so that SysTime.init had a valid timezone without adding runtime checks, and since SysTime.init is currently invalid anyway, it wouldn't break any code.
Comment #3 by issues.dlang — 2014-04-02T23:01:59Z
Comment #4 by issues.dlang — 2014-04-20T10:46:34Z
Comment #5 by harald_zealot — 2015-11-19T15:38:10Z
What is currently status of this? I have hit this just now, and it consumes 1 hour of investigation.
Comment #6 by issues.dlang — 2015-11-22T00:03:44Z
(In reply to Alaksiej Stankievič from comment #5) > What is currently status of this? > > I have hit this just now, and it consumes 1 hour of investigation. As the "Depends on" field indicates, it's blocked by issue# 12624. Attempting to provide a default TimeZone to SysTime won't compile on Windows due to a bug in the compiler backend.
Comment #7 by dlang.org — 2016-07-15T09:06:34Z
(In reply to Jonathan M Davis from comment #6) > (In reply to Alaksiej Stankievič from comment #5) > > What is currently status of this? > > > > I have hit this just now, and it consumes 1 hour of investigation. > > As the "Depends on" field indicates, it's blocked by issue# 12624. > Attempting to provide a default TimeZone to SysTime won't compile on Windows > due to a bug in the compiler backend. Since issue# 12624 has apparently been fixed, how are things looking for this issue?
Comment #8 by issues.dlang — 2016-07-15T09:16:42Z
(In reply to MichaelZ from comment #7) > Since issue# 12624 has apparently been fixed, how are things looking for > this issue? I need to find time to dig out my previous fix and make sure that it's correct and functional, but I haven't had a lot of time for D lately and other issues have been higher priority. I expect to get to it relatively soon though.
Comment #9 by issues.dlang — 2017-08-22T21:14:50Z
*** Issue 17732 has been marked as a duplicate of this issue. ***
Comment #10 by alanb — 2017-11-02T04:05:42Z
I just encounter this issue and spent an hour or so figuring out what the cause was. segfaults tend to be very difficult to track down and deal with. A quick sub-optimal fix will be better than leaving it to seg fault.
Comment #11 by n8sh.secondary — 2018-06-13T17:48:57Z
Pull request: https://github.com/dlang/phobos/pull/6581 I doubt it is of great interest to anyone precisely what is displayed by `SysTime.init.toString`, but it shouldn't cause a segfault, and fixing that is trivial.
Comment #12 by github-bugzilla — 2018-06-26T11:33:56Z
Commits pushed to master at https://github.com/dlang/phobos https://github.com/dlang/phobos/commit/9b1f72d89b6db38a05b958baf2195f552fe0aa57 Fix issue 12507: SysTime.init.toString() segfaults. This adds a special TimeZone type internal to SysTime which _timezone is directly initialized to so that SysTime.init will work without segfaulting but will still be uniquely identifiable with the is operator. Or at least, _timezone is _supposed_ to be directly initialized to it, but issue# 17740 currently prevents that. So, _timezone has been temporarily renamed to _timezoneStorage and private getters and setters named _timezone have been added. The getter then does a null check and returns InitTimeZone() for SysTime.init to simulate the member variable having been initialized to InitTimeZone(). Once issue# 17740 has been fixed, these accessors will be unnecessary, and the code should be updated so that _timezone is properly a variable again and is directly initialized with InitTimeZone(). The new TimeZone type - InitTimeZone - is internal to SysTime and can only be obtained by the timezone getter on SysTime.init. It acts the same as UTC except that it is not special-cased by the to*String functions and thus will print out its timezone as +00:00 instead of z, which is perfectly legitimate per the spec. And as such, if _timezone were directly initialized with InitTimeZone(), there would be no extra checks due to this change, and everything would just work. However, until issue# 17740 is fixed, there will be an extra null check any time that a function is called on _timezone, because _timezone is currently a wrapper that does a null check rather than being a member variable directly like it's supposed to be. Unlike previous attempts along these lines, this does not make it so that SysTime.init has NaN behavior such that any operation (other than assignment) on an an uninitialized SysTime would result in SysTime.init, and the timezone setter property does not set the SysTime to SysTime.init if it's passed this TimeZone. So, unfortunately, it _is_ possible to have other SysTime values with the special TimeZone, but it was deemed unnecessarily complex for too little benefit to add the NaN behavior. And regardless, SysTime.init is still uniquely identifiable via the is operator. It's just that it can't technically be uniquely identified by the timezone getter, which was never a supported feature anyway. https://github.com/dlang/phobos/commit/ec8bb20d28fa2ff9eeac56a00edc9d916638e61c Merge pull request #6591 from jmdavis/issue_17732_again Fix issue 12507: SysTime.init.toString() segfaults. merged-on-behalf-of: Petar Kirov <[email protected]>