Page MenuHome

Crash undo painting on linked image
Closed, ResolvedPublicBUG

Description

System Information
Operating system: Darwin-19.5.0-x86_64-i386-64bit 64 Bits
Graphics card: AMD Radeon Pro 455 OpenGL Engine ATI Technologies Inc. 4.1 ATI-3.9.15

Blender Version
Broken: 2.91.0 Alpha
Broken: 2.81a
Worked: 2.79b

Short description of error
Crash when undoing painting on a linked image.

Exact steps for others to reproduce the error

  • open 'file.blend'
  • paint on the image (linked from 'lib.blend')
  • ctrl-z

# backtrace
0   Blender                             0x000000010aef65a7 BLI_system_backtrace + 55
1   Blender                             0x000000010a0cbbf3 sig_handle_crash + 355
2   libsystem_platform.dylib            0x00007fff715a75fd _sigtramp + 29
3   libsystem_kernel.dylib              0x00007fff714f0170 mach_msg + 60
4   libsystem_c.dylib                   0x00007fff71440891 __vfprintf + 5379
5   libsystem_c.dylib                   0x00007fff71466ad3 __v2printf + 475
6   libsystem_c.dylib                   0x00007fff7144cee7 _vsnprintf + 417
7   libsystem_c.dylib                   0x00007fff7144cf90 vsnprintf + 68
8   Blender                             0x000000010aabbf5b CLG_logf + 2827
9   Blender                             0x000000010a9b77e4 uhandle_restore_list + 756
10  Blender                             0x000000010a9b6afc image_undosys_step_decode + 188
11  Blender                             0x000000010a3a4f1f undosys_step_decode + 271
12  Blender                             0x000000010a3a4d11 BKE_undosys_step_undo_with_data_ex + 257
13  Blender                             0x000000010a9718cf ed_undo_step_impl + 735
14  Blender                             0x000000010a9706c2 ed_undo_exec + 50
15  Blender                             0x000000010a0d71ab wm_operator_invoke + 411
16  Blender                             0x000000010a0d8809 wm_handler_operator_call + 633
17  Blender                             0x000000010a0d7ec6 wm_handlers_do_intern + 1814
18  Blender                             0x000000010a0d35ff wm_handlers_do + 31
19  Blender                             0x000000010a0d31ed wm_event_do_handlers + 3373
20  Blender                             0x000000010a0cc710 WM_main + 32
21  Blender                             0x000000010a0c85f7 main + 759
22  libdyld.dylib                       0x00007fff713aecc9 start + 1

Event Timeline

Philipp Oeser (lichtwerk) changed the task status from Needs Triage to Confirmed.Jul 30 2020, 12:19 PM
Philipp Oeser (lichtwerk) changed the subtype of this task from "Report" to "Bug".

Can confirm the behavior.

on stroke:

  • uhandle_add seems to be doing its thing correctly (adding the image_ref.ptr)
  • undosys_id_ref_store seems to be doing its thing correctly (adding the image_ref.name - but NULLing the ptr again)

on undo:

  • undosys_id_ref_resolve checks for the id being linked though (here) and prevents setting the ptr again.
  • uhandle_restore_list crashes because of that [missing image_ref.ptr]

Taking a step back, I am wondering how useful it is to paint on linked images?

  • In the file provided, the linked image is generated(packed), painting on this will never make it back (saving) into the lib file
  • if the image would not be packed, then I can see workflows that make sense doing this on linked images, saving would then work.

Thinking of possible solutions:

  • prevent painting on linked images all together [could probably be done in some poll]
  • allow undosys_id_ref_resolve to store the pointer (even if image is linked -- exception just for images) [see snippet below]
  • just prevent the crash [see snippet below]
  • workflow alternative: create an override for the linked image (undo then works -- we should still prevent the crash though)

1
2
3diff --git a/source/blender/blenkernel/intern/undo_system.c b/source/blender/blenkernel/intern/undo_system.c
4index 0809e8dda6d..4719ec6bae9 100644
5--- a/source/blender/blenkernel/intern/undo_system.c
6+++ b/source/blender/blenkernel/intern/undo_system.c
7@@ -144,7 +144,9 @@ static void undosys_id_ref_resolve(void *user_data, UndoRefID *id_ref)
8 Main *bmain = user_data;
9 ListBase *lb = which_libbase(bmain, GS(id_ref->name));
10 LISTBASE_FOREACH (ID *, id, lb) {
11- if (STREQ(id_ref->name, id->name) && (id->lib == NULL)) {
12+ /* Allow for undoing painting on linked images. */
13+ const bool is_image = (GS(id_ref->name) == ID_IM);
14+ if (STREQ(id_ref->name, id->name) && (id->lib == NULL || is_image)) {
15 id_ref->ptr = id;
16 break;
17 }
18diff --git a/source/blender/editors/space_image/image_undo.c b/source/blender/editors/space_image/image_undo.c
19index 27b84307f7d..5215b714dec 100644
20--- a/source/blender/editors/space_image/image_undo.c
21+++ b/source/blender/editors/space_image/image_undo.c
22@@ -544,7 +544,11 @@ static void uhandle_restore_list(ListBase *undo_handles, bool use_init)
23 LISTBASE_FOREACH (UndoImageHandle *, uh, undo_handles) {
24 /* Tiles only added to second set of tiles. */
25 Image *image = uh->image_ref.ptr;
26-
27+ /* Prevent crash undoing painting on linked images. */
28+ if (image == NULL) {
29+ CLOG_ERROR(&LOG, "Unable to get image for UndoImageHandle '%s' (might be linked data?)", uh->image_ref.name);
30+ continue;
31+ }
32 ImBuf *ibuf = BKE_image_acquire_ibuf(image, &uh->iuser, NULL);
33 if (UNLIKELY(ibuf == NULL)) {
34 CLOG_ERROR(&LOG, "Unable to get buffer for image '%s'", image->id.name + 2);

Since this probably came with rB651b8fb14eb6: Undo: unified undo system w/ linear history, I would kindly ask @Campbell Barton (campbellbarton) for advice here.
Also @Bastien Montagne (mont29) might have an opinion here?

Painting on linked image should not be allowed... at all.