Coder Social home page Coder Social logo

wolfcw / libfaketime Goto Github PK

View Code? Open in Web Editor NEW
2.6K 58.0 315.0 848 KB

libfaketime modifies the system time for a single application

Home Page: https://github.com/wolfcw/libfaketime

License: GNU General Public License v2.0

Makefile 4.07% C 87.52% Shell 7.47% C++ 0.48% BitBake 0.46%
ld-preload datetime wrapper intercept-calls reproducible-builds hacktoberfest

libfaketime's Introduction

libfaketime, version 0.9.10 (March 2022)
========================================


Content of this file:
---------------------

1. Introduction
2. Compatibility issues
3. Installation
4. Usage
   a) Basics
   b) Using absolute dates
   c) Using 'start at' dates
   d) Using offsets for relative dates
   e) Advanced features and caveats
   f) Faking the date and time system-wide
   g) Using the "faketime" wrapper script
   h) "Limiting" libfaketime based on elapsed time or number of calls
   i) "Limiting" libfaketime per process
   j) Spawning an external process
   k) Saving timestamps to file, loading them from file
   l) Replacing random numbers with deterministic number sequences
5. License
6. Contact


1. Introduction
---------------

libfaketime intercepts various system calls that programs use to retrieve the
current date and time. It then reports modified (faked) dates and times (as
specified by you, the user) to these programs. This means you can modify the
system time a program sees without having to change the time system-wide.

libfaketime allows you to specify both absolute dates (e.g., 01/01/2004) and
relative dates (e.g., 10 days ago).

libfaketime might be used for various purposes, for example

- deterministic build processes
- debugging time-related issues, such as expired SSL certificates
- testing software for year-2038 compliance

libfaketime ships with a command line wrapper called "faketime" that makes it
easier to use, but does not expose all of libfaketime's functionality. If your
use case is not covered by the faketime command, make sure to look in this
documentation whether it can be achieved by using libfaketime directly.


2. Compatibility issues
-----------------------

- libfaketime is supposed to work on Linux and macOS.
  Your mileage may vary; some other *NIXes have been reported to work as well.

- libfaketime uses the library preload mechanism of your operating system's
  linker (which is involved in starting programs) and thus cannot work with
  statically linked binaries or binaries that have the setuid-flag set (e.g.,
  suidroot programs like "ping" or "passwd"). Please see you system linker's
  manpage for further details.

- libfaketime supports the pthreads environment. A separate library is built
  (libfaketimeMT.so.1), which contains the pthread synchronization calls. This
  library also single-threads calls through the time() intercept because
  several variables are statically cached by the library and could cause issues
  when accessed without synchronization.

  However, the performance penalty for this might be an issue for some
  applications. If this is the case, you can try using an unsynchronized time()
  intercept by removing the -DPTHREAD_SINGLETHREADED_TIME from the Makefile and
  rebuilding libfaketimeMT.so.1

* Java-/JVM-based applications work but you need to pass in an extra argument
  (FAKETIME_DONT_FAKE_MONOTONIC).  See usage basics below for details.  Without
  this argument the java command usually hangs.

* libfaketime will eventually be bypassed by applications that dynamically load
  system libraries, such as librt, explicitly themselves instead of relying on
  the linker to do so at application start time. libfaketime will not work with
  those applications unless you can modify them.

  This apparently happens a lot in complex run-time environments, e.g., for
  programs written in golang, for some Java Virtual Machine implementations,
  etc. Since libfaketime is effectively bypassed in such situations, there's
  nothing we can do about it. Please consider asking the appropriate developers
  and vendors to implement their runtime environment in a way that supports
  intercepting selected system calls through LD_PRELOAD.

* Applications can explicitly be designed to prevent libfaketime from working,
  e.g., by checking whether certain environment variables are set or whether
  libfaketime-specific files are present.

* CLOCK_MONOTONIC test: Running "make test" performs a series of tests after
  successful compilation of the libfaketime library. On some platforms, the
  "CLOCK_MONOTONIC test" will apparently hang forever. If and only if this
  happens on your platform, add the CFLAG -DFORCE_MONOTONIC_FIX to
  src/Makefile and recompile libfaketime. Do not set FORCE_MONOTONIC_FIX on
  platforms where the test does not hang.

  If you observe hangs on the CLOCK_REALTIME test, add the CFLAG
  -DFORCE_PTHREAD_NONVER. Also set this FORCE_PTHREAD_NONVER flag in case
  FORCE_MONOTONIC_FIX alone does not solve the hang on the MONOTONIC_CLOCK
  test.

  If FORCE_MONOTONIC_FIX was not set as a compile-time flag, you can also
  set an environment variable FAKETIME_FORCE_MONOTONIC_FIX=1 if you want
  to enable the fix at run-time, or to 0 if you explicitly want to disable
  it. The fix is automatically enabled if libfaketime was compiled on a
  system with glibc as the underlying libc implementation, and a glibc
  version is detected at run-time that is assumed to need this workaround.
  Please use Github issues at https://github.com/wolfcw/libfaketime/issues
  to report any observed hangs during CLOCK_MONOTONIC tests and report
  your CPU architecture, libc implementation (e.g., glibc 2.30) and any
  other details that might help (e.g., Linux distribution, use within, e.g.,
  Docker containers etc.).

  Please try to avoid compiling with FORCE_MONOTONIC_FIX on platforms that
  do not need it. While it won't make a difference in most cases, depending
  on the specific FAKETIME settings in use, it would cause certain
  intercepted functions such as pthread_cond_timedwait() return with a
  time-out too early or too late, which could break some applications.
  Try compiling without FORCE_MONOTONIC_FIX first and check whether the
  tests appear to hang. If they do, you can either set the
  FAKETIME_FORCE_MONOTONIC_FIX environment variable to 1, or re-compile
  with FORCE_MONOTONIC_FIX set.


3. Installation
---------------

Running "make" compiles both library versions and a test program, which it then
also executes.

If the test works fine, you should copy the libfaketime libraries
(libfaketime.so.1, and libfaketimeMT.so.1) to the place you want them in.
Running "make install" will attempt to place them in /usr/local/lib/faketime
and will install the wrapper shell script "faketime" in /usr/local/bin, both of
which most likely will require root privileges. However, from a technical point
of view, there is no necessity for a system-wide installation, so you can use
libfaketime also on machines where you do not have root privileges. You may
want to adjust the PREFIX variable in the Makefiles accordingly.

By default, the Makefile compiles/links libfaketime for your default system
architecture. If you need to build, e.g., 32-bit files on a 64-bit platform,
please see the notes about CFLAGS and LDFLAGS in src/Makefile.

Since version 0.6, system calls to file timestamps are also intercepted,
thanks to a contribution by Philipp Hachtmann. This is especially useful in
combination with relative time offsets as explained in section 4d) below, if a
program writes and reads files whose timestamps also shall be faked. If you do
not need this feature or if it confuses the application you want to use FTPL
with, define the environment variable NO_FAKE_STAT, and the intercepted stat
calls will be passed through unaltered.

On macOS, it is necessary to compile differently, due to the different
behavior dyld has. Use the Makefile.OSX file provided to compile
libfaketime.1.dylib. Additionally, instead of using LD_PRELOAD,
the variable DYLD_INSERT_LIBRARIES should be set to the path to
libfaketime.1.dylib, and the variable DYLD_FORCE_FLAT_NAMESPACE should be
set (to anything). macOS users should read README.OSX for additional
details.


4. Usage
--------

4a) Usage basics
----------------

Using libfaketime on a program of your choice consists of two steps:

1. Making sure libfaketime gets loaded by the system's linker.
2. Specify the faked time.

As an example, we want the "date" command to report our faked time. To do so,
we could use the following command line on Linux:

user@host> date
Tue Nov 23 12:01:05 CEST 2016

user@host> LD_PRELOAD=/usr/local/lib/libfaketime.so.1 FAKETIME="-15d" date
Mon Nov  8 12:01:12 CEST 2016

user@host> LD_PRELOAD=/usr/local/lib/libfaketime.so.1 FAKETIME="-15d"
FAKETIME_DONT_FAKE_MONOTONIC=1 java -version
java version "1.8.0_111"
Java(TM) SE Runtime Environment (build 1.8.0_111-b14)
Java HotSpot(TM) 64-Bit Server VM (build 25.111-b14, mixed mode)

The basic way of running any command/program with libfaketime enabled is to
make sure the environment variable LD_PRELOAD contains the path and
filename of the libfaketime library. This can either be done by setting it once
beforehand:

export LD_PRELOAD=/path/to/libfaketime.so.1
(now run any command you want)

Or it can be done by specifying it on the command line itself:

LD_PRELOAD=/path/to/libfaketime.so.1 your_command_here

(These examples are for the bash shell; how environment variables are set may
vary on your system.)

On Linux, library search paths can be set as part of the linker configuration.
LD_PRELOAD then also works with relative paths. For example, when libfaketime.so.1
is installed as /path/to/libfaketime.so.1, you can add /path/to to an appropriate
linker configuration file, e.g., /etc/ld.so.conf.d/local.conf, and then run
the "ldconfig" command. Afterwards, using LD_PRELOAD=libfaketime.so.1 suffices.

However, also the faked time should be specified; otherwise, libfaketime will
be loaded, but just report the real system time. There are multiple ways to
specify the faked time:

a) By setting the environment variable FAKETIME.
b) By using the file given in the environment variable FAKETIME_TIMESTAMP_FILE
c) By using the file .faketimerc in your home directory.
d) By using the file /etc/faketimerc for a system-wide default.
e) By using FAKETIME_UPDATE_TIMESTAMP_FILE and date -s "<time>" or alike.

If you want to use b) c) or d), $HOME/.faketimerc or /etc/faketimerc consist of
only one line of text with exactly the same content as the FAKETIME environment
variable, which is described below. Note that /etc/faketimerc will only be used
if there is no $HOME/.faketimerc and no FAKETIME_TIMESTAMP_FILE file exists.
Also, the FAKETIME environment variable _always_ has priority over the files.
For FAKETIME_UPDATE_TIMESTAMP_FILE please see below.


4b) Using absolute dates
------------------------

The format that _must_ be used for _absolute_ dates is "YYYY-MM-DD hh:mm:ss".
For example, the 24th of December, 2020, 8:30 PM would have to be specified as
FAKETIME="2020-12-24 20:30:00".


4c) Using 'start at' dates
--------------------------

(Thanks to a major contribution by David North, TDI in version 0.7)

The format that _must_ be used for _start_at_ dates is "@YYYY-MM-DD hh:mm:ss".
For example, the 24th of December, 2020, 8:30 PM would have to be specified as
FAKETIME="@2020-12-24 20:30:00".

The absolute dates described in 4b) simulate a STOPPED system clock at the
specified absolute time. The 'start at' format allows a 'relative' clock
operation as described below in section 4d), but using a 'start at' time
instead of an offset time.

If the started process itself starts other (child) processes, they by default
will start with the specified start-at-date again. If this is not what you need,
set the environment variable FAKETIME_DONT_RESET=1. Try these examples to see
the difference:

LD_PRELOAD=src/libfaketime.so.1 FAKETIME="@2000-01-01 11:12:13" \
  FAKETIME_DONT_RESET=1 \
  /bin/bash -c 'while [ $SECONDS -lt 5 ]; do date; sleep 1; done'

