Skip to content

Releases: shadow/shadow

v3.3.0

16 Oct 16:00
v3.3.0
5a05740

Choose a tag to compare

Summary

The primary changes that we've made in this release include:

  • Support or partial support for new syscalls: chdir, close_range, fstat
  • Better support for running scripts
  • Better support for netlink sockets used in Go programs
  • Converted some networking code from C to Rust: our DNS handler, network interface and queuing disciplines, and our packet object
  • Added another option for escaping pure-CPU busy-loops
  • Many, many bugfixes and other minor improvements

Documentation / policy updates:

  • No major updates in this release

MAJOR changes (breaking):

  • No breaking changes in this release

MINOR changes (backwards-compatible):

  • Implemented the chdir syscall. (#3368)
  • Implemented the close_range syscall. (#3364)
  • Added partial support the fstat syscall with pipes. (#3361)
  • We now support direct execution of scripts in shadow's config file. Instead of specifying {path: '/usr/bin/python3', args: '/path/to/my/script.py'}, you can now use {path: '/path/to/my/script.py'} provided it has an appropriate "shebang" line (e.g. #!/usr/bin/env python3). Likewise execution of such scripts is now supported inside the simulation when spawning processes via execve.
  • Relaxed restriction on assigning restricted IPs (such as 192.168.0.*). Within the simulation these are treated as fully routable IPs, so are required to be unique as with any other IP address assignment. (#3414)
    • Re-added restrictions for broadcast, multicast, and unspecified addresses which Shadow cannot route (#3474)
  • Removed the experimental tracker feature that logged heartbeat messages for every host every second. Also removed the corresponding python scripts for parsing and plotting tracker log messages and data. (#3446)
  • Removed support for Debian 10 (Buster), Ubuntu 20.04 (Focal), and Fedora 40, which have passed EOL. (#3504, #3535, #3663)
  • Added support for Debian 13 (Trixie) and Fedora 42. (#3663)
  • Added a python package shadowtools with auxiliary tools. It currently contains a python module for facilitating dynamic generation of shadow config files, and a command-line tool shadow-exec for streamlining single-host simulations. (#3449)
  • Improved support for netlink sockets with Go. (#3441)
  • Replaced C DNS module with a Rust implementation. Also removed the C Address type. (#3464)
  • Added support for SO_BROADCAST with getsockopt for TCP and UDP, which always returns 0 as Shadow doesn't support broadcast sockets. (#3471)
  • Removed the --coverage option from the setup script. While this is technically a breaking change to the setup script, we don't expect anyone was using this option. (#3478)
  • Converted the network interface and queuing disciplines to Rust and removed the legacy C implementations. (#3480)
  • Converted the legacy C packet and payload structs to Rust for safer reference counting. This also eliminates a payload copy in Rust TCP and UDP code. (#3492)
  • Added the experimental option --native-preemption-enabled for escaping pure-CPU busy-loops. (#3520)

PATCH changes (bugfixes):

  • Log messages about unrecognized sockopt values are now only logged at level WARN once for each distinct value (and at DEBUG afterwards) (#3353).
  • Fixed rust/clippy errors and warnings up to rust 1.90. (#3334, #3354, #3355, #3405, #3406, #3421, #3467, #3491, #3515, #3556, #3591, #3632, #3653, #3674)
  • Fixed a link error for rust 1.82. (#3445)
  • Fixed a shim panic (which causes shadow to hang) when golang's default SIGTERM handler runs in a managed program (and potentially other cases where a signal handler stack is legitimately reused). (#3396)
  • Replaced the experimental option --log-errors-to-tty with the (still experimental) option --report-errors-to-stderr. The new option no longer tries to detect whether stdout or stderr are terminals (or the same destination), and instead reports errors in a different format on stderr to make the duplication easier to sort out in the case that stdout and stderr are merged. (#3428)
  • Sending a packet to an unknown IP address no longer causes Shadow to panic. (#3411)
  • Improved the "deterministic" strace logging mode by hiding some non-deterministic syscall arguments. (#3473)
  • Shadow now overwrites the 16 bytes of random data that the Linux kernel provides in the auxiliary vector, fixing (#3539). This improves determinism, especially for golang programs (#2693), including tor simulations that include golang programs such as the obfs4proxy pluggable transport (#3538). (#3542)
  • Fixed the behavior of sockets bound to the loopback interface: Shadow no longer panics in some cases where connect and sendmsg syscalls are used with a non-loopback address. (#3531)
  • Fixed the behaviour of an implicit bind during a sendmsg syscall for UDP sockets. (#3545)
  • Fixed a TCP socket bug causing the FIN packet to be sent out of order. (#3562, #3570)
  • Fixed (lack of) EPOLLRDHUP reporting in epoll for TCP sockets (#3574), which in turn fixes network connections sometimes trying to read indefinitely after the other end has closed the connection in Rust's tokio async runtime (as in https://gitlab.torproject.org/tpo/core/arti/-/issues/1972).
  • Fixed the faccessat syscall handler to not incorrectly take a flags parameter, and added support the faccessat2 syscall which does take a flags parameter. (#3578)
  • Flags passed to the setup script will now pass "OFF" to CMake explicitly, rather than omitting the value and letting CMake choose whether it's "ON" or "OFF". (#3592)
  • Ensure file descriptors are processed in deterministic (sorted) order when bulk-closing, e.g. via close_range or when terminating a simulated process. (#3614)
  • Fix opening /proc/self/* so that they open the file corresponding to the caller's process instead of shadow's. (#3613)
  • Intercept reads to /proc/sys/kernel/random/uuid and return a simulated pseudorandom result instead of letting the host systerm return an actually-random result. (#3617, fixing #3188).
  • Trap and emulate the cpuid instruction where the platform supports it (currently on relatively new intel processors), to report that the rdrand and rdseed instructions are unavailable. (#3619, fixing #1561 and #3610)
  • Fixed an error when running clippy on Shadow and using newer compiler versions. (#3631)
  • Fixed a bug where a listening TCP socket would be cleaned up only after all its child sockets were closed. (#3643)
  • Fixed a bug where files could have their close() delayed until the application next made a blocking syscall. (#3652)
  • Fixed incorrect handling of most file -at syscalls when called with an empty path string. (#3661)
  • Fixed missing register clobbers that resulted in breakage in rust 1.89. (#3666, fixing #3654)

Full changelog since v3.2.0:

Thanks to this release's contributors: @magnified103, @ppopth, @robgjansen, @sporksmith, @stevenengler

v3.2.0

07 Jun 14:32
v3.2.0
db81738

Choose a tag to compare

Summary

The primary changes that we've made in this release include:

  • Updated our policies regarding supported platforms and contributor guidelines
  • Added new documentation about performance-tuning and profiling
  • Added or extended support for the clone3, lseek, and alarm syscalls
  • New basic support for netlink sockets (thanks @ppopth!)
  • Numerous bug fixes and improvements, including to the build system, syscall handlers, the strace facility, and process spawning/forking.

More details about specific changes are below.

Documentation / policy updates:

MAJOR changes (breaking):

  • No breaking changes in this release

MINOR changes (backwards-compatible):

  • Added support for the CLONE_CLEAR_SIGHAND flag for the clone3 syscall.
  • Improved shadow's "strace" output for unreadable memory accesses (#2821).
  • Added some support for netlink sockets (#3198).
  • Added lseek support for pipes (#3320).
  • Added support for the alarm syscall (#3321).

PATCH changes (bugfixes):

  • On fork and fork-like invocations of clone, signal handlers are now correctly copied from the parent instead of reset to default (unless CLONE_CLEAR_SIGHAND is used) (#3284).
  • Fix exponential slowdown after repeated usage of the wait4 syscall.
  • Fix the build system's clang version check (#3262).
  • Fixed a cmake warning (#3269).
  • Fixed epoll edge trigger behavior with files (#3277, fixing issue #3274).
  • Fixed --version output (#3287).
  • Fixed a panic-causing race condition when logging unsupported syscall numbers (#3288).
  • Fixed behaviour of edge-triggered epoll when more data arrives (#3243).
  • Fixed some panics in debug builds when the clone syscall handler returns abnormally (#3291, fixing #3290).
  • Improved build time of tests (#3304).
  • The build system now logs a warning when detecting golang version 1.21.x, which is incompatible with shadow's golang tests. (#3307, fixing #3267).
  • Changed some syscall error cases to return ENOTSUP instead of ENOSYS (#3314).
  • Fixed error detection and handling when spawning processes (#3344).

Full changelog since v3.1.0:

Thanks to @jtracey, @ppopth, @robgjansen, @sporksmith, and @stevenengler for their contributions to this release!

v3.1.0

31 Dec 02:16
v3.1.0
172f88c

Choose a tag to compare

Summary

The primary user-facing changes that we've made in this release include:

  • New support for spawning processes inside of a Shadow simulation. Technically, this means it now supports fork, vfork, execve, and other related syscalls.
  • A new experimental TCP stack written in Rust, can be enabled with the experimental command-line flag --use-new-tcp. The stack is not yet recommended for default use because it is still missing important TCP features such as congestion control, but work on it continues.
  • Substantial progress in migrating the shim's C code to no_std Rust code.
  • Numerous Socket API improvements, so that Shadow more accurately follows the behaviour of Linux.
  • Additional migration of C code to Rust (we're now below 20% C code remaining).

More details about specific changes are below. We also have a much more detailed writeup of many of these changes in our most recent discussion post #3187

MAJOR changes (breaking):

  • No breaking changes in this release

MINOR changes (backwards-compatible):

  • ERROR-level log lines are now logged to stderr in addition to stdout if stdout is not a tty but stderr is. This helps make errors more visible in the common case that stdout is redirected to a log file but stderr is not. This can currently be disabled via the (unstable) option log-errors-to-tty.
  • Added support for subprocess creation and management.
    • The fork syscall and fork-like invocations of the clone and clone3 syscalls.
    • Process parent pid's, process group IDs, process session IDs, and related syscalls.
    • Child exit signals (e.g. SIGCHLD)
    • The execve syscall.
  • Added Debian 12 (Bookworm) to our supported platforms.
  • Added support for sendmsg, recvmsg, and shutdown for UDP sockets.
  • Added support for MSG_TRUNC and MSG_PEEK as recv syscall argument flags for UDP sockets.
  • Added support for MSG_TRUNC as a recv syscall return flag for UDP and Unix sockets.
  • Added support for the SO_DOMAIN, SO_PROTOCOL, and SO_ACCEPTCONN socket options for TCP and UDP sockets.
  • Added support for the SIOCGSTAMP ioctl for TCP and UDP sockets.
  • Improved the simulation run time performance when there are a large number of active sockets on a single host.
    (#3238)

PATCH changes (bugfixes):

  • Updated documentation and tests to reflect that shadow no longer requires /dev/shm to be executable. (This requirement was actually removed in v3.0.0)
  • Removed several incorrect libc syscall wrappers. These wrappers are a "fast path" for intercepting syscalls at the library level instead of via seccomp. The removed wrappers were for syscalls whose glibc functions have different semantics than the underlying syscall.
  • Fixed a bug in sched_getaffinity. This bug was previously mostly latent due to an incorrectly generated libc syscall wrapper, though would have affected managed programs that made the syscall without going through libc.
  • Fixed #2681: shadow can now escape spin loops that use an inlined syscall instruction to make sched_yield syscalls.
  • Fixed a deadlock when the managed process calls recv (or similar syscalls) on a TCP or UDP socket with an invalid memory address.
  • Fixed a bug that would allow UDP sockets to accept packets from addresses that aren't the peer address.
  • Fixed an incorrect return value from the FIONREAD ioctl for UDP sockets.
  • Fixed the behaviour of the read and recv syscalls when called with 0-length buffers.
  • Fixed incorrect behaviour (incorrect return value or panic) when connect is called on a listening unix or tcp socket.
    (#3191)

Full changelog since v3.0.0:

Thanks to @stevenengler, @sporksmith, @robgjansen, @rwails for their contributions to this release!

v3.0.0

18 May 22:31
v3.0.0
e502d20

Choose a tag to compare

Summary

The dev team had accumulated a large set of breaking changes that would require a major version bump. In this release, we have focused on clearing our breaking changes queue and merging those improvements. Because these are breaking changes, this release has bumped our major version from 2 to 3. This release also significantly improves the runtime performance compared to Shadow 2.5.0.

Configuration format

  • Shadow no longer implicitly searches its working directory for executables to be run under the simulation. If you wish to specify a process path relative to Shadow's working directory, prefix that path with ./.

  • Shadow now supports YAML merge keys and extension fields. This allows you to combine YAML maps using the << key.

    Example:

    # an "extension field" that we use to store common host options
    x-host-client: &host-client
      bandwidth_up: 10Mbps
      bandwidth_down: 10Mbps
    hosts:
      client1:
        # merge the fields from the extension field above
        <<: *host-client
        processes: ...
      client2:
        <<: *host-client
        processes: ...
  • Removed the quantity options for hosts and processes. It's now recommended to use YAML anchors and merge keys instead.

    Shadow 2.x:

    hosts:
      client:
        quantity: 3
        processes: ...

    Shadow 3.x:

    hosts:
      client1: &client
        processes: ...
      # copy all fields from 'client1'
      client2: *client
      # copy all fields from 'client1' and add additional fields
      client3:
        <<: *client
        ip_addr: 152.21.4.24
  • Renamed the host_defaults field to host_option_defaults and renamed the host's options field to host_options.

    Shadow 2.x:

    host_defaults:
      ...
    hosts:
      client:
        options:
          ...

    Shadow 3.x:

    host_option_defaults:
      ...
    hosts:
      client:
        host_options:
          ...
  • Removed the host pcap_directory configuration option and replaced it with a new pcap_enabled option.

    Shadow 2.x:

    hosts:
      client:
        options:
          pcap_directory: ./

    Shadow 3.x:

    hosts:
      client:
        host_options:
          pcap_enabled: true
  • Host names are restricted to the patterns documented in hostname(7).

  • The process environment configuration option now takes a map instead of a semicolon-delimited string.

    Shadow 2.x:

    hosts:
      client:
        processes:
        - path: curl
          environment: ENV_A=1;ENV_B=foo

    Shadow 3.x:

    hosts:
      client:
        processes:
        - path: curl
          environment:
          - ENV_A: "1"
          - ENV_B: foo
  • The per-process option stop_time has been replaced with shutdown_time. When set, the signal specified by shutdown_signal (a new option) will be sent to the process at the specified time. While shadow previously sent SIGKILL at a process's stop_time, the default shutdown_signal is SIGTERM to better support graceful shutdown.

    Shadow 2.x:

    hosts:
      client:
        processes:
        - path: curl
          stop_time: 10s

    Shadow 3.x:

    hosts:
      client:
        processes:
        - path: curl
          shutdown_time: 10s
          shutdown_signal: SIGKILL
  • A new expected_final_state allows you to specify the expected state of the process at the end of the simulation. The supported states are exited, signaled, or running. If any process is not in the correct state at the end of the simulation, Shadow will return a non-zero exit code. The default expected_final_state is exited with code 0.

    In Shadow 2.x the behaviour was to consider any processes which exited with code 0, OR which were still running at the end of the simulation, as a success. Shadow 3.x does not support this specific behaviour, and you must choose a single state.

    Example:

    hosts:
      server:
        processes:
        - path: nginx
          # we expect nginx to run until the end of the simulation
          expected_final_state: running
  • Added support for a parallelism value of 0, which allows Shadow to choose a reasonable parallelism (we currently use the number of physical cores in Shadow's affinity/cgroup). The default value for parallelism has also been changed from 1 to 0.

  • It is now an error to set a process' shutdown_time or start_time to be after the simulation's stop_time.

  • Sub-second configuration values are now allowed for all time-related options, including start_time, stop_time, etc.

  • Removed and updated various experimental options including use_shim_syscall_handler, interface_qdisc, and use_extended_yaml.

File structure

  • A host's data files (files in <data-dir>/hosts/<hostname>/) are no longer prefixed with the hostname. For example a file that was previously named shadow.data/hosts/server/server.curl.1000.stdout is now named shadow.data/hosts/server/curl.1000.stdout.
  • The per-process .exitcode file has been removed due to its confusing semantics, and the new expected_final_state attribute replacing its primary use-case.
  • Generated pcap files are now named using their interface name instead of their IP address. For example "lo.pcap" and "eth0.pcap" instead of "127.0.0.1.pcap" and "11.0.0.1.pcap".

Performance

Shadow's scheduler is very performance-sensitive and needs to run tasks on worker threads with low latency. We added a spinloop in the scheduler that significantly improves Shadow's runtime performance. Some simulations see more than a 2x runtime performance improvement (for example 160 minutes to 47 minutes in a 5% Tor network simulation).

drawing

Supported platforms

We have removed several of our supported platforms. Specifically, we've dropped support for Ubuntu 18.04, Fedora 34/35/36, and CentOS Stream 8. We've also dropped support for Clang, and set a minimum-supported Linux kernel version of 5.4, which requires installing a backports kernel on Debian 10.

Stability guarantees

We've updated our "stability guarantees" document with the following changes:

  • Updated the filenames in Shadow's host-data directories to reflect the removal of the hostname prefix.
  • Added the ability to drop supported platforms in minor releases if the platforms no longer receive free updates and support from the distribution's developer.
  • Shadow no longer guarantees the order in which simulated process IDs (PIDs) are assigned.
  • Shadow will not change the criteria for the minimum supported Linux kernel version as documented in our supported platforms. This still allows us to increase the minimum kernel version as a result of dropping support for a platform.

Additional changes

Minor changes

  • Support the MSG_TRUNC flag for unix sockets. #2841
  • Support the TIMER_ABSTIME flag for clock_nanosleep. #2854
  • Removed the --profile, --include, and --library setup script options.
  • Added partial support for the epoll_pwait2 syscall.
  • Implemented the clone3 syscall. Thread libraries we're aware of that use clone3 were gracefully falling back to clone, but eventually they may not do so. This also reduces noise in shadow's log about an unimplemented syscall being attempted.
  • Shadow no longer requires /dev/shm to be executable.

Bug fixes

  • Fixed a memory leak of about 16 bytes per thread due to failing to unregister exited threads with a watchdog thread. This is unlikely to have been noticeable effect in typical simulations. In particular the per-thread data was already getting freed when the whole process exited, so it would only affect a process that created and terminated many threads over its lifetime.
  • Simulated Processes are now reaped and deallocated after the exit, reducing run-time memory usage when processes exit over the course of the simulation. This was unlikely to have affected most users, since Shadow currently doesn't support fork, so any simulation has a fixed number of processes, all of which are explicitly specified in shadow's config.
  • Fixed a potential race condition when exiting managed threads that did not have the clear_child_tid attribute set. This is unlikely to have affected most software running under Shadow, since most thread APIs use this attribute.
  • Changed an error value in clock_nanosleep and nanosleep from ENOSYS to ENOTSUP.
  • A managed process that tries to call the execve syscall will now get an error instead of escaping the Shadow simulation. #2718
  • Stopped overriding libc's getcwd with an incorrect wrapper that was returning -1 instead of NULL on errors.
  • A call to epoll_ctl with an unknown operation will return EINVAL.
  • Fixed a bug that caused Shadow to panic in some cases when a simulated thread exits. #2913
  • Fixed a bug causing host_options to undo any changes made to host_option_defaults.

Full changelog

Thanks to contributions from @robgjansen,...

Read more

v3.0.0-pre

05 May 19:36
v3.0.0-pre
6cf1b37

Choose a tag to compare

v3.0.0-pre Pre-release
Pre-release

Summary

The dev team had accumulated a large set of breaking changes that would require a major version bump. In this release, we have focused on clearing our breaking changes queue and merging those improvements. Because these are breaking changes, this release has bumped our major version from 2 to 3.

This release is marked as a pre-release because, although our CI tests are passing, we haven't had as long of a testing period as we usually do. Additionally, we have some additional internal improvements we intend to make prior to the full 3.0.0 release. We believe this pre-release should be stable, but please file issues for any bugs you find. Thanks!

Primary user-facing changes since v2.5.0

MAJOR changes (breaking):

  • Removed deprecated python scripts that only worked on Shadow 1.x config files and topologies.
  • Shadow no longer implicitly searches its working directory for executables to be run under the simulation. If you wish to specify a path relative to Shadow's working directory, prefix that path with ./.
  • Shadow now always enables support for YAML merge keys and extension fields.
    The experimental configuration option that previously enabled this support, use_extended_yaml, has been removed.
  • Removed the host pcap_directory configuration option and replaced it with a new pcap_enabled option.
  • A host's data files (files in <data-dir>/hosts/<hostname>/) are no longer prefixed with the hostname. For example a file that was previously named shadow.data/hosts/server/server.curl.1000.stdout is now named shadow.data/hosts/server/curl.1000.stdout.
  • The clang C compiler is no longer supported.
  • Host names are restricted to the patterns documented in hostname(7). #2856
  • The per-process option stop_time has been replaced with shutdown_time. When set, the signal specified by shutdown_signal (a new option) will be sent to the process at the specified time. While shadow previously sent SIGKILL at a process's stop_time, the default shutdown_signal is SIGTERM to better support graceful shutdown.
  • The minimum version of cmake has been bumped from 3.2 to 3.13.4.
  • The minimum version of glib has been bumped from 2.32 to 2.58.
  • Generated pcap files are now named using their interface name instead of their IP address. For example "lo.pcap" and "eth0.pcap" instead of "127.0.0.1.pcap" and "11.0.0.1.pcap".
  • The process environment configuration option now takes a map instead of a semicolon-delimited string.
  • Removed the quantity options for hosts and processes. It's now recommended to use YAML anchors and merge keys instead.
  • Renamed the host_defaults configuration field to host_option_defaults and renamed the host's options field to host_options.
  • Shadow now interprets a process still running at the end of the simulation as an error by default. This can be overridden by the new per-process option expected_final_state. #2886
  • The per-process .exitcode file has been removed due to its confusing semantics, and the new expected_final_state attribute replacing its primary use-case. #2906
  • Shadow no longer guarantees the order in which simulated process IDs (PIDs) are assigned. #2908

MINOR changes (backwards-compatible):

  • Support the MSG_TRUNC flag for unix sockets. #2841
  • Support the TIMER_ABSTIME flag for clock_nanosleep. #2854
  • The experimental config option use_shim_syscall_handler has been removed. This optimization is now always enabled.
  • It is now an error to set a process's stop_time or start_time to be after the simulation's stop_time.
  • Sub-second configuration values are now allowed for all time-related options, including start_time, stop_time, etc.
  • Removed the --profile, --include, and --library setup script options.
  • Added partial support for the epoll_pwait2 syscall.
  • Enabled CPU spinning in Shadow's scheduler. This significantly improves Shadow's runtime performance, but may have higher CPU and power/battery usage. #2877

PATCH changes (bugfixes):

  • Fixed a memory leak of about 16 bytes per thread due to failing to unregister exited threads with a watchdog thread. This is unlikely to
    have been noticeable effect in typical simulations. In particular the per-thread data was already getting freed when the whole process exited, so it would only affect a process that created and terminated many threads over its lifetime.
  • Fixed a potential race condition when exiting managed threads that did not have the clear_child_tid attribute set. This is unlikely to have affected most software running under Shadow, since most thread APIs use this attribute.
  • Changed an error value in clock_nanosleep and nanosleep from ENOSYS to ENOTSUP.
  • A managed process that tries to call the execve syscall will now get an error instead of escaping the Shadow simulation. #2718
  • Stopped overriding libc's getcwd with an incorrect wrapper that was returning -1 instead of NULL on errors.
  • A call to epoll_ctl with an unknown operation will return EINVAL.
  • Simulated Processes are now reaped and deallocated after the exit, reducing run-time memory usage when processes exit over the course of the simulation. This was unlikely to have affected most users, since Shadow currently doesn't support fork, so any simulation has a fixed number of processes, all of which are explicitly specified in shadow's config.

All Merged Pull Requests

Read more

v2.5.0

23 Mar 22:51
v2.5.0
eef64cb

Choose a tag to compare

Summary

In this release, we continue our transition from C to Rust. Most of the changes included in the release are backend changes that support our continued Rust migration. In particular, we've made important progress on migrating some of Shadow's core components, including Host, Process, Thread, and networking code. We also fixed some bugs and made some other changes to improve the experience for users as described below.

This release is intended to be the last stable release in the v2.x series. We have accumulated a fair number of issues that require a major version bump to complete as described in this discussion post, so we intend to take care of these issues within the next couple of weeks. As a result, the next stable release will mark the start of the v3.x series.

Primary user-facing changes since v2.4.0

  • Added a contributor code of conduct.
    https://github.com/shadow/shadow/blob/8003656d94fe781902f8b09420d994963a81c62c/CODE_OF_CONDUCT.md
  • Set the shim library's stdout/stderr to the shim log file. This should only
    affect simulations that use experimental features to disable interposition. #2725
  • Removed the experimental options preload_spin_max and use_explicit_block_message.
    These options were to support an execution model where Shadow workers ran on different
    CPU cores than the managed threads they were controlling, and each side would "spin"
    while waiting for a message from the other side. After extensive benchmarking we found
    that this was rarely a significant win, and dropped support for this behavior while
    migrating the core IPC functionality to Rust.
  • Changed the order that events are processed in Shadow. Some simulations may
    see improved runtime performance. #2522
  • Removed the experimental Dockerfile and related documentation. This is
    unrelated to running Shadow in Docker following the existing supported
    documentation
    , and we continue to support running Shadow in Docker.
  • Fixed the offset calculation in preadv/preadv2/pwritev/pwritev2 to correctly
    handle negative offsets and large offsets. #2802

All Merged Pull Requests

Read more

v2.4.0

25 Jan 15:43
v2.4.0
264a05b

Choose a tag to compare

Summary

In this release, we continue our transition from C to Rust. Most of the changes included in the release are backend changes that support our continued Rust migration. However, we also fixed many bugs and made some other changes to improve the experience for users as described below.

We intend additional work following this release to focus on changes to some of Shadow's core networking components, including the TCP stack and other facilities for forwarding packets between nodes. This is somewhat higher risk work that could result in bugs that affect Shadow's network performance and stability. We are issuing this v2.4.0 release now to ensure that users have a stable version of Shadow that they can use while we work on the high risk networking code.

Primary user-facing changes since v2.3.0

  • Fixed an uncommon memory leak in epoll_ctl. #2586
  • Tests that use shadow and tgen now use the binaries from $PATH and not
    ~/.local/bin. #2572
  • Shadow now forces the use of a specific Rust version using a
    rust-toolchain.toml file. #2614
  • Added official support for Fedora 37. #2687
  • Fixed a bug that could leak closed UDP sockets. #2594
  • Emulate sched_{get,set}affinity syscalls. #2602
  • Emulate reading from /sys/devices/system/cpu/possible and
    /sys/devices/system/cpu/online. #2602
  • Fixed the TCP header sizes in pcap files. #2620
  • Various minor improvements to the experimental strace logger (improved
    formatting of strings, buffers, and socket addresses, added logging of
    vdso-handled syscalls, etc).
  • Added etcd and wget2 examples to the examples/ directory. #2637, #2659
  • Improved the line styles in plotting script. #2638
  • Support higher-level host-specific log levels. #2645
  • Fixed a bug where a socket can receive packets that were intended for a
    different socket. #2593

All Merged Pull Requests

Read more

v2.3.0

29 Nov 22:45
v2.3.0
b09b00e

Choose a tag to compare

Summary

Shadow v2.3.0 is a minor release that contains many bug fixes as well as a large push to convert more code from C to Rust; ~54% of our code is now written in Rust compared to just 39% in C. We have incorporated many improvements to Shadow's design as we migrate to Rust, making the code easier to understand, better tested, and easier to maintain. We plan to continue our focus on migrating code to Rust in our next release.

Primary user-facing changes since v2.2.0:

  • If running Shadow in Docker, you should use
    --tmpfs /dev/shm:rw,nosuid,nodev,exec,size=1024g rather than
    --shm-size=1024g to mount /dev/shm as executable. This fixes errors when
    the managed process maps executable pages. #2400
  • Added latency modeling and potential thread-yield to rdtsc emulation, allowing
    managed code to avoid deadlock in busy-loops that use only the rdtsc
    instruction and no syscalls. #2314
  • The build now internally uses pkg-config to locate glib, instead of a custom
    cmake module. This is the recommended way of getting the
    appropriate glib compile flags, and works better in non-standard layouts such
    as in a guix environment.
  • The setup script now has a --search option, which can be used to add
    additional directories to search for pkg-config files, C headers, and
    libraries. It obsoletes the options --library and --include.
  • Fixed a bug causing mmap to fail when called on a file descriptor that was
    opened with O_NOFOLLOW. #2353
  • Bare executable names are now resolved by searching shadow's PATH.
    Previously these were interpreted as relative to the current directory. For
    backwards compatibility, Shadow will currently prefer a binary in that location
    if one is found but log a warning. Such cases should be disambiguated by using
    an absolute path or prefixing with ./.
  • Fixed order-of-operations bug in CoDel control law that could lead to an
    unexpected packet drop schedule. We think the bug could have caused Shadow to
    slightly more aggressively drop packets that have already been sitting in the
    CoDel queue for longer than 110 milliseconds. Based on the results of some Tor
    network simulations, the bug didn't appear to affect Tor network performance
    enough to lead us to believe that previous Tor simulations are invalid. #2479
  • Changed the default scheduler from thread-per-host to thread-per-core,
    which has better performance on most machines.
  • Experimental host heartbeat log messages are enabled by default
    (experimental.host_heartbeat_interval defaults to "1 sec"), but the format
    of these messages is not stable.
  • Some of Shadow's emulated syscalls and object allocations are counted and
    written to a shadow.data/sim-stats.json file.
  • Improved experimental strace logging for brk, mmap, munmap, mremap,
    mprotect, open, and openat syscalls.
  • Several small simulation examples were added to an examples/ directory.
  • Fixed the file access mode for stdin in the managed process (changed from
    O_WRONLY to O_RDONLY).
  • Fixed support for readv and writev syscalls, and added support for
    preadv and pwritev.
  • Fixed a rare crash in Shadow's shim while logging. #2459
  • Set the ifa_netmask field in getifaddrs() to improve compatibility with
    Node.js applications. #2456
  • Shadow no longer depends on its absolute installed location, allowing the
    installation directory to be safely moved. #2391
  • Shadow now emulated PR_SET_DUMPABLE, allowing it to work for programs that
    try to disable memory inspection. #2370
  • Added new test cases to check Shadow's simulated network performance. These
    new tests help us verify that Shadow's network stack is capable of
    facilitating high-bandwidth transfers when using a single TCP stream or when
    using many streams in parallel, and across networks with various latency and
    bandwidth characteristics. Since we run the tests as part of our CI, it is now
    much more likely that we will notice when we make changes that significantly
    reduces Shadow's simulated network performance. We plan to expand the cases
    that we test in future releases. #2549

New Contributors

Thanks also to Shadow devs @sporksmith, @stevenengler, and @robgjansen!

Full Changelog

The full changelog can be viewed here: v2.2.0...v2.3.0

v2.2.0

19 Jul 20:53
v2.2.0
e36f658

Choose a tag to compare

Summary

Shadow v2.2.0 is a rather small minor release that contains mostly bug fixes but also some new support for dup()ing file descriptors. We believe that our bug fixes improved Shadow's stability enough to warrant a release.

Rust became the majority language in Shadow in this release, and we plan to focus the next release on continuing our Rust migration.

Here is log of the primary user-facing changes we made since the previous release:

  • We have removed ptrace-mode, and the associated experimental options
    use-o-n-waitpid-workaround and --interpose-method. ptrace-mode was an
    alternative to Shadow's current interposition mechanism that uses LD_PRELOAD
    and seccomp. This change should be transparent to most users, since it hasn't
    been the default for several releases, and was only accessible via experimental
    options. See #1945

  • dup() and related syscalls are now supported for all file descriptors

  • Fixed behavior when multiple threads are blocked in epoll_wait on the same epoll
    file description. #2260

  • Fixed bugs causing timerfd_settime to not reset the internal timer's
    expiration count (#2279), and not cancel
    previously scheduled timer-fire events (#2282).

  • Fixed a panic when patching the VDSO in newer kernels, such as those in Ubuntu 22.04.
    #2273

  • Fixed the errno returned from calling connect() on a unix socket. This
    fixes a getaddrinfo() test failure on some systems.
    #2286

  • Fixed minor memory leaks. #2249

All Merged Pull Requests

Full Changelog: v2.1.0...v2.2.0

v2.1.0

03 Jun 22:00
v2.1.0
4226cf2

Choose a tag to compare

Shadow v2.1.0 is a minor release following our significant redesign of Shadow in v2.0.0. See the v2.0.0 release notes for more details about Shadow's new multi-process architecture.

This v2.1.0 release has largely focused on improving support for running various types of applications in Shadow while smoothing some of the rough edges introduced in v2.0.0.

We plan to focus our next release on rust migration, and we expect that Rust will become Shadow's primary programming language in v2.2.0!

New features

  • support for applications that depend on signals
  • support for dynamically linked Go applications
  • support for abstract-named unix sockets
  • VDSO-based function interposition
  • simulation progress messages (general.progress)
  • custom capture sizes for the pcap writer (host_defaults.pcap_capture_size)
  • system call latency modeling (general.model_unblocked_syscall_latency). This feature allows Shadow to escape some "busy loops" it couldn't before, avoiding deadlock in e.g. some versions of curl, iperf, libopenblas, and the golang runtime.
  • a --debug-hosts option to make debugging managed processes easier

New system calls

  • select()
  • getitimer()
  • setitimer()
  • SYS_rseq

New supported platforms

  • Ubuntu 22.04
  • Fedora 35 and 36

Changes

  • significantly improved determinism
  • O_DIRECT flag (packet mode) support for pipes
  • ioctl() support for pipes
  • SYN packets have a sequence number and are now retransmitted if they are not acknowledged
  • TCP sockets have finite-sized accept queues/backlogs
  • listen() can be called more than once for TCP sockets to set the backlog
  • improved error reporting if a process did not start or was killed unexpectedly (for example by the OS)
  • improved ioctl() file flag handling for regular files
  • TCP_NODELAY can be enabled for TCP sockets
  • added limited support for the TCP_CONGESTION socket option
  • pcap writer supports UDP packets
  • improved behaviour when one thread closes a file while another thread is blocked on a syscall that uses that file

Bug fixes

  • fixed broken eventfd and exit syscalls
  • fixed behaviour when reading/writing to a pipe
  • fixed memory leak when calling getservbyname_r()
  • fixed incorrect return value for getaddrinfo()
  • host log level is propagated to the shim log level
  • fixed crash on systems with 64-bit inodes

We've made many other internal improvements, added new test cases, and expanded our documentation.