Docs  /  Guides

Troubleshooting

Common build and runtime issues with Rerius and their solutions.

Repository: https://github.com/ECLS-Studio/rerius


Build Issues#

log2 undefined / linker error#

Symptom: undefined reference to 'log2' or similar during link.

Cause: The entropy module uses log2() from <math.h> which requires -lm on Linux.

Fix: LDFLAGS lives in setup.sh, not the top-level Makefile (which just delegates to setup.sh):

grep LDFLAGS setup.sh   # should include -lm

If it's missing there, that's worth filing as a bug rather than patching locally, since every build would hit this.


open_memstream undeclared / not found#

Symptom: warning: implicit declaration of 'open_memstream' or linker error.

Cause: open_memstream is a POSIX extension. It requires: - Linux: -D_GNU_SOURCE (already set in Makefile) - macOS: -D_DARWIN_C_SOURCE (set automatically in build_js.sh for macOS) - Minimum versions: Linux glibc ≥ 2.10, macOS ≥ 10.13

Fix (macOS):

# Ensure you're on macOS 10.13+
sw_vers -productVersion

Note: setup.sh autodetects its own compiler and doesn't read a CFLAGS_EXTRA environment variable, so make CC=clang CFLAGS_EXTRA=... won't have any effect: if -D_DARWIN_C_SOURCE genuinely isn't being set on macOS, that's a build_js.sh/setup.sh bug worth reporting rather than something to work around with env vars.


node_api.h not found#

Symptom: fatal error: node_api.h: No such file or directory

Fix:

# Debian/Ubuntu
sudo apt install libnode-dev

# Fedora
sudo dnf install nodejs-devel

# Termux - headers bundled with nodejs
pkg install nodejs

# macOS with Homebrew
brew install node
# Headers at: $(brew --prefix)/include/node/

# Or find them manually
node -p "require('path').join(process.execPath,'../../include/node')"

isprint / stdbool undeclared (Clang strict C99)#

Symptom: error: implicit declaration of function 'isprint' or error: unknown type name '_Bool'

Cause: Missing explicit includes in rerius_napi.c.

Fix: <ctype.h> and <stdbool.h> are explicitly included in the current js/src/rerius_napi.c. If you still hit this, make sure you're building from the latest tagged release rather than an old checkout or fork.


auto nested functions (GCC extension rejected by Clang)#

Symptom: error: function definition is not allowed here in src/analysis/decomp.c

Cause: GCC auto nested functions are a non-standard extension, not valid C99.

Fix: The current decomp.c uses static file-scope helpers instead. If you hit this, check you're on the latest release rather than an old checkout or fork.


macOS assembler errors in platform/arm64_bsd.S#

Symptom:

platform/arm64_bsd.S:1:19: error: unexpected token in '.section' directive
.section .note.GNU-stack,"",@progbits

Cause: arm64_bsd.S uses Linux/BSD ELF assembly syntax. macOS uses Mach-O syntax, which platform/arm64_macos.S provides instead.

Fix: build_js.sh should select platform/arm64_macos.S automatically when it detects Darwin as the OS. If you're seeing this error, the OS detection likely picked the wrong stub: check the platform-detection logic in build_js.sh/setup.sh, or file a bug with your uname -a output.


--unresolved-symbols=ignore-all not supported (LLD on Android)#

Symptom: ld: unknown argument '--unresolved-symbols=ignore-all' on Termux.

Cause: Some LLD versions use different flags.

Fix: build_js.sh detects this and falls back automatically. You can also force:

# Try alternate flag
CC=clang LDFLAGS="-Wl,-z,nodefaultlib -lm" bash build_js.sh

make says gmake not found on BSD#

# FreeBSD/OpenBSD/NetBSD
pkg install gmake   # or pkg_add gmake
gmake clean && gmake

dax_guard.h not found#

Symptom: fatal error: dax_guard.h: No such file or directory during compile.

Cause: The fault isolation header introduced in v1.0.0 lives in include/. The compiler needs -I./include to find it. setup.sh includes this in BASE_CFLAGS automatically.

Fix:

# If building manually, add -I./include:
clang -std=c99 -I./include ...

# Verify setup.sh has it:
grep -- "-I./include" setup.sh   # should match

Runtime Issues#

Analysis pass aborted: [!] pass 'X' recovered from fault#

Symptom: stderr shows a yellow warning like:

  [!] pass 'cfg-build' recovered from fault: invalid dax_binary_t

…but analysis continues for other passes.

Cause: This is the fault isolation system (v1.0.0+) working correctly. A pass encountered a structural error in the binary (corrupt section bounds, truncated data, invalid counter) and returned early rather than crashing.

Interpretation: - The binary is likely malformed, packed, or truncated. - The output from the recovered pass is absent or partial; output from all other passes is complete. - This is not a Rerius bug.

