Skip to content

Fix crashes in command features - #1014

Open
magnesj wants to merge 4 commits into
devfrom
fix-command-feature-crashes
Open

Fix crashes in command features#1014
magnesj wants to merge 4 commits into
devfrom
fix-command-feature-crashes

Conversation

@magnesj

@magnesj magnesj commented Jul 24, 2026

Copy link
Copy Markdown
Owner

Four crashes found by exercising the Ric*Feature command layer against a range of selections. Each one is small and independent of the others. Split out from the command feature test work so the fixes can be reviewed on their own.

Clearing source stepping

RicClearSourceSteppingSummaryCurveFeature and RicClearSourceSteppingEnsembleCurveSetFeature resolved the summary plot with firstAncestorOrThisOfTypeAsserted, but picked the candidate object with objectsByType<caf::PdmObject>, which matches any object. Selecting a single object outside a summary plot therefore aborted while the enabled state was evaluated, for instance while building a context menu. The null check on the following line shows the non-asserting lookup was intended.

Converting fracture templates

RicConvertAllFractureTemplatesToFieldFeature dereferenced the fracture template collection without checking it, and aborted when triggered outside a fracture template context. The corresponding Metric feature already has this guard.

Deleting an item

Deleting a 3D view crashed with a pure virtual call. The object was destroyed while it was still attached to its parent field and still referenced by the open editors, and a destructor can re-enter the user interface: removing the view's dock widget makes the dock area activate a sibling, and the resulting selection change both repaints the project tree and rebuilds the property editor. The tree asks its nodes for a name, and the property editor walks project->allViews() to build the comparison view option list, which asks every view for its name. By then the object has lost its derived part, so producing the name calls the pure virtual createAutoName().

The object is now erased from the field and the connected editors refreshed before it is deleted. erase() only detaches, so the object is still valid while the editors are refreshed, and afterwards it is reachable neither through the project nor from any editor.

Reproduced in the application with a project holding three GeoMech views and one Eclipse view, where deleting a GeoMech view aborted. Verified fixed with the same project.

Guards and a wrong target collection

  • RicWellLogTools read eclipseCaseData() without checking it. A case can be part of the project without being opened, and then has no case data.
  • RimEclipseContourMapView dereferenced viewer() when creating the display model and when the axis line setting changed. Both run for a view without a viewer, and two other places in the same file already guard this way.
  • RicNewPolygonFilterFeature resolved the case level data filter collection from the selection itself, so it only reacted to the collection node. Every other cell filter feature resolves it through RicCellFilterFeatureTools::selectedDataFilterCollection, which also accepts a selected Eclipse case. The Data Filters node is hidden while empty, so the case node is what is right clicked, and the polygon filter silently ended up in the active view's collection instead of on the case.
  • RicAppendIntersectionFeature and RicAppendSeparateIntersectionResultFeature had no isCommandEnabled override, so they reported themselves enabled for any selection while onActionTriggered only handles a selection inside an intersection collection. The context menu offers these commands in the right context only, so this part is hardening rather than a user visible fix.

🤖 Generated with Claude Code

magnesj added 4 commits July 24, 2026 20:04
…plates

RicClearSourceSteppingSummaryCurveFeature and
RicClearSourceSteppingEnsembleCurveSetFeature resolved the summary plot with
firstAncestorOrThisOfTypeAsserted, but selected the candidate object with
objectsByType<caf::PdmObject>, which matches any object. Selecting a single
object outside a summary plot therefore aborted while the command enabled
state was evaluated, for instance when building a context menu. The following
null check on the result shows the non-asserting lookup was intended.

RicConvertAllFractureTemplatesToFieldFeature dereferenced the fracture
template collection without checking it, and aborted when triggered outside a
fracture template context. The corresponding Metric feature already has this
guard.
RicAppendIntersectionFeature and RicAppendSeparateIntersectionResultFeature
had no isCommandEnabled override, so they reported themselves enabled for any
selection while onActionTriggered only handles a selection inside an
intersection collection. With another object selected the collection lookup
returns null and only an assert stands between that and the dereference.

The context menu offers these commands in the right context only, so this is
hardening rather than a user visible fix. Resolve the collection once, use it
for both the enabled state and the action, and return early when it is
missing.
…er collection

RicWellLogTools read eclipseCaseData() without checking it. A case can be
part of the project without being opened, and then has no case data.

RimEclipseContourMapView dereferenced viewer() when creating the display
model and when the axis line setting changed. Both run for a view without a
viewer. Two other places in the same file already guard this way.

RicNewPolygonFilterFeature resolved the case level data filter collection
from the selection itself, so it only reacted to the collection node. Every
other cell filter feature resolves it through
RicCellFilterFeatureTools::selectedDataFilterCollection, which also accepts a
selected Eclipse case. The Data Filters node is hidden while empty, so the
case node is what is right clicked, and the polygon filter silently ended up
in the active view's collection instead of on the case.
Deleting a 3D view crashed with a pure virtual call. The object was destroyed
while it was still attached to its parent field and still referenced by the
open editors, and a destructor can re-enter the user interface: removing the
view's dock widget makes the dock area activate a sibling, and the resulting
selection change both repaints the project tree and rebuilds the property
editor. The tree asks its nodes for a name, and the property editor walks
project->allViews() to build the comparison view option list, which asks
every view for its name. By then the object has lost its derived part, so
producing the name calls the pure virtual createAutoName().

Erase the object from the field and refresh the connected editors before
deleting it. erase() only detaches, so the object is still valid while the
editors are refreshed, and afterwards it is reachable neither through the
project nor from any editor.

Reproduced with a project holding three GeoMech views and one Eclipse view,
where deleting a GeoMech view aborted the application.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant