Skip to content
GitLab
    • Why GitLab
    • Pricing
    • Contact Sales
    • Explore
  • Why GitLab
  • Pricing
  • Contact Sales
  • Explore
  • Sign in
  • Get free trial
  • bzt
  • model3dmodel3d
  • Issues
  • #19

Unaligned float pointer accesses

Hello! Author of Mach engine here - we're building model3d's C sources with Zig as the compiler currently, which enables some stricter safety checks like clang's UBSan by default.

When loading most files - like e.g. an icosphere.m3d (just exported via the Blender exporter), we're finding that UBSan picks up undefined behavior in the form of unaligned pointer accesses, specifically here:

(lldb) target create "/Users/slimsag/Desktop/hexops/mach-examples/libs/mach/libs/model3d/zig-cache/o/26c4104a1643fed2068dfa9244dfe90e/model3d-tests"
Current executable set to '/Users/slimsag/Desktop/hexops/mach-examples/libs/mach/libs/model3d/zig-cache/o/26c4104a1643fed2068dfa9244dfe90e/model3d-tests' (arm64).
(lldb) run
Process 6830 launched: '/Users/slimsag/Desktop/hexops/mach-examples/libs/mach/libs/model3d/zig-cache/o/26c4104a1643fed2068dfa9244dfe90e/model3d-tests' (arm64)
Process 6830 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BREAKPOINT (code=1, subcode=0x100033634)
    frame #0: 0x0000000100033634 model3d-tests`m3d_load(data="\xc3.:>", readfilecb=0x0000000000000000, freecb=0x0000000000000000, mtllib=0x0000000000000000) at m3d.h:3356:56
   3353	                        model->tmap[i].v = (M3D_FLOAT)(*((uint16_t*)(data+2))) / (M3D_FLOAT)65535.0;
   3354	                    break;
   3355	                    case 4:
-> 3356	                        model->tmap[i].u = (M3D_FLOAT)(*((float*)(data+0)));
   3357	                        model->tmap[i].v = (M3D_FLOAT)(*((float*)(data+4)));
   3358	                    break;
   3359	                    case 8:

This occurs on the first iteration of the loop i=0, UBSan doesn't like the de-reference *((float*)(data+0)) because that address is not aligned to 4 bytes as expected (not divisible by 4):

(lldb) p data
(unsigned char *) $3 = 0x0000000101008251 "\xc3.:>"

We're fine to just workaround this on our side by disabling alignment sanitization on the m3d_load function (as shown below), but I imagine this signals a real issue somewhere since these should probably be aligned.

+__attribute__((no_sanitize("alignment")))
m3d_t *m3d_load(unsigned char *data, m3dread_t readfilecb, m3dfree_t freecb, m3d_t *mtllib)

Happy to provide more info if helpful.

P.S. model3d looks quite promising! I'm a big fan of what you are building here :) If there's anywhere I can throw coffee money your way, I'd love to do that

Assignee
Assign to
Time tracking