This repository was archived by the owner on Sep 19, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 77
This repository was archived by the owner on Sep 19, 2023. It is now read-only.
Panics on prepared geometry calls #11
Copy link
Copy link
Open
Description
I have observed panics when prepared geometry objects are used:
pure virtual method called
terminate called without an active exception
SIGABRT: abort
PC=0x7fbe473fbd27
signal arrived during cgo execution
goroutine 6 [syscall, locked to thread]:
runtime.cgocall_errno(0x408920, 0xc2080d9218, 0x0)
$GOROOT/src/runtime/cgocall.go:130 +0xf5 fp=0xc2080d91f8 sp=0xc2080d91d0
github.com/paulsmith/gogeos/geos._Cfunc_GEOSPreparedCovers_r(0x2a7eb50, 0x7fbe3c127880, 0x2bb87e0, 0xc208034900)
github.com/paulsmith/gogeos/geos/_obj/_cgo_gotypes.go:672 +0x40 fp=0xc2080d9218 sp=0xc2080d91f8
github.com/paulsmith/gogeos/geos.cGEOSPreparedCovers(0x7fbe3c127880, 0x2bb87e0, 0x4d3200)
$GOPATH/src/github.com/paulsmith/gogeos/geos/cwrappers.go:547 +0x74 fp=0xc2080d9240 sp=0xc2080d9218
github.com/paulsmith/gogeos/geos.(*PGeometry).predicate(0xc20802e068, 0x7c8480, 0x6, 0x87a250, 0xc20802e600, 0x8, 0x0, 0x0)
$GOPATH/src/github.com/paulsmith/gogeos/geos/prepared.go:95 +0x5b fp=0xc2080d92b0 sp=0xc2080d9240
github.com/paulsmith/gogeos/geos.(*PGeometry).Covers(0xc20802e068, 0xc20802e600, 0x348, 0x0, 0x0)
$GOPATH/src/github.com/paulsmith/gogeos/geos/prepared.go:55 +0x63 fp=0xc2080d92f8 sp=0xc2080d92b0
I tried to recreate the behaviour in a test, but I couldn't, at least not consistently. It is related to Go's GC cycles and the finalizer calling cGEOSGeom_destroy(ptr) on the original Geometry. As a workaround, I added:
diff --git a/geos/prepared.go b/geos/prepared.go
index a7af6d1..3383fe8 100644
--- a/geos/prepared.go
+++ b/geos/prepared.go
@@ -14,12 +14,13 @@ import (
// optimized for a limited set of operations.
type PGeometry struct {
p *C.GEOSPreparedGeometry
+ g *Geometry
}
// PrepareGeometry constructs a prepared geometry from a normal geometry object.
func PrepareGeometry(g *Geometry) *PGeometry {
ptr := cGEOSPrepare(g.g)
- p := &PGeometry{ptr}
+ p := &PGeometry{ptr, g}
runtime.SetFinalizer(p, (*PGeometry).destroy)
return p
}
@@ -27,6 +28,7 @@ func PrepareGeometry(g *Geometry) *PGeometry {
func (p *PGeometry) destroy() {
cGEOSPreparedGeom_destroy(p.p)
p.p = nil
+ p.g = nil
}
// Prepared geometry binary predicatesIt fixes the problem by preventing the Geometry from being garbage-collected, but it is not very elegant.
Thoughts? Thanks
Metadata
Metadata
Assignees
Labels
No labels