Skip to content

binutils: keep colons in tool paths that are not name separators - #1025

Merged
aalexand merged 2 commits into
google:mainfrom
HuzaifaAbdulRehman:fix-tools-windows-drive-letter
Aug 30, 2026
Merged

binutils: keep colons in tool paths that are not name separators#1025
aalexand merged 2 commits into
google:mainfrom
HuzaifaAbdulRehman:fix-tools-windows-drive-letter

Conversation

@HuzaifaAbdulRehman

Copy link
Copy Markdown
Contributor

Fixes #1024.

What is broken

-tools takes either a bare directory to search for every object tool, or
<name>:<path> pairs. On Windows the bare form never works with an absolute
path: initTools splits each entry on the first colon, so C:\tools\bin is
filed under a tool named C and the directory is never searched. pprof behaves
as though -tools had not been passed, without a warning. PPROF_TOOLS reads
the same option and fails the same way, and the Go toolchain vendors this file,
so go tool pprof -tools has the same problem.

Root cause

internal/binutils/binutils.go:137-143 treats any prefix before a colon as a
tool name:

if ct := strings.SplitN(t, ":", 2); len(ct) == 2 {
	name, path = ct[0], ct[1]
}

paths["C"] is never looked up, so paths[""] stays empty.

What changed

An entry is read as a pair only when the prefix is one of the four names
initTools looks up: llvm-symbolizer, addr2line, nm, objdump. Anything
else stays a path, so a colon inside a path survives, drive letter or not.
Parsing moved into toolPaths so it can be tested without the filesystem.

A misspelled tool name changes meaning: objdunp:/path was filed under
objdunp and ignored, and now becomes a path searched for every tool. That is
the caveat you raised on the issue, and the only behaviour difference I found.

Test plan

TestToolPaths covers the bare Windows path, the name:path form, all four
tool names, a non-Windows path containing a colon, a misspelled name and a mixed
entry. Four of its six cases fail without the change:

$ go test ./internal/binutils/ -run TestToolPaths -count=1
--- FAIL: TestToolPaths (0.00s)
    binutils_test.go:1025: absolute Windows path is a path, not a tool named C: toolPaths("C:\tools\bin") = map[C:[\tools\bin]]; want map[:[C:\tools\bin]]
FAIL

On Windows 10 with GNU binutils in C:\mingw64\bin, that directory removed from
PATH, built from 67a7179 before and after:

invocation before after
-tools 'C:\mingw64\bin' no tools found disassembly
PPROF_TOOLS='C:\mingw64\bin' no tools found disassembly
-tools 'objdump:C:\mingw64\bin,nm:...' disassembly disassembly
no -tools, tools on PATH disassembly disassembly

gofmt -d -s ., go vet -all ./..., staticcheck ./... and golangci-lint run -D errcheck are clean, and -race passes for the new tests. The full suite
matches the pre-change baseline, where TestPEFile fails in both runs because
this machine has no llvm-symbolizer.

SetTools reads each comma separated entry as "<name>:<path>", splitting on the
first colon. Every absolute Windows path carries a colon after the drive
letter, so -tools 'C:\tools\bin' was filed under a tool named "C" and the
directory was never searched. pprof then behaved as though -tools had not been
passed, with no warning. PPROF_TOOLS reads the same option and was affected the
same way.

An entry is now read as a pair only when the prefix is one of the tool names
initTools looks up: llvm-symbolizer, addr2line, nm and objdump. Anything else
stays a path, so a colon inside a path is preserved.

This changes one existing behaviour. A misspelled tool name such as
"objdunp:/path" used to be filed under "objdunp" and ignored; it now becomes a
path that is searched for every tool.
@aalexand
aalexand enabled auto-merge (squash) August 30, 2026 19:10
@codecov-commenter

codecov-commenter commented Aug 30, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 67.44%. Comparing base (9b110cc) to head (e6be8fa).
⚠️ Report is 1 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1025      +/-   ##
==========================================
+ Coverage   67.38%   67.44%   +0.05%     
==========================================
  Files          45       45              
  Lines        7849     7857       +8     
==========================================
+ Hits         5289     5299      +10     
+ Misses       2115     2114       -1     
+ Partials      445      444       -1     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@aalexand
aalexand merged commit 4932ad3 into google:main Aug 30, 2026
40 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

-tools and PPROF_TOOLS silently ignore absolute Windows paths (drive letter parsed as a tool name)

3 participants