Uploaded image for project: 'Go Driver'
  1. Go Driver
  2. GODRIVER-3051

Panic when decoding is done concurrently

    • Type: Icon: Bug Bug
    • Resolution: Duplicate
    • Priority: Icon: Major - P3 Major - P3
    • None
    • Affects Version/s: 1.13.0
    • Component/s: None
    • None
    • Hide

      1. What would you like to communicate to the user about this feature?
      2. Would you like the user to see examples of the syntax and/or executable code and its output?
      3. Which versions of the driver/connector does this apply to?

      Show
      1. What would you like to communicate to the user about this feature? 2. Would you like the user to see examples of the syntax and/or executable code and its output? 3. Which versions of the driver/connector does this apply to?

      Detailed steps to reproduce the problem?

      Looks like a race condition introduced in this commit:

      https://github.com/mongodb/mongo-go-driver/pull/1313/files#diff-5b3606b3d203800d970ebd0cbea784869ac05fd3421dbec89eeef5a2c528f3b6

      v1.12.1 works fine.

      Same cause as this bug report has, but happens in decoder:

      https://jira.mongodb.org/projects/GODRIVER/issues/GODRIVER-3009

       

      Code that can be used to reproduce:

       

      package main 
      import (
        "log"
        "sync"
      
        "go.mongodb.org/mongo-driver/bson"
      )
      
      func main() {
        data := []byte{16, 0, 0, 0, 10, 108, 97, 115, 116, 101, 114, 114, 111, 114, 0, 0}
        wg := sync.WaitGroup{}
        wg.Add(10_000)
        for i := 0; i < 10_000; i++ {
          go func() {
            defer wg.Done()
            var res struct{ LastError error }
            if err := bson.Unmarshal(data, &res); err != nil {
              log.Printf("Failed to unmarshal: %v", err)
            }
          }()
        }
        wg.Wait()
      } 

       
       

      The stacktrace is:

       

      panic: interface conversion: interface is nil, not bsoncodec.ValueEncodergoroutine 15 [running]:
      go.mongodb.org/mongo-driver/bson/bsoncodec.(*typeEncoderCache).LoadOrStore(...)
              /Users/romantarasov/data/develop/pkg/mod/go.mongodb.org/mongo-driver@v1.13.0/bson/bsoncodec/codec_cache.go:45
      go.mongodb.org/mongo-driver/bson/bsoncodec.(*Registry).storeTypeEncoder(0xc000130c40?, {0x116c3e0?, 0x111b580?}, {0x0, 0x0})
              /Users/romantarasov/data/develop/pkg/mod/go.mongodb.org/mongo-driver@v1.13.0/bson/bsoncodec/registry.go:416 +0x77
      go.mongodb.org/mongo-driver/bson/bsoncodec.(*Registry).LookupEncoder(0xc000130c40, {0x116c3e0, 0x111b580})
              /Users/romantarasov/data/develop/pkg/mod/go.mongodb.org/mongo-driver@v1.13.0/bson/bsoncodec/registry.go:411 +0x1fa
      go.mongodb.org/mongo-driver/bson/bsoncodec.(*StructCodec).describeStructSlow(0xc00010a1c0, 0xc000130c40?, {0x116c3e0, 0x111d600}, 0x0, 0x0)
              /Users/romantarasov/data/develop/pkg/mod/go.mongodb.org/mongo-driver@v1.13.0/bson/bsoncodec/struct_codec.go:515 +0x225
      go.mongodb.org/mongo-driver/bson/bsoncodec.(*StructCodec).describeStruct(0xc00010a1c0, 0x0?, {0x116c3e0?, 0x111d600}, 0x0?, 0x0?)
              /Users/romantarasov/data/develop/pkg/mod/go.mongodb.org/mongo-driver@v1.13.0/bson/bsoncodec/struct_codec.go:483 +0x9a
      go.mongodb.org/mongo-driver/bson/bsoncodec.(*StructCodec).DecodeValue(0xc00010a1c0, {0xc000130c40, 0x0, {0x0, 0x0}, {0x0, 0x0}, 0x0, 0x0, 0x0, ...}, ...)
              /Users/romantarasov/data/develop/pkg/mod/go.mongodb.org/mongo-driver@v1.13.0/bson/bsoncodec/struct_codec.go:282 +0x111
      go.mongodb.org/mongo-driver/bson.(*Decoder).Decode(0xc000686000, {0x1111c80, 0xc000680000})
              /Users/romantarasov/data/develop/pkg/mod/go.mongodb.org/mongo-driver@v1.13.0/bson/decoder.go:134 +0x3e3
      go.mongodb.org/mongo-driver/bson.unmarshalFromReader({0xc000130c40, 0x0, {0x0, 0x0}, {0x0, 0x0}, 0x0, 0x0, 0x0, 0x0, ...}, ...)
              /Users/romantarasov/data/develop/pkg/mod/go.mongodb.org/mongo-driver@v1.13.0/bson/unmarshal.go:176 +0x188
      go.mongodb.org/mongo-driver/bson.UnmarshalWithRegistry(0xc000130c40, {0xc000012700, 0x10, 0x10}, {0x1111c80, 0xc000680000})
              /Users/romantarasov/data/develop/pkg/mod/go.mongodb.org/mongo-driver@v1.13.0/bson/unmarshal.go:63 +0x125
      go.mongodb.org/mongo-driver/bson.Unmarshal(...)
              /Users/romantarasov/data/develop/pkg/mod/go.mongodb.org/mongo-driver@v1.13.0/bson/unmarshal.go:45
      main.main.func1()
              /Users/romantarasov/data/develop/src/github.com/autopilot3/ap3-crm-api-go/cmd/main.go:18 +0xa9
      created by main.main in goroutine 1
              /Users/romantarasov/data/develop/src/github.com/autopilot3/ap3-crm-api-go/cmd/main.go:15 +0x66

       

      Definition of done: what must be done to consider the task complete?

      The exact Go version used, with patch level:

       

      go version go1.21.0 darwin/amd64

       

      The exact version of the Go driver used:

       

      go.mongodb.org/mongo-driver v1.13.0

       

      The operating system and version:

       

      macOS Ventura 13.5.1
      

       

       

       

        1. Screenshot 2023-11-17 at 1.19.01 PM.png
          291 kB
          Sebastian B Kottaram
        2. Screenshot 2023-11-17 at 12.43.56 PM.png
          666 kB
          Sebastian B Kottaram

            Assignee:
            qingyang.hu@mongodb.com Qingyang Hu
            Reporter:
            roman@ortto.com Roman Tarasov
            Votes:
            0 Vote for this issue
            Watchers:
            5 Start watching this issue

              Created:
              Updated:
              Resolved: