I have a C++ application running on a Raspberry Pi (DietPi Distro - Jessie) and am using GPS data to update the system time at boot. The code is simple, however, it crashes or locks up the application about 50% of the time. No exceptions are thrown and I've tried to capture any stderr in a log file with no success. Occasionally I see a segmentation fault, but I think this may be unrelated.
The portion of the code that clearly causes the crash is "settimeofday(&tv, NULL)". I can comment out only this and it will run fine, but here's the segment of code that assigns timeval 'tv' and changes the system time:
//Convert gps_data_t* member 'time' to timeval
timeval tv;
double wholeseconds, decimalseconds, offsettime;
offsettime = gpsdata->fix.time - (5.0 * 3600.0);
decimalseconds = modf(offsettime, &wholeseconds);
tv.tv_sec = static_cast<int32_t>(wholeseconds);
tv.tv_usec = static_cast<int32_t>(decimalseconds * 1000000.0);
//Set system time - THIS IS CAUSING CRASHES, WHY?
if ( settimeofday(&tv, NULL) >= 0) {
std::cout << "Time set successful!" << '\n';
} else {
std::cout << "Time set failure!" << '\n';
}
A point I would like to make is the setting of the time is successful when the system crashes. I have seen it unsuccessful in the case where gpsdata->fix.time is 'NaN', and it seems to handle this well and just report a failure. My own theories of possible causes:
This is a multi-threading program where several other threads are in a sleep state (std::this_thread::sleep_for() used extensively). Does changing the system time while these threads are in a sleep state interfere with the time it comes out of sleep?
I know there is a time service (NTP?) in the Debian distro that manages system time synchronization. Could this be interfering?
Anyways, I've got some more experimenting to do but it seems like something somebody may recognize immediately. All advice is appreciated.
A few other points, I've followed this link to remove the ntpd service and the issue still stands, ruling that cause out. Furthermore, I found this link that says changing the system time during a sleeping thread doesn't impact when it wakes up. So now my two theories are shot. Any other ideas are appreciated!
Because of the occasional segmentation fault that occurs, which is not clear if it's related or not to the freezing/crashing, I went ahead and updated the code to prevent the only source of undefined behavior I could identify. So I added uniform initialization for all the variables used in the modf function and made my timeval const. Also changed the type casts per advice below. Behavior is still the same.
//Loop until first GPS lock to set system time
while ( (gpsdata == NULL) ||
(gpsdata->fix.mode <= 1) ||
(gpsdata->fix.time < 1) ||
std::isnan(gpsdata->fix.time) ) {
gpsdata = gps_rec.read();
}
//Convert gps_data_t* member 'time' to timeval
double offsettime{ gpsdata->fix.time - (5.0 * 3600.0) }; //5.0 hr offset for EST
double seconds{ 0.0 };
double microseconds{ 1000000.0 * modf(offsettime, &seconds) };
const timeval tv{ static_cast<time_t>(seconds),
static_cast<suseconds_t>(microseconds) };
//Set system time - THIS IS CAUSING CRASHES, WHY?
if ( settimeofday(&tv, NULL) >= 0) {
std::cout << "Time set successful!" << '\n';
} else {
std::cout << "Time set failure!" << '\n';
}