LD_PRELOAD=src/libfaketime.so.1 FAKETIME="@2000-01-01 11:12:13" \
  /bin/bash -c 'while [ $SECONDS -lt 5 ]; do date; sleep 1; done'

In the second example, the "date" command will always print the same time,
while in the first example, with FAKETIME_DONT_RESET set, time will increment
even though all the "date" commands are new processes.


4d) Using offsets for relative dates
------------------------------------

Relative date offsets can be positive or negative, thus what you put into
FAKETIME _must_ either start with a + or a -, followed by a number, and
optionally followed by a multiplier:

- By default, the offset you specify is in seconds. Example:

  export FAKETIME="-120" will set the faked time 2 minutes (120 seconds) behind
  the real time.

- The multipliers "m", "h", "d" and "y" can be used to specify the offset in
  minutes, hours, days and years (365 days each), respectively. Examples:

  export FAKETIME="-10m" sets the faked time 10 minutes behind the real time.
  export FAKETIME="+14d" sets the faked time to 14 days in the future.

  Please note that if you need other multipliers (weeks, months etc.) or higher
  precision (e.g., correct leap year handling), you should use either the
  faketime wrapper or the GNU date command as shown in the first of the three
  examples below.

You now should understand the complete example we've used before:

LD_PRELOAD=/usr/local/lib/libfaketime.so.1 FAKETIME="-15d" date

This command line makes sure libfaketime gets loaded and sets the faked time to
15 days in the past.

Moreno Baricevic has contributed support for the FAKETIME_FMT environment
variable, which allows you to optionally set the strptime() format:

Some simple examples:
LD_PRELOAD=./libfaketime.so.1 FAKETIME_FMT=%s FAKETIME="`date +%s -d'1 year ago'`" date
LD_PRELOAD=./libfaketime.so.1 FAKETIME_FMT=%s FAKETIME="`stat -c %Y somefile`" date
LD_PRELOAD=./libfaketime.so.1 FAKETIME_FMT=%c FAKETIME="`date`" date


4e) Advanced features and caveats
---------------------------------

Advanced time specification options:
------------------------------------

Since version 0.8, thanks to a contribution by Karl Chen, fractions can be used
in the specification of time offsets. For example,

FAKETIME="+1,5h"

is equivalent to FAKETIME="+90m". Please be aware that the fraction delimiter
depends on your locale settings, so actually you might need to use

FAKETIME="+1.5h"

You should figure out the proper delimiter, e.g., by using libfaketime on
a command like /bin/date where you immediately can verify whether it worked as
expected.

Also contributed by Karl Chen in v0.8 is the option to speed up or slow
down the wall clock time for the program which is executed using libfaketime.
For example,

FAKETIME="+1y x2"

will set the faked time one year into the future and will make the clock run
twice as fast. Similarly,

FAKETIME="+1y x0,5"

will make the clock run only half as fast. As stated above, the fraction
delimiter depends on your locale. Furthermore,

FAKETIME="+1y i2,0"

will make the clock step two seconds per each time(), etc. call, being
completely independently of the system clock. It helps running programs
with some determinism. In this single case all spawned processes will use
the same global clock without restarting it at the start of each process.

Please note that using "x" or "i" in FAKETIME still requires giving an offset
(see section 4d). This means that "+1y x2" will work, but "x2" only will not.
If you do not want to fake the time, but just modify clock speed, use something
like "+0 x2", i.e., use an explicit zero offset as a prefix in your FAKETIME.

For testing, your should run a command like

LD_PRELOAD=./libfaketime.so.1 FAKETIME="+1,5y x10,0" \
/bin/bash -c 'while true; do echo $SECONDS ; sleep 1 ; done'

For each second that the endless loop sleeps, the executed bash shell will
think that 10 seconds have passed ($SECONDS is a bash-internal variable
measuring the time since the shell was started).

(Please note that replacing "echo $SECONDS" e.g. with a call to "/bin/date"
will not give the expected result, since /bin/date will always be started as a
new process for which also libfaketime will be re-initialized. It will show the
correct offset (1.5 years in the future), but no speed-ups or slow-downs.)

For applications that should use a different date & time each time they are
run, consider using the included timeprivacy wrapper shellscript (contributed
by adrelanos at riseup dot net).


Caveats:
--------

Whenever possible, you should use relative offsets or 'start at' dates,
and not use absolute dates.

Why? Because the absolute date/time you set is fixed, i.e., if a program
retrieves the current time, and retrieves the current time again 5 minutes
later, it will still get the same result twice. This is likely to break
programs which measure the time passing by (e.g., a mail program which checks
for new mail every X minutes).

Using relative offsets or 'start at' dates solves this problem.
libfaketime then will always report the faked time based on the real
current time and the offset you've specified.

Please also note that your default specification of the fake time is cached for
10 seconds in order to enhance the library's performance. Thus, if you change the
content of $HOME/.faketimerc or /etc/faketimerc while a program is running, it
may take up to 10 seconds before the new fake time is applied. If this is a
problem in your scenario, you can change number of seconds before the file is read
again with environment variable FAKETIME_CACHE_DURATION, or disable caching at all
with FAKETIME_NO_CACHE=1. Remember that disabling the cache may negatively
influence the performance (especially when not using FAKETIME environment
but configuration files, such as FAKETIME_TIMESTAMP_FILE).


Setting FAKETIME by means of a file timestamp
---------------------------------------------

Based on a proposal by Hitoshi Harada (umitanuki), the "start at" time can now be
set through any file in the file system by setting the FAKETIME environment variable
to "%" (a percent sign) and FAKETIME_FOLLOW_FILE to the name of the file whose
modification timestamp shall be used as source for the "start at" time.

Usage example:

# create any file with December 24th, 2009, 12:34:56 as timestamp
touch -t 0912241234.56 /tmp/my-demo-file.tmp

# run a bash shell with an endless loop printing the current time
LD_PRELOAD=/path/to/libfaketime.so.1 \
  FAKETIME='%' FAKETIME_FOLLOW_FILE=/tmp/my-demo-file.tmp \
  FAKETIME_DONT_RESET=1 \
  bash -c 'while true ; do date ; sleep 1 ; done'

# now, while the above is running, change the file's timestamp
# (in a different terminal window or whatever)
touch -t 2002290123.45 /tmp/my-demo-file.tmp


Changing the 'x' modifier during run-time
-----------------------------------------

Using FAKETIME_TIMESTAMP_FILE allows for easily changing the FAKETIME setting
while a program is running:

echo "+0 x1" > /tmp/my-faketime.rc
LD_PRELOAD=libfaketime.so.1 FAKETIME_TIMESTAMP_FILE="/tmp/my-faketime.rc" \
  FAKETIME_NO_CACHE=1 ./some-program &
sleep 10 ; echo "+0 x10" > /tmp/my-faketime.rc

Changing the speed of the wall clock time, i.e., using a different 'x' modifier
during run-time, by default can lead to greater jumps that may confuse the
program. For example, if the program has been running for 10 seconds on 'x1',
and then the setting is changed to 'x10', the faked time will look to the
program as if it has been running for more than 100 instead of just more than
10 seconds.

By setting the environment variable FAKETIME_XRESET to any value, transitions
between different 'x' modifier values will be significantly smoothed:

LD_PRELOAD=libfaketime.so.1 FAKETIME_TIMESTAMP_FILE="/tmp/my-faketime.rc" \
  FAKETIME_NO_CACHE=1 FAKETIME_XRESET=1 ./some-program &

Setting FAKETIME_XRESET ensures that wall clock time begins to run faster
only after the 'x' modifier has been changed (when increasing it) and also
ensures that the reported faked time does not jump back to past values
(when decreasing it).

Please note that FAKETIME_XRESET internally works by resetting libfaketime's
internal time-keeping data structures, which may have side effects on reported
file timestamps. Using FAKETIME_XRESET should be considered experimental at
the moment.


Cleaning up shared memory
-------------------------

libfaketime uses semaphores and shared memory on platforms that support it in
order to sync faketime settings across parent-child processes.

Please note that this does not share the time set by settimeofday (for that
see FAKETIME_UPDATE_TIMESTAMP_FILE below).

libfaketime will clean up when it exits properly.
However, when processes are terminated (e.g., by Ctrl-C on command line),
shared memory cannot be cleaned up properly. In such
cases, you should occasionally delete

  /dev/shm/faketime_shm_* and
  /dev/shm/sem.faketime_sem_*

manually (or properly automated). Leftover files there from processes that
already have been terminated are not a problem in general, but result in a
libfaketime error the next time a process is started with a process id for
which such a stale semaphore/shared memory exists. Thus, if you run across
the following error message

  libfaketime: In ft_shm_create(), shm_open failed: File exists

please cleanup /dev/shm as described above. This is especially relevant
for long-running systems (servers with high uptime) and systems on which
a lot of processes are started (e.g., servers handling many containers
or similar virtualization mechanisms).

Use of shared memory can be disabled by setting the FAKETIME_DISABLE_SHM
environment variable, or equivalently, passing --disable-shm to faketime.


Intercepting time-setting calls
-------------------------------

libfaketime can be compiled with the CFLAG "-DFAKE_SETTIME" in order
to also intercept time-setting functions, i.e., clock_settime(),
settimeofday(), and adjtime(). The FAKETIME environment
variable will be adjusted on each call.

When the environment variable FAKETIME_TIMESTAMP_FILE is set, points to a
writeable (creatable) custom config file and the environment variable
FAKETIME_UPDATE_TIMESTAMP_FILE is "1", then the file also is updated on each
call. By this, a common "virtual time" can be shared by several
processes, where each can adjust the time for all.


Sharing "virtual settable time" between independent processes
-------------------------------------------------------------

When libfaketime was compiled with FAKETIME_COMPILE_CFLAGS="-DFAKE_SETTIME",
it can be configured to support a common time offset for multiple processes.
This for example allows to use "ntpdate" as normal user without affecting
system clock, interactively testing software with different dates or testing
complex software with multiple independent processes that themself use
settime internally.

Examples:

  $ export LD_PRELOAD=libfaketime.so.1
  $ export FAKETIME_TIMESTAMP_FILE="/tmp/my-faketime.rc"
  $ export FAKETIME_UPDATE_TIMESTAMP_FILE=1
  $ export FAKETIME_CACHE_DURATION=1 # in seconds
  # or: export FAKETIME_NO_CACHE=1

  $ date -s "1999-12-24 16:00:00"
  Fri Dec 24 16:00:00 CET 1999
  $ LD_PRELOAD="" date
  Thu Apr  9 15:19:38 CEST 2020
  $ date
  Fri Dec 24 16:00:02 CET 1999
  $ /usr/sbin/ntpdate -u clock.isc.org
   9 Apr 15:18:37 ntpdate[718]: step time server xx offset 640390517.057257 sec
  $ date
  Thu Apr  9 15:18:40 CEST 2020

In another terminal, script or environmment the same variables could be set
and the same time would be printed.
This also avoid the need to directly update the rc config file to use
different times, but of course only supports time offsets.

Please note that this feature is not compatible with several other features,
such as FAKETIME_FOLLOW_FILE, FAKETIME_XRESET and maybe others. After first
settime, offsets will be used in FAKETIME_TIMESTAMP_FILE, even if it
initially used advanced time specification options.


