Files
Laszlo NagyandClaude Opus 4.8 c29e41ca0e feat(logging): unify diagnostics into user and developer formats
Bear's log output serves two readers, and one format could not serve
both. A user running a build wants terse, program-prefixed messages like
every other UNIX tool; a developer debugging Bear wants a rich trace that
tells apart the driver, wrapper, and preload processes as their lines
interleave on one terminal.

The old code had three divergent init sites: the driver used env_logger's
default format, which tags each line with the Rust module path rather than
the process, so a single process spanning many crates was mislabelled;
the wrapper and preload each hand-rolled a timestamped format with
duplicated epoch math.

Replace all three with one shared initializer in the intercept crate
(the only dependency common to every binary). It picks a format from the
environment: unset RUST_LOG gives the UNIX user view "prog: message" on
stderr with warning:/error: qualifiers; a set RUST_LOG gives the developer
view tagging every line with a timestamp, level, process identity plus
pid, and source module. Process identities are stable: bear, wrapper,
preload.

Behavior change worth noting for release: the wrapper and preload
previously had no explicit default filter (effectively error level); they
now default to warn like the driver, so a rare preload warning (non-UTF-8
popen/system command, or a double-init guard) can reach an intercepted
compiler's stderr. This is intentional per the new contract.

Governed by the new requirement cli-diagnostic-format, verified by unit
tests on the format helpers and integration tests on the format switch.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-23 10:59:07 +00:00
..

Dynamic library for Bear interception

This crate provides a dynamic library for Unix systems that can be used with Bear for intercepting system calls via the LD_PRELOAD mechanism (or DYLD_INSERT_LIBRARIES on macOS).

Overview

libexec is designed to work with the Bear compilation database generator. It intercepts system calls like execve to track command execution during builds.

The library is split into a C shim (src/c/shim.c) and Rust implementation (src/implementation.rs). This separation exists because:

  1. Stable Rust cannot handle C variadic arguments (execl family)
  2. On FreeBSD, libc functions may call each other internally — having all exported symbols in C call into Rust (which uses dlsym(RTLD_NEXT, ...)) avoids recursive interception issues

Supported Platforms

Platform Mechanism Symbol visibility
Linux, FreeBSD, OpenBSD, NetBSD, DragonFly BSD LD_PRELOAD ELF version scripts
macOS DYLD_INSERT_LIBRARIES -exported_symbols_list

On unsupported platforms (e.g. Windows), the build displays a warning and skips library generation.

Features

  • Intercepts exec family calls, posix_spawn, popen, and system
  • Automatically "doctors" child process environments to maintain interception across exec calls
  • Reports intercepted executions to a TCP collector
  • Platform capability detection at build time (only intercepts functions available on the host)

Building

To build libexec in debug mode:

cargo build -p intercept-preload

For the release version:

cargo build -p intercept-preload --release

The resulting shared library will be in target/debug/libexec.so (or .dylib on macOS) and target/release/libexec.so respectively.