Bug 187485

Summary: JavaScriptCore doesn't work with musl-libc
Product: WebKit Reporter: Bernd <beb5pft5lz>
Component: JavaScriptCoreAssignee: Nobody <webkit-unassigned>
Status: RESOLVED DUPLICATE    
Severity: Major CC: aperez, bugs-noreply, clopez, contact+bugs.webkit.org, h4yfx4vuvg, mark.lam, pwr, ysuzuki
Priority: P2    
Version: Other   
Hardware: PC   
OS: Linux   
See Also: https://bugs.webkit.org/show_bug.cgi?id=210068
Bug Depends on: 208223, 210068, 225099    
Bug Blocks:    
Attachments:
Description Flags
Minimal test program to reproduce the issue
none
Valgrind output for the test program none

Description Bernd 2018-07-09 14:49:35 PDT
Hello there,

I wanted to run luakit (a javascript based webbrowser) on Alpine Linux (uses musl libc) and noticed that it wasn't able to evaluate any javascript. After some research I found the following issue in the luakit bugtracker:

* https://github.com/luakit/luakit/issues/550

According to this GitHub issue in the luakit bug tracker this isn't a problem with luakit but instead a problem with webkit itself (or more specific JavaScriptCore). I did some further research and found additional entries in bug trackers of musl-based linux distributions also claiming that this is a bug in webkit:

* https://github.com/voidlinux/void-packages/issues/5360
* https://bugs.alpinelinux.org/issues/8492

Most of these bug reports claim that this might be related to the default stack size for new threads in musl. Which is a lot smaller than the default stack size in glibc (see: https://wiki.musl-libc.org/functional-differences-from-glibc.html#Thread-stack-size)

To make sure that this is really a bug in webkit I came up with a little C example evaluating a simple javascript expression using JavaScriptCore. This C program is attached it is mostly based on a code snippet from `Source/JavaScriptCore/API/tests/testapi` (thus I assume that it should work).

I compiled the attached code snippet with `gcc -o test test.c $(pkg-config --cflags webkit2gtk-4.0) $(pkg-config --libs webkit2gtk-4.0)` on Alpine Linux Edge (x86_64) using webkit 2.20.3. Invoking the resulting binary produces the following output: `test: JSEvaluateScript failed`.

I also invoked the binary with valgrind (the output can be found here https://paste42.de/13254/) which makes me believe that this is really an issue regarding the thread stack size since various attempts are made to access memory below the stack pointer. Besides the test program segfaults when started with valgrind which is also strange.

I (and the people who created the bugs linked above) would be very happy if this could be investigated further and (hopefully) be fixed soon. I would also suggest that you run your test suite on a musl-based system as well to prevent these kind of issues in the future.
Comment 1 Bernd 2018-07-09 14:50:29 PDT
Created attachment 344619 [details]
Minimal test program to reproduce the issue
Comment 2 Bernd 2018-07-09 14:51:13 PDT
Created attachment 344620 [details]
Valgrind output for the test program
Comment 3 Yusuke Suzuki 2018-07-10 15:15:46 PDT
Yeah, this is because musl's stack size is very small[1].
So, all the stack overflow checks fail since soft stack limit is smaller than the current stack pointer.

We can make JSC work by changing MinimumReservedZoneSize.h from `static const unsigned minimumReservedZoneSize = 16 * KB;` to `static const unsigned minimumReservedZoneSize = 4 * KB;` or smaller value (At least in my Linux box using glibc, with `ulimit -s 80`).
But it seems dangerous to me. Personally, I think increasing the default stack size of musl is the right way to fix.
When setting `ulimit -s 100` in my Linux box (using glibc), even gdb fails to start.

The difficult thing is that we cannot deploy this tweak for musl, since musl does not provide any macro / definition to detect musl intentionally[1], while musl's behavior is different from glibc (actually stack size is small) :(.

Mark, what do you think of?

[1]: https://wiki.musl-libc.org/functional-differences-from-glibc.html#Thread-stack-size
[2]: https://wiki.musl-libc.org/faq.html#Q:-Why-is-there-no-%3Ccode%3E__MUSL__%3C/code%3E-macro?
Comment 4 h4yfx4vuvg 2019-01-02 03:48:23 PST
Unfourtunatly, simply increasing the stack size is not enough. The following patch is currently used by Alpine Linux and Void Linux for their webkit2gtk package: https://git.alpinelinux.org/cgit/aports/tree/community/webkit2gtk/musl-fixes.patch?id=609fbb0235cf6440f5d502885c4e0531c835aed7
Comment 5 Haelwenn (lanodan) Monnier 2020-02-15 07:40:49 PST
One way which seems less hacky/faulty than the alpine patch there would be to use pthread_attr_setstacksize like musl suggests (and no #ifdef should be required as it is POSIX) and/or "increasing the default stack size via the PT_GNU_STACK program header, which can be set at link time via -Wl,-z,stack-size=N".

I don't have much compiling power on my musl machine now (~2012 laptop with intel vulns, will replace it) but I'll try the latter.
Comment 6 Adrian Perez 2020-02-26 13:40:10 PST
(In reply to Haelwenn (lanodan) Monnier from comment #5)
> One way which seems less hacky/faulty than the alpine patch there would be
> to use pthread_attr_setstacksize like musl suggests (and no #ifdef should be
> required as it is POSIX) and/or "increasing the default stack size via the
> PT_GNU_STACK program header, which can be set at link time via
> -Wl,-z,stack-size=N".
> 
> I don't have much compiling power on my musl machine now (~2012 laptop with
> intel vulns, will replace it) but I'll try the latter.

The patch in bug #208223 adds configuring stack sizes, so once that
lands maybe the only leftover thing to do in this regard is to detect
if Musl is being used (tricky, maybe it's better to check for “not
glibc”) and set some sane value for DEFAULT_THREAD_STACK_SIZE_IN_KB.
Comment 7 Paul W. Rankin 2020-10-11 20:57:08 PDT
Thank you guys for looking into this :)

I'd very much like to use a WebKit browser on a musl system (Alpine Linux).

(In reply to Adrian Perez from comment #6)
> The patch in bug #208223 adds configuring stack sizes, so once that
> lands maybe the only leftover thing to do in this regard is to detect
> if Musl is being used (tricky, maybe it's better to check for “not
> glibc”) and set some sane value for DEFAULT_THREAD_STACK_SIZE_IN_KB.

Now that bug 208223 is resolved, is detecting mucl the only thing left to do?

For what my razor-thin understanding is worth, musl is a strict C library compared to the GNU C library with its own additions? If this is the case, could the condition case not be reversed, i.e. if GNU C additions are available, target those, otherwise, target strict C?
Comment 8 Adrian Perez 2021-05-25 15:28:09 PDT
JSC is working fine after the patch for bug #210068 landed,
so let's close this :)

*** This bug has been marked as a duplicate of bug 210068 ***