Page MenuHome

Blender crashes when using "spline" or "segments" for bevel curve factor.
Closed, ResolvedPublic

Description

System Information
OS X 10.8.5
NVIDIA GeForce GT 650M 1024 MB

Blender Version
Broken: 2.71 2f03ccc and offical 2.71 9337574
Worked: ???

When animating the bevel factor of a complicated bezier curve, Blender crashes when using "spline" or "segments" for the beginning and end bevel factor. When using "resolution" there is no problem. If the end bevel factor is 1, it's okay, but as soon as you make it smaller, Blender crashes. On simple curves it's no problem, but on complicated/heavy curves it is.

If it helps, the error message from the console:

blender(1001,0x7fff75fe0180) malloc: *** error for object 0x108585608: incorrect checksum for freed object - object was probably modified after being freed.
*** set a breakpoint in malloc_error_break to debug)

Exact steps for others to reproduce the error
Open attached blend-file and change the end bevel factor.

Event Timeline

I'm getting:

BLI_assert failed: /home/kevin/src/blender-git/blender/source/blender/blenkernel/intern/displist.c:1443, calc_bevfac_mapping(), at 'bevp_i < bl->nr - 1'
*** Error in `/home/kevin/src/blender-git/build_linux_debug/bin/blender': free(): invalid next size (normal): 0x0000000007936860 ***

Program received signal SIGABRT, Aborted.
0x00007ffff3203f79 in raise () from /lib/x86_64-linux-gnu/libc.so.6

OS: Arch Linux 64
GFX: Nvidia GeForce GTX 560 1024MB
Blender: git-master dfe1b9b

Didn't get a crash immediately, but had to slide the value up and down a bit. Tried 3 times, and 2 of the crash-logs looked like this:

Blender 2.71 (sub 2), Commit date: 2014-07-16 00:52, Hash dfe1b9b
  
# backtrace

./blender() [0x8db788]
/usr/lib/libc.so.6(+0x33df0) [0x7f53e47bedf0]
./blender() [0xe98b92]
./blender(BKE_displist_make_curveTypes+0x59) [0xe97629]
./blender(BKE_object_handle_update_ex+0x5f5) [0xf0f4d5]
./blender() [0xf4dd26]
./blender(BLI_task_pool_work_and_wait+0x95) [0x1059305]
./blender() [0xf4dea3]
./blender() [0xf4ef48]
./blender(BKE_scene_update_tagged+0x7e) [0xf4f1be]
./blender(wm_event_do_notifiers+0x48a) [0x8e216a]
./blender(WM_main+0x20) [0x8dd680]
./blender(main+0xd6f) [0x8c4a2f]
/usr/lib/libc.so.6(__libc_start_main+0xf0) [0x7f53e47ab000]
./blender() [0x8db004]

And the last one was this:

Blender 2.71 (sub 2), Commit date: 2014-07-16 00:52, Hash dfe1b9b

# backtrace
./blender() [0x8db788]
/usr/lib/libc.so.6(+0x33df0) [0x7fa01ba19df0]
/usr/lib/libpthread.so.0(pthread_mutex_lock+0x4) [0x7fa027e228b4]
/usr/lib/libjemalloc.so.1(+0x266c2) [0x7fa01efe86c2]
/usr/lib/libjemalloc.so.1(+0x26b0d) [0x7fa01efe8b0d]
./blender(uiBlockLayoutResolve+0x8e) [0xa8dc7e]
./blender(ED_region_panels+0x2ad) [0xb5c7cd]
./blender(ED_region_do_draw+0x895) [0xb5ba95]
./blender(wm_draw_update+0x457) [0x8e03f7]
./blender(WM_main+0x28) [0x8dd688]
./blender(main+0xd6f) [0x8c4a2f]
/usr/lib/libc.so.6(__libc_start_main+0xf0) [0x7fa01ba06000]
./blender() [0x8db004]

Can confirm an assert failure here:
https://developer.blender.org/diffusion/B/browse/master/source/blender/blenkernel/intern/displist.c;57a3403bc08d71d851cbded1c08913f0402d994c$1443

Tried simplifying the curve because debugging an object like this is almost impossible. However, there seems to be a secondary bug: Selecting all except one vertex and deleting them gives another assert failure in GHash duplicates:
https://developer.blender.org/diffusion/B/browse/master/source/blender/blenlib/intern/BLI_ghash.c;57a3403bc08d71d851cbded1c08913f0402d994c$207

Here's the simplified .blend

The thing here is: bevel list will remove points if they're appearing to be on the same position. So pointsu*resoution could be totally dirrerent from the actual number of bevel points. This fact is totally ignored in calc_bevfac_mapping. This function should really always use bl->nr actually..

@Lukas Treyer (cnd), do you have time to look into this code?

Sergey Sharybin (sergey) triaged this task as Normal priority.Jul 18 2014, 10:09 AM
Lukas Treyer (cnd) added a comment.EditedJul 19 2014, 9:45 AM

Yes I will have a look at it.
EDIT: What about calculating the length of curves directly in BKE_curve_bevelList_make() in STEP 2 ? I don't see any other reliable possibility to find out whether some bevpoints where omitted for optimization reasons. Would you agree on this?

Lukas Treyer (cnd) added a comment.EditedJul 28 2014, 5:24 PM

I've been working on a fix. Had some other work to do first. Struggling with Phabricator again, therefore only a diff:

EDIT: What does it do?: By calculating the bevels of a curve it also stores the offset between bevels in BevPoint->offset. BevList now also stores the length of segments and the amount of bevels per segment (aka resolution per segment), since this number can differ if two curve points are equal.

@Lukas Treyer (cnd), here's an updated patch fr you.

Changes:

  • C standard forbids declaring variables in the middle of the block, fixed it now
  • Added a proper bevel list free function now
  • In the if (nu->type == CU_BEZIER) { you've used the wrong length, which lead to bad memory access on differentiation, it should be len = segcount * resolu + 1; Without this blender crashed for me instantly on opening the file i've attached here.

There's at least one renaming issue: with the file i've attached above tweak End Factor. It'll make first start segment to disappear.

Same i see when replacing MEM_callocN with MEM_mallocN for the new arrays. And the thing is, it seems all the elements of new arrays are expected to be initialized and it shouldn't matter if you use calloc or malloc apart form using malloc wouldn't waste time on memsetting the allocated memory. I guess it's some non-initialized segment or length or so is happening?

Thank you for the corrections. The issue with the first segment disappearing was an small mistake of mine: move "bevp++;" from line 1398 to line 1393 and it should work out fine.
When I replace MEM_callocN with MEMmallocN I get a strange flickering of the beveled curve when sliding the factor sliders. I propose to leave it with MEM_callocN. There must be a reason why "bl" is initialized with MEM_callocN.

Attaching

If calloc works and malloc gives flickering it might mean you're not initializing some values in the loops..


malloc: I was adding with "+= value" to uninitialized values when using malloc. I init them now with *seglen = 0 (on line 2726 for instance).

in curve.c --> BKE_curve_bevelList_make --> STEP2 I took out the redundant calculation of bevp->offset. it is being calculated already in STEP 1.

re: T41085_4.diff

Possible to make it that bl->seglen and bl->segbevcount are only allocated when needed? - so if you aren't setting curve bevel factors (which isnt especially common), it doesn't bother allocating?

Another note if (a != segcount) printf("a != segcount"); -- rather just keep asserts here.

Sergey Sharybin (sergey) removed Sergey Sharybin (sergey) as the assignee of this task.

Attaching patch which tries to avoid unneeded calculations

. Seems to be rather fine for beziers now, but nurbs fails a lot. Basically all the part under

/* match seglen and segbevcount to the cleaned up bevel lists (see STEP 2) */

is just wrong. It writes far pas the seglen array. Also not really sure, do we need to handle seglen and segbevcount in a different way for path/bezier/nurbs?

Seems made it working now

@Campbell Barton (campbellbarton), mind having your hands on tests? :)

Managed to crash, add splint, duplicate, set bev depth 0.1, Set start end fact to anything. Alt+Mousewheel over bevel factor.

You may want to change bevel factor a bit... but for me it crashes quite fast,

Attaching fix for this

Fixed issue reported by asan

Just applied T41085_8.patch and tried hard to crash Blender, luckily without success. :)

Checked T41085, also tried to break but couldn't - LGTM