4f) Faking the date and time system-wide
----------------------------------------

David Burley of SourceForge, Inc. reported an interesting use case of applying
libfaketime system-wide: Currently, all virtual machines running inside
an OpenVZ host have the same system date and time. In order to use multiple
sandboxes with different system dates, the libfaketime library can be put into
/etc/ld.so.preload; it will then be applied to all commands and programs
automatically. This is of course best used with a system-wide /etc/faketimerc
file. Kudos to SourceForge, Inc. for providing the patch!

Caveat: If you run a virtual machine, its real-time clock might be reset to the
real world date & time when you reboot. Depending on your FAKETIME setting,
this may lead to side effects, such as forced file system checks on each reboot.
System-wide faked time may also lead to unexpected side effects with software
auto-update tools, if the offset between real world time and faked system time
is too large. If in doubt, set your system's date to the faked time and try out
whether everything still works as expected before applying libfaketime
system-wide.


4g) Using the "faketime" wrapper
--------------------------------

As of version 0.8, libfaketime provides a command named "faketime", which is
placed into /usr/bin by "make install". It spares the hassle of setting
the LD_PRELOAD and FAKETIME environment variables manually, but only exposes
a subset of libfaketime's functionality. On the other hand, it uses the date
interpretation function by /bin/date in order to provide higher flexibility
regarding the specification of the faked date and time. For example, you
can use

faketime 'last Friday 5 pm' /your/command/here

Of course, also absolute dates can be used, such as in

faketime '2018-12-24 08:15:42' /bin/date

Thanks to Daniel Kahn Gillmor for providing these suggestions!

Balint Reczey has rewritten the wrapper in 0.9.5 from a simple shell script
to an efficient wrapper application.


4h) "Limiting" libfaketime based on elapsed time or number of calls
-------------------------------------------------------------------

Starting with version 0.9, libfaketime can be configured to not be continuously
active, but only during a certain time interval.

For example, you might want to start a program with the real current time, but
after 5 minutes of usage, you might want it to see a faked time, e.g., a year
in the future.

Dynamic changes to the faked time are alternatively possible by

- changing the FAKETIME environment variable at run-time; this is the preferred
  way if you use libfaketime for debugging and testing as a programmer, as it
  gives you the most direct control of libfaketime without any performance
  penalties.

- not using the FAKETIME environment variable, but specifying the fake time in
  a file (such as ~/.faketimerc). You can change the content of this file at
  run-time. This works best with caching disabled, but comes at a performance
  cost because this file has to be read and evaluated each time.

The feature described here works based on two pairs of environment variables,

  FAKETIME_START_AFTER_SECONDS and FAKETIME_STOP_AFTER_SECONDS, and
  FAKETIME_START_AFTER_NUMCALLS and FAKETIME_STOP_AFTER_NUMCALLS

The default value for each of these environment variables is -1, which means
"ignore this value".

If you want libfaketime to be only active during the run-time minutes 2 to 5
of your application, you would set

  FAKETIME_START_AFTER_SECONDS=60
  FAKETIME_STOP_AFTER_SECONDS=300

This means that your application will work with the real time from start (second
0) up to second 60. It will then see a faked time from run-time seconds 60 to
300 (minutes 2, 3, 4, and 5). After run-time second 600, it will again see the
real (not-faked) time.

This approach is not as flexible as changing the FAKETIME environment variable
during runtime, but may be easier to use, works on a per-program (and not a
per-user or system-wide) scope, and has only a minor performance overhead.

Using the other pair of environment variables, you can limit the activity time
of libfaketime not based on wall-clock seconds, but on the number of
time-related function calls the started program performs. This alternative is
probably only suitable for programmers who either know the code of the program
in order to determine useful start/stop values or want to perform fuzzing
tests.

Both pairs of environment variables can be combined to further restrict
libfaketime activity, although this is only useful in very few scenarios.

Limiting libfaketime activity in this way is not recommended in general. Many
programs will break when they are subject to sudden changes in time, especially
if they are started using the current (real) time and are then sent back into
the past after, e.g., 5 minutes. For example, they may appear to be frozen or
stuck because they are waiting until a certain point in time that, however, is
never reached due to the delayed libfaketime activity. Avoid using this
functionality unless you are sure you really need it and know what you are
doing.


4i) "Limiting" libfaketime per process
--------------------------------------

faketime can be instructed to fake time related calls only for selected
commands or to fake time for each command except for a certain subset of
commands.

The environment variables are FAKETIME_ONLY_CMDS and FAKETIME_SKIP_CMDS
respectively.

Example:
    FAKETIME_ONLY_CMDS=javadoc faketime '2008-12-24 08:15:42' make
will run the "make" command but the time faking will only be applied
to javadoc processes.

Multiple commands are separated by commas.

Example:
    FAKETIME_SKIP_CMDS="javadoc,ctags" faketime '2008-12-24 08:15:42' make
will run the "make" command and apply time faking for everything "make"
does except for javadoc and ctags processes.

FAKETIME_ONLY_CMDS and FAKETIME_SKIP_CMDS are mutually exclusive, i.e.,
you cannot set them both at the same time. faketime will terminate with
an error message if both environment variables are set.


4j) Spawning an external process
--------------------------------

From version 0.9 on, libfaketime can execute a shell command once after a) an
arbitrary number of seconds has passed or b) a number of time-related system
calls has been made by the program since it started. This has two limitations
one needs to be aware of:

* Spawning the external process happens during a time-related system call
  of the original program. If you want the external process to be started
  5 seconds after program start, but this program does not make any time-
  related system calls before run-time second 8, the start of your external
  process will be delayed until run-time second 8.

* The original program is blocked until the external process is finished,
  because the intercepting time-related system call will not return earlier. If
  you need to start a long-running external process, make sure it forks into the
  background.

Spawning the external process is controlled using three environment variables:
FAKETIME_SPAWN_TARGET, FAKETIME_SPAWN_SECONDS, FAKETIME_SPAWN_NUMCALLS.

Example (using bash on Linux):

(... usual libfaketime setup here, setting LD_PRELOAD and FAKETIME ...)
export FAKETIME_SPAWN_TARGET="/bin/echo 'Hello world'"
export FAKETIME_SPAWN_SECONDS=5
/opt/local/bin/myprogram

This will run the "echo" command with the given parameter during the first
time-related system function call that "myprogram" performs after running for 5
seconds.


4k) Saving timestamps to file, loading them from file
-----------------------------------------------------

To store and load timestamp _offsets_ using _one and the same_ file allowing
to share a common "virtual time" between independent processes, please see
FAKETIME_UPDATE_TIMESTAMP_FILE above. The FAKETIME_SAVE_FILE feature is
different.

faketime can save faked timestamps to a file specified by FAKETIME_SAVE_FILE
environment variable. It can also use the file specified by FAKETIME_LOAD_FILE
to replay timestamps from it. After consuming the whole file, libfaketime
returns to using the rule set in FAKETIME variable, but the timestamp processes
will start counting from will be the last timestamp in the file.

The file stores each timestamp in a stream of saved_timestamp structs
without any metadata or padding:

/* Storage format for timestamps written to file. Big endian. */
struct saved_timestamp {
  int64_t sec;
  uint64_t nsec;
};

faketime needs to be run using the faketime wrapper to use these files. This
functionality has been added by Balint Reczey in v0.9.5.


4l) Replacing random numbers with deterministic number sequences
----------------------------------------------------------------

libfaketime can be compiled with the CFLAG FAKE_RANDOM set (see src/Makefile).

When compiled this way, libfaketime additionally intercepts calls to the
function getrandom(), which currently is Linux-specific.

This functionality is intended to feed a sequence of deterministic, repeatable
numbers to applications, which use getrandom(), instead of the random numbers
provided by /dev/[u]random.

For creating the deterministic number sequence, libfaketime internally
uses Bernard Widynski's Middle Square Weyl Sequence Random Number Generator,
see https://mswsrng.wixsite.com/rand.

It requires a 64-bit seed value, which has to be passed via the environment
variable FAKERANDOM_SEED, as in, for example

  LD_PRELOAD=src/libfaketime.so.1 \
  FAKERANDOM_SEED="0x12345678DEADBEEF" \
  test/getrandom_test

Whenever the same seed value is used, the same sequence of "random-looking"
numbers is generated.

Please be aware that this definitely breaks any security properties that
may be attributed to random numbers delivered by getrandom(), e.g., in the
context of cryptographic operations. Use it for deterministic testing
purposes only. Never use it in production.

For a discussion on why this apparently not date-/time-related function
has been added to libfaketime and how it may evolve, see Github issue #275.


5. License
----------

libfaketime has been released under the GNU General Public License, GPL.
Please see the included COPYING file.


6. Contact
-----------

Bug reports, feature suggestions, success reports, and patches/pull
requests are highly appreciated:

            https://github.com/wolfcw/libfaketime

libfaketime's People

Contributors

a1346054 avatar andir avatar azat avatar compholio avatar daglem avatar dariaphoebe avatar dfong avatar dkg avatar domo141 avatar dubek avatar feepingcreature avatar fixindan avatar gk-tpo avatar jimklimov avatar jwilk avatar kilobyte avatar mac-joker avatar manchicken avatar martinetd avatar mliertzer avatar psychon avatar rbalint avatar ringlej avatar rob--w avatar sirainen avatar sleepsort avatar terceiro avatar tpetazzoni avatar v-gb avatar wolfcw avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

libfaketime's Issues

Changing faketime value in already-running processes via changing ~/.faketimerc or /etc/faketimerc contents?

I was hoping that libfaketime would pick up changes in the rc files from already running processes, but that doesn't seem to be the case. Would you be open to implementing such functionality, or accepting pull requests for it?

Another way of doing it could be via touching a /tmp/updatefaketime file, and comparing timestamps...

Our use case is the testing of multiple long running processes, and needing to switch time frequently in tests. Till now we've had to change actual system time, but that has many unwanted side effects, and we'd like to try avoiding that...

glibc 2.5 compatibility

How difficult would it be to make libfaketime compatible with glibc 2.5 libraries (on CentOS 5.11)?

When I try to run make, I get the following error:

gcc -o libfaketime.o -c -I/home/vagrant/anaconda3/envs/_build/include -std=gnu99 -Wall -Wextra -Werror -DFAKE_STAT -DFAKE_SLEEP -DFAKE_TIMERS -DFAKE_INTERNAL_CALLS -fPIC -DPREFIX='"'/home/vagrant/anaconda3/envs/_build'"' -DLIBDIRNAME='"'/lib/faketime'"'  libfaketime.c
libfaketime.c: In function 'timespec_from_saved':
libfaketime.c:182:3: error: implicit declaration of function 'be64toh' [-Werror=implicit-function-declaration]
   tp->tv_sec = be64toh(saved->sec);
   ^
libfaketime.c: In function 'save_time':
libfaketime.c:370:5: error: implicit declaration of function 'htobe64' [-Werror=implicit-function-declaration]
     time_write.sec = htobe64(tp->tv_sec);
     ^
