Page MenuHome

Grease Pencil crashes in 32-Bit version
Open, Confirmed, MediumPublic

Description

System Information
Operating system: win 7
Graphics card: Vega 64
Full System Information: Here

Blender Version
Broken: -69b2f5268114-windows32
Works: -69b2f5268114-windows64

Short description of error

32-Bit Blender crashes when drawing with grease pencil.

Exact steps for others to reproduce the error

  • Open Blender
  • New --> 2D Animation

At which point I get this:

  • Select a brush and start drawing
  • Switch to eraser and crash

This file was saved in the 32-bit version:


Open and start drawing and erasing.


Here's the log from --debug --factory-startup

location: <unknown location>:-1
Traceback (most recent call last):
  File "N:\Temp\Blender\blender-2.80.0-git.69b2f5268114-windows32\2.80\scripts\startup\bl_ui\space_topbar.py", line 94, in draw
    self.draw_left(context)
  File "N:\Temp\Blender\blender-2.80.0-git.69b2f5268114-windows32\2.80\scripts\startup\bl_ui\space_topbar.py", line 119, in draw_left
    draw_fn(context, layout, tool)
  File "N:\Temp\Blender\blender-2.80.0-git.69b2f5268114-windows32\2.80\scripts\startup\bl_ui\space_topbar.py", line 353, in PAINT_GPENCIL
    draw_color_selector()
  File "N:\Temp\Blender\blender-2.80.0-git.69b2f5268114-windows32\2.80\scripts\startup\bl_ui\space_topbar.py", line 323, in draw_color_selector
    ma = gp_settings.material
AttributeError: 'NoneType' object has no attribute 'material'

Issues:

  • .blend files can load invalid brushes
    • Invalid brushes for Draw, Fill, Erase causes crash. rBb8dc7e9cb844
      • x64
      • x86
    • Invalid brushes for Primitives causes crash.
      • x64
      • x86
  • Application template loads invalid brushes. b82afb4b016c

Event Timeline

Jacques Lucke (JacquesLucke) triaged this task as Confirmed, Medium priority.

I get an assert when I open this file. Bisecting...

@Jacques Lucke (JacquesLucke) I got to open it once...now get the assert. The problem is related to brushes. They have forgotten the gp_settings... I'm investigating.

The eraser brush is damaged and the same for the default draw brush.

I going to do some changes to avoid crashes if the brush is damaged, but we need to know how the brush was damaged.

@Christopher Anderssarian (Christopher_Anderssarian) Could you tell us the steps you did with the brushes to get this situation? did you have any other crash before?

