Page MenuHome

"Add plane > align" causes crash when certain rigs are in the scene (2.83, fixed in 2.90)
Closed, ResolvedPublic


System Information
Operating system: Windows-10-10.0.18362-SP0 64 Bits
Graphics card: GeForce GTX 750 Ti/PCIe/SSE2 NVIDIA Corporation 4.5.0 NVIDIA 446.14

Blender Version
Broken: version: 2.83.0, branch: master, commit date: 2020-06-03 14:38, hash: rB211b6c29f771

Short description of error
I can't simplify the scene anymore. Deleting anything more fixes the crash. There are two rigs - rigify and camera rig. There's a rigify script and some leftover copies of it. In this particular example allowing rigify script to run seems to prevent the crash, but in my original project it doesn't matter if the script is executed or not. It doesn't crash in 2.90, although there are other bugs there that I already reported.

Exact steps for others to reproduce the error

  • Open file:

  • I have automatic execution of scripts disabled, so when prompted about rigify script I press ignore:

  • Add Plane or UV Sphere or Ico Spehere (shift+a). Other types of meshes don't crash for some reason.
  • In the "Adjust last operation" window go to "Align" dropdown menu. Choosing any of the three options should crash Blender.

It will not crash if you first change selection to other object. In my original project however it doesn't matter what's selected.

Event Timeline

Philipp Oeser (lichtwerk) changed the task status from Needs Triage to Needs Information from User.Jun 15 2020, 10:47 AM

Hm, no crash here (tried 2.83 and rB9f5cc128d955).

Just to make sure: does this hapen with Factory Defaults as well?

When I load factory settings it crashes too, but not every time. When I run debug .cmd files, then it seems to crash more often:

I managed to reproduce the problem on a different Windows machine, although it does seem to happen at random:

Philipp Oeser (lichtwerk) changed the task status from Needs Information from User to Needs Triage.Jul 6 2020, 9:50 AM
Germano Cavalcante (mano-wii) changed the task status from Needs Triage to Needs Information from User.Jul 8 2020, 8:21 PM

I cannot reproduce this with either the latest stable or current development versions of Blender.

I tested with Plane, UV Sphere and Ico Sphere and tested all the alignment options.

Please try the latest daily build:

Go to File → Defaults → Load Factory Settings and then load your file to see if you still can reproduce this issue.

If the problem persists, please give us more clear instructions on how to reproduce it from scratch.

As I wrote, it doesn't happen in 2.90. In 2.83.1 best way to reproduce it for me is to use debug modes. Then it crashes 100% times:

Just tested on 2.83.2 and it's the same.

Here's a different test with the same file and 2.90 3623db7784b3 (on a different Windows 10 machine). Reopening the file quickly will crash Blender, but that could be a different bug altogether:

Robert Guetzkow (rjg) changed the task status from Needs Information from User to Needs Triage.Jul 8 2020, 9:02 PM

I managed to redo a crash with

switching view types, although it crashed when switching to the "3D cursor" in my case.

This is the ASAN output:

@Bastien Montagne (mont29), this looks to be an issue in memfile undo/redo, are you aware which change in 2.90x that would have fixed this?

Campbell Barton (campbellbarton) renamed this task from "Add plane > align" causes crash when certain rigs are in the scene to "Add plane > align" causes crash when certain rigs are in the scene (2.83, fixed in 2.90).Aug 5 2020, 7:25 AM
Campbell Barton (campbellbarton) changed the task status from Needs Triage to Confirmed.

Fwiw, bisect shows rBcda15408582e: Undo: Detect/find proper memchunk for a given ID during undo step writing. "fixes" the issue... basically by avoiding a lot of useless re-reading (so it actually rather hides it).

In any case, it's again those horrible bone pointers in pose data, crash happens when storing an undo step with dirty pose data needing to be rebuilt. That very ugly quickpatch (based on rBcda15408582) fixes it for me:

diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c
index e3b4166a4bf..31e80b9d260 100644
--- a/source/blender/blenloader/intern/writefile.c
+++ b/source/blender/blenloader/intern/writefile.c
@@ -151,6 +151,7 @@
 #include "MEM_guardedalloc.h"  // MEM_freeN
 #include "BKE_action.h"
+#include "BKE_armature.h"
 #include "BKE_blender_version.h"
 #include "BKE_bpath.h"
 #include "BKE_collection.h"
@@ -4214,9 +4215,14 @@ static bool write_file_handle(Main *mainvar,
           case ID_AC:
             write_action(wd, (bAction *)id_buffer, id);
-          case ID_OB:
+          case ID_OB: {
+            Object *object = (Object *)id_buffer;
+            if (object->pose != NULL && (object->pose->flag & POSE_RECALC) != 0) {
+              BKE_pose_rebuild(mainvar, object, object->data, true);
+            }
             write_object(wd, (Object *)id_buffer, id);
+          }
           case ID_MA:
             write_material(wd, (Material *)id_buffer, id);

But I would rather avoid such horror... We could also maybe just call BKE_pose_clear_pointers() instead ? Not sure how the read code would react to that though...
I wonder if we should not rather just systematically re-build from scratch pose data in readcode? Would be the safest way to deal with those issues imho.

@Brecht Van Lommel (brecht), @Sybren A. Stüvel (sybren), any thoughts on this?

lib_link_pose already has code for rebuilding the pose and looking up the bone pointers again? If that works correctly there should be no invalid bone pointers after file load.

From what I understand it's this code that is crashing, and it's the only code that is accessing the bone pointer in the file writing code.

/* prevent crashes with autosave,
 * when a bone duplicated in editmode has not yet been assigned to its posechannel */
if (chan->bone) {
  /* gets restored on read, for library armatures */
  chan->selectflag = chan->bone->flag & BONE_SELECTED;

BKE_pose_clear_pointers would disable this code, then we might as well remove it.

Something like this I guess will work. Preserving selection here seems important, and I don't immediately have a better solution.

Bone *bone = (pose->flag & POSE_RECALC) ? BKE_armature_find_bone_name(arm, pchan->name) : pchan->bone;
if (bone) {
   chan->selectflag = bone->flag & BONE_SELECTED;