]> Cypherpunks repositories - gostls13.git/commitdiff
encoding/gob: avoid race on idToType
authorIan Lance Taylor <iant@golang.org>
Thu, 4 Jan 2018 01:50:47 +0000 (17:50 -0800)
committerIan Lance Taylor <iant@golang.org>
Thu, 4 Jan 2018 02:17:33 +0000 (02:17 +0000)
Fixes #23328

Change-Id: Ie4864d7f388d363860318fe41431d8a9719e9a75
Reviewed-on: https://go-review.googlesource.com/86075
Run-TryBot: Ian Lance Taylor <iant@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Reviewed-by: Rob Pike <r@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>

src/cmd/dist/test.go
src/encoding/gob/decode.go
src/encoding/gob/type_test.go

index 5842a982331072152966d3bc71b5899ca7f10507..44971ecf17172c283cb9ed09d2360279b1b5e919 100644 (file)
@@ -1286,7 +1286,7 @@ func (t *tester) runFlag(rx string) string {
 func (t *tester) raceTest(dt *distTest) error {
        t.addCmd(dt, "src", t.goTest(), "-race", "-i", "runtime/race", "flag", "os", "os/exec")
        t.addCmd(dt, "src", t.goTest(), "-race", t.runFlag("Output"), "runtime/race")
-       t.addCmd(dt, "src", t.goTest(), "-race", t.runFlag("TestParse|TestEcho|TestStdinCloseRace|TestClosedPipeRace"), "flag", "os", "os/exec")
+       t.addCmd(dt, "src", t.goTest(), "-race", t.runFlag("TestParse|TestEcho|TestStdinCloseRace|TestClosedPipeRace|TestTypeRace"), "flag", "os", "os/exec", "encoding/gob")
        // We don't want the following line, because it
        // slows down all.bash (by 10 seconds on my laptop).
        // The race builder should catch any error here, but doesn't.
index 8dece42e908b87b8ad014eede09b004aab3131ad..2da913fceb3ff3ea470418991e66345c8d75e190 100644 (file)
@@ -1038,6 +1038,8 @@ func (dec *Decoder) compatibleType(fr reflect.Type, fw typeId, inProgress map[re
 
 // typeString returns a human-readable description of the type identified by remoteId.
 func (dec *Decoder) typeString(remoteId typeId) string {
+       typeLock.Lock()
+       defer typeLock.Unlock()
        if t := idToType[remoteId]; t != nil {
                // globally known type.
                return t.string()
index 14f25d8ac4c7fee172041d63cf08d54852a5630c..934270eedd8a547d5af9a2dc070de0c244d9c03b 100644 (file)
@@ -7,6 +7,7 @@ package gob
 import (
        "bytes"
        "reflect"
+       "sync"
        "testing"
 )
 
@@ -218,3 +219,44 @@ func TestStressParallel(t *testing.T) {
                <-c
        }
 }
+
+// Issue 23328. Note that this test name is known to cmd/dist/test.go.
+func TestTypeRace(t *testing.T) {
+       c := make(chan bool)
+       var wg sync.WaitGroup
+       for i := 0; i < 2; i++ {
+               wg.Add(1)
+               go func(i int) {
+                       defer wg.Done()
+                       var buf bytes.Buffer
+                       enc := NewEncoder(&buf)
+                       dec := NewDecoder(&buf)
+                       var x interface{}
+                       switch i {
+                       case 0:
+                               x = &N1{}
+                       case 1:
+                               x = &N2{}
+                       default:
+                               t.Errorf("bad i %d", i)
+                               return
+                       }
+                       m := make(map[string]string)
+                       <-c
+                       if err := enc.Encode(x); err != nil {
+                               t.Error(err)
+                               return
+                       }
+                       if err := enc.Encode(x); err != nil {
+                               t.Error(err)
+                               return
+                       }
+                       if err := dec.Decode(&m); err == nil {
+                               t.Error("decode unexpectedly succeeded")
+                               return
+                       }
+               }(i)
+       }
+       close(c)
+       wg.Wait()
+}