LLDB and attach failed while debugging JNI code
You may have encountered following issue while attaching to JVM
error: process exited with status -1 (attach failed ...
You can easily reproduce this issue following way
> export JAVA_HOME=~/opt/java/jdk-18.jdk/Contents/Home/ > lldb $JAVA_HOME/bin/java (lldb) target create "~/opt/java/jdk-18.jdk/Contents/Home//bin/java" Current executable set to '~/opt/java/jdk-18.jdk/Contents/Home/bin/java' (x86_64). (lldb) run error: process exited with status -1 (attach failed (Not allowed to attach to process. Look in the console messages (Console.app), near the debugserver entries, when the attach failed. The subsystem that denied the attach permission will likely have logged an informative message about why it was denied.)) (lldb)
You can fix it. It’s just a matter of few steps
1. Create code signing certificate
First of all, you need signing certificate that can sign code. Create one using Keychain Access.
Applications -> Utilities -> Keychain Access.app
once started, follow these steps:
– Keychain Access -> Certificate Assistant -> Create a Certificate…
– set Name to jvm-debugger
– select Let me override defaults -> Continue
– make sure to select Code Signing
– create certificate inside System Keychain
2. Make sure the certificate is trusted
Select the certificate and double click it
Make sure to select Trust to Always Trust.
Note! – Restart macOS!
3. Get current entitlements of java
> codesign -d --entitlements :- $JAVA_HOME/bin/java 2>/dev/null \ | XMLLINT_INDENT=" " xmllint -format -recover -
you will get something like this
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "https://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>com.apple.security.cs.debugger</key> <true/> <key>com.apple.security.cs.allow-jit</key> <true/> <key>com.apple.security.device.audio-input</key> <true/> <key>com.apple.security.cs.disable-library-validation</key> <true/> <key>com.apple.security.cs.allow-dyld-environment-variables</key> <true/> <key>com.apple.security.cs.allow-unsigned-executable-memory</key> <true/> </dict> </plist>
you can save this XML inside jvm.xml
4. Add com.apple.security.get-task-allow entitlement to the list
You want to merge original file (one that you have gotten in previous step) with this one
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>com.apple.security.get-task-allow</key> <true/> </dict> </plist>
That’s what you want to have – debugger.xml
5. sign Java with newly created certificate and new entitlements
> sudo codesign --sign "jvm-debugger" -f --timestamp --options=runtime \ --entitlements ./debugger.xml $JAVA_HOME/bin/java
6. Test whether it works as expected
> lldb $JAVA_HOME/bin/java (lldb) target create "~/opt/java/jdk-18.jdk/Contents/Home//bin/java" Current executable set to '~/opt/java/jdk-18.jdk/Contents/Home/bin/java' (x86_64). (lldb) breakpoint set -n main Breakpoint 1: 22 locations. (lldb) run Process 5511 launched: '~/opt/java/jdk-18.jdk/Contents/Home/bin/java' (x86_64) Process 5511 stopped * thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1 frame #0: 0x0000000100003a80 java`main java`main: -> 0x100003a80 <+0>: pushq %rbp 0x100003a81 <+1>: movq %rsp, %rbp 0x100003a84 <+4>: pushq %r15 0x100003a86 <+6>: pushq %r14 Target 0: (java) stopped. (lldb) process handle --pass true --stop false --notify true SIGSEGV NAME PASS STOP NOTIFY =========== ===== ===== ====== SIGSEGV true false true (lldb) continue Process 5511 resuming Process 5511 stopped and restarted: thread 3 received signal: SIGSEGV Usage: java [options] <mainclass> [args...] (to execute a class) or java [options] -jar <jarfile> [args...] (to execute a jar file) or java [options] -m <module>[/<mainclass>] [args...] java [options] --module <module>[/<mainclass>] [args...] (to execute the main class in a module) or java [options] <sourcefile> [args] (to execute a single source-file program) Arguments following the main class, source file, -jar <jarfile>, -m or --module <module>/<mainclass> are passed as the arguments to main class. ... ... Process 5511 exited with status = 1 (0x00000001) (lldb)