Fix crashes in GeoJsonDocumentRasterOverlayTileProvider::loadTileImage#1314
Conversation
…Also capture _pDocument by value since the Quadtree holds raw pointers into the document data.
Change QuadtreeGeometryData::pStyle from a raw pointer to the tile provider's _defaultStyle to a VectorStyle stored by value. The raw pointer could dangle when the tile provider was destroyed while worker threads were still rasterizing tiles. Also clamp the computed textureSize to a minimum of 1x1 to prevent Blend2D from crashing when getTargetScreenPixels() / maximumScreenSpaceError truncates to zero in one dimension. Co-Authored-By: Claude Opus 4.6 <[email protected]>
|
@baruchInsert-tech The first and third changes you list seem like good fixes. However, I'm not sure about the second one. The Besides that, this change is looking good! |
…t per-object copy
|
@azrogers
|
|
It doesn't look like that change quite did it. Ironically, I don't experience any crashes using the |
|
the crash happens when using Cesium for Unity: I load a tileset, draw a polygon over an area and when zooming in and roaming around, the Unity editor/application crashes after a couple of seconds. I tracked down the root cause, and it also explains the 3 failing CI tests (can render lines with bounding box height set by pixels, ...by meters, ...wrapping around the earth). The problem is that buildQuadtree() returns a Quadtree by value, and the constructor does: this->_pTree = std::make_shared(buildQuadtree(...)); Inside buildQuadtree, addPrimitivesToData stores raw pointers like pStyle = &tree.defaultStyle - pointing into the Fix: allocate the Quadtree on the heap first, then populate it in-place so &tree.defaultStyle always refers to the final address: this->_pTree = std::make_shared(); With buildQuadtree changed from returning by value to taking a Quadtree& parameter. Pushed the fix. |
…-after-free-geojson-loadtileimage
|
Thanks @baruchInsert-tech! |
Summary
Three bugs in
GeoJsonDocumentRasterOverlayTileProvider::loadTileImagethat caused native crashes when roaming around a tileset with a GeoJSON raster overlay.Details
Bug 1: Dangling reference capture of
_treeIn
GeoJsonDocumentRasterOverlayTileProvider::loadTileImage(), therunInWorkerThreadlambda captured_treeby reference (&tree = this->_tree). All other captures in the lambda were correctly by value.RasterOverlayTileProvideris reference-counted viaReferenceCountedNonThreadSafe, and the lambda did not capture any reference-counted pointer to the tile provider. When tiles were unloaded (e.g., camera moves away), the tile provider could be destroyed before queued worker thread tasks executed, leaving the&treereference dangling.Fix:
_treefromQuadtreetostd::shared_ptr<Quadtree>so worker thread lambdas can share ownershippTreeby value (shared_ptr copy) in the lambda to keep the quadtree alive_pDocumentby value since the Quadtree holds rawconst GeoJsonObject*pointers into the document dataBug 2: Dangling raw pointer in
QuadtreeGeometryData::pStyleQuadtreeGeometryDatastored aconst VectorStyle*raw pointer to the tile provider's_defaultStyle. When the tile provider was destroyed, worker threads still accessed the freed style through this pointer.Fix:
QuadtreeGeometryData::pStylefromconst VectorStyle*toVectorStyle stylestored by valueBug 3: Zero-dimension texture size crash
The texture size computation could produce a zero width or height when
getTargetScreenPixels()returns a small value in one dimension. Dividing bymaximumScreenSpaceErrorand truncating tointproduced 0, causing Blend2D to crash when creating a zero-size image.Fix:
textureSizeto a minimum of 1×1 withglm::max(..., glm::ivec2(1))Closes #1313
@j9liu