Hello Guest

[Bug] Cannot free Yoga Node on Mac OS

  • 8 Replies
  • 8090 Views
[Bug] Cannot free Yoga Node on Mac OS
« on: January 25, 2018, 23:24:43 »
Trying to use Yoga with lwjgl. If I run this code:
Code: [Select]
long a =  Yoga.YGNodeNew();
Yoga.YGNodeFree(a);

The 2nd line (freeing the memory) crashes the JVM.

Here's a copy of the crash report:
https://pastebin.com/yMKngwC2
« Last Edit: January 25, 2018, 23:32:33 by orange451 »

*

Offline spasi

  • *****
  • 2258
    • WebHotelier
Re: [Bug] Cannot free Yoga Node on Mac OS
« Reply #1 on: January 26, 2018, 07:34:27 »
Does it work if you run it with -Dorg.lwjgl.system.allocator=system?

Also, how do you launch the application? (IDE? terminal?)

Re: [Bug] Cannot free Yoga Node on Mac OS
« Reply #2 on: January 26, 2018, 17:55:03 »
Adding
Code: [Select]
-Dorg.lwjgl.system.allocator=system fixes the problem

Thanks.

*

Offline CoDi

  • *
  • 49
Re: [Bug] Cannot free Yoga Node on Mac OS
« Reply #3 on: January 26, 2018, 21:29:12 »
This doesn't fix the problem, just hides it.

I believe this is a bug in Yoga:

https://github.com/facebook/yoga/blob/master/yoga/Yoga.cpp#L218
https://github.com/facebook/yoga/blob/master/yoga/Yoga.cpp#L259

Matching new and free is undefined behavior, as far as I remember. The MacOS system allocator may just get over it silently.

*

Offline spasi

  • *****
  • 2258
    • WebHotelier
Re: [Bug] Cannot free Yoga Node on Mac OS
« Reply #4 on: January 27, 2018, 00:26:10 »
Good catch CoDi! Indeed, using delete instead of free fixes the crash for me.

But now I'm curious why using -Dorg.lwjgl.system.allocator=system makes a difference. Yoga does not use the LWJGL allocator (which is jemalloc on macOS by default), in any way.

*

Offline CoDi

  • *
  • 49
Re: [Bug] Cannot free Yoga Node on Mac OS
« Reply #5 on: January 27, 2018, 01:05:01 »
Well, it looks like jemalloc "simply" hooks into the stdlib functions, so the free() call goes through jemalloc. I have no idea how the default operator new is wired internally to do the actual allocation.

Re: [Bug] Cannot free Yoga Node on Mac OS
« Reply #6 on: January 27, 2018, 02:07:39 »
So to clarify, what is the "correct" way of handling this?

*

Offline spasi

  • *****
  • 2258
    • WebHotelier
Re: [Bug] Cannot free Yoga Node on Mac OS
« Reply #7 on: January 27, 2018, 08:23:40 »
So to clarify, what is the "correct" way of handling this?

The next 3.1.6 snapshot (build 12) will have a modified Yoga with delete instead of free, so hopefully you won't have to do anything.

*

Offline spasi

  • *****
  • 2258
    • WebHotelier
Re: [Bug] Cannot free Yoga Node on Mac OS
« Reply #8 on: January 27, 2018, 12:29:49 »
Well, it looks like jemalloc "simply" hooks into the stdlib functions, so the free() call goes through jemalloc. I have no idea how the default operator new is wired internally to do the actual allocation.

I've had a better look at this, because the jemalloc build that comes with LWJGL is built with `--disable-zone-allocator`, which means it does not replace the default macOS allocator.

Turns out it does override C++ new/delete with jemalloc_cpp.cpp. So with the way jemalloc is built, YGNodeNew goes to je_malloc via the overridden new, but YGNodeFree goes to the default zone allocator's free. Which tries to free a pointer it doesn't know about and crashes.

I couldn't believe you can override new/delete by loading a shared library without something like LD_PRELOAD, but apparently it's actually possible on macOS.

Build 12 will include both the Yoga fix and a jemalloc built with `--disable-cxx --disable-zone-allocator` (i.e. neither the default zone allocator, nor new/delete will be overridden).