From b6b0ebb4dcdf86ad4d207b764d1bb04085c8336f Mon Sep 17 00:00:00 2001 From: forbes Date: Sat, 21 Feb 2026 09:47:15 -0600 Subject: [PATCH] fix(assembly): prevent segfault when all joints are removed updateSolveStatus() calls solve() when lastResult_.placements is empty, but solve() calls updateSolveStatus() at the end. When an assembly has zero constraints (all joints removed), the solver returns zero placements, causing infinite recursion until stack overflow (segfault). Add a static re-entrancy guard so the recursive solve() call is skipped if updateSolveStatus() is already on the call stack. --- src/Mod/Assembly/App/AssemblyObject.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/Mod/Assembly/App/AssemblyObject.cpp b/src/Mod/Assembly/App/AssemblyObject.cpp index 6902acd44b..a8c498cffa 100644 --- a/src/Mod/Assembly/App/AssemblyObject.cpp +++ b/src/Mod/Assembly/App/AssemblyObject.cpp @@ -275,8 +275,14 @@ void AssemblyObject::updateSolveStatus() //+1 because there's a grounded joint to origin lastDoF = (1 + numberOfComponents()) * 6; - if (!solver_ || lastResult_.placements.empty()) { + // Guard against re-entrancy: solve() calls updateSolveStatus(), so if + // placements are legitimately empty (e.g. zero constraints / all parts + // grounded) the recursive solve() would never terminate. + static bool updating = false; + if (!updating && (!solver_ || lastResult_.placements.empty())) { + updating = true; solve(); + updating = false; } if (!solver_) { -- 2.49.1