If you believe this is a Rerius bug (the pass fails on a valid binary), build with ASan directly (setup.sh doesn't read CFLAGS_EXTRA, so compile by hand: see the source list in BUILDING.md):

clang -std=c99 -D_GNU_SOURCE -O1 -g -fsanitize=address,undefined \
    -I./include -I./include/core -I./include/formats -I./include/arch -I./include/ui \
    src/cli/main.c src/cli/interactive.c src/core/*.c src/formats/*.c src/arch/*.c \
    src/analysis/*.c src/emu/*.c src/util/*.c -lm -o rerius-asan

# -X also enables interactive mode -- close stdin so it exits after the analysis output
./rerius-asan -X ./binary < /dev/null 2>&1 | grep -A2 "recovered from fault"

Then open a bug report with the fault message and binary details.


rerius.node not found after npm install#

Symptom: Error: Rerius native addon not found: .../js/rerius.node

Fix:

# Trigger rebuild
npm run build
# or
npm rebuild
# or from repo root
bash build_js.sh

sections() returns empty array on macOS binary#

Symptom: sections: 0 when analyzing a macOS .app binary or /bin/ls.

Cause: If this happens on the current release, check whether the Mach-O magic constants in your build match what a little-endian CPU actually reads from the file: 0xFEEDFACF should be ARM64 LE (swap=0), not big-endian. See MACHO_SUPPORT.md.

Verify:

node -e "const n=require('rerius'); n.withBinary('/bin/ls', b => console.log('sections:', b.sections().length));"
# Should print: sections: 20+  (not 0)

functions() returns empty on macOS stripped binary#

Symptom: functions: 0 on macOS ARM64 stripped binary.

Expected behavior: the prologue detector recognizes stp x29,x30, paciasp, bti, and sub sp,sp,#N (common on macOS ARM64) and falls back to the section entry point if no prologue is recognized, so functions().length should be ≥ 1 on any binary with a code section. If you're seeing 0 on the current release, that's worth a bug report with the binary's file output: see FUNCTION_DETECTION.md for how detection works and its known limitations.


disasmJson() segfaults (exit code 139)#

Symptom: Node process exits with code 139 when calling bin.disasmJson('.text') on x86-64.

Cause: A struct-layout mismatch between a local typedef in rerius_napi.c and the real x86_insn_t in x86.h would cause this kind of out-of-bounds read. If the layouts are still out of sync in the release you're on, that's a real bug worth reporting with a minimal reproduction.

The fault isolation layer (dax_guard.h) now guards all three disassembly entry points. If a section read would cause a fault, the pass recovers and prints a diagnostic instead of crashing the process.


rda() returns object instead of string#

Symptom: typeof bin.rda('.text') === 'object' (should be 'string').

Expected behavior: rda() should return an empty string "" (not null) when the section isn't found: typeof null === 'object' in JavaScript, which is the likely source of this symptom if you see it. If the current release still returns null here, that's a real bug worth reporting.


Analysis is slow on large binaries (> 10 MB)#

The main bottlenecks (see PERFORMANCE.md for measured numbers on a small binary) are: - dax_xref_build() - single-pass O(instructions), fast in practice - dax_rda_section() - BFS with an O(N) linear visited-set lookup (up to 65,536 entries), which dominates on large binaries with a lot of reachable code

For large binaries in a production service, cache parsed handles keyed by SHA-256:

const cache = new Map();
function getCached(file) {
    const b = rerius.load(file);
    if (cache.has(b.sha256)) { b.close(); return cache.get(b.sha256); }
    cache.set(b.sha256, b);
    return b;
}
// Clean up on exit
process.on('exit', () => cache.forEach(b => b.close()));

Valgrind reports memory errors#

setup.sh doesn't read a CFLAGS_EXTRA variable, so build with ASan directly instead (see the full source list in BUILDING.md):

clang -std=c99 -D_GNU_SOURCE -O1 -g -fsanitize=address,undefined \
    -I./include -I./include/core -I./include/formats -I./include/arch -I./include/ui \
    src/cli/main.c src/cli/interactive.c src/core/*.c src/formats/*.c src/arch/*.c \
    src/analysis/*.c src/emu/*.c src/util/*.c -lm -o rerius-asan
./rerius-asan -x ./binary

ASan will print exact locations of any memory errors. Report findings via SECURITY.md.


AIRE#

Q: AIRE prints nothing / "no significant patterns detected".

AIRE needs upstream analysis data to synthesize. Run with the full pipeline:

./rerius -V -I --poly --aire ./binary

Without -V (IVF), --poly, and -I (emulator), AIRE has no data to interpret and will report nothing significant.

Q: AIRE shows a Memory recall banner for a binary I've never analyzed.

Memory entries are keyed by SHA-256 content hash, not file path. If you received a copy of a binary that was previously analyzed (e.g. from a coworker or CI system that also has .aire_memory in the same working directory), AIRE will match on content. Delete .aire_memory to start fresh.

Q: .aire_memory is growing too large / I want to reset it.

Delete .aire_memory from your working directory. It will be recreated fresh on the next AIRE run. The file holds at most 32 entries (~20 KB); it does not grow unboundedly.

Q: AIRE context block says "general analysis" even though the binary is clearly packed.

AIRE's packer detection requires entropy scan data. Make sure to include -e in your flags:

./rerius -e -V --poly --aire ./binary

Getting Help#

If none of the above solves your issue:

  1. Check existing issues
  2. Include: Rerius version, OS/arch, compiler version, exact error output
  3. Open a bug report

For security vulnerabilities, see SECURITY.md - do not open public issues.

Edit this page on GitHub Source: docs/TROUBLESHOOTING.md · Rerius v1.0.0
On this page
Troubleshooting Build Issues log2 undefined / linker error open_memstream undeclared / not found node_api.h not found isprint / stdbool undeclared (Clang strict C99) auto nested functions (GCC extension rejected by Clang) macOS assembler errors in platform/arm64_bsd.S --unresolved-symbols=ignore-all not supported (LLD on Android) make says gmake not found on BSD dax_guard.h not found Runtime Issues Analysis pass aborted: [!] pass 'X' recovered from fault rerius.node not found after npm install sections() returns empty array on macOS binary functions() returns empty on macOS stripped binary disasmJson() segfaults (exit code 139) rda() returns object instead of string Analysis is slow on large binaries (> 10 MB) Valgrind reports memory errors AIRE Getting Help
ESC
↑↓ navigate openesc close