Skip to content

encoding/gob: race on idToType #23328

@ianlancetaylor

Description

@ianlancetaylor

On current master, this program sometimes fails when using the race detector:

package main

import (
	"bytes"
	"encoding/gob"
	"fmt"
	"sync"
)

type S0 struct {
	I int
}

type S1 struct {
	I int
}

type S2 struct {
	I int
}

type S3 struct {
	I int
}

type S4 struct {
	I int
}

type S5 struct {
	I int
}

type S6 struct {
	I int
}

type S7 struct {
	I int
}

type S8 struct {
	I int
}

type S9 struct {
	I int
}

func main() {
	c := make(chan bool)
	var wg sync.WaitGroup
	for i := 0; i < 10; i++ {
		wg.Add(1)
		go func(i int) {
			defer wg.Done()
			var buf bytes.Buffer
			var x interface{}
			switch i {
			case 0:
				x = &S0{0}
			case 1:
				x = &S1{1}
			case 2:
				x = &S2{2}
			case 3:
				x = &S3{3}
			case 4:
				x = &S4{4}
			case 5:
				x = &S5{5}
			case 6:
				x = &S6{6}
			case 7:
				x = &S7{7}
			case 8:
				x = &S8{8}
			case 9:
				x = &S9{9}
			default:
				panic(i)
			}
			enc := gob.NewEncoder(&buf)
			dec := gob.NewDecoder(&buf)
			<-c
			if err := enc.Encode(x); err != nil {
				fmt.Println(err)
			}
			if err := enc.Encode(x); err != nil {
				fmt.Println(err)
			}
			m := make(map[string]string)
			// This call to Decode is expected to fail.
			dec.Decode(&m)
		}(i)
	}
	close(c)
	wg.Wait()
}

Sample failure:

==================
WARNING: DATA RACE
Write at 0x00c4200961e0 by goroutine 7:
  runtime.mapassign_fast32()
      /home/iant/go/src/runtime/hashmap_fast.go:350 +0x0
  encoding/gob.setTypeId()
      /home/iant/go/src/encoding/gob/type.go:186 +0xf8
  encoding/gob.newStructType()
      /home/iant/go/src/encoding/gob/type.go:429 +0xb6
  encoding/gob.newTypeObject()
      /home/iant/go/src/encoding/gob/type.go:522 +0xd36
  encoding/gob.getType()
      /home/iant/go/src/encoding/gob/type.go:598 +0x112
  encoding/gob.getBaseType()
      /home/iant/go/src/encoding/gob/type.go:585 +0x94
  encoding/gob.buildTypeInfo()
      /home/iant/go/src/encoding/gob/type.go:715 +0x106
  encoding/gob.getTypeInfo()
      /home/iant/go/src/encoding/gob/type.go:702 +0xed
  encoding/gob.(*Encoder).sendActualType()
      /home/iant/go/src/encoding/gob/encoder.go:96 +0xcb
  encoding/gob.(*Encoder).sendType()
      /home/iant/go/src/encoding/gob/encoder.go:168 +0x116
  encoding/gob.(*Encoder).sendTypeDescriptor()
      /home/iant/go/src/encoding/gob/encoder.go:190 +0x166
  encoding/gob.(*Encoder).EncodeValue()
      /home/iant/go/src/encoding/gob/encoder.go:243 +0x52c
  encoding/gob.(*Encoder).Encode()
      /home/iant/go/src/encoding/gob/encoder.go:175 +0x72
  main.main.func1()
      /home/iant/foo8.go:86 +0x1d8

Previous read at 0x00c4200961e0 by goroutine 13:
  runtime.mapaccess1_fast32()
      /home/iant/go/src/runtime/hashmap_fast.go:12 +0x0
  encoding/gob.(*Decoder).typeString()
      /home/iant/go/src/encoding/gob/decode.go:1041 +0x76
  encoding/gob.(*Decoder).compileSingle()
      /home/iant/go/src/encoding/gob/decode.go:1056 +0x563
  encoding/gob.(*Decoder).compileDec()
      /home/iant/go/src/encoding/gob/decode.go:1088 +0x132
  encoding/gob.(*Decoder).getDecEnginePtr()
      /home/iant/go/src/encoding/gob/decode.go:1145 +0x23b
  encoding/gob.(*Decoder).decodeValue()
      /home/iant/go/src/encoding/gob/decode.go:1190 +0x10b
  encoding/gob.(*Decoder).DecodeValue()
      /home/iant/go/src/encoding/gob/decoder.go:212 +0x1cb
  encoding/gob.(*Decoder).Decode()
      /home/iant/go/src/encoding/gob/decoder.go:187 +0x1c9
  main.main.func1()
      /home/iant/foo8.go:94 +0x371

Goroutine 7 (running) created at:
  main.main()
      /home/iant/foo8.go:55 +0xd9

Goroutine 13 (finished) created at:
  main.main()
      /home/iant/foo8.go:55 +0xd9
==================
Found 1 data race(s)
exit status 66

This is not a new failure but it's probably simple to fix.

Metadata

Metadata

Assignees

No one assigned

    Labels

    FrozenDueToAgeNeedsFixThe path to resolution is known, but the work has not been done.

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions