Skip to content

Commit 2963443

Browse files
bbarenblatianlancetaylor
authored andcommitted
cmd/cgo: ensure GCC does not use ANSI escape sequences in errors
cgo parses GCC’s error messages to classify C identifiers referenced from Go programs (are they integer constants? type names?). If GCC tries to colorize its errors, cgo can’t figure out what GCC is saying. GCC avoids escape sequences in this scenario by default, but the default behavior can be overridden in at least two places: - The user can set `CGO_COPTS=-fdiagnostics-color`. - Whoever compiled GCC can configure GCC itself to always colorize output. The most reliable way to ensure that GCC doesn’t colorize output is to append `-fdiagnostics-color=never` to the GCC command line; do so. Fixes #40415 Change-Id: Id4bdf8d92fac8b038340b4264f726e8fe38875b4 Reviewed-on: https://go-review.googlesource.com/c/go/+/248398 Run-TryBot: Ian Lance Taylor <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Ian Lance Taylor <[email protected]>
1 parent 7615b20 commit 2963443

File tree

2 files changed

+24
-9
lines changed

2 files changed

+24
-9
lines changed

src/cmd/cgo/gcc.go

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -369,7 +369,18 @@ func (p *Package) guessKinds(f *File) []*Name {
369369
fmt.Fprintf(&b, "#line 1 \"completed\"\n"+
370370
"int __cgo__1 = __cgo__2;\n")
371371

372-
stderr := p.gccErrors(b.Bytes())
372+
// We need to parse the output from this gcc command, so ensure that it
373+
// doesn't have any ANSI escape sequences in it. (TERM=dumb is
374+
// insufficient; if the user specifies CGO_CFLAGS=-fdiagnostics-color,
375+
// GCC will ignore TERM, and GCC can also be configured at compile-time
376+
// to ignore TERM.)
377+
stderr := p.gccErrors(b.Bytes(), "-fdiagnostics-color=never")
378+
if strings.Contains(stderr, "unrecognized command line option") {
379+
// We're using an old version of GCC that doesn't understand
380+
// -fdiagnostics-color. Those versions can't print color anyway,
381+
// so just rerun without that option.
382+
stderr = p.gccErrors(b.Bytes())
383+
}
373384
if stderr == "" {
374385
fatalf("%s produced no output\non input:\n%s", p.gccBaseCmd()[0], b.Bytes())
375386
}
@@ -1970,22 +1981,25 @@ func (p *Package) gccDefines(stdin []byte) string {
19701981
// gccErrors runs gcc over the C program stdin and returns
19711982
// the errors that gcc prints. That is, this function expects
19721983
// gcc to fail.
1973-
func (p *Package) gccErrors(stdin []byte) string {
1984+
func (p *Package) gccErrors(stdin []byte, extraArgs ...string) string {
19741985
// TODO(rsc): require failure
19751986
args := p.gccCmd()
19761987

19771988
// Optimization options can confuse the error messages; remove them.
1978-
nargs := make([]string, 0, len(args))
1989+
nargs := make([]string, 0, len(args)+len(extraArgs))
19791990
for _, arg := range args {
19801991
if !strings.HasPrefix(arg, "-O") {
19811992
nargs = append(nargs, arg)
19821993
}
19831994
}
19841995

1985-
// Force -O0 optimization but keep the trailing "-" at the end.
1986-
nargs = append(nargs, "-O0")
1987-
nl := len(nargs)
1988-
nargs[nl-2], nargs[nl-1] = nargs[nl-1], nargs[nl-2]
1996+
// Force -O0 optimization and append extra arguments, but keep the
1997+
// trailing "-" at the end.
1998+
li := len(nargs) - 1
1999+
last := nargs[li]
2000+
nargs[li] = "-O0"
2001+
nargs = append(nargs, extraArgs...)
2002+
nargs = append(nargs, last)
19892003

19902004
if *debugGcc {
19912005
fmt.Fprintf(os.Stderr, "$ %s <<EOF\n", strings.Join(nargs, " "))

src/cmd/dist/test.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1106,8 +1106,9 @@ func (t *tester) cgoTest(dt *distTest) error {
11061106

11071107
cmd := t.addCmd(dt, "misc/cgo/test", t.goTest())
11081108
cmd.Env = append(os.Environ(), "GOFLAGS=-ldflags=-linkmode=external")
1109-
// A -g argument in CGO_CFLAGS should not affect how the test runs.
1110-
cmd.Env = append(cmd.Env, "CGO_CFLAGS=-g0")
1109+
// cgo should be able to cope with both -g arguments and colored
1110+
// diagnostics.
1111+
cmd.Env = append(cmd.Env, "CGO_CFLAGS=-g0 -fdiagnostics-color")
11111112

11121113
t.addCmd(dt, "misc/cgo/testtls", t.goTest(), "-ldflags", "-linkmode=auto")
11131114
t.addCmd(dt, "misc/cgo/testtls", t.goTest(), "-ldflags", "-linkmode=external")

0 commit comments

Comments
 (0)