Skip to content

Commit 9af8b24

Browse files
Attempt to catch crashes with backtrace script
1 parent 2092da0 commit 9af8b24

3 files changed

Lines changed: 105 additions & 4 deletions

File tree

‎.github/workflows/ci.yml‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ jobs:
5757
- client-sdk-rust/**
5858
- cmake/**
5959
- .token_helpers/**
60+
- scripts/run-with-backtrace.sh
6061
- CMakeLists.txt
6162
- CMakePresets.json
6263
- build*

‎.github/workflows/tests.yml‎

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ permissions:
117117

118118
env:
119119
CARGO_TERM_COLOR: always
120+
RUST_BACKTRACE: full
120121
# Disable Cargo incremental artifacts. The Rust FFI is built once per
121122
# submodule SHA and cached whole (see the cargo target cache below), so
122123
# incremental dirs add nothing but bloat the cached target/ directory and
@@ -220,7 +221,7 @@ jobs:
220221
libabsl-dev \
221222
libcurl4-openssl-dev \
222223
libwayland-dev libdecor-0-dev \
223-
jq
224+
gdb jq
224225
225226
- name: Install deps (macOS)
226227
if: runner.os == 'macOS'
@@ -285,6 +286,16 @@ jobs:
285286
LLVM_VERSION=$(llvm-config --version | cut -d. -f1)
286287
echo "LIBCLANG_PATH=/usr/lib/llvm-${LLVM_VERSION}/lib" >> "$GITHUB_ENV"
287288
289+
- name: Configure Unix crash diagnostics
290+
if: runner.os != 'Windows'
291+
shell: bash
292+
run: |
293+
echo "LIVEKIT_CRASH_DIAGNOSTICS=1" >> "$GITHUB_ENV"
294+
if [[ "$RUNNER_OS" == "Linux" ]]; then
295+
echo "LIVEKIT_CORE_DIR=${RUNNER_TEMP}" >> "$GITHUB_ENV"
296+
sudo sysctl -w "kernel.core_pattern=${RUNNER_TEMP}/livekit-core.%p"
297+
fi
298+
288299
# ---------- Build (tests on, examples off) ----------
289300
- name: Build tests (Unix)
290301
if: runner.os != 'Windows'
@@ -309,7 +320,8 @@ jobs:
309320
timeout-minutes: ${{ inputs.unit_timeout_minutes }}
310321
shell: bash
311322
run: |
312-
${{ env.BUILD_DIR }}/bin/livekit_unit_tests \
323+
bash scripts/run-with-backtrace.sh \
324+
${{ env.BUILD_DIR }}/bin/livekit_unit_tests \
313325
--gtest_repeat=${{ inputs.unit_repeat }} \
314326
--gtest_brief=1 \
315327
--gtest_output=xml:${{ env.BUILD_DIR }}/unit-test-results.xml
@@ -383,7 +395,8 @@ jobs:
383395
set -euo pipefail
384396
source .token_helpers/set_data_track_test_tokens.bash
385397
# TODO(BOT-477) Temporarily disable platform audio integration tests in CI until instability is resolved
386-
${{ env.BUILD_DIR }}/bin/livekit_integration_tests \
398+
bash scripts/run-with-backtrace.sh \
399+
${{ env.BUILD_DIR }}/bin/livekit_integration_tests \
387400
--gtest_filter='-PlatformAudioIntegrationTest.*' \
388401
--gtest_repeat=${{ inputs.integration_repeat }} \
389402
--gtest_recreate_environments_when_repeating=1 \
@@ -398,7 +411,8 @@ jobs:
398411
run: |
399412
set -euo pipefail
400413
source .token_helpers/set_data_track_test_tokens.bash
401-
${{ env.BUILD_DIR }}/bin/livekit_stress_tests \
414+
bash scripts/run-with-backtrace.sh \
415+
${{ env.BUILD_DIR }}/bin/livekit_stress_tests \
402416
--gtest_repeat=${{ inputs.stress_repeat }} \
403417
--gtest_recreate_environments_when_repeating=1 \
404418
--gtest_output=xml:${{ env.BUILD_DIR }}/stress-test-results.xml

‎scripts/run-with-backtrace.sh‎

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
#!/usr/bin/env bash
2+
#
3+
# Copyright 2026 LiveKit
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
17+
# Runs a command under platform-appropriate crash diagnostics and prints a
18+
# native backtrace if it crashes. Linux core files are inspected with GDB;
19+
# macOS commands run under LLDB. The command's original exit code is preserved.
20+
set -euo pipefail
21+
22+
if (($# == 0)); then
23+
echo "Usage: $0 COMMAND [ARG ...]" >&2
24+
exit 2
25+
fi
26+
27+
platform="$(uname -s)"
28+
29+
# Keep this wrapper transparent on Windows and in unconfigured environments.
30+
if [[ "${platform}" != "Linux" && "${platform}" != "Darwin" ]] || [[ "${LIVEKIT_CRASH_DIAGNOSTICS:-}" != "1" ]]; then
31+
exec "$@"
32+
fi
33+
34+
if [[ "${platform}" == "Darwin" ]]; then
35+
set +e
36+
lldb --batch \
37+
-o run \
38+
-o 'script import lldb, os; os._exit(lldb.debugger.GetSelectedTarget().GetProcess().GetExitStatus())' \
39+
-k "process status" \
40+
-k "thread backtrace all" \
41+
-k 'script import lldb, os; t = lldb.debugger.GetSelectedTarget().GetProcess().GetSelectedThread(); os._exit(128 + t.GetStopReasonDataAtIndex(0))' \
42+
-- "$@"
43+
exit_code=$?
44+
set -e
45+
exit "${exit_code}"
46+
fi
47+
48+
if [[ -z "${LIVEKIT_CORE_DIR:-}" ]]; then
49+
echo "LIVEKIT_CORE_DIR must be set when Linux crash diagnostics are enabled." >&2
50+
exit 2
51+
fi
52+
53+
mkdir -p "${LIVEKIT_CORE_DIR}"
54+
rm -f "${LIVEKIT_CORE_DIR}"/livekit-core.*
55+
ulimit -c unlimited
56+
57+
set +e
58+
"$@"
59+
exit_code=$?
60+
set -e
61+
62+
shopt -s nullglob
63+
core_files=("${LIVEKIT_CORE_DIR}"/livekit-core.*)
64+
65+
if ((${#core_files[@]} > 0)); then
66+
for core_file in "${core_files[@]}"; do
67+
if [[ -n "${GITHUB_ACTIONS:-}" ]]; then
68+
echo "::group::Native crash backtrace ($(basename "${core_file}"))"
69+
fi
70+
71+
timeout 120s gdb --batch --quiet \
72+
-ex "set pagination off" \
73+
-ex "info threads" \
74+
-ex "thread apply all backtrace" \
75+
"$1" "${core_file}" || true
76+
77+
if [[ -n "${GITHUB_ACTIONS:-}" ]]; then
78+
echo "::endgroup::"
79+
fi
80+
rm -f "${core_file}"
81+
done
82+
elif ((exit_code >= 128)); then
83+
echo "::warning::Test process exited from a signal (${exit_code}), but no core file was produced."
84+
fi
85+
86+
exit "${exit_code}"

0 commit comments

Comments
 (0)