Open-Source Wikis

/

curl

/

How to contribute

/

Debugging

curl/curl

Debugging

curl has rich introspection built in. This page collects the knobs.

Trace and verbose output

curl -v https://example.com/                # request/response headers
curl --trace - https://example.com/         # full hex dump
curl --trace-ascii - https://example.com/   # readable trace
curl --trace-config "ssl,multi,http/2" -v   # per-component trace, since 8.3.0

--trace-config accepts a comma-separated list of tracer names matching the components in lib/curl_trc.h (e.g. dns, multi, http/2, http/3, ssl, ftp, smtp). The component table is in lib/curl_trc.c; new tracers are added there.

Application-level equivalent: set CURLOPT_VERBOSE and CURLOPT_DEBUGFUNCTION to capture the same data via CURLINFO_TEXT, CURLINFO_HEADER_*, and CURLINFO_DATA_* callbacks (include/curl/curl.h).

Debug builds

./configure --enable-debug --enable-curldebug --with-openssl

What this enables:

  • DEBUGBUILD symbol — turns on internal DEBUGASSERT() (defined in lib/curl_setup.h)
  • lib/memdebug.c allocation tracking
  • Extra invariants in multi.c, cfilters.c, etc.
  • CURL_DEBUGOUTPUT and curl_debug_dump_* helpers

This build is not intended for production. Linker visibility, memory accounting, and error injection make it slower and bigger.

Memory leak hunting

./configure --enable-debug --enable-curldebug
make
CURL_MEMDEBUG=/tmp/memlog src/curl https://example.com/
tests/memanalyze.pl /tmp/memlog

memanalyze.pl reports leaks, double-frees, and corruptions. The analyser is also wired into runtests.pl so leaks fail the test.

Torture mode

( cd tests && ./runtests.pl -t 1 )

Torture mode reruns the test once per allocation point, returning NULL from each in turn. Most error paths in libcurl are exercised this way, which is how curl avoids unfreed-memory regressions in failure paths.

Sanitizers

CFLAGS="-fsanitize=address,undefined -fno-sanitize-recover -O1 -g" \
  ./configure --enable-debug --with-openssl
make
make test

ASan, UBSan, and (on supported toolchains) MSan. The linux.yml workflow uses these for every PR — local sanitizer runs are recommended only for sweeping changes.

SSL/TLS keylog

For Wireshark TLS decryption, set SSLKEYLOGFILE:

SSLKEYLOGFILE=/tmp/sslkeys.txt curl https://example.com/

The keylog is implemented in lib/vtls/keylog.c and is shared by all TLS backends.

Connection-cache and DNS-cache state

Build with -DDEBUGBUILD and CURL_TRC_FT_CONN to dump cache state on close:

curl --trace-config "conn,dns" -v https://example.com/

The dumped data is documented in lib/conncache.c and lib/dnscache.c.

Common pitfalls

Symptom Probable cause
Hangs in Curl_multi_runsingle Forgot to call curl_multi_socket_action for a ready FD; check CURLMOPT_SOCKETFUNCTION
Bad function argument while writing Returned wrong value from CURLOPT_WRITEFUNCTION; must equal nmemb*size
TLS handshake fails on Windows after upgrade Schannel CA-store changes; lib/vtls/schannel_verify.c and docs/SSLCERTS.md
HTTP/2 stalls at exactly 64 KiB Window-update pacing — see lib/http2.c flow-control logic
FTP "PASV failed" through NAT Server returns LAN address; use --ftp-skip-pasv-ip (lib/ftp.c)

For deeper protocol issues, the --trace output combined with the matching test in tests/data/ is usually enough to localize the bug to one source file.

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

Debugging – curl wiki | Factory