Before the fix, sample PPS Logs: gpsd:PROG: KPPS:/dev/pps0 Clear cycle: -1236963952, duration: 1000000 @ (null) gpsd:PROG: PPS:/dev/pps0 Clear cycle: 0, duration: 1000000 @ (null) With this fix, we see logs like this: gpsd:PROG: KPPS:/dev/pps0 Clear cycle: 1000010, duration: 100003 @ 1577729345.554599378 gpsd:PROG: PPS:/dev/pps0 Clear cycle: 1000010, duration: 100003 @ 1577729345.554599378 When the system clock changes without this fix, and the debug level is 4 or greater, GPSD crashes on 32 bit ARM. This fix prevents strlen() in vfprintf() from being given a garbage pointer. cycle, cycle_kpps, duration and duration_kpps are defined as long long, so by the C standard, the format string is %lld. ======================================================================= diff -Naur old/ppsthread.c new/ppsthread.c --- old/ppsthread.c 2017-02-01 11:36:31.575212221 -0600 +++ new/ppsthread.c 2017-02-01 11:44:48.269536679 -0600 @@ -770,10 +770,9 @@ edge_str = edge ? "Assert" : "Clear"; cycle = cycle_tio; duration = duration_tio; - timespec_str( &clock_ts, ts_str1, sizeof(ts_str1) ); thread_context->log_hook(thread_context, THREAD_PROG, - "TPPS:%s %.10s cycle: %d, duration: %d @ %s\n", + "TPPS:%s %.10s cycle: %lld, duration: %lld @ %s\n", thread_context->devicename, edge_str, cycle, duration, ts_str1); @@ -840,7 +839,7 @@ timespec_str( &clock_ts_kpps, ts_str1, sizeof(ts_str1) ); thread_context->log_hook(thread_context, THREAD_PROG, - "KPPS:%s %.10s cycle: %7d, duration: %7d @ %s\n", + "KPPS:%s %.10s cycle: %7lld, duration: %7lld @ %s\n", thread_context->devicename, edge_str, cycle_kpps, duration_kpps, ts_str1); @@ -898,7 +897,7 @@ state_last = state; timespec_str( &clock_ts, ts_str1, sizeof(ts_str1) ); thread_context->log_hook(thread_context, THREAD_PROG, - "PPS:%s %.10s cycle: %7d, duration: %7d @ %s\n", + "PPS:%s %.10s cycle: %7lld, duration: %7lld @ %s\n", thread_context->devicename, edge_str, cycle, duration, ts_str1);