Skip to content

Batch: crash fixes from stacktrace triage + defensive hardening - #14849

Merged
magnesj merged 9 commits into
OPM:devfrom
magnesj:multiple-crash-fixes
Oct 5, 2026
Merged

magnesj merged 9 commits into
OPM:devfrom
magnesj:multiple-crash-fixes

Conversation

@magnesj

@magnesj magnesj commented Oct 4, 2026

Copy link
Copy Markdown
Member

Summary

Batch of crash fixes found via automated crash-report stacktrace triage, built
and combined on one branch for convenience. See #14848 for the consolidated
stacktraces.

This PR combines the following, each of which also has its own standalone PR
open (listed for reference — merging either this PR or the individual ones
makes the other redundant):

Plus additional defensive hardening not tied to a specific reported crash:

  • RicHistogramPlotTools: null-guard every public entry point (plot, data
    source, curve, collection, ensemble arguments) and RiaGuiApplication/
    RimMainPlotCollection singleton lookups.
  • RimStimPlanModelCalculator: initialize m_stimPlanModel to nullptr in the
    constructor (was previously left uninitialized), null-guard every entry point
    that dereferences it, bounds-check findValueAtTopOfLayer/
    findValueAtBottomOfLayer, and guard computeAverageByLayer against
    division by zero on empty layers.

Verification

  • Built ResInsight and ResInsight-tests targets (RelWithDebInfo, existing
    build folder/config).
  • Ran the StimPlan-related unit tests; all pass.

Fixes #14848.

… is null

synchronize2dIntersectionViews() could crash in two ways: when the view's ownerCase() is null, and when the collection has no Rim3dView ancestor at all (e.g. mid-destruction after detaching from the PDM tree, where firstAncestorOrThisOfTypeAsserted<Rim3dView>() returns null since CAF_ASSERT is compiled out in release). Both cases are now guarded.
Guarded two unconditional null derefs: dockWidget->setWidget(viewWidget) when viewWidget creation fails, and viewPdmObject() in handleViewerDeletion() when no view has ever been assigned to control. Added regression test for the handleViewerDeletion() case; the setWidget() path requires a running GUI/main window and isn't reachable from the headless unit test harness.
…nker

RimViewController::masterView() dereferenced ownerViewLinker() without a
null check, causing a crash when the controller has been detached from
its RimViewLinker parent (e.g. mid-destruction, after the owning
child-array field has already erased it but before delete runs).

The same unguarded ownerViewLinker() dereference existed in several other
methods: isActive(), isCameraLinked(), isTimeStepLinked(),
isResultColorControlled(), isLegendDefinitionsControlled(),
isPropertyFilterOveridden(), updateOverrides(),
updateDuplicatedPropertyFilters(), updateCameraLink(),
updateTimeStepLink(), updateResultColorsControl(),
updateLegendDefinitions() and applyCellFilterCollectionByUserChoice().
All now store ownerViewLinker() in a local and null-check it before use,
matching the pattern already used in isCellFiltersControlled().
…nd missing singletons

Guard all public entry points against null plot/data-source/curve/ensemble arguments, null-check RiaGuiApplication::instance() and RimMainPlotCollection::current() before dereferencing, and skip null curves/data sources when collecting existing data sources.
dir^up becomes a zero vector when the view direction and up vector are parallel, producing an invalid zero-normal plane. Plane::distanceToOrigin() then asserts/aborts (CVF_ASSERT, always active). Fall back to an arbitrary axis to compute a valid right vector in this degenerate case.
- Fix out-of-bounds vector access in calculateFormation when an index derived from curve data falls outside formationNamesVector, including when the value is invalid (NaN/inf) or negative.
- Initialize m_stimPlanModel to nullptr in the constructor; it was previously left uninitialized until setStimPlanModel() was called.
- Guard all entry points that dereference m_stimPlanModel directly (extractCurveData, calculateLayers, findCurveAndComputeLayeredAverage, findCurveAndComputeTopOfLayer, calculateStressWithGradients, calculateTemperature, calculateFacies, calculateFormation) and return a safe default/log an error when it is null.
- Bounds-check findValueAtTopOfLayer/findValueAtBottomOfLayer against both the layer index and the underlying values vector, returning quiet_NaN instead of out-of-bounds access or a thrown exception from vector::at().
- Guard computeAverageByLayer against out-of-range indices and empty layers (division by zero), returning 0.0 for empty layers instead of NaN/inf.
@magnesj
magnesj requested a review from kriben October 4, 2026 15:59
@magnesj magnesj self-assigned this Oct 5, 2026

