From: FX (fxcoudert_at_gmail.com)
Date: Fri Apr 03 2020 - 06:18:01 CDT

Hello,

A segfault was reported to me that occurs with my 64-bit macOS build, when drawing an isosurface for a cube file (which you can download at https://www.dropbox.com/s/g4oh8w0ih3xnlqe/cluster-SPIN_DENSITY-1_0.cube?dl=0)

Yet I look at the segfault and I don’t see how it could be mac-specific or 64-bit-specific. The backtrace is:

* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x10f2bc000)
   frame #0: 0x00000001001110d5 VMD`DrawMolItem::draw_volume_isosurface_points(this=<unavailable>, v=0x0000000100d5a070, isovalue=0, stepsize=1, thickness=<unavailable>) at DrawMolItemVolume.C:337:23 [opt]
  334 // draw perf gain here by eliminating them...
  335 printf("### %d/%d\n", idx, lastgrid);
  336 cols[idx ] = cp[0];
-> 337 cols[idx+1] = cp[1];
  338 cols[idx+2] = cp[2];
  339
  340 idx+=3;
Target 0: (VMD) stopped.
(lldb) bt
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x10f2bc000)
 * frame #0: 0x00000001001110d5 VMD`DrawMolItem::draw_volume_isosurface_points(this=<unavailable>, v=0x0000000100d5a070, isovalue=0, stepsize=1, thickness=<unavailable>) at DrawMolItemVolume.C:337:23 [opt]
   frame #1: 0x00000001000f7a58 VMD`DrawMolItem::create_cmdlist(this=<unavailable>) at DrawMolItem.C:386:7 [opt]
   frame #2: 0x00000001000f28dc VMD`Displayable::draw_prepare(this=0x00000001042aee00) at Displayable.C:261:3 [opt]
   frame #3: 0x00000001000f28ff VMD`Displayable::draw_prepare(this=0x0000000106854c00) at Displayable.C:267:29 [opt]
   frame #4: 0x00000001000f28ff VMD`Displayable::draw_prepare(this=0x0000000103b7c250) at Displayable.C:267:29 [opt]
   frame #5: 0x000000010017d785 VMD`Scene::prepare(this=0x0000000103b78e00) at Scene.C:396:15 [opt]
   frame #6: 0x0000000100195c12 VMD`VMDApp::VMDupdate(this=0x0000000100f0ae50, check_for_events=<unavailable>) at VMDApp.C:837:27 [opt]
   frame #7: 0x00000001001ca205 VMD`main(argc=<unavailable>, argv=<unavailable>) at vmdmain.C:93:16 [opt]

and the crash occurs because vmd is trying to write past the end of the colors buffer:

(lldb) p idx
(int) $0 = 31743
(lldb) p colors
(ResizeArray<float>) $1 = {
  data = 0x000000010f3b9000
  sz = 30003
  currSize = 0
}

I have tried to understand the logic in DrawMolItem::draw_volume_isosurface_points, but I fail:

- centers and colors are ResizeArray’s
- they are extended by around line 302, based on a comparison on centers.num(), i.e. the *actual* size of the ResizeArray (not the space allocated)
- because the code below does not use the C++ methods of ResizeArray, but writes directly into the buffers, colors.num() and centers.num() always return 0
- therefore the buffer are always extended… it shouldn’t crash, but it’s weird to do it that way
- the extend code is relying on actual data size to copy, which isn’t correctly updated (because direct access to the buffers). So if the data did extend, it would be crap anyway
- but extend also takes into account only the current size of data stored, which isn’t updated: which is why after the first extend, further calls are no-ops, and we end up writing past the end of the array

Maybe I missed something, because I really wonder how this could ever work? Help is welcome.

Thanks,
FX