]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/cgo: make it safe to run gcc in parallel
authormatloob <matloob@golang.org>
Mon, 25 Aug 2025 21:36:30 +0000 (17:36 -0400)
committerMichael Matloob <matloob@golang.org>
Wed, 27 Aug 2025 12:49:15 +0000 (05:49 -0700)
Use a new filename for each invocation so invocations run
concurrently don't overwrite the same file.

Change-Id: I6a6a696478b596a4819f41b3ac738263d41bbabf
Reviewed-on: https://go-review.googlesource.com/c/go/+/699017
Reviewed-by: Michael Matloob <matloob@google.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>

src/cmd/cgo/gcc.go

index edb910a8da324c7b29400f8e1393265e57d74993..f5b9eb90865daf83882b031402fbd837c8068689 100644 (file)
@@ -27,6 +27,7 @@ import (
        "slices"
        "strconv"
        "strings"
+       "sync/atomic"
        "unicode"
        "unicode/utf8"
 
@@ -1756,20 +1757,23 @@ func gccMachine() []string {
        return nil
 }
 
+var n atomic.Int64
+
 func gccTmp() string {
-       return *objDir + "_cgo_.o"
+       c := strconv.Itoa(int(n.Add(1)))
+       return *objDir + "_cgo_" + c + ".o"
 }
 
 // gccCmd returns the gcc command line to use for compiling
 // the input.
-func (p *Package) gccCmd() []string {
+func (p *Package) gccCmd(ofile string) []string {
        c := append(gccBaseCmd,
-               "-w",          // no warnings
-               "-Wno-error",  // warnings are not errors
-               "-o"+gccTmp(), // write object to tmp
-               "-gdwarf-2",   // generate DWARF v2 debugging symbols
-               "-c",          // do not link
-               "-xc",         // input language is C
+               "-w",         // no warnings
+               "-Wno-error", // warnings are not errors
+               "-o"+ofile,   // write object to tmp
+               "-gdwarf-2",  // generate DWARF v2 debugging symbols
+               "-c",         // do not link
+               "-xc",        // input language is C
        )
        if p.GccIsClang {
                c = append(c,
@@ -1806,7 +1810,8 @@ func (p *Package) gccCmd() []string {
 // gccDebug runs gcc -gdwarf-2 over the C program stdin and
 // returns the corresponding DWARF data and, if present, debug data block.
 func (p *Package) gccDebug(stdin []byte, nnames int) (d *dwarf.Data, ints []int64, floats []float64, strs []string) {
-       runGcc(stdin, p.gccCmd())
+       ofile := gccTmp()
+       runGcc(stdin, p.gccCmd(ofile))
 
        isDebugInts := func(s string) bool {
                // Some systems use leading _ to denote non-assembly symbols.
@@ -1856,11 +1861,11 @@ func (p *Package) gccDebug(stdin []byte, nnames int) (d *dwarf.Data, ints []int6
                }
        }
 
-       if f, err := macho.Open(gccTmp()); err == nil {
+       if f, err := macho.Open(ofile); err == nil {
                defer f.Close()
                d, err := f.DWARF()
                if err != nil {
-                       fatalf("cannot load DWARF output from %s: %v", gccTmp(), err)
+                       fatalf("cannot load DWARF output from %s: %v", ofile, err)
                }
                bo := f.ByteOrder
                if f.Symtab != nil {
@@ -1934,11 +1939,11 @@ func (p *Package) gccDebug(stdin []byte, nnames int) (d *dwarf.Data, ints []int6
                return d, ints, floats, strs
        }
 
-       if f, err := elf.Open(gccTmp()); err == nil {
+       if f, err := elf.Open(ofile); err == nil {
                defer f.Close()
                d, err := f.DWARF()
                if err != nil {
-                       fatalf("cannot load DWARF output from %s: %v", gccTmp(), err)
+                       fatalf("cannot load DWARF output from %s: %v", ofile, err)
                }
                bo := f.ByteOrder
                symtab, err := f.Symbols()
@@ -2034,11 +2039,11 @@ func (p *Package) gccDebug(stdin []byte, nnames int) (d *dwarf.Data, ints []int6
                return d, ints, floats, strs
        }
 
-       if f, err := pe.Open(gccTmp()); err == nil {
+       if f, err := pe.Open(ofile); err == nil {
                defer f.Close()
                d, err := f.DWARF()
                if err != nil {
-                       fatalf("cannot load DWARF output from %s: %v", gccTmp(), err)
+                       fatalf("cannot load DWARF output from %s: %v", ofile, err)
                }
                bo := binary.LittleEndian
                for _, s := range f.Symbols {
@@ -2106,11 +2111,11 @@ func (p *Package) gccDebug(stdin []byte, nnames int) (d *dwarf.Data, ints []int6
                return d, ints, floats, strs
        }
 
-       if f, err := xcoff.Open(gccTmp()); err == nil {
+       if f, err := xcoff.Open(ofile); err == nil {
                defer f.Close()
                d, err := f.DWARF()
                if err != nil {
-                       fatalf("cannot load DWARF output from %s: %v", gccTmp(), err)
+                       fatalf("cannot load DWARF output from %s: %v", ofile, err)
                }
                bo := binary.BigEndian
                for _, s := range f.Symbols {
@@ -2176,7 +2181,7 @@ func (p *Package) gccDebug(stdin []byte, nnames int) (d *dwarf.Data, ints []int6
                buildStrings()
                return d, ints, floats, strs
        }
-       fatalf("cannot parse gcc output %s as ELF, Mach-O, PE, XCOFF object", gccTmp())
+       fatalf("cannot parse gcc output %s as ELF, Mach-O, PE, XCOFF object", ofile)
        panic("not reached")
 }
 
@@ -2196,7 +2201,7 @@ func gccDefines(stdin []byte, gccOptions []string) string {
 // gcc to fail.
 func (p *Package) gccErrors(stdin []byte, extraArgs ...string) string {
        // TODO(rsc): require failure
-       args := p.gccCmd()
+       args := p.gccCmd(gccTmp())
 
        // Optimization options can confuse the error messages; remove them.
        nargs := make([]string, 0, len(args)+len(extraArgs))