Open-Source Wikis

/

fd

/

How to contribute

/

Debugging

sharkdp/fd

Debugging

There is no built-in --verbose or log flag in fd. Debugging relies on stderr error messages, the --show-errors flag, panic backtraces, and the usual Rust toolchain.

Where errors come from

fd has a single error formatter, print_error in src/error.rs:

pub fn print_error(msg: impl Into<String>) {
    eprintln!("[fd error]: {}", msg.into());
}

Anything you see prefixed with [fd error]: was emitted by this function. Search for callers of print_error to find where a given message originates.

The top-level entry point also wraps run()'s Result:

fn main() {
    let result = run();
    match result {
        Ok(exit_code) => exit_code.exit(),
        Err(err) => {
            eprintln!("[fd error]: {err:#}");
            ExitCode::GeneralError.exit();
        }
    }
}

anyhow::Error formatted with {:#} prints the full causal chain.

--show-errors

Filesystem traversal errors (permission denied, broken symlinks, partial ignore-file parses) are silenced by default. The walker buries them in WorkerResult::Error(...), and the receiver only prints them when Config::show_filesystem_errors is true. That flag is wired to --show-errors in src/cli.rs. Always pass --show-errors when investigating "why didn't fd find this directory?" complaints.

RUST_BACKTRACE

For unexpected panics:

RUST_BACKTRACE=1 ./target/debug/fd 2>&1 | less
RUST_BACKTRACE=full cargo test failing_test_name -- --nocapture

Cargo.toml defines a debugging profile with debug = true, which produces nicer backtraces:

cargo build --profile debugging
RUST_BACKTRACE=1 ./target/debugging/fd

Common pitfalls

Symptom Likely cause
"fd does not find my file." Default ignores hidden files, .gitignore, .fdignore, and the global ignore. Try -uu (--unrestricted twice) to disable everything, or -HI. The README has a long troubleshooting section.
Pattern containing / returns 0 results By default fd matches against file names, not paths. The error checker ensure_search_pattern_is_not_a_path (in src/main.rs) emits a friendly suggestion telling you to use --full-path.
Pattern starting with ^\. returns 0 results ensure_use_hidden_option_for_leading_dot_pattern flags this and points at -H.
--exec/--exec-batch runs the wrong command after a positional pattern Anything after -x/-X belongs to the command template, not to fd. Either put -x/-X last, or terminate it with \; as documented in src/cli.rs.
Output looks unsorted fd only sorts the first batch of results (up to 1000 entries or 100 ms, see MAX_BUFFER_LENGTH/DEFAULT_MAX_BUFFER_TIME in src/walk.rs). Once it switches to streaming, results come out in the walker's natural order.
Stuck or hung process Press Ctrl-C twice. The first SIGINT sets quit_flag; the second one calls ExitCode::KilledBySigint.exit() immediately. See WorkerState::scan in src/walk.rs.
--exec produces interleaved or garbled output Each per-result Command runs with inherited stdio when there is only one thread. With multiple threads, execute_commands in src/exec/command.rs buffers stdout/stderr per command and flushes them under a stdout lock.

Tracing what fd is doing

Without a logging framework, the easiest way to inspect intermediate state is eprintln! debugging. Useful spots:

  • WorkerState::spawn_senders (in src/walk.rs) is where every entry is filtered. Add an eprintln!("{}", entry.path().display()) near the top to see every filesystem entry the walker visits.
  • construct_config in src/main.rs is where CLI input is reified into Config. Print the resulting Config to confirm what fd thinks the user asked for.
  • CommandTemplate::generate and FormatTemplate::generate (src/exec/mod.rs, src/fmt/mod.rs) are where placeholder substitution happens.

Remember to remove the eprintln! lines before submitting a PR; CI will fail if cargo clippy -- -Dwarnings finds dead _ bindings or unused_variables.

Performance debugging

  • The release profile in Cargo.toml enables LTO and codegen-units = 1. Always benchmark a cargo build --release binary, not the debug build.
  • The README links to https://github.com/sharkdp/fd-benchmarks, which provides scripts for running fd against find, rg --files, and similar tools.
  • --threads=N is exposed for measuring scaling. The default is min(available_parallelism, 64) (default_num_threads in src/cli.rs).

Getting help

  • GitHub issues are the canonical place to ask. The maintainers are responsive.
  • Security issues go through the GitHub Security Advisory form (see SECURITY.md).

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

Debugging – fd wiki | Factory