I am working on an embedded Linux system (kernel-5.10.24), and I am testing libfaketime
in the system.
I got the master of libfaketime
, after built it, I ran my test in shell as follows.
- with
sleep 4
in shell, with 'x2' inFAKETIME="+0h x2"
# date && LD_PRELOAD=/usr/lib/libfaketime.so.1 FAKETIME="+0h x2" sleep 4 && date
Mon Feb 17 16:57:15 UTC 2025
Mon Feb 17 16:57:19 UTC 2025
My expectation is its real run-time should be 2 seconds, but from the output of date
, it is 4 seconds, not 2 seconds.
- with
mysleep 4
and 'x2' inFAKETIME="+0h x2"
# date && LD_PRELOAD=/usr/lib/libfaketime.so.1 FAKETIME="+0h x2" /test/mysleep 4
&& date
Mon Feb 17 16:57:03 UTC 2025
Mon Feb 17 16:57:05 UTC 2025
It really slept for 2 seconds, meeting my expectation.
- with
mysleep 4
and no using of FAKETIME, it really slept for 4 seconds as I expected.
# date && /test/mysleep 4 && date
Mon Feb 17 17:36:03 UTC 2025
Mon Feb 17 17:36:07 UTC 2025
Here is mysleep.c
.
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int main(int argc, char **argv)
{
unsigned long msecond;
double a;
if (argc != 2) {
printf("sleep secs\n");
exit(1);
}
sscanf(argv[1], "%lf", &a);
msecond = a*1000.0*1000.0;
usleep(msecond);
retrn 0;
}
I ran strace sleep 4
and strace mysleep 4
, not found big difference to cause this different behavior.
# strace sleep 4
execve("/bin/sleep", ["sleep", "4"], 0x7fa59f94 /* 16 vars */) = 0
brk(NULL) = 0x169d000
mmap2(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x77e27000
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/lib/libm.so.6", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = 3
read(3, "\177ELF\1\1\1\0\3\0\0\0\0\0\0\0\3\0\10\0\1\0\0\0\220{\0\0004\0\0\0"..., 512) = 512
prctl(PR_GET_FP_MODE) = 1 (PR_FP_MODE_FR)
statx(3, "", AT_STATX_SYNC_AS_STAT|AT_NO_AUTOMOUNT|AT_EMPTY_PATH, STATX_BASIC_STATS, {stx_mask=STATX_BASIC_STATS|0x1000, stx_attributes=STATX_ATTR_COMPRESSED, stx_mode=S_IFREG|0755, stx_size=400448, ...}) = 0
mmap2(NULL, 516928, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_DENYWRITE, -1, 0) = 0x77d72000
mmap2(0x77d80000, 451392, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0) = 0x77d80000
munmap(0x77d72000, 57344) = 0
munmap(0x77def000, 4928) = 0
mprotect(0x77dde000, 61440, PROT_NONE) = 0
mmap2(0x77ded000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x5d000) = 0x77ded000
close(3) = 0
openat(AT_FDCWD, "/lib/libc.so.6", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = 3
read(3, "\177ELF\1\1\1\0\3\0\0\0\0\0\0\0\3\0\10\0\1\0\0\0t\23\2\0004\0\0\0"..., 512) = 512
prctl(PR_GET_FP_MODE) = 1 (PR_FP_MODE_FR)
statx(3, "", AT_STATX_SYNC_AS_STAT|AT_NO_AUTOMOUNT|AT_EMPTY_PATH, STATX_BASIC_STATS, {stx_mask=STATX_BASIC_STATS|0x1000, stx_attributes=STATX_ATTR_COMPRESSED, stx_mode=S_IFREG|0755, stx_size=1877208, ...}) = 0
mmap2(NULL, 1918672, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_DENYWRITE, -1, 0) = 0x77bab000
mmap2(0x77bb0000, 1853136, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0) = 0x77bb0000
munmap(0x77bab000, 20480) = 0
munmap(0x77d75000, 42704) = 0
mprotect(0x77d39000, 61440, PROT_NONE) = 0
mmap2(0x77d48000, 143360, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x188000) = 0x77d48000
mmap2(0x77d6b000, 38608, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x77d6b000
close(3) = 0
mmap2(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x77e25000
set_thread_area(0x77e2c500) = 0
set_tid_address(0x77e25088) = 6427
set_robust_list(0x77e2508c, 12) = 0
rseq(0x77e254c0, 0x20, 0, 0x350000d) = -1 ENOSYS (Function not implemented)
mprotect(0x77d48000, 131072, PROT_READ) = 0
mprotect(0x77ded000, 4096, PROT_READ) = 0
mprotect(0x77e29000, 4096, PROT_READ) = 0
getrlimit(RLIMIT_STACK, {rlim_cur=8192*1024, rlim_max=2147483647}) = 0
getrandom("\x6f\xfa\x46\x00", 4, GRND_NONBLOCK) = 4
getuid() = 0
clock_nanosleep(CLOCK_REALTIME, 0, {tv_sec=4, tv_nsec=0},
0x7fdc78c0) = 0
exit_group(0) = ?
+++ exited with 0 +++
strace /test/mysleep 4
execve("/test/mysleep", ["/test/mysleep", "4"], 0x7f7b1714 /* 16 vars */) = 0
brk(NULL) = 0x1afd000
mmap2(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x77e8a000
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/lib/libc.so.6", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = 3
read(3, "\177ELF\1\1\1\0\3\0\0\0\0\0\0\0\3\0\10\0\1\0\0\0t\23\2\0004\0\0\0"..., 512) = 512
prctl(PR_GET_FP_MODE) = 1 (PR_FP_MODE_FR)
statx(3, "", AT_STATX_SYNC_AS_STAT|AT_NO_AUTOMOUNT|AT_EMPTY_PATH, STATX_BASIC_STATS, {stx_mask=STATX_BASIC_STATS|0x1000, stx_attributes=STATX_ATTR_COMPRESSED, stx_mode=S_IFREG|0755, stx_size=1877208, ...}) = 0
mmap2(NULL, 1918672, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_DENYWRITE, -1, 0) = 0x77c7f000
mmap2(0x77c80000, 1853136, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0) = 0x77c80000
munmap(0x77c7f000, 4096) = 0
munmap(0x77e45000, 59088) = 0
mprotect(0x77e09000, 61440, PROT_NONE) = 0
mmap2(0x77e18000, 143360, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x188000) = 0x77e18000
mmap2(0x77e3b000, 38608, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x77e3b000
close(3) = 0
set_thread_area(0x77e92760) = 0
set_tid_address(0x77e8b2e8) = 6445
set_robust_list(0x77e8b2ec, 12) = 0
rseq(0x77e8b720, 0x20, 0, 0x350000d) = -1 ENOSYS (Function not implemented)
mprotect(0x77e18000, 131072, PROT_READ) = 0
mprotect(0x77e8c000, 4096, PROT_READ) = 0
getrlimit(RLIMIT_STACK, {rlim_cur=8192*1024, rlim_max=2147483647}) = 0
clock_nanosleep(CLOCK_REALTIME, 0, {tv_sec=4, tv_nsec=0}, 0x7fcecd10) = 0
exit_group(0) = ?
+++ exited with 0 +++
So why sleep 4
in shell worked differently with mysleep
, is there anything I missed or misunderstood of libfaketime
?