hashicorp / raft-boltdb

Raft backend implementation using BoltDB
Mozilla Public License 2.0
645 stars 113 forks source link

NewBoltStore failing race condition test with error `converted pointer straddles multiple allocations`. #21

Closed ankur-anand closed 3 years ago

ankur-anand commented 3 years ago

Hi,

When opening a new file in NewBoltStore -race condition test fails

Go Version Used: go version go1.15.6 linux/amd64

How To reproduce locally.

import (
    "fmt"
    "os"
    "path/filepath"
    boltstore "github.com/hashicorp/raft-boltdb"
)
func NewStorage() {
    dir := os.TempDir()
    stableStore, err := boltstore.NewBoltStore(filepath.Join(dir, "test.file"))
    if err != nil {
        panic(err)
    }
    fmt.Println(stableStore)
}

Test:

func TestStraddles(t *testing.T) {
    t.Parallel()
    NewStorage()
}

Run Test with -race flag. go test -v err.go err_test.go -race

test will panic.

=== RUN   TestStraddles
=== PAUSE TestStraddles
=== CONT  TestStraddles
fatal error: checkptr: converted pointer straddles multiple allocations
goroutine 5 [running]:
runtime.throw(0xc1b46f, 0x3a)
    /usr/lib/go/src/runtime/panic.go:1116 +0x72 fp=0xc000053a18 sp=0xc0000539e8 pc=0x451f52
runtime.checkptrAlignment(0xc0000286d0, 0xbc54a0, 0x1)
    /usr/lib/go/src/runtime/checkptr.go:20 +0xc9 fp=0xc000053a48 sp=0xc000053a18 pc=0x420f29
github.com/boltdb/bolt.(*Bucket).write(0xc000053bb8, 0x0, 0x0, 0x0)
    /home/ankur/go/pkg/mod/github.com/boltdb/bolt@v1.3.1/bucket.go:626 +0x15f fp=0xc000053ab0 sp=0xc000053a48 pc=0x64213f
github.com/boltdb/bolt.(*Bucket).CreateBucket(0xc0002ea018, 0xf63dd8, 0x4, 0x4, 0xc00000c1e0, 0xc0002ea000, 0x0)
    /home/ankur/go/pkg/mod/github.com/boltdb/bolt@v1.3.1/bucket.go:188 +0x32d fp=0xc000053c68 sp=0xc000053ab0 pc=0x63e58d
github.com/boltdb/bolt.(*Bucket).CreateBucketIfNotExists(0xc0002ea018, 0xf63dd8, 0x4, 0x4, 0x0, 0xc000021050, 0xc00000f420)
    /home/ankur/go/pkg/mod/github.com/boltdb/bolt@v1.3.1/bucket.go:206 +0x5e fp=0xc000053cd0 sp=0xc000053c68 pc=0x63ea1e
github.com/boltdb/bolt.(*Tx).CreateBucketIfNotExists(...)
    /home/ankur/go/pkg/mod/github.com/boltdb/bolt@v1.3.1/tx.go:115
github.com/hashicorp/raft-boltdb.(*BoltStore).initialize(0xc00000f420, 0x0, 0x0)
    /home/ankur/go/pkg/mod/github.com/hashicorp/raft-boltdb@v0.0.0-20171010151810-6e5ba93211ea/bolt_store.go:98 +0x128 fp=0xc000053d88 sp=0xc000053cd0 pc=0x8e2b08
github.com/hashicorp/raft-boltdb.New(0xc000024420, 0xe, 0x0, 0xc000024400, 0xe, 0xc000001710, 0xc000001610)
    /home/ankur/go/pkg/mod/github.com/hashicorp/raft-boltdb@v0.0.0-20171010151810-6e5ba93211ea/bolt_store.go:81 +0x1bb fp=0xc000053e28 sp=0xc000053d88 pc=0x8e289b
github.com/hashicorp/raft-boltdb.NewBoltStore(...)
    /home/ankur/go/pkg/mod/github.com/hashicorp/raft-boltdb@v0.0.0-20171010151810-6e5ba93211ea/bolt_store.go:60
github.com/ankur-anand/dkvdb.NewStroage()
    /home/ankur/Documents/github@ankur-anand/go-workspace/dkvdb/err.go:13 +0xf2 fp=0xc000053eb8 sp=0xc000053e28 pc=0xa55832
command-line-arguments_test.TestStraddles(0xc000001680)
    /home/ankur/Documents/github@ankur-anand/go-workspace/dkvdb/err_test.go:11 +0x3e fp=0xc000053ed0 sp=0xc000053eb8 pc=0xa55a7e
testing.tRunner(0xc000001680, 0xc24ea8)
    /usr/lib/go/src/testing/testing.go:1123 +0x203 fp=0xc000053fd0 sp=0xc000053ed0 pc=0x5b0ec3
runtime.goexit()
    /usr/lib/go/src/runtime/asm_amd64.s:1374 +0x1 fp=0xc000053fd8 sp=0xc000053fd0 pc=0x48b421
created by testing.(*T).Run
    /usr/lib/go/src/testing/testing.go:1168 +0x5bc
goroutine 1 [chan receive]:
testing.tRunner.func1(0xc000001500)
    /usr/lib/go/src/testing/testing.go:1088 +0x333
testing.tRunner(0xc000001500, 0xc000377ce0)
    /usr/lib/go/src/testing/testing.go:1127 +0x22b
testing.runTests(0xc00000f400, 0xf4e980, 0x1, 0x1, 0xc0083dfb0d990b3d, 0x8bb384cd56, 0xf98000, 0xc000253308)
    /usr/lib/go/src/testing/testing.go:1437 +0x613
testing.(*M).Run(0xc000200180, 0x0)
    /usr/lib/go/src/testing/testing.go:1345 +0x3b4
main.main()
    _testmain.go:45 +0x237
goroutine 6 [chan receive]:
testing.runTests.func1.1(0xc000001500)
    /usr/lib/go/src/testing/testing.go:1444 +0x65
created by testing.runTests.func1
    /usr/lib/go/src/testing/testing.go:1444 +0xdb
FAIL    command-line-arguments  0.023s
FAIL
ankur-anand commented 3 years ago

This can also be replicated running this library test along with -race flag

It seems boltdb/bolt is resizing an array from an unsafe pointer incorrectly here.

    // Convert byte slice to a fake page and write the root node.
    var p = (*page)(unsafe.Pointer(&value[bucketHeaderSize]))

Switching to go.etcd.io/bbolt fixes the above issue too.