www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Segfault when using SysTime

reply knommad <spam_D asylum.id.au> writes:
Hi,

(I'm not sure whether I should be posting these here...apologies if this is 
inappropriate).


Test case: (test.d)
import std.datetime;
import std.stdio;


void main()
{
    // SysTime is a struct that should be default initialised
    SysTime unInitialisedTime;

    // Will segfault on this next line...
    writeln("Time is: ", unInitialisedTime );

    writeln("ending now...");

}

Compiled with dmd 2.056: dmd -wi -oftest test.d.

Result:
Segmentation Fault.

I did attempt to delve into the intricacies of the std.datetime library, but 
understanding the techniques used is currently beyond my skill level.

Obviously, something is not being initialised properly?

regards,
ted


-- 
                  Experience is simply the name we give our mistakes.
                                                       -- Oscar Wilde
Nov 04 2011
next sibling parent reply Jonathan M Davis <jmdavisProg gmx.com> writes:
On Friday, November 04, 2011 18:53:28 knommad wrote:
 Hi,
 
 (I'm not sure whether I should be posting these here...apologies if this is
 inappropriate).
 
 
 Test case: (test.d)
 import std.datetime;
 import std.stdio;
 
 
 void main()
 {
     // SysTime is a struct that should be default initialised
     SysTime unInitialisedTime;
 
     // Will segfault on this next line...
     writeln("Time is: ", unInitialisedTime );
 
     writeln("ending now...");
 
 }
 
 Compiled with dmd 2.056: dmd -wi -oftest test.d.
 
 Result:
 Segmentation Fault.
 
 I did attempt to delve into the intricacies of the std.datetime library, but
 understanding the techniques used is currently beyond my skill level.
 
 Obviously, something is not being initialised properly?