@kriben kriben left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mostly good stuff! Some of the commit messages talk about being cherry-picked from some other commit, but I could not make sense of it. So probably better to remove the comment in the commit messages?

Comment thread ApplicationLibCode/ProjectDataModel/StimPlanModel/RimStimPlanModelCalculator.cpp Outdated

@kriben kriben left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Additional findings from a full branch review.

Comment thread Fwk/VizFwk/LibRender/cvfCamera.cpp Outdated
Comment thread ApplicationLibCode/ProjectDataModel/RimViewController.cpp Outdated
Comment thread ApplicationLibCode/Commands/RicHistogramPlotTools.cpp Outdated
Comment thread ApplicationLibCode/ProjectDataModel/RimDockWindowController.cpp Outdated
Comment thread ApplicationLibCode/ProjectDataModel/StimPlanModel/RimStimPlanModelCalculator.cpp Outdated
@magnesj
magnesj force-pushed the multiple-crash-fixes branch from 460879c to abbfc3c Compare October 5, 2026 06:53
- Camera::fitView/computeFitViewEyePosition: derive one corrected, non-parallel up vector and use it consistently for right, upNorm, planeTop and the final setFromLookAt(), instead of only repairing the right vector. Previously the degenerate (parallel dir/up) case still produced a singular view matrix because up itself was never corrected. Added a regression test exercising fitView() end-to-end (not just computeFitViewEyePosition()) that checks the resulting direction/up/right form a valid orthonormal basis.
- RimViewController::updateCameraLink/updateTimeStepLink: guard against ownerViewLinker()->masterView() being null (RimViewLinker::setMasterView(nullptr) is a supported state), not only against a null view linker.
- RicHistogramPlotTools: use RiaGuiApplication::isRunning() before calling RiaGuiApplication::instance(), since instance() itself asserts when there is no running GUI application.
- RimDockWindowController::updateViewerWidget: create the view widget before the dock widget, so a failed view-widget creation does not leave a dock widget allocated without a dock manager (which deleteDockWidget() cannot clean up).
- RimStimPlanModelCalculator::calculateFormation: avoid continue via a small lambda, and reject double values outside the range of int before the static_cast to avoid undefined behavior.
@magnesj

magnesj commented Oct 5, 2026

Copy link
Copy Markdown
Member Author

Addressed all review feedback in 54291c6:

  • Camera: now derives one corrected, non-parallel up vector and uses it consistently for right, upNorm, planeTop and the final setFromLookAt() (not just the right vector). Added a regression test exercising fitView() end-to-end that checks direction/up/right form a valid orthonormal basis.
  • RimViewController: updateCameraLink()/updateTimeStepLink() now also guard against masterView() being null, not only a null view linker.
  • RicHistogramPlotTools: now checks RiaGuiApplication::isRunning() before calling instance() (which asserts otherwise) in both createHistogramCurve() and addHistogramCurveToPlot().
  • RimDockWindowController: view widget is now created before the dock widget, with cleanup if dock widget creation fails afterwards, avoiding a leaked unmanaged dock widget.
  • RimStimPlanModelCalculator: replaced continue with a lambda, and now rejects double values outside int range before casting.

Re commit messages: checked the current 8 commits on this branch and none mention cherry-picking from other commits/repos, so I believe that's already fine.

@magnesj
magnesj merged commit 63eaa12 into OPM:dev Oct 5, 2026
11 checks passed
@magnesj
magnesj deleted the multiple-crash-fixes branch October 5, 2026 17:56
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.

Crash fixes batch: stacktraces fixed by PRs #14838-#14846

2 participants