[GH-ISSUE #2785] [Bug] Ghidra doctor passes but analysis fails when the JDK runs as x86_64 under Rosetta on Apple silicon #997

Closed
opened 2026-10-15 18:30:13 +00:00 by bsakaguchi · 0 comments
Owner

Originally created by @dogskip on GitHub (Oct 13, 2026).
Original GitHub issue: https://github.com/morluto/rea/issues/2785

Before submitting

  • I searched the open and closed issues for a related report.
  • I removed credentials, tokens, private paths, and sensitive target data.

Related but not duplicates: #1994, #2112 and #1870 document how to build the macOS decompiler; none covers a JVM whose architecture differs from Node's.

Area

Providers (Ghidra), rea doctor

Observed behavior

On Apple silicon, if the JDK that Ghidra runs on is an x86_64 build under Rosetta 2 and the decompiler was built for mac_arm_64, rea doctor --provider ghidra passes every Ghidra check, but every Ghidra analysis fails with execution_failure.

Doctor (healthy: true for the requested scope; environment_healthy is false only because of unrelated client registrations and other providers):

ghidra-architecture       ok  arm64
ghidra-native_decompiler  ok  .../Decompiler/build/os/mac_arm_64/decompile reports mach-o arm64, which matches darwin/arm64
ghidra-java               ok  21.0.10; 64-bit; JDK; /Library/Java/JavaVirtualMachines/temurin-21.jdk/Contents/Home; accepted a 64-bit full JDK 21 or newer

Analysis on main (6.4.0 differs only in the message text):

code: execution_failure
message: Analysis could not complete. Run `rea doctor` and review the reported details; repeating the unchanged request is not expected to succeed.

So the error message sends the user to rea doctor, and doctor reports nothing wrong.

The Ghidra output kept in details.diagnostics shows the cause:

ERROR os/mac_x86_64/decompile does not exist (see GettingStarted.md, 'Building Native Components') (DecompileProcessFactory)
ERROR REPORT SCRIPT ERROR:  (HeadlessAnalyzer) java.lang.IllegalStateException: Ghidra decompiler could not open the imported Program

Ghidra selects the native directory from the JVM's os.arch (ghidra.framework.Architecture in Generic.jar reads that property), which is x86_64 under Rosetta. Doctor's architecture and decompiler checks use Node's process.arch (arm64). On main, probeJava in src/ghidra/GhidraInstallation.ts reads java.version, java.home, java.vm.name and sun.arch.data.model, but not os.arch, so this mismatch is never detected.

Reproduction

  1. Apple silicon Mac. Ghidra 12.1.4 PUBLIC, with only Ghidra/Features/Decompiler/build/os/mac_arm_64/decompile built locally (the release ships no macOS decompiler). Set GHIDRA_INSTALL_DIR.
  2. Make an x86_64 JDK 21 the java that Ghidra uses: leave JAVA_HOME unset with x86_64 Temurin 21 as the system default. java -XshowSettings:properties -version then prints os.arch = x86_64.
  3. rea doctor --provider ghidra --json returns healthy: true.
  4. rea function <arm64 Mach-O> <function> --json returns execution_failure.
  5. Change only JAVA_HOME, pointing it at an arm64 JDK 21 (Homebrew openjdk@21). The same command then returns Evidence.

Both arms were run under env -i with an identical environment except JAVA_HOME, three times each, on both versions:

REA JDK doctor healthy function result
6.4.0 (npm) Temurin 21.0.10 x86_64 (Rosetta) true 3/3 execution_failure 3/3
6.4.0 (npm) openjdk@21 arm64 true 3/3 Evidence 3/3
main fb28ec153 (npm ci --ignore-scripts && npm run compile) Temurin 21.0.10 x86_64 (Rosetta) true 3/3 execution_failure 3/3
main fb28ec153 openjdk@21 arm64 true 3/3 Evidence 3/3

Expected behavior

Doctor should report the Ghidra provider as unavailable when the JVM's os.arch maps to a different native directory from the one it validated, with a remediation such as "point JAVA_HOME at an arm64 JDK". One possible fix: have probeJava also read os.arch, and have ghidra-java (or ghidra-native_decompiler) check the decompiler for the JVM's architecture rather than for process.arch.

Impact and scope

This affects Apple silicon hosts where the JDK Ghidra resolves is x86_64 and the decompiler was built for arm64 (for example, an x86_64 Temurin left as the default java). I verified only that combination. The reverse mismatch was not tested.

REA version

rea-agents 6.4.0 (npm) and main at fb28ec153, both reproduced.

Runtime and platform

macOS 27.2 (arm64), Node.js 26.0.0, Ghidra 12.1.4 PUBLIC. JDKs: Temurin 21.0.10 x86_64 (via Rosetta 2) and Homebrew openjdk@21 (arm64).

Target

Any arm64 Mach-O. Reproduced with a small C test program compiled locally.

Originally created by @dogskip on GitHub (Oct 13, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/2785 ### Before submitting - [x] I searched the open and closed issues for a related report. - [x] I removed credentials, tokens, private paths, and sensitive target data. Related but not duplicates: #1994, #2112 and #1870 document how to build the macOS decompiler; none covers a JVM whose architecture differs from Node's. ### Area Providers (Ghidra), `rea doctor` ### Observed behavior On Apple silicon, if the JDK that Ghidra runs on is an x86_64 build under Rosetta 2 and the decompiler was built for `mac_arm_64`, `rea doctor --provider ghidra` passes every Ghidra check, but every Ghidra analysis fails with `execution_failure`. Doctor (`healthy: true` for the requested scope; `environment_healthy` is false only because of unrelated client registrations and other providers): ``` ghidra-architecture ok arm64 ghidra-native_decompiler ok .../Decompiler/build/os/mac_arm_64/decompile reports mach-o arm64, which matches darwin/arm64 ghidra-java ok 21.0.10; 64-bit; JDK; /Library/Java/JavaVirtualMachines/temurin-21.jdk/Contents/Home; accepted a 64-bit full JDK 21 or newer ``` Analysis on main (6.4.0 differs only in the message text): ``` code: execution_failure message: Analysis could not complete. Run `rea doctor` and review the reported details; repeating the unchanged request is not expected to succeed. ``` So the error message sends the user to `rea doctor`, and doctor reports nothing wrong. The Ghidra output kept in `details.diagnostics` shows the cause: ``` ERROR os/mac_x86_64/decompile does not exist (see GettingStarted.md, 'Building Native Components') (DecompileProcessFactory) ERROR REPORT SCRIPT ERROR: (HeadlessAnalyzer) java.lang.IllegalStateException: Ghidra decompiler could not open the imported Program ``` Ghidra selects the native directory from the JVM's `os.arch` (`ghidra.framework.Architecture` in `Generic.jar` reads that property), which is `x86_64` under Rosetta. Doctor's architecture and decompiler checks use Node's `process.arch` (`arm64`). On main, `probeJava` in `src/ghidra/GhidraInstallation.ts` reads `java.version`, `java.home`, `java.vm.name` and `sun.arch.data.model`, but not `os.arch`, so this mismatch is never detected. ### Reproduction 1. Apple silicon Mac. Ghidra 12.1.4 PUBLIC, with only `Ghidra/Features/Decompiler/build/os/mac_arm_64/decompile` built locally (the release ships no macOS decompiler). Set `GHIDRA_INSTALL_DIR`. 2. Make an x86_64 JDK 21 the `java` that Ghidra uses: leave `JAVA_HOME` unset with x86_64 Temurin 21 as the system default. `java -XshowSettings:properties -version` then prints `os.arch = x86_64`. 3. `rea doctor --provider ghidra --json` returns `healthy: true`. 4. `rea function <arm64 Mach-O> <function> --json` returns `execution_failure`. 5. Change only `JAVA_HOME`, pointing it at an arm64 JDK 21 (Homebrew `openjdk@21`). The same command then returns Evidence. Both arms were run under `env -i` with an identical environment except `JAVA_HOME`, three times each, on both versions: | REA | JDK | doctor `healthy` | `function` result | | --- | --- | --- | --- | | 6.4.0 (npm) | Temurin 21.0.10 x86_64 (Rosetta) | true 3/3 | `execution_failure` 3/3 | | 6.4.0 (npm) | openjdk@21 arm64 | true 3/3 | Evidence 3/3 | | main fb28ec153 (`npm ci --ignore-scripts && npm run compile`) | Temurin 21.0.10 x86_64 (Rosetta) | true 3/3 | `execution_failure` 3/3 | | main fb28ec153 | openjdk@21 arm64 | true 3/3 | Evidence 3/3 | ### Expected behavior Doctor should report the Ghidra provider as unavailable when the JVM's `os.arch` maps to a different native directory from the one it validated, with a remediation such as "point JAVA_HOME at an arm64 JDK". One possible fix: have `probeJava` also read `os.arch`, and have `ghidra-java` (or `ghidra-native_decompiler`) check the decompiler for the JVM's architecture rather than for `process.arch`. ### Impact and scope This affects Apple silicon hosts where the JDK Ghidra resolves is x86_64 and the decompiler was built for arm64 (for example, an x86_64 Temurin left as the default `java`). I verified only that combination. The reverse mismatch was not tested. ### REA version rea-agents 6.4.0 (npm) and main at fb28ec153, both reproduced. ### Runtime and platform macOS 27.2 (arm64), Node.js 26.0.0, Ghidra 12.1.4 PUBLIC. JDKs: Temurin 21.0.10 x86_64 (via Rosetta 2) and Homebrew openjdk@21 (arm64). ### Target Any arm64 Mach-O. Reproduced with a small C test program compiled locally.
bsakaguchi 2026-10-15 18:30:13 +00:00
  • closed this issue
  • added the
    bug
    label
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
morluto/rea#997
No description provided.