Skip to content

Commit aab7be5

Browse files
fix: MetalRT segfault crashes, missing dylib packaging, and M5+ forward-compatibility (#19)
* refactor: remove all benchmarking code and metrics except TTFA Remove the entire benchmark subsystem and inline performance metrics (tok/s, TTFT, prefill, decode, STT ms, TTS ms) while preserving TTFA (Time To First Audio) tracking throughout the pipeline. Deleted: - src/bench/ directory (benchmark.h, benchmark.cpp) - rcli bench CLI command and all bench arguments - rcli metalrt bench subcommand - [B] bench panel and [V] verbose metrics toggle in TUI - API functions: rcli_benchmark, rcli_run_full_benchmark, rcli_get_last_llm_perf, rcli_get_last_llm_perf_extended, rcli_get_last_tts_perf, rcli_get_last_stt_perf - print_llm_perf, print_tts_perf, print_stt_perf helpers Preserved: - TTFA tracking and display in TUI models panel - rcli_get_context_info (context window gauge) - Voice bench test (TTFA-only) in test_pipeline.cpp * fix: MetalRT segfault on M3/M4, missing dylib packaging, null engine fallback Addresses three distinct crash scenarios from issue #5: 1. MetalRT GPU crash guard now covers verification inference. The crash guard (SIGSEGV handler + breadcrumb) previously only protected metalrt_.init() but the actual Metal GPU compute can segfault on certain M3/M4 hardware. Now a verification generate runs inside the protected section — if it crashes, the breadcrumb persists and next launch falls back to llama.cpp. Also removed the unprotected warm-up call from main.cpp. 2. package.sh now fails if libonnxruntime is missing instead of silently producing an incomplete tarball. Added a recursive fallback search path and post-copy validation that checks every @rpath dylib the binary references is present in lib/. 3. Defensive null checks: when MetalRT verification fails, attempts late llama.cpp init as fallback. Added null-safety guard in rcli_process_command MetalRT path. Final validation catches impossible states (MetalRT flagged active but not initialized). Closes #5 * fix: future-proof Metal 3.1 chip detection for M5+ support Switch gpu_supports_metal31() from an allowlist (M3, M4) to a denylist (M1, M2) so future Apple Silicon generations are automatically supported without requiring a code change each generation. --------- Co-authored-by: AmanSwar <aman.swar001@gmail.com>
1 parent f9d5266 commit aab7be5

14 files changed

Lines changed: 139 additions & 1980 deletions

File tree

CMakeLists.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,6 @@ add_library(rcli STATIC
104104
src/pipeline/orchestrator.cpp
105105
src/pipeline/sentence_detector.cpp
106106
src/tools/tool_engine.cpp
107-
src/bench/benchmark.cpp
108107

109108
# --- RAG retrieval engine ---
110109
src/engines/embedding_engine.cpp

Formula/rcli.rb

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,6 @@ def caveats
4040
rcli models # manage all AI models (LLM, STT, TTS)
4141
rcli cleanup # remove unused models to free disk space
4242
43-
Benchmarks:
44-
rcli bench # run all benchmarks (STT, LLM, TTS, E2E)
4543
EOS
4644
end
4745

scripts/package.sh

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,13 @@ if [ -z "$ONNX_DYLIB" ]; then
4040
ONNX_DYLIB=$(find "$BUILD_DIR/_deps/onnxruntime-src/lib" -name "libonnxruntime.*.dylib" ! -name "libonnxruntime.dylib" 2>/dev/null | head -1)
4141
fi
4242
if [ -z "$ONNX_DYLIB" ]; then
43-
echo " WARNING: Could not find versioned libonnxruntime dylib"
43+
ONNX_DYLIB=$(find "$BUILD_DIR" -name "libonnxruntime.*.dylib" ! -name "libonnxruntime.dylib" 2>/dev/null | head -1)
44+
fi
45+
if [ -z "$ONNX_DYLIB" ]; then
46+
echo " ERROR: Could not find versioned libonnxruntime dylib anywhere in $BUILD_DIR"
47+
echo " Searched: _deps/onnxruntime-src/lib and recursive fallback"
48+
echo " The packaged binary will fail with dyld errors without this library."
49+
exit 1
4450
fi
4551
DYLIBS+=("$ONNX_DYLIB")
4652

@@ -59,6 +65,35 @@ if [ ! -f "$DIST_DIR/lib/libonnxruntime.dylib" ] && [ -f "$DIST_DIR/lib/$ONNX_BA
5965
(cd "$DIST_DIR/lib" && ln -sf "$ONNX_BASENAME" libonnxruntime.dylib)
6066
fi
6167

68+
# --- Validate all required dylibs are present ---
69+
echo ""
70+
echo "Validating packaged dylibs..."
71+
REQUIRED_LIBS=(libllama libggml libsherpa-onnx-c-api libonnxruntime)
72+
MISSING=0
73+
for req in "${REQUIRED_LIBS[@]}"; do
74+
if ! ls "$DIST_DIR/lib/"${req}* 1>/dev/null 2>&1; then
75+
echo " ERROR: Required library missing: $req"
76+
MISSING=1
77+
fi
78+
done
79+
80+
# Verify the binary can find its dylibs via otool
81+
NEEDED=$(otool -L "$DIST_DIR/bin/rcli" | grep '@rpath' | awk '{print $1}' | sed 's|@rpath/||')
82+
for lib in $NEEDED; do
83+
if [ ! -f "$DIST_DIR/lib/$lib" ] && [ ! -L "$DIST_DIR/lib/$lib" ]; then
84+
echo " ERROR: Binary references @rpath/$lib but it's not in lib/"
85+
MISSING=1
86+
fi
87+
done
88+
89+
if [ "$MISSING" -ne 0 ]; then
90+
echo ""
91+
echo " Package is incomplete — missing required shared libraries."
92+
echo " The binary will crash with dyld errors on user machines."
93+
exit 1
94+
fi
95+
echo " All required dylibs present."
96+
6297
echo ""
6398
echo "Fixing rpaths..."
6499

0 commit comments

Comments
 (0)