LWJGL Forum

Please login or register.

Login with username, password and session length

Author Topic: [Bug] Cannot free Yoga Node on Mac OS  (Read 238 times)

orange451

  • Newbie
  • *
  • Offline Offline
  • Posts: 33
[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
Logged

spasi

  • Administrator
  • Nerdus Imperius
  • *****
  • Offline Offline
  • Posts: 1939
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?)
Logged

orange451

  • Newbie
  • *
  • Offline Offline
  • Posts: 33
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.
Logged

CoDi

  • Newbie
  • *
  • Offline Offline
  • Posts: 43
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.
Logged

spasi

  • Administrator
  • Nerdus Imperius
  • *****
  • Offline Offline
  • Posts: 1939
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.
Logged

CoDi

  • Newbie
  • *
  • Offline Offline
  • Posts: 43
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.
Logged

orange451

  • Newbie
  • *
  • Offline Offline
  • Posts: 33
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?
Logged

spasi

  • Administrator
  • Nerdus Imperius
  • *****
  • Offline Offline
  • Posts: 1939
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.
Logged

spasi

  • Administrator
  • Nerdus Imperius
  • *****
  • Offline Offline
  • Posts: 1939
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).
Logged