libfaketime.c: In function 'ftpl_init':
libfaketime.c:1747:60: error: 'O_CLOEXEC' undeclared (first use in this function)
     if (-1 == (outfile = open(tmp_env, O_RDWR | O_APPEND | O_CLOEXEC | O_CREAT,
                                                            ^
libfaketime.c:1747:60: note: each undeclared identifier is reported only once for each function it appears in
cc1: all warnings being treated as errors

I tried adding:

#ifndef O_CLOEXEC
#define O_CLOEXEC 0
#endif

to libfaketime.c, as described here, but then I get a different error:

make  -C src all
make[1]: Entering directory `/home/vagrant/anaconda3/conda-bld/work/src'
gcc -o libfaketime.o -c -I/home/vagrant/anaconda3/include -std=gnu99 -Wall -Wextra -Werror -DFAKE_STAT -DFAKE_SLEEP -DFAKE_TIMERS -DFAKE_INTERNAL_CALLS -fPIC -DPREFIX='"'/home/vagrant/anaconda3/envs/_build'"' -DLIBDIRNAME='"'/lib/faketime'"'  libfaketime.c
libfaketime.c: In function ‘timespec_from_saved’:
libfaketime.c:185:3: error: implicit declaration of function ‘be64toh’ [-Werror=implicit-function-declaration]
   tp->tv_sec = be64toh(saved->sec);
   ^
libfaketime.c: In function ‘save_time’:
libfaketime.c:373:5: error: implicit declaration of function ‘htobe64’ [-Werror=implicit-function-declaration]
     time_write.sec = htobe64(tp->tv_sec);
     ^
cc1: all warnings being treated as errors
make[1]: *** [libfaketime.o] Error 1
make[1]: Leaving directory `/home/vagrant/anaconda3/conda-bld/work/src'
make: *** [all] Error 2

The be64toh function is defined in the endian.h header file, which was introduced into glibc beginning with version 2.9 (http://man7.org/linux/man-pages/man3/endian.3.html).

Would it be difficult to remove the dependency on endian.h?

Thanks!

faketime passes by

On Debian Jessie. This is the relevant except of code. (Tested and reproducible.)

#!/bin/bash
set -x

rm debian/changelog

sudo -E -u "user" \
   faketime "2013-08-15T11:02:35" \
      debchange \
         --vendor "whonix" \
         --create \
         --package "whonix" \
         --distribution "codename" \
         --newversion "8" \
         "This is an auto-generated file."

cat debian/changelog

Sometimes debian/changelog contains

 -- MAINTAINER <[email protected]>  Thu, 15 Aug 2013 11:02:35 +0000

Sometimes a few seconds have passed by, such as.

 -- MAINTAINER <[email protected]>  Thu, 15 Aug 2013 11:02:38 +0000

This happens especially under high hdd load.

Can something be done to enforce seconds as well and not let them pass by?

process lifetime issues

faketime is a great tool! I've been using it for a few things, but there's one problem that keeps biting me: after the faketime process ends, it can leave env vars like LD_PRELOAD and the faketime date set in child processes' environment, and those processes will fail to create children because said children always fail in calls to sem_open (because the faketime process has terminated).

An example:

$ faketime '' sh
sh-4.3$ xterm &
sh-4.3$ exit

then try to run a command in the xterm. It will fail with sem_open: No such file or directory.

It's not hard to manually avoid this problem when using faketime in the shell, but it becomes an issue when using faketime on complex shell scripts that run commands in the background, and it's not feasible to rewrite all of those.

clang build -Werror -Wempty-body

  • CFLAGS='-Oz -gdwarf-4 -Wstrict-aliasing=2 -pipe -Wformat -Werror=format-security -D_FORTIFY_SOURCE=2 -fstack-protector --param=ssp-buffer-size=4 -fPIC -flto -Wno-error -Wno-pointer-bool-conversion'
  • export CFLAGS
  • CXXFLAGS='-Oz -gdwarf-4 -Wstrict-aliasing=2 -pipe -Wformat -Werror=format-security -D_FORTIFY_SOURCE=2 -fstack-protector --param=ssp-buffer-size=4 -fPIC -flto -Wno-error -Wno-pointer-bool-conversion'
  • export CXXFLAGS
  • FFLAGS='-Oz -gdwarf-4 -Wstrict-aliasing=2 -pipe -Wformat -Werror=format-security -D_FORTIFY_SOURCE=2 -fstack-protector --param=ssp-buffer-size=4 -fPIC -flto -Wno-error -Wno-pointer-bool-conversion'
  • export FFLAGS
  • LDFLAGS='-Oz -gdwarf-4 -Wstrict-aliasing=2 -pipe -Wformat -Werror=format-security -D_FORTIFY_SOURCE=2 -fstack-protector --param=ssp-buffer-size=4 -fPIC -flto -Wno-error -Wno-pointer-bool-conversion -Wl,-O2 -Wl,--no-undefined -flto '
  • export LDFLAGS
  • CROSSCOMPILE='--target=x86_64-mandriva-linux-gnu --build=x86_64-mandriva-linux-gnu'
  • export CROSSCOMPILE
  • /usr/bin/make -j8 -O PREFIX=/usr LIBDIRNAME=/lib64
    /usr/bin/make -C src all
    make[1]: Entering directory '/home/omv/faketime/BUILD/libfaketime-0.9.6/src'
    /usr/bin/clang -o libfaketimeMT.o -c -Oz -gdwarf-4 -Wstrict-aliasing=2 -pipe -Wformat -Werror=format-security -D_FORTIFY_SOURCE=2 -fstack-protector --param=ssp-buffer-size=4 -fPIC -flto -Wno-error -Wno-pointer-bool-conversion -std=gnu99 -Wall -Wextra -Werror -DFAKE_STAT -DFAKE_SLEEP -DFAKE_TIMERS -DFAKE_INTERNAL_CALLS -fPIC -DPREFIX='"'/usr'"' -DLIBDIRNAME='"'/lib64'"' libfaketime.c
    libfaketime.c:312:72: error: while loop has empty body [-Werror,-Wempty-body]
    DONT_FAKE_TIME((_real_clock_gettime)(CLOCK_REALTIME, &systime->real));
    ^
    libfaketime.c:312:72: note: put the semicolon on a separate line to silence this warning
    libfaketime.c:313:72: error: while loop has empty body [-Werror,-Wempty-body]
    DONT_FAKE_TIME((_real_clock_gettime)(CLOCK_MONOTONIC, &systime->mon));
    ^
    libfaketime.c:313:72: note: put the semicolon on a separate line to silence this warning

valgrind complains memory leak due to lack of sem_close()

command to reproduce:

$ valgrind --tool=memcheck --leak-check=full --show-leak-kinds=all ./src/faketime '2008-01-01' /bin/date

simple fix:

diff --git a/src/faketime.c b/src/faketime.c
index 9062d96..f222627 100644
--- a/src/faketime.c
+++ b/src/faketime.c
@@ -271,6 +271,7 @@ int main (int argc, char **argv)

     snprintf(shared_objs, PATH_BUFSIZE, "%s %s", sem_name, shm_name);
     setenv("FAKETIME_SHARED", shared_objs, true);
+    sem_close(sem);
   }

   {

CPU usage too high

There appears to be a problem with cpu usage. I have tested this with thunderbird for example:

faketime -f '-10m' thunderbird - ~80% usage on all cores on i7
faketime -m '-10m' thunderbird - ~50% usage on all cores on i7

This appears to be a problem for other people and other programs as well:
https://bugs.launchpad.net/ubuntu/+source/faketime/+bug/1190566

My environment (libfaketime was compiled with gcc-4.7.3):

Portage 2.2.8-r1 (default/linux/amd64/13.0, gcc-4.7.3, glibc-2.17, 3.14.5-gentoo x86_64)

System uname: Linux-3.14.5-gentoo-x86_64-Intel-R-_Core-TM-i7-4700MQ_CPU@_2.40GHz-with-gentoo-2.2
KiB Mem: 16366492 total, 12333924 free
KiB Swap: 0 total, 0 free
Timestamp of tree: Wed, 04 Jun 2014 12:45:01 +0000
ld GNU ld (GNU Binutils) 2.23.2
app-shells/bash: 4.2_p45
dev-java/java-config: 2.2.0
dev-lang/python: 2.7.6, 3.2.5-r3, 3.3.3
dev-util/cmake: 2.8.12.2
dev-util/pkgconfig: 0.28-r1
sys-apps/baselayout: 2.2
sys-apps/openrc: 0.12.4
sys-apps/sandbox: 2.6-r1
sys-devel/autoconf: 2.13, 2.69
sys-devel/automake: 1.11.6, 1.12.6, 1.13.4
sys-devel/binutils: 2.23.2
sys-devel/gcc: 4.7.3-r1
sys-devel/gcc-config: 1.7.3
sys-devel/libtool: 2.4.2
sys-devel/make: 3.82-r4
sys-kernel/linux-headers: 3.13 (virtual/os-headers)
sys-libs/glibc: 2.17
Repositories: gentoo sunrise x-portage
ACCEPT_KEYWORDS="amd64"
ACCEPT_LICENSE="*"
CBUILD="x86_64-pc-linux-gnu"
CFLAGS="-march=core-avx2 -O2 -pipe -fomit-frame-pointer"
CHOST="x86_64-pc-linux-gnu"
CONFIG_PROTECT="/etc /usr/share/config /usr/share/gnupg/qualified.txt"
CONFIG_PROTECT_MASK="/etc/ca-certificates.conf /etc/env.d /etc/fonts/fonts.conf /etc/gconf /etc/gentoo-release /etc/php/apache2-php5.2/ext-active/ /etc/php/apache2-php5.3/ext-active/ /etc/php/apache2-php5.4/ext-active/ /etc/php/apache2-php5.5/ext-active/ /etc/php/cgi-php5.2/ext-active/ /etc/php/cgi-php5.3/ext-active/ /etc/php/cgi-php5.4/ext-active/ /etc/php/cgi-php5.5/ext-active/ /etc/php/cli-php5.2/ext-active/ /etc/php/cli-php5.3/ext-active/ /etc/php/cli-php5.4/ext-active/ /etc/php/cli-php5.5/ext-active/ /etc/revdep-rebuild /etc/sandbox.d /etc/terminfo"
CXXFLAGS="-march=core-avx2 -O2 -pipe -fomit-frame-pointer"
DISTDIR="/usr/portage/distfiles"
FCFLAGS="-O2 -pipe"
FEATURES="assume-digests binpkg-logs config-protect-if-modified distlocks ebuild-locks fixlafiles merge-sync news parallel-fetch preserve-libs protect-owned sandbox sfperms strict unknown-features-warn unmerge-logs unmerge-orphans userfetch userpriv usersandbox usersync"
FFLAGS="-O2 -pipe"
GENTOO_MIRRORS="http://portage.home http://gentoo.cites.uiuc.edu/pub/gentoo/ http://gentoo.mirrors.easynews.com/linux/gentoo/ http://mirror.phy.olemiss.edu/mirror/gentoo"
LANG="en_US.utf8"
LDFLAGS="-Wl,-O1 -Wl,--as-needed"
MAKEOPTS="-j9"
PKGDIR="/usr/portage/packages"
PORTAGE_CONFIGROOT="/"
PORTAGE_RSYNC_OPTS="--recursive --links --safe-links --perms --times --omit-dir-times --compress --force --whole-file --delete --stats --human-readable --timeout=180 --exclude=/distfiles --exclude=/local --exclude=/packages"
PORTAGE_TMPDIR="/tmp"
PORTDIR="/usr/portage"
PORTDIR_OVERLAY="/var/lib/layman/sunrise /usr/local/portage"
SYNC="rsync://rsync.namerica.gentoo.org/gentoo-portage"
USE="X a52 aac acl acpi adns ads alsa amd64 apache2 apm audiofile avi avx2 bcmath bdf berkdb bluetooth bzip2 cairo calendar caps cdda cdr chardet cjk cli consolekit cracklib crypt css ctype cups curl curlwrappers cxx dbus declarative device-mapper dga dhcp directfb dri dts dvb dvd dvdread egl enca encode exif fbcon ffmpeg flac foomaticdb fortran ftp fts3 gd gdbm gif gmp gnutls gpm gsm gtk gtk2 gzip hal hash hbci iconv ieee1394 imagemagick imap imlib innodb iproute2 ipv6 java java6 javascript jpeg jpeg2k json kde keymap kipi lcms libcaca libkms libnotify lm_sensors logrotate lzma lzo mad matroska mcal mhash mime mjpeg mms mmx mmxext mng modules mp3 mp4 mpeg mplayer msession multilib mysql mysqli mythtv ncurses network nls nptl nptlonly nsplugin nss ntp nvidia offensive ofx ogg openal opengl openmp osc osmesa oss pam pcntl pcre pdf pdo pear perl pgo php png policykit posix ppds python qt qt3 qt3support qt4 quicktime readline real reflection rtc samba sasl scanner sdl semantic-desktop session simplexml soap sockets spell spl sql sqlite sse sse2 sse4_1 sse4_2 ssl ssse3 subversion suhosin svg syslog system-cairo system-icu system-jpeg system-sqlite tcpd theora thumbnail tidy tiff tokenizer transcode truetype tslib udev unicode usb utempter v4l v4l2 vaapi vcd vdpau vorbis vpx wddx webkit x264 xcb xcomposite xine xinerama xml xmp xpm xsl xv xvfb xvid xvmc zip zlib" ABI_X86="32 64" ALSA_CARDS="hda-intel" APACHE2_MODULES="actions alias auth_basic auth_digest authn_anon authn_dbd authn_dbm authn_default authn_file authz_dbm authz_default authz_groupfile authz_host authz_owner authz_user autoindex cache dav dav_fs dav_lock dbd deflate dir disk_cache env expires ext_filter file_cache filter headers ident imagemap include info log_config logio mem_cache mime mime_magic negotiation proxy proxy_ajp proxy_balancer proxy_connect proxy_http rewrite setenvif so speling status unique_id userdir usertrack vhost_alias" CALLIGRA_FEATURES="kexi words flow plan sheets stage tables krita karbon braindump author" CAMERAS="ptp2" COLLECTD_PLUGINS="df interface irq load memory rrdtool swap syslog" ELIBC="glibc" GPSD_PROTOCOLS="ashtech aivdm earthmate evermore fv18 garmin garmintxt gpsclock itrax mtk3301 nmea ntrip navcom oceanserver oldstyle oncore rtcm104v2 rtcm104v3 sirf superstar2 timing tsip tripmate tnt ublox ubx" GRUB_PLATFORMS="pc efi-64" INPUT_DEVICES="evdev tslib" KERNEL="linux" LCD_DEVICES="bayrad cfontz cfontz633 glk hd44780 lb216 lcdm001 mtxorb ncurses text" LIBREOFFICE_EXTENSIONS="presenter-console presenter-minimizer" LINGUAS="en ru" OFFICE_IMPLEMENTATION="libreoffice" PHP_TARGETS="php5-2 php5-3 php5-4 php5-5" PYTHON_SINGLE_TARGET="python2_7" PYTHON_TARGETS="python2_7 python3_3" QEMU_SOFTMMU_TARGETS="i386 x86_64" QEMU_USER_TARGETS="i386 x86_64" RUBY_TARGETS="ruby19 ruby20" USERLAND="GNU" VIDEO_CARDS="intel nvidia" XTABLES_ADDONS="quota2 psd pknock lscan length2 ipv4options ipset ipp2p iface geoip fuzzy condition tee tarpit sysrq steal rawnat logmark ipmark dhcpmac delude chaos account"
Unset: CPPFLAGS, CTARGET, EMERGE_DEFAULT_OPTS, INSTALL_MASK, LC_ALL, PORTAGE_BUNZIP2_COMMAND, PORTAGE_COMPRESS, PORTAGE_COMPRESS_FLAGS, PORTAGE_RSYNC_EXTRA_OPTS, USE_PYTHON

Install error with Makefile.MacOS

Env: OS X Mountain Lion 10.8.2 with zsh

Copying the faketime libraries to /usr/local/lib/faketime and the faketime wrapper script to /usr/local/bin ...
install -dm0755 "/usr/local/lib/faketime/"
install -m0644 libfaketime.dylib.1 "/usr/local/lib/faketime/"
install -Dm0755 faketime "/usr/local/bin/faketime"
install: illegal option -- D
usage: install [-bCcpSsv] [-B suffix] [-f flags] [-g group] [-m mode]
               [-o owner] file1 file2
       install [-bCcpSsv] [-B suffix] [-f flags] [-g group] [-m mode]
               [-o owner] file1 ... fileN directory
       install -d [-v] [-g group] [-m mode] [-o owner] directory ...
make: *** [install] Error 64

After change it like this, it succeed:

diff --git a/src/Makefile.MacOS b/src/Makefile.MacOS
index a95c9e3..191e769 100644
--- a/src/Makefile.MacOS
+++ b/src/Makefile.MacOS
@@ -81,7 +81,7 @@ install: ${LIBS}
    @echo "Copying the faketime libraries to ${DESTDIR}${PREFIX}/lib/faketime and the faketime wrapper script to ${DESTDIR}${PREFIX}/bin ..."
    $(INSTALL) -dm0755 "${DESTDIR}${PREFIX}/lib/faketime/"
    $(INSTALL) -m0644 ${LIBS} "${DESTDIR}${PREFIX}/lib/faketime/"
-   $(INSTALL) -Dm0755 faketime "${DESTDIR}${PREFIX}/bin/faketime"
+   $(INSTALL) -m0755 faketime "${DESTDIR}${PREFIX}/bin/faketime"

 uninstall:
    for f in ${LIBS}; do rm -f "${DESTDIR}${PREFIX}/lib/faketime/$$f"; done

Installation results:

> make -f Makefile.MacOS install  

Copying the faketime libraries to /usr/local/lib/faketime and the faketime wrapper script to /usr/local/bin ...
install -dm0755 "/usr/local/lib/faketime/"
install -m0644 libfaketime.dylib.1 "/usr/local/lib/faketime/"
install -m0755 faketime "/usr/local/bin/faketime"

fails with `shm_open: Bad address` inside chroot

Forwarding the Debian bug report at https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=747078

faketime fails to work inside a chroot (e.g. a typical Debian sbuild/schroot chroot):

Inside a chroot:

$ findmnt
TARGET       SOURCE               FSTYPE   OPTIONS
/            debci-unstable-amd64 aufs     rw,relatime,si=97da38e4278c5ac6
|-/proc      proc                 proc     rw,nosuid,nodev,noexec,relatime
|-/sys       sysfs                sysfs    rw,nosuid,nodev,noexec,relatime
`-/dev       udev                 devtmpfs rw,relatime,size=10240k,nr_inodes=737877,mode=755
  |-/dev/pts devpts               devpts   rw,nosuid,noexec,relatime,gid=5,mode=620,ptmxmode=000
  `-/dev/shm tmpfs                tmpfs    rw,relatime
$ faketime +1day date
shm_open: Bad address

Another example of this can be found in this Debian bug:
https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=747720

GHC segfaults with faketime

GHC, as well as any program compiled with it (e.g. cabal or a no-op Haskell program) crashes immediately with faketime.

The symptom is always:

$ FAKETIME='2001-02-25 11:22:33' LD_PRELOAD=/usr/lib/faketime/libfaketime.so.1 ghc
Segmentation fault (core dumped)

No-op Haskell program:

echo 'main = return ()' > minimal.hs
ghc -o minimal minimal.hs
FAKETIME='2001-02-25 11:22:33' LD_PRELOAD=/usr/lib/faketime/libfaketimeMT.so.1 ./minimal
Segmentation fault (core dumped)

A backtrace from GDB:

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7bd71e2 in clock_gettime () from /usr/lib/faketime/libfaketimeMT.so.1
(gdb) bt 10
#0  0x00007ffff7bd71e2 in clock_gettime () from /usr/lib/faketime/libfaketimeMT.so.1
#1  0x00007ffff7bd7222 in clock_gettime () from /usr/lib/faketime/libfaketimeMT.so.1
#2  0x00007ffff7bd7222 in clock_gettime () from /usr/lib/faketime/libfaketimeMT.so.1
#3  0x00007ffff7bd7222 in clock_gettime () from /usr/lib/faketime/libfaketimeMT.so.1
#4  0x00007ffff7bd7222 in clock_gettime () from /usr/lib/faketime/libfaketimeMT.so.1
#5  0x00007ffff7bd7222 in clock_gettime () from /usr/lib/faketime/libfaketimeMT.so.1
#6  0x00007ffff7bd7222 in clock_gettime () from /usr/lib/faketime/libfaketimeMT.so.1
#7  0x00007ffff7bd7222 in clock_gettime () from /usr/lib/faketime/libfaketimeMT.so.1
#8  0x00007ffff7bd7222 in clock_gettime () from /usr/lib/faketime/libfaketimeMT.so.1
#9  0x00007ffff7bd7222 in clock_gettime () from /usr/lib/faketime/libfaketimeMT.so.1
(More stack frames follow...)
(gdb) bt -10
#174635 0x00007ffff7bd7222 in clock_gettime () from /usr/lib/faketime/libfaketimeMT.so.1
#174636 0x00007ffff7bd7222 in clock_gettime () from /usr/lib/faketime/libfaketimeMT.so.1
#174637 0x00007ffff7bd54b3 in ?? () from /usr/lib/faketime/libfaketimeMT.so.1
#174638 0x00007ffff7bd4f4c in ftpl_init () from /usr/lib/faketime/libfaketimeMT.so.1
#174639 0x00007ffff7dea9ca in call_init.part () from /lib64/ld-linux-x86-64.so.2
#174640 0x00007ffff7deaab3 in _dl_init_internal () from /lib64/ld-linux-x86-64.so.2
#174641 0x00007ffff7ddd2aa in _dl_start_user () from /lib64/ld-linux-x86-64.so.2
#174642 0x0000000000000001 in ?? ()
#174643 0x00007fffffffdfba in ?? ()
#174644 0x0000000000000000 in ?? ()

build in solaris11

any comments or suggestions of building in solaris11?

/tmp/libfaketime-0.9.1# gmake

gmake -C src all
gmake[1]: Entering directory /tmp/libfaketime-0.9.1/src' /opt/solarisstudio12.3/bin/cc -o faketime.o -c -std=gnu99 -Wall -DFAKE_STAT -DFAKE_INTERNAL_CALLS -fPIC -DPOSIX_REALTIME -DLIMITEDFAKING -DSPAWNSUPPORT faketime.c cc: Warning: Option -d=gnu99 passed to ld, if ld is invoked, ignored otherwise cc: -W option with unknown program all gmake[1]: *** [faketime.o] Error 1 gmake[1]: Leaving directory/tmp/libfaketime-0.9.1/src'
gmake: *** [all] Error 2

OSX ML CPU usage

It appears as if ML CPU usage for any app that uses faketime increases quite a bit!

millisecond resolution?

(edit: whoops, hit enter by accident)

I know millisecond resolution is tough in ansi c, but would it be possible to support since we just target unix-likes?

Alternatively, I'm bundling a fork in https://github.com/simon-weber/python-libfaketime; if there are easy modifications I could make that aren't backwards-compatible, I'd be happy to keep them on the fork.

Linking the faketime wrapper

As reported by Daniel from Debian:

The faketime wrapper, unlike the libfaketime library, does not need to be linked with -lm and -ldl ; the Makefile should be updated to reduce the amount of dynamic linking required.

/etc/faketimerc

What is valid for config system-wide install ?
"+369m"

+369m

gdate command not found

/usr/local/bin/faketime: line 97: gdate: command not found

env: OS X Mountain Lion with zsh

I googled a lot for gdate, but found nothing.

Chrome in OS X not working

I'm reporting this here because of this 😄:

Please feel free to report non-working applications on the Github
libfaketime issues website. This may help us to identify further
time-related system calls that need to be intercepted on OS X.

  • I installed faketime 0.9.5 using Homebrew on OS X El Capitan (10.11.2).
  • If I run faketime '2014-06-04T12:34:56Z' gdate I correctly get the faked time.
  • But if I run faketime '2014-06-04T12:34:56Z' /Applications/Google\ Chrome\ Canary.app/Contents/MacOS/Google\ Chrome\ Canary and then run new Date() in the DevTools I get the real (current) OS X date.

Thanks!

Extremely high CPU use with Java running Tomcat or Jboss

Tested this with multiple Java versions and Tomcat Jboss applications. The side effect of using faketime is extreme CPU load and load averages. Basically the apps are unusable.

What was tested:

  • OS: SmartOS 20150320T005835Z
  • java 1.5, 1.7 both Oracle and OpenJDK
  • Jboss
  • Tomcat 6

Further to this managed to run some simple DTrace probes and it seems that the java processes are super busy with syscalls: lwp_park and lwp_cond_wait which indicates Mutex locking issues.

This is most likely related to #46

Regression: Xilinx "xtclsh" does not work with faketime

I performed a regression test and the issue stems from the change in b9a46c9 where a library constructor is used instead of a mutex to initialize the function pointers. After some rather exhaustive investigation it appears that the loader calls the faketime constructor after another constructor (and that other constructor uses some of the functions in faketime). Since this occurs during construction (a single-threaded environment), the following patch should do the trick safely:
http://pastebin.com/Xze9fGLT

faketime - Error LD_PRELOAD cannot be preloaded

Hello Faketime Team,

I am using Faketime to change system date on temporary basis for a particular application user (siebel) in RHEL 5.6. I am able to change system date for siebel user but when I try start SIEBEL server, it fails with below error.

Error: id.so: object ‘/usr/local/lib/faketime/libfaketime.so.1’ from LD_PRELOAD cannot be preloaded: ignored.

libfaketime.so.1 is present at ‘/usr/local/lib/faketime/libfaketime.so.1’ and environment variable LD_PRELOAD also present which is pointing to it.Its permissions are 755 and I am able to change date of Siebel user but the issue comes at the time of starting the Siebel server in loading the /libfaketime.so.1 libraries.

In our Solaris systems we are using Time Machine provided by SolutionSoft Systems and it serve our purpose of changing date in Siebel Server.

Can you please provide a solution of doing it using Faketime.

Thanks Devesh

Unbalanced parenthesis in libfaketime.c

--- libfaketime-0.9.5pre/src/libfaketime.c.original 2013-09-04 13:41:52.000000000 +0000
+++ libfaketime-0.9.5pre/src/libfaketime.c 2013-09-04 22:08:52.907888913 +0000
@@ -614,14 +614,13 @@
return -1;
}

  • if (buf != NULL)
  • if (!fake_stat_disabled)
  • if ((buf != NULL) && !fake_stat_disabled)
    {
    buf->st_ctime = fake_time(&(buf->st_ctime));
    buf->st_atime = fake_time(&(buf->st_atime));
    buf->st_mtime = fake_time(&(buf->st_mtime));
    }
  • }

return result;
}

Mac OS X El Capitan 'Timestamp to fake not recognized'

Used Macports to install via:
sudo port install libfaketime

For any faketime command, this error returns:
Running (g)date failed: No such file or directory
Error: Timestamp to fake not recognized, please re-try with a different timestamp.

Examples that I used:
-faketime '-15d' date
-faketime '2008-12-24 08:15:42' /bin/date
and more...

I know this has been an issue with previous versions of libfaketime, but is there a workaround/fix for this?

Xcode (with command-line tools) is installed

Kubernetes Pod does not come up cleanly status CrashLoopBackOff

Hi Team,

I am trying to create a pod in Kubernetes cluster. I am working in intranet and do not have internet on Kubernetes master and nodes VMs to download docker images.

Hosted Plateform - VMWare VMs
OS - RHEL 7.1
Networking setup - Flannel & SkyDNS

Below kubernetes master components are running as a service
etcd v2.2.2,
flannel v0.5.5,
skydns,
kube-apiserver v1.1.0,
kube-controller-manager,
kube-scheduler

When I trying to create kubernetes pods I am getting below error.

[root@km01 kube_files]# kubectl run abc --image=gf01:5000/jenkins:1.592
Error from server: the server could not find the requested resource (post deploymentconfigs)

[root@km01 jdbc]# kubectl version
Client Version: version.Info{Major:"", Minor:"", GitVersion:"v1.1.0-alpha.1-653-g86b4e77", GitCommit:"86b4e77", GitTreeState:"not a git tree"}
Server Version: version.Info{Major:"", Minor:"", GitVersion:"v1.1.0-alpha.1-653-g86b4e77", GitCommit:"86b4e77", GitTreeState:"not a git tree"}

Even I have tried to create pods by creating service and rc. But status is CrashLoopBackOff - Back-off restarting failed docker container

It creates container on Node but not able to connect it.

Below are the details

Content of rc yaml file

cat jenkins-rc.yaml
kind: ReplicationController
apiVersion: v1
metadata:
name: jenkins1-controller
spec:
replicas: 1
selector:
name: jenkins1
template:
spec:
containers:

  • name: jenkins1
    image: gf01:5000/jenkins:1.592
    ports:
  • containerPort: 8080
    protocol: TCP
    metadata:
    labels:
    name: "jenkins1"
    selectorname: "jenkins1"
    labels:
    name: "jenkins1"
Content of sevice yaml file

[root@km01 kube_files]# cat jenkins-service.yaml
apiVersion: v1
kind: Service
metadata:
labels:
name: jenkins1
name: jenkins1-service
namespace: default
spec:
ports:

  • port: 8080
    selector:
    name: jenkins1
Created the service

[root@km01 kube_files]# kubectl create -f jenkins-service.yaml
service "jenkins1-service" created

Created the rc

[root@km01 kube_files]# kubectl create -f jenkins-rc.yaml
replicationcontroller "jenkins1-controller" created

list of running services

[root@km01 kube_files]# kubectl get services
NAME CLUSTER_IP EXTERNAL_IP PORT(S) SELECTOR AGE
jenkins1-service 10.254.127.188 8080/TCP name=jenkins1 15s
kubernetes 192.168.128.1 443/TCP 25d

list of running endpoints

[root@km01 kube_files]# kubectl get endpoints
NAME ENDPOINTS AGE
jenkins1-service 32s
kubernetes 10.137.28.138:6443 25d

list of runing rc

[root@km01 kube_files]# kubectl get rc
CONTROLLER CONTAINER(S) IMAGE(S) SELECTOR REPLICAS AGE
jenkins1-controller jenkins1 gf01:5000/jenkins:1.592 name=jenkins1 1 32s

list of pods

[root@km01 jdbc]# kubectl get pods
NAME READY STATUS RESTARTS AGE
jenkins1-controller-pca1x 0/1 CrashLoopBackOff 1 4h

list of nodes

[root@km01 ~]# kubectl get nodes
NAME LABELS STATUS AGE
kn01.dwpptp.londondc.com kubernetes.io/hostname=kn01.dwpptp.londondc.com Ready 19h
kn02.dwpptp.londondc.com kubernetes.io/hostname=kn02.dwpptp.londondc.com Ready 2d

details of pods which have error while creating it

[root@km01 jdbc]# kubectl describe pods jenkins1-controller-pca1x
Name: jenkins1-controller-pca1x
Namespace: default
Image(s): gf01:5000/jenkins:1.592
Node: kn01.dwpptp.londondc.com/10.137.28.139
Start Time: Tue, 05 Jan 2016 07:53:41 +0000
Labels: name=jenkins1
Status: Running
Reason:
Message:
IP: 10.20.87.12
Replication Controllers: jenkins1-controller (1/1 replicas created)
Containers:
jenkins1:
Container ID: docker://a76bdf4d89cb518fc3f7cde224e708cc329d53aba8dc812193b11aaa9b25be4d
Image: gf01:5000/jenkins:1.592
Image ID: docker://f6a5de5e326f266231e6b57c46b66d81fe9a3739f5ad8f1f39a925c96e322873
State: Waiting
Reason: CrashLoopBackOff
Last Termination State: Terminated
Reason: Error
Exit Code: 0
Started: Tue, 05 Jan 2016 12:29:05 +0000
Finished: Tue, 05 Jan 2016 12:29:06 +0000
Ready: False
Restart Count: 1
Environment Variables:
Conditions:
Type Status
Ready False
No volumes.
Events:
FirstSeen LastSeen Count From SubobjectPath Reason Message
âââââââââ ââââââââ âââââ ââââ âââââââââââââ ââââââ âââââââ
.
.
id 0d233c538882
2m 2m 1 {kubelet kn01.dwpptp.londondc.com} spec.containers{jenkins1} Started Started with docker id a76bdf4d89cb
2m 2m 1 {kubelet kn01.dwpptp.londondc.com} spec.containers{jenkins1} Created Created with docker id a76bdf4d89cb
4h 2s 1607 {kubelet kn01.dwpptp.londondc.com} spec.containers{jenkins1} Backoff Back-off restarting failed docker container

[root@km01 jdbc]# kubectl get events
FIRSTSEEN LASTSEEN COUNT NAME KIND SUBOBJECT REASON SOURCE MESSAGE

6m 6m 1 jenkins1-controller-pca1x Pod spec.containers{jenkins1} Created {kubelet kn01.dwpptp.londondc.com} Created with docker id c67b4f729dd6
6m 6m 1 jenkins1-controller-pca1x Pod spec.containers{jenkins1} Started {kubelet kn01.dwpptp.londondc.com} Started with docker id c67b4f729dd6
5h 1m 74 jenkins1-controller-pca1x Pod spec.containers{jenkins1} Pulled {kubelet kn01.dwpptp.londondc.com} Container image "gf01:5000/jenkins:1.592" already present on machine
1m 1m 1 jenkins1-controller-pca1x Pod spec.containers{jenkins1} Started {kubelet kn01.dwpptp.londondc.com} Started with docker id 05bc0bd38759
1m 1m 1 jenkins1-controller-pca1x Pod spec.containers{jenkins1} Created {kubelet kn01.dwpptp.londondc.com} Created with docker id 05bc0bd38759
5h 6s 1914 jenkins1-controller-pca1x Pod spec.containers{jenkins1} Backoff {kubelet kn01.dwpptp.londondc.com} Back-off restarting failed docker container

[root@km01 jdbc]# kubectl log --previous jenkins1-controller-pca1x
W0105 13:26:02.546595 4300 cmd.go:182] log is DEPRECATED and will be removed in a future version. Use logs instead.