Similar to how float.init is not a valid value (float.NAN), SysTime.init is not a valid value. Aside from arguments over whether a struct's init value should be a value intended to be used or not, SysTime has a member which is a class - TimeZone - and since CTFE can't handle classes - let alone one which is initialized at compile time and then used at runtime - SysTime.init _cannot_ have a valid TimeZone and therofere SysTime.init cannot be valid (unless we were to introduce the extra overhead of constantly checking that the TimeZone isn't null and setting it to LocalTime if it is, which is unacceptable IMHO). And since, SysTime.init isn't valid, you _must_ initialize a SysTime if you want to avoid segfaults. If you want to know more about std.datetime, I suggest that you read this article: http://d-programming-language.org/intro-to-datetime.html - Jonathan M Davis
Nov 04 2011
next sibling parent reply knommad <spam_D asylum.id.au> writes:
Jonathan M Davis wrote:

 On Friday, November 04, 2011 18:53:28 knommad wrote:
 Hi,
 
 (I'm not sure whether I should be posting these here...apologies if this
 is inappropriate).
 
 
 Test case: (test.d)
 import std.datetime;
 import std.stdio;
 
 
 void main()
 {
     // SysTime is a struct that should be default initialised
     SysTime unInitialisedTime;
 
     // Will segfault on this next line...
     writeln("Time is: ", unInitialisedTime );
 
     writeln("ending now...");
 
 }
 
 Compiled with dmd 2.056: dmd -wi -oftest test.d.
 
 Result:
 Segmentation Fault.
 
 I did attempt to delve into the intricacies of the std.datetime library,
 but understanding the techniques used is currently beyond my skill level.
 
 Obviously, something is not being initialised properly?

Similar to how float.init is not a valid value (float.NAN), SysTime.init is not a valid value. Aside from arguments over whether a struct's init value should be a value intended to be used or not, SysTime has a member which is a class - TimeZone - and since CTFE can't handle classes - let alone one which is initialized at compile time and then used at runtime - SysTime.init _cannot_ have a valid TimeZone and therofere SysTime.init cannot be valid (unless we were to introduce the extra overhead of constantly checking that the TimeZone isn't null and setting it to LocalTime if it is, which is unacceptable IMHO). And since, SysTime.init isn't valid, you _must_ initialize a SysTime if you want to avoid segfaults. If you want to know more about std.datetime, I suggest that you read this article: http://d-programming-language.org/intro-to-datetime.html - Jonathan M Davis

Hi, Thanks for the answer (nicely written article btw). I actually found this issue via a problematic path. I'm writing a (multi- threaded) application in D (within the company I work for), and have structures that have SysTime elements within them. I hadn't always been ensuring that this member was initialised properly (not always important for the task), but when I wanted to toString() the members - I had a silent death. The silent death was not a segfault, and gdb considered the application to have exited normally. This was not easy to nail down ! (a nice segfault would have been helpful at that point....:) I guess I'm also expecting (hoping ?) that stray pointer-like behaviours in D to be few and far between (as opposed to the float.NAN issue). I'm happy to accept that I may be naive here, however. Keep up the good work ! regards, ted -- When the student is ready, the teacher will appear -- Buddhist Proverb
Nov 04 2011
parent Kagamin <spam here.lot> writes:
knommad Wrote:

 structures that have SysTime elements within them. I hadn't always been 
 ensuring that this member was initialised properly (not always important for 
 the task), but when I wanted to toString() the members - I had a silent 
 death.

try std.conv.text, it may handle null pointers.
Nov 04 2011
prev sibling parent reply bearophile <bearophileHUGS lycos.com> writes:
Jonathan M Davis:

 and since CTFE can't handle classes - let alone one which is 
 initialized at compile time and then used at runtime

I think CTFE will handle classes in the next DMD version (and in the current GitHub one). Bye, bearophile
Nov 04 2011
parent Don <nospam nospam.com> writes:
On 04.11.2011 18:27, Jonathan M Davis wrote:
 On Friday, November 04, 2011 06:07 bearophile wrote:
 Jonathan M Davis:
 and since CTFE can't handle classes - let alone one which is
 initialized at compile time and then used at runtime

I think CTFE will handle classes in the next DMD version (and in the current GitHub one).

But it's not just a question of handling classes. It has to handle the case where the class persists during runtime. From what Don has said in the past, I'm pretty sure that supporting classes in CTFE is going to translate to being able to use functions that use classes but that none of the classes created will be able to be assigned to any variables which persist beyond compilation. It needs to become possible to do something like static immutable _localTime = new immutable(LocalTime)(); For SysTime.init to be valid, LocalTime's instance must be created at compile time and persist beyond compilation, and then SysTime's _timezone member variable needs to be initialized to it - which would also persist beyond compilation. If Don manages to make that work, that's fantastic, but there's a definite difference between being able to use classes with CTFE and initialize member and static variables with classes using CTFE, and it is my understanding that that we're only getting to use classes in CTFE, not persist them. But maybe we're lucky, and I'm wrong about that. - Jonathan M Davis

That's right. The next release will support classes (and exceptions) in CTFE, but as you say, it cannot pass them to run time. This is an issue of the glue layer in the compiler. I do know how it could be done. It will happen eventually, but not soon.
Nov 04 2011
prev sibling next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Friday, November 04, 2011 19:37:56 knommad wrote:
 Hi,
 Thanks for the answer (nicely written article btw).
 
 I actually found this issue via a problematic path. I'm writing a (multi-
 threaded) application in D (within the company I work for), and have
 structures that have SysTime elements within them. I hadn't always been
 ensuring that this member was initialised properly (not always important for
 the task), but when I wanted to toString() the members - I had a silent
 death.
 
 The silent death was not a segfault, and gdb considered the application to
 have exited normally. This was not easy to nail down ! (a nice segfault
 would have been helpful at that point....:)
 
 I guess I'm also expecting (hoping ?) that stray pointer-like behaviours in
 D to be few and far between (as opposed to the float.NAN issue). I'm happy
 to accept that I may be naive here, however.
 
 Keep up the good work !

I would have expected a segfault, since that's what normally happens when dereferencing a null reference, so I don't know what the issue there is. If you could come up with a small enough test case, it may be worth looking into. I'd love for SysTime.init's time zone to be LocalTime, but that's just not possible at this point, so we're pretty much stuck with a null reference. But the lack of segfault is still weird. - Jonathan M Davis
Nov 04 2011
prev sibling parent "Jonathan M Davis" <jmdavisProg gmx.com> writes:
On Friday, November 04, 2011 06:07 bearophile wrote:
 Jonathan M Davis:
 and since CTFE can't handle classes - let alone one which is
 initialized at compile time and then used at runtime

I think CTFE will handle classes in the next DMD version (and in the current GitHub one).

But it's not just a question of handling classes. It has to handle the case where the class persists during runtime. From what Don has said in the past, I'm pretty sure that supporting classes in CTFE is going to translate to being able to use functions that use classes but that none of the classes created will be able to be assigned to any variables which persist beyond compilation. It needs to become possible to do something like static immutable _localTime = new immutable(LocalTime)(); For SysTime.init to be valid, LocalTime's instance must be created at compile time and persist beyond compilation, and then SysTime's _timezone member variable needs to be initialized to it - which would also persist beyond compilation. If Don manages to make that work, that's fantastic, but there's a definite difference between being able to use classes with CTFE and initialize member and static variables with classes using CTFE, and it is my understanding that that we're only getting to use classes in CTFE, not persist them. But maybe we're lucky, and I'm wrong about that. - Jonathan M Davis
Nov 04 2011