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 -- --nocaptureCargo.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(insrc/walk.rs) is where every entry is filtered. Add aneprintln!("{}", entry.path().display())near the top to see every filesystem entry the walker visits.construct_configinsrc/main.rsis where CLI input is reified intoConfig. Print the resultingConfigto confirm what fd thinks the user asked for.CommandTemplate::generateandFormatTemplate::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
releaseprofile inCargo.tomlenables LTO andcodegen-units = 1. Always benchmark acargo build --releasebinary, 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=Nis exposed for measuring scaling. The default ismin(available_parallelism, 64)(default_num_threadsinsrc/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.