details of pods on node

[root@kn01 ~]# docker ps -a |grep jenkins1-controller-pca1x
05bc0bd38759 gf01:5000/jenkins:1.592 "/bin/bash" 2 minutes ago Exited (0) 2 minutes ago k8s_jenkins1.612cff5a_jenkins1-controller-pca1x_default_6fcba14c-b381-11e5-87b3-0050568273fc_e86dc316
c67b4f729dd6 gf01:5000/jenkins:1.592 "/bin/bash" 7 minutes ago Exited (0) 7 minutes ago k8s_jenkins1.612cff5a_jenkins1-controller-pca1x_default_6fcba14c-b381-11e5-87b3-0050568273fc_48fdc8df
0d233c538882 gcr.io/google_containers/pause:0.8.0 "/pause" 57 minutes ago Up 57 minutes k8s_POD.9f81f942_jenkins1-controller-pca1x_default_6fcba14c-b381-11e5-87b3-0050568273fc_ebfdbb7a

Another issue is I have two Kubernetes nodes.

When rc create pod on first node kn01 – it creates pod and container but stuck at the time of restarting it and error/status - CrashLoopBackOff

And when the same rc tries to create pod on second node kn02 – It even fails to create pod and container. The Pod status is ContainerCreating and as it trying to download the image from gcr.io/google.

