about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorSergey Bronnikov <estetus@gmail.com>2024-03-30 11:26:38 +0300
committerSergey Bronnikov <sergeyb@tarantool.org>2024-03-31 11:11:29 +0300
commit5ffc8c70761f97fbaffa3a98a6c472d35930c7b2 (patch)
treed2aaa36211067c66fbf0530d68cb4db6738890c8 /src
parent775861ea94d00672c9e868db329073afd699b994 (diff)
downloadafl++-5ffc8c70761f97fbaffa3a98a6c472d35930c7b2.tar.gz
src: fix calculation of fuzzing time in statistics
When the computer is suspended during a fuzzing session,
the time spent in suspended state is counted as a "run time"
on a statistics screen.

The time returned by `gettimeofday(2)` is affected by discontinuous
jumps in the system time. It is better using `clock_gettime(2)`.

The patch replace `gettimeofday` with `clock_gettime` [1].
`clock_gettime` uses a CLOCK_MONOTONIC_COARSE clock type,
it is faster than CLOCK_MONOTONIC, but still has resolution (~1ms)
that is adequate for our purposes. However, CLOCK_MONOTONIC_COARSE
is a Linux-specific clock variant, so on macOS it is replaced
with CLOCK_MONOTONIC, and with CLOCK_MONOTONIC_FAST on FreeBSD [2].

Closes #1241

1. https://pubs.opengroup.org/onlinepubs/9699919799/functions/clock_gettime.html
2. https://man.freebsd.org/cgi/man.cgi?query=clock_gettime
Diffstat (limited to 'src')
-rw-r--r--src/afl-common.c49
1 files changed, 35 insertions, 14 deletions
diff --git a/src/afl-common.c b/src/afl-common.c
index 87003b03..53524e96 100644
--- a/src/afl-common.c
+++ b/src/afl-common.c
@@ -34,6 +34,7 @@
 #endif
 #include <string.h>
 #include <strings.h>
+#include <time.h>
 #include <math.h>
 #include <sys/mman.h>
 
@@ -58,6 +59,26 @@ u8  last_intr = 0;
   #define AFL_PATH "/usr/local/lib/afl/"
 #endif
 
+/* - Some BSD (i.e.: FreeBSD) offer the FAST clock source as
+ *   equivalent to Linux COARSE clock source. Aliasing COARSE to
+ *   FAST on such systems when COARSE is not already defined.
+ * - macOS has no support of CLOCK_MONOTONIC_COARSE clock type.
+ */
+#if defined (OS_DARWIN) || defined (OS_SUNOS)
+#    define CLOCK_MONOTONIC_COARSE CLOCK_MONOTONIC
+#elif defined (OS_FREEBSD)
+#    define CLOCK_MONOTONIC_COARSE CLOCK_MONOTONIC_FAST
+#endif
+
+/* Convert seconds to milliseconds. */
+#define SEC_TO_MS(sec) ((sec)*1000)
+/* Convert seconds to microseconds. */
+#define SEC_TO_US(sec) ((sec)*1000000)
+/* Convert nanoseconds to milliseconds. */
+#define NS_TO_MS(ns)   ((ns)/1000000)
+/* Convert nanoseconds to microseconds. */
+#define NS_TO_US(ns)   ((ns)/1000)
+
 void *afl_memmem(const void *haystack, size_t haystacklen, const void *needle,
                  size_t needlelen) {
 
@@ -973,27 +994,27 @@ void read_bitmap(u8 *fname, u8 *map, size_t len) {
 /* Get unix time in milliseconds */
 
 inline u64 get_cur_time(void) {
+  struct timespec ts;
+  int rc = clock_gettime(CLOCK_MONOTONIC_COARSE, &ts);
+  if (rc == -1) {
+    PFATAL("Failed to obtain timestamp (errno = %i: %s)\n",
+           errno, strerror(errno));
+  }
 
-  struct timeval  tv;
-  struct timezone tz;
-
-  gettimeofday(&tv, &tz);
-
-  return (tv.tv_sec * 1000ULL) + (tv.tv_usec / 1000);
-
+  return SEC_TO_MS((uint64_t)ts.tv_sec) + NS_TO_MS((uint64_t)ts.tv_nsec);
 }
 
 /* Get unix time in microseconds */
 
 u64 get_cur_time_us(void) {
+  struct timespec ts;
+  int rc = clock_gettime(CLOCK_MONOTONIC_COARSE, &ts);
+  if (rc == -1) {
+    PFATAL("Failed to obtain timestamp (errno = %i: %s)\n",
+           errno, strerror(errno));
+  }
 
-  struct timeval  tv;
-  struct timezone tz;
-
-  gettimeofday(&tv, &tz);
-
-  return (tv.tv_sec * 1000000ULL) + tv.tv_usec;
-
+  return SEC_TO_US((uint64_t)ts.tv_sec) + NS_TO_US((uint64_t)ts.tv_nsec);
 }
 
 /* Describe integer. The buf should be