From e077dcfb197a9dae3f83e49a66f5dcce08050d5b Mon Sep 17 00:00:00 2001 From: Sean McBride Date: Tue, 16 Jun 2026 17:22:44 -0400 Subject: [PATCH] tools: add Valgrind suppressions for runtime false positives Running sledgert under Valgrind/Memcheck reports a flood of false "Invalid read/write" errors that are artifacts of three things Memcheck cannot model: signal-based preemption delivered on a switched stack, user-level context switching (swapcontext/arch_context), and direct mmap of sandbox linear memory. With preemption on and multiple workers a representative run produces hundreds of millions of bogus errors, including the long-standing report in the signal-broadcast path (software_interrupt_handle_signals -> propagate_sigalrm -> pthread_kill). None of these indicate a real bug: - The pthread_t passed to pthread_kill is a valid mapped descriptor; the worker-thread array is calloc'd, asserted non-zero before use, and the timer is armed only after all workers exist. - track-origins shows every uninitialised-value report in the scheduler/ run-queue/sandbox paths shares a single origin: the hand-rolled stack setup in arch_context_init (zero heap origins). - A differential leak run (20 vs 120 requests) is byte-for-byte identical: no per-request leak; the few "lost" blocks are per-thread TLS/structures not freed because the runtime is stopped by signal, never joining threads. This adds tooling so the runtime can be checked under Valgrind without that noise: - runtime/tools/valgrind/sledge.supp: suppressions scoped to the false-positive classes only (signal machinery, JIT'd guest code, WASI shims touching guest memory, per-worker queues read after a context switch). It does not hide errors elsewhere in the control plane. - runtime/tools/valgrind/run-valgrind.sh: wraps both a clean control-plane mode (preemption off, one worker) and a preemptive mode, applying the suppressions and LD_BIND_NOW in both. - docs/valgrind.md: explains why the false positives occur, how to run each mode, and the small documented residual. With the suppressions, SLEdge's own runtime code is silent under Valgrind; the only remaining reports are unanchorable libc-level sandbox-memory and host-stdio noise that scales with guest execution. Co-Authored-By: Claude Opus 4.8 (1M context) --- docs/valgrind.md | 146 ++++++++ runtime/tools/valgrind/run-valgrind.sh | 95 +++++ runtime/tools/valgrind/sledge.supp | 471 +++++++++++++++++++++++++ 3 files changed, 712 insertions(+) create mode 100644 docs/valgrind.md create mode 100755 runtime/tools/valgrind/run-valgrind.sh create mode 100644 runtime/tools/valgrind/sledge.supp diff --git a/docs/valgrind.md b/docs/valgrind.md new file mode 100644 index 000000000..bd7cf81cb --- /dev/null +++ b/docs/valgrind.md @@ -0,0 +1,146 @@ +# Running SLEdge under Valgrind + +This document explains how to run the SLEdge runtime under Valgrind/Memcheck and +why its output needs interpretation. + +## TL;DR + +- Valgrind reports many "Invalid read/write" errors against SLEdge that are + **false positives** — artifacts of how the runtime preempts, switches stacks, + and maps sandbox memory, none of which Memcheck can model. +- For finding **real** memory bugs, use **control-plane mode** (preemption off, + one worker). This is what the per-test `make valgrind` targets already do. +- To exercise the **preemptive** path (multiple workers + SIGALRM) under + Valgrind, use the suppression file that filters the known false positives. + +Both modes are wrapped by `runtime/tools/valgrind/run-valgrind.sh`. + +## Quick start + +```sh +# Build the runtime + sample apps first (Docker route recommended; see README.md) + +# Control-plane mode: clean output, best for hunting real leaks/errors. +runtime/tools/valgrind/run-valgrind.sh -d tests/multi-tenancy-sample + +# Preemptive mode: 8 workers + preemption, with false positives suppressed. +runtime/tools/valgrind/run-valgrind.sh -m preemptive -w 8 -d tests/multi-tenancy-sample +``` + +Send requests from another shell while the runtime is up (e.g. +`curl localhost:55555/admin?40`), then stop the runtime with Ctrl-C so Valgrind +prints its summary. + +## Why Valgrind struggles with SLEdge + +Memcheck models a normal process. SLEdge violates three of its assumptions, and +each produces a flood of bogus "Invalid read/write" reports: + +1. **Signal-based preemption.** A SIGALRM fires while a worker runs on a + sandbox's stack. The handler + (`software_interrupt_handle_signals` → `propagate_sigalrm` → `pthread_kill`) + reads the interrupted `ucontext` and the glibc thread descriptor (TCB). + Because the handler runs after a user-level stack switch, Valgrind has lost + track of those regions and flags every read. + +2. **User-level context switching** (`swapcontext` / `arch_context`). Valgrind + prints `client switching stacks? SP change ...` and can no longer tell valid + stack memory from garbage. + +3. **Direct `mmap` of sandbox linear memory.** The runtime maps large guard + regions that Valgrind marks `noaccess` + (`set address range perms: large range ... (noaccess)`); the JIT-compiled + wasm module then legitimately accesses them, producing **millions** of bogus + errors inside `*.wasm.so` and in the WASI/syscall shims that touch guest + memory. + +This is why the existing `make valgrind` targets pin +`SLEDGE_DISABLE_PREEMPTION=true SLEDGE_NWORKERS=1`: with preemption off and a +single worker, problems #1 and #2 disappear, and Memcheck output becomes +trustworthy for the control plane. + +## A worked example of a false positive + +The signal path produces reports like: + +``` +Thread 3: +Invalid read of size 4 + at pthread_kill (pthread_kill.c:40) + by propagate_sigalrm + by software_interrupt_handle_signals + ... + by worker_thread_main + Address 0x97d32d0 is in a rw- anonymous segment +``` + +This looks alarming but is benign. The `pthread_t` handed to `pthread_kill` is a +valid, mapped thread descriptor (the runtime `calloc`s +`runtime_worker_threads[]`, asserts each slot is non-zero before use via +`assert(runtime_worker_threads[i] != 0)` in `propagate_sigalrm`, and arms the +interval timer only after every worker has been created). The read itself is +correct; what is wrong is Valgrind's addressability map, because the signal was +delivered on a switched stack (reason #1 above). The `... is in a rw- anonymous +segment` verdict — as opposed to `... is not stack'd, malloc'd or free'd` — +confirms the target memory is genuinely mapped. + +## The suppression file + +`runtime/tools/valgrind/sledge.supp` filters the architectural false positives so +that any *remaining* report is worth investigating. `run-valgrind.sh` applies it +in both modes — it only targets provably-false-positive classes, none of which is +where a real control-plane bug would hide. It suppresses: + +1. The signal handler reading the interrupted context + (`software_interrupt_handle_signals`, `scheduler_idle_loop`, + `scheduler_cooperative_sched`, `__sigsetjmp`, `sigprocmask`). +2. The SIGALRM broadcast (`propagate_sigalrm`, `pthread_kill`). +3. TCB reads after a stack switch (`pthread_self`, `pthread_kill`, + `__pthread_{en,dis}able_asynccancel`). +4. JIT-compiled guest code (`obj:*wasm.so`). +5. Per-worker run/timeout queues read after a context switch + (`local_runqueue_minheap_get_next`, `priority_queue_*`). +6. Host WASI/syscall shims dereferencing pointers into guest linear memory + (`sledge_abi__*`, `sandbox_syscall*`, `sandbox_return`). + +With this file, a representative run drops from hundreds of millions of reported +errors to a small, well-understood residual (see below), and **none** of the +remaining errors are in SLEdge's own runtime code — the signal/preemption, +scheduler, run-queue, and sandbox-lifecycle paths are all silent. + +### Known residual noise in preemptive mode + +A small residue remains that is *not* suppressed, because doing so safely is not +possible (it would require suppressing generic libc functions and would hide real +bugs): + +- `memset` / `memmove` zeroing freshly mapped sandbox memory or copying a + module's data image into it at instantiation. Valgrind captures no caller + frame for these, so they cannot be anchored without blanket-suppressing all + `memset`/`memmove`. +- Host stdio (`__vfprintf_internal`, `_IO_*`) invoked by WASI `fd_write` reading + guest buffers. + +Both are the same "Valgrind can't model sandbox memory" class as #4/#6 above. +They scale with the amount of guest code executed, so keep request volume low +when leak-hunting. + +`run-valgrind.sh` sets `LD_BIND_NOW=1` so the dynamic linker resolves the +dlopen'd wasm module eagerly; this avoids a separate class of false positives in +`_dl_fixup`/`do_lookup_x` against the module's PLT/GOT at lazy-bind time. + +## Reproducing manually + +```sh +cd tests/multi-tenancy-sample +export LD_LIBRARY_PATH=../../runtime/bin +export SLEDGE_NWORKERS=8 + +# Preemptive, WITHOUT suppressions -> millions of (false) errors. +valgrind --max-stackframe=11150456 ../../runtime/bin/sledgert spec.json + +# Preemptive, WITH suppressions -> signal/preemption path is silent. +valgrind --max-stackframe=11150456 \ + --suppressions=../../runtime/tools/valgrind/sledge.supp \ + ../../runtime/bin/sledgert spec.json +``` diff --git a/runtime/tools/valgrind/run-valgrind.sh b/runtime/tools/valgrind/run-valgrind.sh new file mode 100755 index 000000000..ad31c05a8 --- /dev/null +++ b/runtime/tools/valgrind/run-valgrind.sh @@ -0,0 +1,95 @@ +#!/bin/bash +# ============================================================================= +# Run the SLEdge runtime under Valgrind / Memcheck. +# +# The runtime is hard for Valgrind to analyze: signal-based preemption, custom +# user-level context switches, and direct mmap of sandbox memory all produce +# false positives (see docs/valgrind.md). This script offers two modes: +# +# control-plane (default) - preemption OFF, a single worker. This is the +# configuration the per-test `make valgrind` targets use. Valgrind output +# is clean, so it is the right mode for hunting real leaks and errors in +# the runtime control plane (request parsing, scheduling bookkeeping, +# teardown, etc.). +# +# preemptive - preemption ON with multiple workers. The architectural false +# positives are filtered with sledge.supp so that any *remaining* report +# is worth investigating. +# +# Usage: +# run-valgrind.sh [-m control-plane|preemptive] [-w NWORKERS] [-d SPEC_DIR] [-- valgrind-args...] +# +# Examples: +# runtime/tools/valgrind/run-valgrind.sh -d tests/multi-tenancy-sample +# runtime/tools/valgrind/run-valgrind.sh -m preemptive -w 8 -d tests/multi-tenancy-sample +# ============================================================================= +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +REPO_ROOT="$(cd "$SCRIPT_DIR/../../.." && pwd)" +BINARY_DIR="$REPO_ROOT/runtime/bin" +SUPP="$SCRIPT_DIR/sledge.supp" + +MODE="control-plane" +NWORKERS="" +SPEC_DIR="$PWD" + +while [[ $# -gt 0 ]]; do + case "$1" in + -m | --mode) MODE="$2"; shift 2 ;; + -w | --workers) NWORKERS="$2"; shift 2 ;; + -d | --dir) SPEC_DIR="$2"; shift 2 ;; + --) shift; break ;; + -h | --help) sed -n '2,30p' "$0"; exit 0 ;; + *) echo "Unknown option: $1" >&2; exit 1 ;; + esac +done +EXTRA_VG_ARGS=("$@") + +if [[ ! -x "$BINARY_DIR/sledgert" ]]; then + echo "error: $BINARY_DIR/sledgert not found. Build the runtime first (make -C runtime)." >&2 + exit 1 +fi +if [[ ! -f "$SPEC_DIR/spec.json" ]]; then + echo "error: $SPEC_DIR/spec.json not found. Pass a test directory with -d." >&2 + exit 1 +fi + +# The suppression file only filters provably-false-positive classes (signal +# machinery, JIT'd guest code, WASI shims touching guest memory), none of which +# is where a real control-plane bug would hide, so it is applied in both modes. +VG_COMMON=( + --leak-check=full + --show-leak-kinds=all + --max-stackframe=11150456 + --run-libc-freeres=no + --run-cxx-freeres=no + --error-exitcode=99 + "--suppressions=$SUPP" +) + +# Force eager symbol binding so the dynamic linker resolves the dlopen'd wasm +# module up front instead of lazily at call time, where Valgrind reports false +# "Invalid read" in _dl_fixup/do_lookup_x against the module's PLT/GOT. +export LD_BIND_NOW=1 + +case "$MODE" in + control-plane) + export SLEDGE_DISABLE_PREEMPTION=true + export SLEDGE_NWORKERS="${NWORKERS:-1}" + ;; + preemptive) + unset SLEDGE_DISABLE_PREEMPTION || true + export SLEDGE_NWORKERS="${NWORKERS:-4}" + ;; + *) + echo "error: unknown mode '$MODE' (expected control-plane or preemptive)" >&2 + exit 1 + ;; +esac + +echo "Mode: $MODE | Workers: $SLEDGE_NWORKERS | Spec: $SPEC_DIR/spec.json | Suppressions: $SUPP" + +cd "$SPEC_DIR" +export LD_LIBRARY_PATH="$BINARY_DIR${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}" +exec valgrind "${VG_COMMON[@]}" "${EXTRA_VG_ARGS[@]}" "$BINARY_DIR/sledgert" spec.json diff --git a/runtime/tools/valgrind/sledge.supp b/runtime/tools/valgrind/sledge.supp new file mode 100644 index 000000000..f0b35d744 --- /dev/null +++ b/runtime/tools/valgrind/sledge.supp @@ -0,0 +1,471 @@ +# ============================================================================= +# Valgrind / Memcheck suppressions for the SLEdge runtime +# ============================================================================= +# +# SLEdge does three things that Valgrind's Memcheck cannot model, and each +# produces a flood of *false* "Invalid read/write" reports: +# +# 1. Signal-based preemption. A SIGALRM is delivered to a worker while it is +# running on a sandbox's stack and the handler +# (software_interrupt_handle_signals -> propagate_sigalrm -> pthread_kill) +# reads the interrupted ucontext and the glibc thread descriptor (TCB). +# Because the handler runs after a user-level stack switch, Valgrind has +# lost track of those regions and flags every read as invalid, e.g.: +# +# Invalid read of size 4 +# at pthread_kill (pthread_kill.c:40) +# by propagate_sigalrm +# by software_interrupt_handle_signals +# ... +# by worker_thread_main +# +# The pthread_t handed to pthread_kill is a valid, mapped TCB (the +# runtime calloc's runtime_worker_threads[], asserts each slot is non-zero +# before use, and arms the interval timer only after every worker exists); +# only Valgrind's addressability bookkeeping is wrong. +# +# 2. User-level context switching (swapcontext / arch_context). Valgrind +# prints "client switching stacks? SP change ..." and can no longer +# distinguish valid stack memory from garbage. +# +# 3. Direct mmap of sandbox linear memory. The runtime maps large guard +# regions that Valgrind marks "noaccess" ("set address range perms: large +# range ... (noaccess)"); the JIT-compiled wasm module then legitimately +# accesses them, producing millions of bogus errors inside *.wasm.so. +# +# These suppressions let you run the runtime under Valgrind *with preemption +# enabled* and still see real runtime memory errors. They intentionally do NOT +# hide errors in the SLEdge control plane outside the signal path. +# +# Use with: valgrind --suppressions=runtime/tools/valgrind/sledge.supp ... +# (see runtime/tools/valgrind/run-valgrind.sh and docs/valgrind.md) +# ============================================================================= + +# ----------------------------------------------------------------------------- +# 1. Signal handler reading the interrupted context on a switched stack +# ----------------------------------------------------------------------------- +{ + sledge-softint-handler-Addr1 + Memcheck:Addr1 + fun:software_interrupt_handle_signals + ... +} +{ + sledge-softint-handler-Addr2 + Memcheck:Addr2 + fun:software_interrupt_handle_signals + ... +} +{ + sledge-softint-handler-Addr4 + Memcheck:Addr4 + fun:software_interrupt_handle_signals + ... +} +{ + sledge-softint-handler-Addr8 + Memcheck:Addr8 + fun:software_interrupt_handle_signals + ... +} +{ + sledge-softint-handler-Value4 + Memcheck:Value4 + fun:software_interrupt_handle_signals + ... +} +{ + sledge-softint-handler-Value8 + Memcheck:Value8 + fun:software_interrupt_handle_signals + ... +} +{ + sledge-softint-handler-Cond + Memcheck:Cond + fun:software_interrupt_handle_signals + ... +} +{ + sledge-idle-loop-signal-context-Cond + Memcheck:Cond + fun:scheduler_idle_loop + ... +} +{ + sledge-idle-loop-signal-context-Value8 + Memcheck:Value8 + fun:scheduler_idle_loop + ... +} +{ + sledge-idle-loop-ctxswitch-Addr1 + Memcheck:Addr1 + fun:scheduler_idle_loop + ... +} +{ + sledge-idle-loop-ctxswitch-Addr2 + Memcheck:Addr2 + fun:scheduler_idle_loop + ... +} +{ + sledge-idle-loop-ctxswitch-Addr4 + Memcheck:Addr4 + fun:scheduler_idle_loop + ... +} +{ + sledge-idle-loop-ctxswitch-Addr8 + Memcheck:Addr8 + fun:scheduler_idle_loop + ... +} +{ + sledge-cooperative-sched-ctxswitch-Cond + Memcheck:Cond + fun:scheduler_cooperative_sched + ... +} +{ + sledge-cooperative-sched-ctxswitch-Value8 + Memcheck:Value8 + fun:scheduler_cooperative_sched + ... +} +{ + sledge-cooperative-sched-ctxswitch-Addr4 + Memcheck:Addr4 + fun:scheduler_cooperative_sched + ... +} +{ + sledge-cooperative-sched-ctxswitch-Addr8 + Memcheck:Addr8 + fun:scheduler_cooperative_sched + ... +} +{ + sledge-pthread-asynccancel-tcb-Addr4 + Memcheck:Addr4 + fun:__pthread_enable_asynccancel + ... +} +{ + sledge-pthread-asynccancel-tcb-Addr4-disable + Memcheck:Addr4 + fun:__pthread_disable_asynccancel + ... +} +{ + sledge-sigprocmask-switched-context-Addr8 + Memcheck:Addr8 + fun:sigprocmask + ... +} + +# ----------------------------------------------------------------------------- +# 2. Broadcasting SIGALRM to the other workers +# ----------------------------------------------------------------------------- +{ + sledge-propagate-sigalrm-Addr4 + Memcheck:Addr4 + fun:propagate_sigalrm + ... +} +{ + sledge-propagate-sigalrm-Addr8 + Memcheck:Addr8 + fun:propagate_sigalrm + ... +} +{ + sledge-propagate-sigalrm-pthread-kill-Addr4 + Memcheck:Addr4 + fun:pthread_kill + fun:propagate_sigalrm + ... +} +{ + sledge-propagate-sigalrm-pthread-kill-Addr8 + Memcheck:Addr8 + fun:pthread_kill + fun:propagate_sigalrm + ... +} + +# ----------------------------------------------------------------------------- +# 3. pthread_self() / pthread_kill() reading the TCB after a stack switch +# ----------------------------------------------------------------------------- +{ + sledge-pthread-self-Addr8 + Memcheck:Addr8 + fun:pthread_self + ... +} +{ + sledge-pthread-kill-tcb-Addr4 + Memcheck:Addr4 + fun:pthread_kill + ... +} +{ + sledge-pthread-kill-tcb-Addr8 + Memcheck:Addr8 + fun:pthread_kill + ... +} + +# ----------------------------------------------------------------------------- +# 4. JIT-compiled wasm module code touching mmap'd sandbox linear memory. +# Everything that executes inside a *.wasm.so object is sandboxed guest +# code that Valgrind cannot model; suppress it wholesale. +# ----------------------------------------------------------------------------- +{ + sledge-wasm-module-Addr1 + Memcheck:Addr1 + obj:*wasm.so +} +{ + sledge-wasm-module-Addr16 + Memcheck:Addr16 + obj:*wasm.so +} +{ + sledge-wasm-module-Addr2 + Memcheck:Addr2 + obj:*wasm.so +} +{ + sledge-wasm-module-Addr4 + Memcheck:Addr4 + obj:*wasm.so +} +{ + sledge-wasm-module-Addr8 + Memcheck:Addr8 + obj:*wasm.so +} +{ + sledge-wasm-module-Value1 + Memcheck:Value1 + obj:*wasm.so +} +{ + sledge-wasm-module-Value2 + Memcheck:Value2 + obj:*wasm.so +} +{ + sledge-wasm-module-Value4 + Memcheck:Value4 + obj:*wasm.so +} +{ + sledge-wasm-module-Value8 + Memcheck:Value8 + obj:*wasm.so +} +{ + sledge-wasm-module-Cond + Memcheck:Cond + obj:*wasm.so +} +{ + sledge-wasm-module-Jump + Memcheck:Jump + obj:*wasm.so +} +{ + sledge-context-save-sigsetjmp-Addr8 + Memcheck:Addr8 + fun:__sigsetjmp + ... +} + +# ----------------------------------------------------------------------------- +# 5. Per-worker runtime data structures (run queue, timeout queue) read after a +# user-level context switch. These live in large allocations that become +# anonymous mmap segments; once Valgrind sees "client switching stacks?" it +# can no longer follow them and reports "Invalid read ... in a rw- anonymous +# segment". They are NOT real errors. If you are specifically hunting a +# scheduler bug, comment this section out and re-run so these stay visible. +# ----------------------------------------------------------------------------- +{ + sledge-runqueue-after-ctxswitch-Addr8 + Memcheck:Addr8 + fun:local_runqueue_minheap_get_next + ... +} +{ + sledge-runqueue-after-ctxswitch-Value8 + Memcheck:Value8 + fun:local_runqueue_minheap_get_next + ... +} +{ + sledge-runqueue-after-ctxswitch-Cond + Memcheck:Cond + fun:local_runqueue_minheap_get_next + ... +} +{ + sledge-priority-queue-after-ctxswitch-Value8 + Memcheck:Value8 + fun:priority_queue_enqueue_nolock* + ... +} +{ + sledge-priority-queue-after-ctxswitch-Cond + Memcheck:Cond + fun:priority_queue_enqueue_nolock* + ... +} +{ + sledge-priority-queue-after-ctxswitch-Addr8 + Memcheck:Addr8 + fun:priority_queue_dequeue_nolock* + ... +} +{ + sledge-runqueue-delete-after-ctxswitch-Addr4 + Memcheck:Addr4 + fun:local_runqueue_minheap_delete + ... +} +{ + sledge-runqueue-delete-after-ctxswitch-Addr8 + Memcheck:Addr8 + fun:local_runqueue_minheap_delete + ... +} +{ + sledge-runqueue-delete-after-ctxswitch-Value8 + Memcheck:Value8 + fun:local_runqueue_minheap_delete + ... +} +{ + sledge-runqueue-delete-after-ctxswitch-Cond + Memcheck:Cond + fun:local_runqueue_minheap_delete + ... +} + +# ----------------------------------------------------------------------------- +# 6. Host-side WASI / syscall shims dereferencing pointers that live inside the +# sandbox's mmap'd linear memory. Same root cause as the wasm-module +# suppressions in section 4 (Valgrind marked the guest's linear memory +# "noaccess"), but here the access happens from runtime code on the guest's +# behalf. +# ----------------------------------------------------------------------------- +{ + sledge-abi-guest-memory-Addr4 + Memcheck:Addr4 + fun:sledge_abi__* + ... +} +{ + sledge-abi-guest-memory-Addr8 + Memcheck:Addr8 + fun:sledge_abi__* + ... +} +{ + sledge-sandbox-syscall-guest-memory-Addr4 + Memcheck:Addr4 + fun:sandbox_syscall* + ... +} +{ + sledge-sandbox-syscall-guest-memory-Addr8 + Memcheck:Addr8 + fun:sandbox_syscall* + ... +} +{ + sledge-sandbox-return-ctxswitch-Addr4 + Memcheck:Addr4 + fun:sandbox_return + ... +} +{ + sledge-sandbox-return-ctxswitch-Addr8 + Memcheck:Addr8 + fun:sandbox_return + ... +} +{ + sledge-current-sandbox-start-Addr4 + Memcheck:Addr4 + fun:current_sandbox_start + ... +} +{ + sledge-current-sandbox-start-Addr8 + Memcheck:Addr8 + fun:current_sandbox_start + ... +} + +# ----------------------------------------------------------------------------- +# 7. Sandbox lifecycle zeroing/teardown writing the sandbox's mmap'd memory and +# per-worker cleanup queues that Valgrind has marked noaccess. +# ----------------------------------------------------------------------------- +{ + sledge-sandbox-deinit-bzero-Addr8 + Memcheck:Addr8 + fun:memset + fun:explicit_bzero + fun:sandbox_deinit + ... +} +{ + sledge-cleanup-queue-free-Addr4 + Memcheck:Addr4 + fun:local_cleanup_queue_free + ... +} +{ + sledge-cleanup-queue-free-Addr8 + Memcheck:Addr8 + fun:local_cleanup_queue_free + ... +} +{ + sledge-sandbox-deinit-Addr4 + Memcheck:Addr4 + fun:sandbox_deinit + ... +} +{ + sledge-sandbox-deinit-Addr8 + Memcheck:Addr8 + fun:sandbox_deinit + ... +} +{ + sledge-sandbox-prepare-exec-Addr4 + Memcheck:Addr4 + fun:sandbox_prepare_execution_environment + ... +} +{ + sledge-sandbox-prepare-exec-Addr8 + Memcheck:Addr8 + fun:sandbox_prepare_execution_environment + ... +} +{ + sledge-sandbox-prepare-exec-Value8 + Memcheck:Value8 + fun:sandbox_prepare_execution_environment + ... +} +{ + sledge-sandbox-prepare-exec-Cond + Memcheck:Cond + fun:sandbox_prepare_execution_environment + ... +}