I have verified the configuration of both kubernetes nodes but it looks similar

Please let me know if you have resolution.

Thanks in advance

-Devesh

Please tag releases

Hello,

I would like to kindly request tagging of releases. This makes it easier to see what has changed in a new version.

Thanks!

CLOCK_MONOTONIC_RAW undeclared

I tried to compile the libfaketime library and I got the following compiling error:

libfaketime.c: In function ‘system_time_from_system’:
libfaketime.c:302: error: ‘CLOCK_MONOTONIC_RAW’ undeclared (first use in this  function)
libfaketime.c:302: error: (Each undeclared identifier is reported only once
libfaketime.c:302: error: for each function it appears in.)
libfaketime.c: In function ‘fake_clock_gettime’:
libfaketime.c:1601: error: ‘CLOCK_MONOTONIC_RAW’ undeclared (first use in this function)

I managed to figure it out by moving the definition

#define CLOCK_MONOTONIC_RAW          4

out of the #ifndef #endif block in libfaketime.c file

Segmentation fault

It works on my local machine (Debian), but not on Ubuntu.

The full log is here (you can search search for "faketime --version" to find the relevant part):
https://drone.io/github.com/Whonix/Whonix/298

The relevant excerpt:

+ faketime --version

/usr/bin/faketime: Version 0.8
For usage information please use '/usr/bin/faketime --help'.

