boltdb / bolt

An embedded key/value database for Go.
MIT License
14.24k stars 1.51k forks source link

SIGSEGV when running benchmark test #719

Closed patrobinson closed 7 years ago

patrobinson commented 7 years ago

When executing an Update() within a benchmark test we receive a SIGSEGV

Environment

Go: 1.8.1 OS: darwin BoltDB: v1.3.1 2f1ce7a837dcb8da3ec595b1dac9d0632f0f99e8

Stack trace

panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x1c0 pc=0x10f9e71]

goroutine 21 [running]:
github.com/boltdb/bolt.(*DB).beginRWTx(0x0, 0x0, 0x0, 0x0)
    /Users/patrickrobinson/go/src/github.com/boltdb/bolt/db.go:506 +0x41
github.com/boltdb/bolt.(*DB).Begin(0x0, 0x11de001, 0x1, 0x8, 0x4d0)
    /Users/patrickrobinson/go/src/github.com/boltdb/bolt/db.go:461 +0x38
github.com/boltdb/bolt.(*DB).Update(0x0, 0xc4200fcf00, 0x0, 0x0)
    /Users/patrickrobinson/go/src/github.com/boltdb/bolt/db.go:582 +0x46
github.com/patrobinson/replicate-boltdb-bug.setUp()
    /Users/patrickrobinson/go/src/github.com/patrobinson/replicate-boltdb-bug/main.go:19 +0xf1
github.com/patrobinson/replicate-boltdb-bug.BenchmarkRun(0xc4200c0000)
    /Users/patrickrobinson/go/src/github.com/patrobinson/replicate-boltdb-bug/main_test.go:6 +0x22
testing.(*B).runN(0xc4200c0000, 0x64)
    /usr/local/Cellar/go/1.8.3/libexec/src/testing/benchmark.go:140 +0xb2
testing.(*B).launch(0xc4200c0000)
    /usr/local/Cellar/go/1.8.3/libexec/src/testing/benchmark.go:281 +0x122
created by testing.(*B).doBench
    /usr/local/Cellar/go/1.8.3/libexec/src/testing/benchmark.go:250 +0x70
exit status 2
FAIL    github.com/patrobinson/replicate-boltdb-bug 1.013s

Code to replicate

main.go

package main

import (
    "github.com/boltdb/bolt"
    "time"
)

var db *bolt.DB

func main() {
    setUp()
    for i := 0; i < 100000; i++ {
        run()
    }
}

func setUp() {
    var err error
    db, err = bolt.Open("foo", 0600, &bolt.Options{Timeout: 1 * time.Second})
    db.Update(func(tx *bolt.Tx) error {
        _, err = tx.CreateBucket([]byte("bar"))
        if err != nil {
            return err
        }
        return nil
    })
}

func run() {
    db.Update(func(tx *bolt.Tx) error {
            b := tx.Bucket([]byte("bar"))
            err := b.Put([]byte("foo"), []byte("bar"))
            return err
    })
}

main_test.go

package main

import "testing"

func BenchmarkRun(b *testing.B) {
    setUp()
    for i := 0; i < b.N; i++ {
        run()
    }
}

Running the program itself doesn't trigger the crash, but go test -bench . does.

heyitsanthony commented 7 years ago

bolt.Open returns an error because the db is still open after the first BenchmarkRun call.

patrobinson commented 7 years ago

I have a lot of questions about why BenchmarkRun is opening the DB more than ocne but that doesn't seem like it's relevant to this issue. Thank you.