Panic when PIndexImplType New function returns nil Dest, nil error
tleyden opened this issue · comments
I think that the RegisterPIndexImplType.New
function that is passed to CBGT:
cbgt.RegisterPIndexImplType(base.IndexTypeSyncGateway, &cbgt.PIndexImplType{
New: <--
is returning nil
, and it's causing CBGT to panic. I think in general, libraries shouldn't panic .. I guess maybe we could provide an OnError
callback function or something instead?
015-12-17T14:48:25.672-08:00 WARNING: Could not find database for bucket name: bucket-1. Unable to instantiate this pindex from disk. -- rest.(*ServerContext).SyncGatewayPIndexFactoryCommon() at server_context.go:185
2015/12/17 14:48:25 manager: loading dataDir... done
2015/12/17 14:48:25 planner: awakes, reason: start
2015/12/17 14:48:25 janitor: awakes, reason: start
2015/12/17 14:48:25 janitor: pindexes to remove: 0
2015/12/17 14:48:25 janitor: pindexes to add: 0
2015/12/17 14:48:25 janitor: feeds to remove: 0
2015/12/17 14:48:25 janitor: feeds to add: 1
2015/12/17 14:48:25 bucket-17732d5ba13e3a6f221f7d00f3e8c6234_2ff2a92097a52ba3
2015/12/17 14:48:25 feed_dcp: start, name: bucket-17732d5ba13e3a6f221f7d00f3e8c6234_2ff2a92097a52ba3
panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xb code=0x1 addr=0x48 pc=0x41bdb3e]
goroutine 81 [running]:
github.com/couchbase/cbgt.(*DCPFeed).GetMetaData.func1(0x0, 0x0)
/Users/tleyden/Development/sync_gateway/src/github.com/couchbase/cbgt/feed_dcp.go:477 +0x12e
github.com/couchbase/cbgt.Timer.func1()
/Users/tleyden/Development/sync_gateway/src/github.com/couchbase/cbgt/misc.go:234 +0x25
github.com/rcrowley/go-metrics.(*StandardTimer).Time(0xc8206224e0, 0xc8203ea960)
/Users/tleyden/Development/sync_gateway/src/github.com/rcrowley/go-metrics/timer.go:212 +0x3d
github.com/couchbase/cbgt.Timer(0xc8204083f0, 0x5640b28, 0xc8206224e0, 0x0, 0x0)
/Users/tleyden/Development/sync_gateway/src/github.com/couchbase/cbgt/misc.go:235 +0xa7
github.com/couchbase/cbgt.(*DCPFeed).GetMetaData(0xc820604c30, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0)
/Users/tleyden/Development/sync_gateway/src/github.com/couchbase/cbgt/feed_dcp.go:480 +0x123
github.com/couchbase/go-couchbase/cbdatasource.(*bucketDataSource).getVBucketMetaData(0xc820375680, 0x20, 0x60, 0x486e340, 0x0, 0x0)
/Users/tleyden/Development/sync_gateway/src/github.com/couchbase/go-couchbase/cbdatasource/cbdatasource.go:1235 +0xa2
github.com/couchbase/go-couchbase/cbdatasource.(*bucketDataSource).sendStreamReq(0xc820375680, 0xc8203b0ae0, 0x20, 0x0, 0x0)
/Users/tleyden/Development/sync_gateway/src/github.com/couchbase/go-couchbase/cbdatasource/cbdatasource.go:1275 +0x53
github.com/couchbase/go-couchbase/cbdatasource.(*bucketDataSource).refreshWorker(0xc820375680, 0xc8203b0ae0, 0xc820408180, 0xc8200b8400, 0x40, 0x40, 0x0, 0x0)
/Users/tleyden/Development/sync_gateway/src/github.com/couchbase/go-couchbase/cbdatasource/cbdatasource.go:1011 +0x84e
github.com/couchbase/go-couchbase/cbdatasource.(*bucketDataSource).worker(0xc820375680, 0xc8203ce6c0, 0xf, 0xc82014f860, 0x0)
/Users/tleyden/Development/sync_gateway/src/github.com/couchbase/go-couchbase/cbdatasource/cbdatasource.go:957 +0x11ea
github.com/couchbase/go-couchbase/cbdatasource.(*bucketDataSource).workerStart.func1.1(0x2)
/Users/tleyden/Development/sync_gateway/src/github.com/couchbase/go-couchbase/cbdatasource/cbdatasource.go:681 +0x48
github.com/couchbase/go-couchbase/cbdatasource.ExponentialBackoffLoop(0xc820150e10, 0x23, 0xc820289f38, 0x64, 0x3fc00000, 0x4e20)
/Users/tleyden/Development/sync_gateway/src/github.com/couchbase/go-couchbase/cbdatasource/cbdatasource.go:1518 +0x2b
github.com/couchbase/go-couchbase/cbdatasource.(*bucketDataSource).workerStart.func1(0xc820375680, 0xc8203ce6c0, 0xf, 0xc82014f860, 0x64, 0xc83fc00000, 0x4e20)
/Users/tleyden/Development/sync_gateway/src/github.com/couchbase/go-couchbase/cbdatasource/cbdatasource.go:682 +0x112
created by github.com/couchbase/go-couchbase/cbdatasource.(*bucketDataSource).workerStart
/Users/tleyden/Development/sync_gateway/src/github.com/couchbase/go-couchbase/cbdatasource/cbdatasource.go:685 +0xb7
Noticed this during some experimentation trying to fix couchbase/sync_gateway#1299
Actually, it looks like in this case the RegisterPIndexImplType.Open
function is returning nil, nil, nil
. If OTOH it returns nil, nil, err
then there is no panic.
I guess I should probably post which CBGT commit I'm using, eh?
Looks like it's a fairly old commit: 7e6a6dc
I will see if I can reproduce on the current master branch.
Reproduced on CBGT commit 17117fb
panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xb code=0x1 addr=0x48 pc=0x41be42e]
goroutine 123 [running]:
github.com/couchbase/cbgt.(*DCPFeed).GetMetaData.func1(0x0, 0x0)
/Users/tleyden/Development/sync_gateway/src/github.com/couchbase/cbgt/feed_dcp.go:477 +0x12e
github.com/couchbase/cbgt.Timer.func1()
/Users/tleyden/Development/sync_gateway/src/github.com/couchbase/cbgt/misc.go:234 +0x25
github.com/rcrowley/go-metrics.(*StandardTimer).Time(0xc8205bc7b0, 0xc820440e60)
/Users/tleyden/Development/sync_gateway/src/github.com/rcrowley/go-metrics/timer.go:212 +0x3d
github.com/couchbase/cbgt.Timer(0xc820518f00, 0x52a97a8, 0xc8205bc7b0, 0x0, 0x0)
/Users/tleyden/Development/sync_gateway/src/github.com/couchbase/cbgt/misc.go:235 +0xa7
github.com/couchbase/cbgt.(*DCPFeed).GetMetaData(0xc820074270, 0x2d, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0)
/Users/tleyden/Development/sync_gateway/src/github.com/couchbase/cbgt/feed_dcp.go:480 +0x123
github.com/couchbase/go-couchbase/cbdatasource.(*bucketDataSource).getVBucketMetaData(0xc820620900, 0x2d, 0x60, 0x4878dc0, 0x0, 0x0)
/Users/tleyden/Development/sync_gateway/src/github.com/couchbase/go-couchbase/cbdatasource/cbdatasource.go:1235 +0xa2
github.com/couchbase/go-couchbase/cbdatasource.(*bucketDataSource).sendStreamReq(0xc820620900, 0xc8203647e0, 0x2d, 0x0, 0x0)
/Users/tleyden/Development/sync_gateway/src/github.com/couchbase/go-couchbase/cbdatasource/cbdatasource.go:1275 +0x53
github.com/couchbase/go-couchbase/cbdatasource.(*bucketDataSource).refreshWorker(0xc820620900, 0xc8203647e0, 0xc820518d80, 0xc8200a6580, 0x40, 0x40, 0x0, 0x0)
/Users/tleyden/Development/sync_gateway/src/github.com/couchbase/go-couchbase/cbdatasource/cbdatasource.go:1011 +0x84e
github.com/couchbase/go-couchbase/cbdatasource.(*bucketDataSource).worker(0xc820620900, 0xc820414ba0, 0xf, 0xc82016d1a0, 0x0)
/Users/tleyden/Development/sync_gateway/src/github.com/couchbase/go-couchbase/cbdatasource/cbdatasource.go:957 +0x11ea
github.com/couchbase/go-couchbase/cbdatasource.(*bucketDataSource).workerStart.func1.1(0x2)
/Users/tleyden/Development/sync_gateway/src/github.com/couchbase/go-couchbase/cbdatasource/cbdatasource.go:681 +0x48
github.com/couchbase/go-couchbase/cbdatasource.ExponentialBackoffLoop(0xc8205bd2c0, 0x23, 0xc820591f38, 0x64, 0x3fc00000, 0x7d0)
/Users/tleyden/Development/sync_gateway/src/github.com/couchbase/go-couchbase/cbdatasource/cbdatasource.go:1518 +0x2b
github.com/couchbase/go-couchbase/cbdatasource.(*bucketDataSource).workerStart.func1(0xc820620900, 0xc820414ba0, 0xf, 0xc82016d1a0, 0x64, 0xc83fc00000, 0x7d0)
/Users/tleyden/Development/sync_gateway/src/github.com/couchbase/go-couchbase/cbdatasource/cbdatasource.go:682 +0x112
created by github.com/couchbase/go-couchbase/cbdatasource.(*bucketDataSource).workerStart
/Users/tleyden/Development/sync_gateway/src/github.com/couchbase/go-couchbase/cbdatasource/cbdatasource.go:685 +0xb7
Yep, I agree libraries shouldn't panic, and in this case cbgt is not invoking panic(), but it's a nil pointer dereference.
The feed_dcp line 477 is ...
value, lastSeq, err = dest.OpaqueGet(partition)
So, that means dest is nil.
From tracing the code paths, dest can be nil if the pindex implementation returns a nil for the Dest return value in the New or Open callbacks...
https://github.com/couchbase/cbgt/blob/master/pindex_impl.go#L39
https://github.com/couchbase/cbgt/blob/master/pindex_impl.go#L45
New func(indexType, indexParams, path string, restart func()) (
PIndexImpl, Dest, error)
Open func(indexType, path string, restart func()) (
PIndexImpl, Dest, error)
So, @tleyden, wondering if there are any codepaths in sync-gateway's pindex New/Open callbacks that might return a nil Dest and nil error?
Yeah, it was only a codepath that came up while doing some intermediate changes, but it was returning a nil dest and a nil error.
Thanks - I'm going to close this as won't fix, then, on the hope that the elite corps who implement new PIndex types (*) always return a non-nil Dest when nil error.
(*) - same folks deserve to receive "PIndex" or "cbgt" t-shirt. :-)
What about detecting this situation and doing an explicit panic?
The value add is that instead of the meaningless error:
panic: runtime error: invalid memory address or nil pointer dereference
you could return:
panic: runtime error: you returned a nil Dest and nil error, and that's just something I can't deal with