+ sudo -E -u ubuntu faketime 2013-08-15T11:02:35 debchange --distributor whonix --create --package whonix --distribution local --newversion 2:100-debpackage1 'This is an auto-generated file.'
Segmentation fault
Error: Timestamp to fake not recognized, please re-try with a different timestamp.

Is the syntax really wrong?

It shouldn't Segmentation fault anyway?

libfaketime + java troubles

I have been trying to use libfaketime to avoid system lock adjustments.
We use java extensively so in order to be able to use libfaketime it must work with java,
therefore I have tried this simple program to verify if libfaketime is working:

The test is performed on a RHEL 6.5 server with kernel 2.6.32-431.23.3 kernel

$ cat time.java
import java.util.*;

class TimeTest {

public static void main(String[] s) {

long timeInMillis = System.currentTimeMillis();
Calendar cal = Calendar.getInstance();
cal.setTimeInMillis(timeInMillis);
java.util.Date date = cal.getTime();

System.out.println("Date: " + date);

}
}

(srvappserver@myhost):/home/srvappserver
$ export LD_PRELOAD=/usr/lib64/libfaketime.so.1
(srvappserver@myhost):/home/srvappserver
$ export LD_ASSUME_KERNEL=2.6.18
(srvappserver@myhost):/home/srvappserver
$ export FAKETIME="+15d"
(srvappserver@myhost):/home/srvappserver
$ date
Tue Oct 21 10:30:48 CEST 2014
(srvappserver@myhost):/home/srvappserver
$ /opt/IBM/WebSphere/AppServer/java_1.7_64/bin/java TimeTest
Invalid clock_id for clock_gettime: -179362(srvappserver@myhost):/home/srvappserver

I did set the LD_ASSUME_KERNEL to 2.6.18 after checking the required ABI version of
libpthreads.so.0 with eu-readelf -n /lib/libpthread.so.0
(the documentation in libfaketime specified 2.4.19 as the correct version to use, but that
does not work as I get error messages like: "error loading shared libraries: libpthread.so.0: cannot open shared object file: No such file or directory").

As you can see I get this error:
"invalid clock_id for clock_gettime".

Sorry if this is a basic issue, I'm a systems administrator not a developer (I did not find a mailing list or user oriented forum for libfaketime so I try to ask here).

Best regards,

Erling

segmentation fault when using faketime with meld

On Debian Wheezy. How to reproduce:

Install faketime, meld.

sudo apt-get install faketime meld

Try if meld is working.

meld

Should work fine.

Now try with faketime.

faketime "2013-05-17 00:02:43" meld

Will result in:

Segmentation fault

Date is wrong on aws rhel

When I use faketime, it is getting the date badly wrong. Demonstrated:

[ec2-user@ip-10-230-17-224 ~]$ date
Thu  7 May 14:50:53 UTC 2015
[ec2-user@ip-10-230-17-224 ~]$ faketime 'last friday 5 pm' /bin/date
Fri 26 Dec 02:09:06 UTC 1969
[ec2-user@ip-10-230-17-224 ~]$ faketime '2008-12-24 08:15:42' /bin/date
Tue 20 Aug 17:24:46 UTC 1963
[ec2-user@ip-10-230-17-224 ~]$ faketime -m '2008-12-24 08:15:42' /bin/date
Tue 20 Aug 17:24:43 UTC 1963
[ec2-user@ip-10-230-17-224 ~]$ cat /etc/system-release
Amazon Linux AMI release 2015.03
[ec2-user@ip-10-230-17-224 ~]$ cat /etc/os-release
NAME="Amazon Linux AMI"
VERSION="2015.03"
ID="amzn"
ID_LIKE="rhel fedora"
VERSION_ID="2015.03"
PRETTY_NAME="Amazon Linux AMI 2015.03"
ANSI_COLOR="0;33"
CPE_NAME="cpe:/o:amazon:linux:2015.03:ga"
HOME_URL="http://aws.amazon.com/amazon-linux-ami/"

The target app is running but is extremely slow.

I tried to run myeclipse in different ways (i.e. wrapper and pre-load with absolute, start at and relative time). It runs but is very slow (it cannot be ready to use after even 20 minutes!). It sleeps for almost long time then does a few jobs then goes to sleep again.

High ksoftirqd activity when used with tomcat 7.0.53

Starting tomcat 7.0.53 with libfaketime 0.9.5 causes CPU to lock and high CPU activity for
ksoftirqd when an offset other than 0 is used. If offset "-0d" is specified at the command line or in /etc/faketimerc, there are no issues. If offset "-20d" is used at tomcat startup or if /etc/faketimerc is changed from "-0d" to "-20d" after tomcat starts then there is high CPU in top for java and ksoftirqd

Merge Linux and OS X Makefiles; eventually use autoconf

Packaging for OS X could be simplified by not having to use a separate Makefile called Makefile.OSX; this could also avoid build processes from drifting apart too much.

Eventually, autoconf should be used so we have the classical ./configure && make && make install process for libfaketime.

Proposal for the addition of new command line switches

I'd like to propose the implementation of three new command line switches, all related to being able to choose which types of clocks are affected by faketime. This is a generalization of the recently added --exclude-monotonic flag.

Proposed additions

--list-clocks

--list-clocks outputs a list of all types of clocks supported on the current operating system. For instance, faketime --list-clocks would output, on a POSIX system, something like:

$ faketime --list-clocks
Your system supports the following clocks:
- wall
- monotonic
- cpu-process
- cpu-thread

wall corresponds to CLOCK_REALTIME, monotonic to CLOCK_MONOTONIC and CLOCK_MONOTONIC_RAW, cpu-process to CLOCK_PROCESS_CPUTIME_ID and cpu-thread to CLOCK_THREAD_CPUTIME_ID.

These clocks are all defined by POSIX, and in an ideal world should thus be available on all compliant systems. I did a quick check and they are present on GNU/Linux and SmartOS.

On a system without clock_gettime such as MacOS X, the output would be:

$ faketime --list-clocks
Your system supports the following clocks:
- wall
- system

wall would correspond to CALENDAR_CLOCK and system would correspond to SYSTEM_CLOCK and REALTIME_CLOCK.

The output could be different on other systems.

--only-clocks

--only-clocks would be used to make faketime override calls to to time API functions only for the types of clocks passed to this command line option. For instance, if you wanted to override only the calls to functions that affect wall clock time, you could use:

$ faketime --only-clocks=wall

--only-clocks could take a list of comma-separated clock type names like following:

$ faketime --only-clocks=wall,monotonic

--exclude-clocks

--exclude-clocks would be used the same way as --only-clocks described above, but its effect would be the opposite. It would make faketime not override the behavior of time functions for the specified types of clocks.

Rationale

These additions are proposed because they can be helpful when testing a program that uses the time API of an operating system and trying to understand its behavior depending on the type of clock considered.

A good example of such a use case is when testing a program that used to rely on wall-clock time to compute time intervals, and that has been fixed to use monotonic time instead.

To make sure that the program indeed does use only monotonic time to compute time intervals anymore, faketime --exclude-clocks=monotonic some-test-program -f 'some-specific-date' could be used to "freeze" time for all but monotonic clocks. If the program fails to compute timer intervals, it means it still uses wall-clock time, and is not properly fixed.

This use case can be extended to all types of clocks available on a system.

Breakdown of tasks

  1. Because the --exclude-clocks and --only-clocks command line switches both take some values as parameters, the current command line parsing code would need to be augmented with the ability to parse these values in a flexible way. This could be a good opportunity to integrate a third party command line parsing library such as GNU Getopt.

  2. Actual implementation of all three command line switches.

Please let me know what you think!

Core dump on SmartOS when using /etc/faketimerc

Applications core dumping when /etc/faketimerc is used. Apps work as expected when the FAKETIME variable is used only.

Cored dump stack is below:

