graalvm

Ingy döt Net 2024-10-21T00:21:45.397329Z

I just tried building a native-image binary with --static --libc=musl see https://www.graalvm.org/latest/reference-manual/native-image/guides/build-static-executables/ and it all worked except I get a stack overflow on one of my tests:

Exception in thread "main" java.lang.StackOverflowError
        at org.graalvm.nativeimage.builder/com.oracle.svm.core.graal.snippets.StackOverflowCheckImpl.newStackOverflowError0(StackOverflowCheckImpl.java:360)
        at org.graalvm.nativeimage.builder/com.oracle.svm.core.graal.snippets.StackOverflowCheckImpl.newStackOverflowError(StackOverflowCheckImpl.java:356)
        at org.graalvm.nativeimage.builder/com.oracle.svm.core.graal.snippets.StackOverflowCheckImpl.throwNewStackOverflowError(StackOverflowCheckImpl.java:336)
        at java.base@23.0.1/java.util.regex.Pattern$BmpCharProperty.match(Pattern.java:4133)
        at java.base@23.0.1/java.util.regex.Pattern$Branch.match(Pattern.java:4914)
        at java.base@23.0.1/java.util.regex.Pattern$GroupHead.match(Pattern.java:4969)
        at java.base@23.0.1/java.util.regex.Pattern$Pos.match(Pattern.java:5348)
        at java.base@23.0.1/java.util.regex.Pattern$LazyLoop.match(Pattern.java:5142)
        at java.base@23.0.1/java.util.regex.Pattern$GroupTail.match(Pattern.java:5000)
        at java.base@23.0.1/java.util.regex.Pattern$BranchConn.match(Pattern.java:4878)
        at java.base@23.0.1/java.util.regex.Pattern$CharProperty.match(Pattern.java:4110)
        at java.base@23.0.1/java.util.regex.Pattern$Branch.match(Pattern.java:4914)
        at java.base@23.0.1/java.util.regex.Pattern$GroupHead.match(Pattern.java:4969)
        at java.base@23.0.1/java.util.regex.Pattern$LazyLoop.match(Pattern.java:5146)
        at java.base@23.0.1/java.util.regex.Pattern$GroupTail.match(Pattern.java:5000)
        at java.base@23.0.1/java.util.regex.Pattern$BranchConn.match(Pattern.java:4878)
        at java.base@23.0.1/java.util.regex.Pattern$CharProperty.match(Pattern.java:4110)
        at java.base@23.0.1/java.util.regex.Pattern$Branch.match(Pattern.java:4914)
        at java.base@23.0.1/java.util.regex.Pattern$GroupHead.match(Pattern.java:4969)
        at java.base@23.0.1/java.util.regex.Pattern$LazyLoop.match(Pattern.java:5146)
I've never seen this running code in jvm or graalvm compiled before. It's caused involving a string that at length 322 works but 323 errors. Obviously involving a regex. I think it will be hard to track down, so asking here first if anyone has ideas of what might be happening.

Bob B 2024-10-21T01:31:58.896489Z

possibly related: <https://rules.sonarsource.com/java/tag/regex/RSPEC-5998/>

Ingy döt Net 2024-10-21T01:35:40.923809Z

Interesting and thanks. I don't get how statically linking musl would change the stack size though. Any thoughts there?

Ingy döt Net 2024-10-21T01:39:06.413429Z

heh, here's a possible answer from (a 3 years younger) @borkdude! https://github.com/oracle/graal/issues/3398

Ingy döt Net 2024-10-21T01:54:27.186829Z

@highpressurecarsalesm how did you find https://rules.sonarsource.com/java/tag/regex/RSPEC-5998/ btw?

Bob B 2024-10-21T02:06:49.382449Z

googled "java stackoverflow regex"

Ingy döt Net 2024-10-21T02:43:12.934929Z

I need to learn about this google thing!

Ingy döt Net 2024-10-21T03:06:30.161919Z

I'll try to make an adaptation of https://github.com/babashka/babashka/blob/master/src/babashka/main.clj#L1232-L1267

Ingy döt Net 2024-10-21T05:53:50.433619Z

I got it working. Thank you again @highpressurecarsalesm for finding the right path for me to pursue.

Ingy döt Net 2024-10-21T05:56:11.859529Z

@borkdude I believe that you no longer need this code https://github.com/babashka/babashka/blob/master/src/babashka/main.clj#L1232-L1250 I believe that -H:CCompilerOption=-Wl,-z,stack-size=2097152 now applies to the main thread as well. Perhaps that's what wirthi meant in https://github.com/oracle/graal/issues/3398#issuecomment-1907980571

👍 1
Ingy döt Net 2024-10-21T00:37:22.742359Z

Unrelated to the problem above, here is something that is very interesting... The --static binary startup time is nearly twice as fast as the binary that dynamically loads libc

$ time ./bin/ys -e1

real    0m0.011s
user    0m0.005s
sys     0m0.007s
vs
$ time ys -e1

real    0m0.020s
user    0m0.005s
sys     0m0.015s
(the ys binary is using SCI, similar to bb) Also I noticed that the static binary is 53MB and the non-static one is 68MB.
$ ls -lh bin/ys-0.1.80 
-rwxr-xr-x 1 ingy ingy 53M Oct 20 16:36 bin/ys-0.1.80*
$ ls -lh ~/.local/bin/ys-0.1.80 
-rwxr-xr-x 1 ingy ingy 68M Oct 20 11:24 /home/ingy/.local/bin/ys-0.1.80*
that doesn't make sense to me.

Ingy döt Net 2024-10-21T01:19:12.415599Z

Also interesting, I build a native shared library in addition to the native binary executable. I assumed I could static link musl there but that's not the case. See https://github.com/oracle/graal/issues/3053 There are some interesting workarounds in that thread. Something for another day...

2024-10-24T02:42:53.746169Z

Well, dynamically linking probably add some startup time. The file size difference is surprising, but maybe the dynamic linking machinery takes more space than the small amount of things you have to statically link against?

Ingy döt Net 2024-10-24T04:56:48.807939Z

> Well, dynamically linking probably add some startup time. Certainly agree. > The file size difference is surprising, but maybe the dynamic linking machinery takes more space than the small amount of things you have to statically link against? I don't think that's it. 15MB is a lot. Earlier this year @borkdude helped me reduce the binary size a bunch with some tricks he did for babashka. See https://github.com/babashka/babashka/tree/master/src/aaaa_this_has_to_be_first. A few months later my binary size grew unexpectedly (by 15MB I just checked). It's been on my list to investigate but hasn't been important enough for me to do it yet. I'm (totally) guessing that this did something to reverse that.