Okay, new update, I had been running with --debug (I'm having the same problems as reported in T60089 and with debug is the only way to run Blender)
For some spontaneous reason, Blender* launched (without the debug command)
Here's what I found:
Launching Blender's 32-Bit & 64-Bit build (-69b2f5268114-) both with --debug --factory-startup show different results:

-69b2f5268114-windows32-69b2f5268114-windows64

*(At least with Correction: -7f77961f1c38-windows32 it did, I haven't managed to get -69b2f5268114-windows32 running without --debug)

69b2f5268114-windows32 has brush damaged... maybe it's the template.

Are you able to reproduce the issue in a new file still?

@Jacques Lucke (JacquesLucke) Yep

March 22, 00:28:10 - 1ae6aaad43ad 2.80 Beta Windows 32 bit

Thanks, I was able to reproduce it now.

I'm investigating this. Right now I'm trying to figure out how to make a 32 bit debug build on windows that does not crash when I remove any object...

No, 64 bit seems fine in my initial test.

Brecht Van Lommel (brecht) lowered the priority of this task from Confirmed, Medium to Needs Information from User.

Please try again with the very latest 2.80 32bit build:
https://builder.blender.org/download/

rB4f4cea727efd: Fix T63164: DNA size mismatches on 32bit, causing memory corruption and crashes. may have fixed some or all of these issues.

Christopher Anderssarian (Christopher_Anderssarian) raised the priority of this task from Needs Information from User to Needs Triage by Developer.Apr 2 2019, 4:32 PM

Well, this task has sort of lost it's identity, with crash being fixed already.
But I still have the damaged brushes as seen in T61413#646242.

Also after File > Load Factory Settings while in the 2D Animation workspace?

If so, does it also happen when adding a new grease pencil object?

Brecht Van Lommel (brecht) triaged this task as Needs Information from User priority.Apr 2 2019, 4:35 PM

Also after File > Load Factory Settings while in the 2D Animation workspace?
If so, does it also happen when adding a new grease pencil object?

Checking...

Also after File > Load Factory Settings while in the 2D Animation workspace?

Yes, I still get damaged brushes.

If so, does it also happen when adding a new grease pencil object?

I actually get a crash.

Quick repo steps:

blender-2.80.0-git.d986b04bd302-windows32

  • New 2D animation template
  • Switch to object mode
  • Add blank GPencil object
  • Crash
Brecht Van Lommel (brecht) raised the priority of this task from Needs Information from User to Confirmed, Medium.Apr 2 2019, 5:02 PM

I'm now getting a crash just by opening the 2D Animation template:

blender-2.80.0-git.75f551facaf0-windows32

  • New 2D animation template
  • Crash

After more investigation it looks like you can't open blend files (with GPencil data) on different architectures than what it was made on.

In opening the 64-bit .blend with 32-bit I get:
blender-2.80.0-git.009dbc2bc9fb-windows32

GPencil - Starting Drawing
Error: Not freed memory blocks: 2, total unfreed memory 0.001961 MB
GPUVertBuf len: 940 0DD5E818
GPUBatch len: 88 29272480

In opening the 32-bit .blend with 64-bit I get:
blender-2.80.0-git.009dbc2bc9fb-windows64

Memoryblock MORE THAN 1 MEMORYBLOCK CORRUPT: error in header
Memoryblock Data from SCE: end corrupt
Memoryblock MORE THAN 1 MEMORYBLOCK CORRUPT: is also corrupt
Memoryblock Data from SCE: end corrupt
Memoryblock MORE THAN 1 MEMORYBLOCK CORRUPT: is also corrupt
Memoryblock Data from SCE: end corrupt
Memoryblock MORE THAN 1 MEMORYBLOCK CORRUPT: is also corrupt
Memoryblock Data from SCE: end corrupt
Memoryblock MORE THAN 1 MEMORYBLOCK CORRUPT: is also corrupt
Memoryblock Data from SCE: end corrupt
Memoryblock MORE THAN 1 MEMORYBLOCK CORRUPT: is also corrupt
Memoryblock MORE THAN 1 MEMORYBLOCK CORRUPT: error in header
Memoryblock MORE THAN 1 MEMORYBLOCK CORRUPT: error in header
Memoryblock MORE THAN 1 MEMORYBLOCK CORRUPT: error in header
Read blend: R:\Blender\BugFinds\GP Crash 32-bit\Test\2D Animation Template x86 remade.blend
read file R:\Blender\BugFinds\GP Crash 32-bit\Test\2D Animation Template x86 remade.blend
  Version 280 sub 55 date 2019-04-09 18:12 hash 009dbc2bc9fb
Memoryblock MORE THAN 1 MEMORYBLOCK CORRUPT: error in header
GPencil - Starting Drawing
GPencil - Starting Drawing
GPencil - Starting Drawing
GPencil - Starting Drawing
GPencil - Starting Drawing
GPencil - Starting Drawing
GPencil - Starting Drawing
GPencil - Starting Drawing
GPencil - Starting Drawing
GPencil - Starting Drawing
GPencil - Starting Drawing
GPencil - Starting Drawing
GPencil - Starting Drawing
Memoryblock Data from SCE: end corrupt
Memoryblock MORE THAN 1 MEMORYBLOCK CORRUPT: is also corrupt
Memoryblock Data from SCE: end corrupt
Memoryblock MORE THAN 1 MEMORYBLOCK CORRUPT: is also corrupt
Memoryblock Data from SCE: end corrupt
Memoryblock MORE THAN 1 MEMORYBLOCK CORRUPT: is also corrupt
Memoryblock Data from SCE: end corrupt
Memoryblock MORE THAN 1 MEMORYBLOCK CORRUPT: is also corrupt
Memoryblock MORE THAN 1 MEMORYBLOCK CORRUPT: error in header
Memoryblock Data from SCE: end corrupt
Memoryblock MORE THAN 1 MEMORYBLOCK CORRUPT: is also corrupt
Memoryblock MORE THAN 1 MEMORYBLOCK CORRUPT: error in header
Error: Not freed memory blocks: 2, total unfreed memory 0.003937 MB
(null) len: 0 0000000014BC4258
Data from SCE len: 32 000000001B4F02E8
Data from SCE len: 32 000000001B4EFF68
Data from SCE len: 80 0000000014BC41B8
Data from SCE len: 12 0000000014C8F628
Data from SCE len: 24 0000000014C87A68
Data from SCE len: 24 0000000014C87AC8
reconstruct len: 40 000000001B4F0358
reconstruct len: 40 000000001B4EFFD8
GPUVertBuf len: 1272 000000000F4835A8
GPUBatch len: 152 000000000FFC0858
MemFileChunk len: 32 000000000FA86188
Data from SCE len: 32 000000000FA86118
Data from SCE len: 32 000000000FA85E78
Data from SCE len: 80 000000000FFE6E88
Data from SCE len: 12 000000000FE893F8
Data from SCE len: 24 000000000FE895D8
Data from SCE len: 24 000000000FE89578
reconstruct len: 32 000000000FA85EE8

up until last week, there was an issue in blenders DNA code for 32 bit, fields were not the size blender though they were, can you still reproduce the issue in files created in a recent build?

@Brecht Van Lommel (brecht) beat you to it :) T61413#653490

But yeah stupid of me not including the hash... updated comment!

yeah but you mentioned opening, files created with 'bad dna' are gonna have bad dna, but is the issue still there when you create a new file in a recent version?

Ahh... yes, the template files bundled with Blender would have the 'bad dna'.

checking...

Well I think that's it. I can't get it to crash anymore.
So are the template files going to have to get updated, as opening 2D Animation still crashes 32-bit?

Actually I can crash x64 (edc1b0167518-windows64) with a file created in blender-2.80.0-git.e2102e991764-windows32 without ...\Blender\2.80\config\startup.blend and 2D animation template:

For me 32bit Blender crashes when opening the default "2D Animation". The problem seems to be that 32bit Blender somehow gets to use "Draw" where 64bit Blender is using "Draw Pencil". But "Draw" is not a grease pencil tool.

This fix allows to open "2D Animation".

diff --git a/source/blender/draw/engines/gpencil/gpencil_engine.c b/source/blender/draw/engines/gpencil/gpencil_engine.c
index ea578187765..72ca0fd30c3 100644
--- a/source/blender/draw/engines/gpencil/gpencil_engine.c
+++ b/source/blender/draw/engines/gpencil/gpencil_engine.c
@@ -306,9 +306,11 @@ void GPENCIL_cache_init(void *vedata)
   if (obact && (obact->type == OB_GPENCIL) && (obact->data)) {
     obact_gpd = (bGPdata *)obact->data;
     /* use the brush material */
-    Material *ma = BKE_gpencil_object_material_get_from_brush(obact, brush);
-    if (ma != NULL) {
-      gp_style = ma->gp_style;
+    if (brush->gpencil_settings) {
+      Material *ma = BKE_gpencil_object_material_get_from_brush(obact, brush);
+      if (ma != NULL) {
+        gp_style = ma->gp_style;
+      }
     }
     /* this is not common, but avoid any special situations when brush could be without material */
     if (gp_style == NULL) {

When opening a 32bit .blend file in 64bit Blender one of the following errors is happening on first or second attempt to open the file.

HEAP CORRUPTION DETECTED: after Normal block (#75637) at 0x000001C45B168E40

HEAP CORRUPTION DETECTED: after Normal block (#74620) at 0x000001DDEA6EEE10.

Exception thrown at 0x000000005F758928 (atio6axx.dll) in blender.exe: 0xC0000005: Access violation reading location 0x0000000000000008.

Critical error detected c0000374
Exception thrown at 0x00007FF88B6CAF89 (ntdll.dll) in blender.exe: 0xC0000374: A heap has been corrupted (parameters: 0x00007FF88B7327F0).

Exception thrown at 0x000000005F758928 (atio6axx.dll) in blender.exe: 0xC0000005: Access violation reading location 0x0000000000000008.

Critical error detected c0000374

Critical error detected c0000374

@matc (matc) It's better a more general check:

diff --git a/source/blender/blenkernel/intern/gpencil.c b/source/blender/blenkernel/intern/gpencil.c
index c82b2c377fa..439005ca1b4 100644
--- a/source/blender/blenkernel/intern/gpencil.c
+++ b/source/blender/blenkernel/intern/gpencil.c
@@ -1109,7 +1109,8 @@ Material *BKE_gpencil_object_material_new(Main *bmain, Object *ob, const char *n
 /* Returns the material for a brush with respect to its pinned state. */
 Material *BKE_gpencil_object_material_get_from_brush(Object *ob, Brush *brush)
 {
-  if ((brush) && (brush->gpencil_settings->flag & GP_BRUSH_MATERIAL_PINNED)) {
+  if ((brush) && (brush->gpencil_settings) &&
+      (brush->gpencil_settings->flag & GP_BRUSH_MATERIAL_PINNED)) {
     Material *ma = BKE_gpencil_brush_material_get(brush);
     return ma;
   }

It looks the old Draw brush has the Pinned enabled for some reason.

I'm ok with that. There is still something wrong with having the "Draw" there. Or is ts->gp_paint not limited to grease pencil tools? And it should be the same for 32bit and 64bit anyway.

It looks the old Draw brush has the Pinned enabled for some reason.

For me gpencil_settings is NULL in 32bit and 64bit.

I think I found where "Draw" is coming from.

wm_toolsystem.c:

static void toolsystem_ref_link(bContext *C, WorkSpace *workspace, bToolRef *tref){
//....
//line: 253
            Paint *paint = BKE_paint_get_active_from_paintmode(scene, paint_mode);
            struct Brush *brush = BKE_paint_toolslots_brush_get(paint, slot_index);
            if (brush == NULL) {
              /* Could make into a function. */
              brush = (struct Brush *)BKE_libblock_find_name(bmain, ID_BR, items[i].name);
              if (brush && slot_index == BKE_brush_tool_get(brush, paint)) {
                /* pass */
              }
              else {
                brush = BKE_brush_add(bmain, items[i].name, paint->runtime.ob_mode);
                BKE_brush_tool_set(brush, paint, slot_index);
              }
              BKE_paint_brush_set(paint, brush);
            }
//....
}

For 64bit brush is "Draw Pencil" and for 32bit null. items[i].name is "Draw". BKE_paint_brush_set will then set paint->brush to "Draw" with paint being ts->gp_paint. items is rna_enum_brush_gpencil_types_items and only contains "Draw", "Erease" and "Fill". Maybe those need to be updated.

The reason why brush is null for 32bit seems to be in link_paint(FileData *fd, Scene *sce, Paint *p) (readfile.c) where p->tool_slots[i].brush = newlibadr_us(fd, sce->id.lib, p->tool_slots[i].brush); fails to return a brush for 32bit.

Thanks for investigating that.

This is possibly related to T63046: Crashing loading .blend file with missing paint tool slots, if there's something broken in read/write of paint slots.

Before newlibadr_us() the lower 32bit of p->tool_slots[i].brush are the same for 64bit and 32bit.

The paint tool slots are written wrong, they should use writestruct instead of writedata.

I'll see how we can detect that case and discard paint slots then.

The startup.blend file will need to be updated as I can still crash 32-bit with invalid brushes in the 2D Animation template.

Quick repo steps:

blender-2.80.0-git.c0432c2385e6-windows32

  • New > 2D animation
  • Add GPencil line
  • Crash

That may be a different issue, not sure how the current code would make it crash.

It's probably the same as when @Antonio Vazquez (antoniov) first fixed the crash: T61413#617884, just needs to be for the rest of the tools (Line, Arc, Curve ect..).

But, when loading the 2D template it still has invalid brushes.

I cannot compile now on 32bits, but I think this could fix the issue (code not tested)

diff --git a/source/blender/editors/gpencil/gpencil_primitive.c b/source/blender/editors/gpencil/gpencil_primitive.c
index 08fee2bb393..bff17bf5078 100644
--- a/source/blender/editors/gpencil/gpencil_primitive.c
+++ b/source/blender/editors/gpencil/gpencil_primitive.c
@@ -314,7 +314,7 @@ static void gp_primitive_set_initdata(bContext *C, tGPDprimitive *tgpi)
   /* if brush doesn't exist, create a new one */
   Paint *paint = &ts->gp_paint->paint;
   /* if not exist, create a new one */
-  if (paint->brush == NULL) {
+  if ((paint->brush == NULL) || (paint->brush->gpencil_settings == NULL)) {
     /* create new brushes */
     BKE_brush_gpencil_presets(C);
   }

This will create a new set of valid brushes and assign the first one (valid).

This fixes tool_slots with NULL brushes.

It's only looking for one slot of scene->toolsettings->sculpt, which should not be problem unless sculpt only recently started using tool_slots.

diff --git a/source/blender/blenloader/intern/versioning_280.c b/source/blender/blenloader/intern/versioning_280.c
index f1c92dedd33..79cc37f18f7 100644
--- a/source/blender/blenloader/intern/versioning_280.c
+++ b/source/blender/blenloader/intern/versioning_280.c
@@ -1081,6 +1081,19 @@ void do_versions_after_linking_280(Main *bmain)
       BKE_rigidbody_constraints_collection_validate(scene, rbw);
     }
   }
+
+  if (!MAIN_VERSION_ATLEAST(bmain, 280, 61)) {
+    /* Recovering tool_slots written in 64bit and read in 32bit. */
+    Scene *scene = bmain->scenes.first;
+    if (scene && scene->toolsettings && scene->toolsettings->sculpt) {
+      Paint *sculpt = &scene->toolsettings->sculpt->paint;
+      /* Sculpt slot 0 is always null, testing slot 1. If one slot is broken, all are expected to
+       * be broken (including other paints). */
+      if (sculpt->tool_slots_len > 1 && sculpt->tool_slots[1].brush == NULL) {
+        BKE_paint_toolslots_init_from_main(bmain);
+      }
+    }
+  }

@Brecht Van Lommel (brecht) I cannot test 32 bits version... can you confirm the diff from @matc (matc) fix the problem?

@Antonio Vazquez (antoniov) There isn't a difference between the 32 & 64-bit's crashing (at the moment) only the invalid brushes appearing on 32-bit.

You can still crash x64 with the original given .blend:

  • Add GPencil line
  • Crash

Once the crash is fixed, updating the "2D Animation" Application Template should make it so that it's not possible to have invalid brushes in the first place.

I tried opening all files mentioned in this thread with x86 and x64 blender (version 3f23299403d4f20f) on windows 10. Initially no file causes a crash for either version. Only the broken eraser tool can cause problems when gp_get_default_eraser finds the broken eraser before the default eraser (gpencil_settings is NULL).

Only one file showed differences between x86 and x64 (blender-2.80.0-git.e2102e991764-windows32.blend). Where the initially selected tools are broken for x64, but not for x86.

win32_Save.blend has for both versions the broken tools initially selected.

The file 2D Animation Template x64 empty.blend appears to have lost the grease pencil stroke object for both x86 and x64. Adding a new stroke caused no problems.

The current "2D Animation" did not cause any problems for either version.

Nice, so the template has been updated:

(New) (Old)
blender-2.80.0-git.cc600de6695a-windows32 (31 May 2019, 23:17:41)blender-2.80.0-git.8accb5a46f4a-windows32 (22 ‎May ‎2019)

I guess it's up to @Antonio Vazquez (antoniov) whether to fix old .blend files, as you can't create this issue(s) from scratch anymore.

IMHO if an old file created during beta was damaged, it's not logic to waste time fixing it in code. We have too many things to do and the important point is the issue is not present, so we could close the task report.

If some very important damaged file need to be recovered, we could try to fix it manually, but not adding code in master for that.

@Brecht Van Lommel (brecht) what do you think?

The old startup.blend has the broken tools for x86, but is otherwise working. One thing I noticed is that bmain->brushes initially contains only valid Grease Pencil brushes with gpencil_settings. But once the broken tools are manually switched to working ones, then the brush of the broken tool (with gpencil_settings set to NULL) is added to bmain->brushes. This does somehow only happen for Erase and Fill but not for Draw.

This happens with the old startup.blend for x86 and with win32_Save.blend for x64 and x86.

If this can be avoided, then a broken .blend file could manually be fixed by opening, switching tools and saving. Otherwise the broken brushes can carry over to save files of newer versions, which would be hard to fix in versioning.

@Antonio Vazquez (antoniov) Can you at least fix the crashing for Primitives like you did for the main Grease Pencil tools?
If there is a invalid brush, for whatever reason, I'd be more comfortable if Blender did nothing, rather then crash...
Opening up the original supplied .blend in your build should show the crash on using the Primitive tools...

My understanding is that with the latest code in master, the brush pointers would simply become NULL. If that still causes a crash, it means there is an issue in other code, because Blender code should assume that any datablock pointer can become NULL on file read or after scene edits

matc (matc) added a comment.EditedWed, Jun 5, 11:43 PM

I think the problem originates in the use of rna_Brush_gpencil_tool_items. I guess it is using the names of annotation brushes. At least BKE_libblock_find_name returns a brush without gpencil_settings for "Erase". This is the brush that causes the crash I described further up. Otherwise I don't experience any crashes.

wm_toolsystem.c line 254 in toolsystem_ref_link(...):

struct Brush *brush = BKE_paint_toolslots_brush_get(paint, slot_index);
if (brush == NULL) {
  /* Could make into a function. */
  brush = (struct Brush *)BKE_libblock_find_name(bmain, ID_BR, items[i].name);
  if (brush && slot_index == BKE_brush_tool_get(brush, paint)) {
    /* pass */
  }
  else {
    brush = BKE_brush_add(bmain, items[i].name, paint->runtime.ob_mode);
    BKE_brush_tool_set(brush, paint, slot_index);
  }
  BKE_paint_brush_set(paint, brush);
}

d46aee298210282 did not solve this problem