ffffdf7fffdfea10 libc.so.1`_lwp_kill+0xa()
ffffdf7fffdfea40 libc.so.1`raise+0x20(6)
ffffdf7fffdfea50 libumem.so.1`umem_do_abort+0x44()
ffffdf7fffdfeb50 0xffffdf7ffec37fb2()
ffffdf7fffdfebe0 0xffffdf7ffec40b28()
ffffdf7fffdfec20 libumem.so.1`umem_alloc_retry+0xc0(ffffdf7ffec6a180, 0)
ffffdf7fffdfec80 libumem.so.1`umem_alloc+0x9b(218, 0)
ffffdf7fffdfecb0 libumem.so.1`umem_malloc+0x3f(208)
ffffdf7fffdfed80 libc.so.1`_findbuf+0x100(4298c0)
ffffdf7fffdfee00 libc.so.1`fgets+0x1ed(ffffdf7fffdfee40, 100, 4298c0)
ffffdf7fffdff7a0 libfaketimeMT.so.1`fake_clock_gettime+0x6cc()
ffffdf7fffdff7f0 libfaketimeMT.so.1`fake_gettimeofday+0x7a()
ffffdf7fffdff820 libfaketimeMT.so.1`gettimeofday+0xd0()
ffffdf7fffdff8b0 libumem.so.1`umem_init+0x4b4()
ffffdf7fffdff8f0 libumem.so.1`umem_alloc_retry+0xc0(ffffdf7ffec6a180, 0)
ffffdf7fffdff950 libumem.so.1`umem_alloc+0x9b(32, 0)
ffffdf7fffdff980 libumem.so.1`umem_malloc+0x3f(22)
ffffdf7fffdff9d0 libintl.so.8.1.2`set_binding_values.part.0+0x195()
ffffdf7fffdff9f0 libintl.so.8.1.2`libintl_bindtextdomain+0x2b()
ffffdf7fffdffb00 main+0x46()
ffffdf7fffdffb10 _start+0x6c()

Application hangs with libfaketime

I was using libfaketime with my Web application by setting libfaketime path first and then setting Faketime to previous date and then starts my application. But my application hang at different different points, every time I tries to start my application and stopped printing logs but whatever logs it created all are in previous date which I set.
While I am using Linux date command for setting previous date, my application comes online in back date successfully.
Can any one help on this? Is there way I can see libfaketime logs and see what is happening inside it?
I am using libfaketime 0.9.6 with my Web application which makes asynchronous calls through its startup services.

Support 32bit building on 64bit systems

Adding -m32 flag to the CFLAGS when compiling leads to several undefined references. Preloading libfaketime before starting a 32bit program on a 64bit system is not possiblel.
Got any ideas @wolfcw ?

Typo when showing version information


diff --git a/src/faketime.c b/src/faketime.c
--- a/src/faketime.c
+++ b/src/faketime.c
@@ -126,7 +126,7 @@ int main (int argc, char **argv)
              (0 == strcmp(argv[curr_opt], "--version")))
     {
       printf("\n%s: Version %s\n"
-         "For usage information please use '%s --help\n'.",
+         "For usage information please use '%s --help'.\n",
          argv[0], version, argv[0]);
       exit(EXIT_SUCCESS);
     }

Yosemite (10.10.5) Compatibility Issue

As of the latest Yosemite Update the library doesn't seem to work anymore. Applications crash right at launch or show unexspected behaviour.

Anyone experiencing the same issues?

Wrong pthread_cond_timedwait behavior

Test example (below) uses pthread_cond_timedwait as incorruptible delay for 2s.
It was run with environment:

LD_PRELOAD=/usr/lib/x86_64-linux-gnu/faketime/libfaketimeMT.so.1
FAKETIME=+2
FAKETIME_FMT=%s

Estimated printed time difference is 2s
Actual printed time difference is 5s (2s by libfaketime + 3s in code)

It show internal pthread_cond_timedwait time source don't affected by libfaketime
So pthread_cond_timedwait call should be handled by libfaketime

My environment: Ubuntu 14.04
faketime: Version 0.9.5
GNU C Library (Ubuntu EGLIBC 2.19-0ubuntu6.6) stable release version 2.19

#include <pthread.h>
#include <errno.h>
#include <time.h>
#include <stdio.h>
#include <sys/time.h>

int main(int, char* []) {
    pthread_mutex_t mutex;
    int const res1 = pthread_mutex_init(&mutex, NULL);
    if (res1) {
        return res1;
    }

    pthread_cond_t cond;
    int const res2 = pthread_cond_init(&cond, NULL);
    if (res2) {
        return res2;
    }
    printf("%d\n", time(NULL));
    struct timeval now;
    struct timespec timeout;
    gettimeofday(&now, NULL);
    timeout.tv_sec = now.tv_sec + 3; // 3 sec
    timeout.tv_nsec = now.tv_usec * 1000; // nsec
    int cond_res = pthread_cond_timedwait(&cond, &mutex, &timeout);
    if (cond_res != ETIMEDOUT) {
        return cond_res;
    }
    printf("%d\n", time(NULL));

    return 0;
}

Fix --exclude-monotonic test on MacOS X

Hi,

This test fails on MacOS X because the system doesn't have the clock_gettime API, and Perl's Time::HiRes doesn't support clock_get_time. Because submitting a patch to Perl's Time::HiRes seems to be both difficult (I wasn't able to find a repository of the source code) and overkill, I'd like to change the way this test is implemented. Instead of using Perl, I'd like to write a small program that simply calls:

  • clock_gettime with a CLOCK_MONOTONIC clock on POSIX compliant systems.
  • clock_get_time on MacOS X.

Does that sound reasonable to you?

Also, when looking into that, I found that on MacOS X, the clock_get_time override seems to ignore any type of clock other than a "realtime" clock. What's the reason behind that limitation?

Can libfaketime work on static binary

Hi

I have a program compiled as a static binary in 32 bits long time ago.
I would like to use libfaketime on it but it fails to change time.
I compiled libfaketime as 64 bits.

Could it be that libfaketime fails cause of the 64 - 32 bits #33 ?

Or maybe libfaketime cannot change time on static binary?

Core dump on SmartOS joyent_20150320T005835Z

Successfully compiles on SmartOS but core dumps when running date.

Extracted a core stack with mdb please see below if this is of any help.
If required can also provide the full coredump file.

Release is: joyent_20150320T005835Z

ffffdf7fffdfef70 libc.so.1`_lwp_kill+0xa()
ffffdf7fffdfefa0 libc.so.1`raise+0x20(6)
ffffdf7fffdfefb0 libumem.so.1`umem_do_abort+0x44()
ffffdf7fffdff0b0 0xffffdf7ffec37fb2()
ffffdf7fffdff140 0xffffdf7ffec40b28()
ffffdf7fffdff180 libumem.so.1`umem_alloc_retry+0xc0(ffffdf7ffec6a180, 0)
ffffdf7fffdff1e0 libumem.so.1`umem_alloc+0x9b(120, 0)
ffffdf7fffdff210 libumem.so.1`umem_malloc+0x3f(110)
ffffdf7fffdff240 libumem.so.1`calloc+0x60(22, 8)
ffffdf7fffdff280 libgcc_s.so.1`__emutls_get_address+0x10e()
ffffdf7fffdff2b0 libfaketimeMT.so.1`gettimeofday+0x4f()
ffffdf7fffdff340 libumem.so.1`umem_init+0x4b4()
ffffdf7fffdff380 libumem.so.1`umem_alloc_retry+0xc0(ffffdf7ffec6a180, 0)
ffffdf7fffdff3e0 libumem.so.1`umem_alloc+0x9b(120, 0)
ffffdf7fffdff410 libumem.so.1`umem_malloc+0x3f(110)
ffffdf7fffdff440 libumem.so.1`calloc+0x60(22, 8)
ffffdf7fffdff480 libgcc_s.so.1`__emutls_get_address+0x10e()
ffffdf7fffdff4b0 libfaketimeMT.so.1`system_time_from_system+0x18()
ffffdf7fffdff580 libfaketimeMT.so.1`ftpl_init+0x922()
ffffdf7fffdff5a0 0xffffdf7fe9b47b66()
ffffdf7fffdff5b0 libfaketimeMT.so.1`_init+0xe()
ffffdf7fffdff630 ld.so.1`call_init+0x117(ffffdf7fff340db0, 1)
ffffdf7fffdff970 ld.so.1`setup+0xdb8(ffffdf7fffdffb38, ffffdf7fffdffc08, 0, ffffdf7fffdfffcd, 1000, 
ffffdf7fff3abd0e)
ffffdf7fffdffa90 ld.so.1`_setup+0x282(ffffdf7fffdffaa0, 190)
ffffdf7fffdffb20 ld.so.1`_rt_boot+0x6c()
0000000000000001 0xffffdf7fffdffcf8()

Alternative to file-based communication from target process?

Context: I'm looking for an alternative to https://github.com/spulec/freezegun. I've got a large python test suite, and freezegun's need to search for already-imported datetime objects is too slow for me.

libfaketime is much faster. The complication is my desire to dynamically set the time from inside python:

# test.py
import datetime
import os

print datetime.datetime.now()

os.environ["FAKETIME"] = "2013-01-01 00:00:00"
print datetime.datetime.now()
$ LD_PRELOAD=src/libfaketime.so.1 FAKETIME="2014-01-01 00:00:00" python test.py
2014-01-01 00:00:00
2014-01-01 00:00:00  # I'd like this to be 2013 instead

libfaketime + a faketime file modified from python works - and is actually still faster than freezegun - but feels like a hack. Can you think of an alternative? I only need to support linux.

README: setting library search paths should be mentioned

Setting an absolute library path to LD_PRELOAD all the time is quite cumbersome.
IMHO it should be mentioned that a library search path can be set.

E.g. on Linux the following works fine as root:

Ensure that the ld.so config includes /usr/local/lib*:
$ echo -e "/usr/local/lib\n/usr/local/lib64" >> /etc/ld.so.conf.d/local.conf
$ ldconfig -v # regenerate the ld.so cache

Installing to an already existing library search path is even better.

Cannot get libfaketime to work on OSX Lion

libfaketime compiles fine but I cannot seem to get it to work on OSX Lion. Trying multiple variations of the faketime binary all produce the error as seen below:

./faketime '2008-12-24 08:15:42' /bin/date
usage: date [-jnu] [-d dst] [-r seconds] [-t west] [-v[+|-]val[ymwdHMS]] ... 
            [-f fmt date | [[[mm]dd]HH]MM[[cc]yy][.ss]] [+format]
Error: Timestamp to fake not recognized, please re-try with a different timestamp.

I saw a note in master about fixing Lion support but I thought I'd track the issue anyways so I'd be notified when it was resolved. Thanks for libfaketime and to the gentlemen who ported to OSX. You guys are awesome!

Add support for CLOCK_BOOTTIME

The Linux kernel 2.6.39 added support for another clock entitled CLOCK_BOOTTIME. Fake time errors out with the following message when launching Node.js: Invalid clock_id for clock_gettime: 7.

I have a partial implementation which shows the issue can be resolved by adding support for CLOCK_BOOTTIME, check out commit 628c70a. I'm not sure this is a complete solution since I don't know all of the nuances of how libfaketime works. I'm not submitting a pull request, but thought I'd give you a head start.

From http://man7.org/linux/man-pages/man2/clock_gettime.2.html

   CLOCK_BOOTTIME (since Linux 2.6.39; Linux-specific)
          Identical to CLOCK_MONOTONIC, except it also includes
          any time that the system is suspended.  This allows
          applications to get a suspend-aware monotonic clock
          without having to deal with the complications of
          CLOCK_REALTIME, which may have discontinuities if the
          time is changed using settimeofday(2).

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.