Skip to content

Commit a611ae1

Browse files
committed
Debug workflow: drop duplicate --force-rerun (harness adds it); trace real test binary
1 parent 3a0e91f commit a611ae1

2 files changed

Lines changed: 33 additions & 54 deletions

File tree

.github/debug_so.sh

Lines changed: 32 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
#!/usr/bin/env bash
22
# Automated diagnostic for the stack-overflow detection miscompilation.
33
# Runs in CI on failure; everything is printed to the job log.
4-
# Compiletest deletes the run-pass exe, so we compile our own repro (which
5-
# matches the failing tests) and trace it.
64
set +e
75

86
SYSROOT="$PWD/build/build_sysroot/sysroot"
@@ -17,60 +15,25 @@ uname -a
1715
ldd --version 2>/dev/null | head -1
1816
LIB=$(ls "$STDLIB"/libstd*.so 2>/dev/null | head -1)
1917
echo "libstd.so: $LIB size=$(stat -c%s "$LIB" 2>/dev/null)"
20-
echo "backend: $BACKEND"
21-
echo "rustc: $RUSTC"
2218

23-
echo "===================== BUILD REPRO ====================="
24-
D=$(mktemp -d)
25-
cat > "$D/repro.rs" <<'RS'
26-
use std::hint::black_box;
27-
use std::mem::MaybeUninit;
28-
use std::thread;
29-
use std::env;
30-
#[allow(unconditional_recursion)]
31-
fn recurse(a: &MaybeUninit<[u64; 1024]>) {
32-
black_box(a.as_ptr() as u64);
33-
let l: MaybeUninit<[u64; 1024]> = MaybeUninit::uninit();
34-
recurse(&l);
35-
}
36-
fn overflow_recurse() { recurse(&MaybeUninit::uninit()); }
37-
fn overflow_frame() {
38-
const S: usize = 512 * 1024;
39-
thread::Builder::new().stack_size(S).spawn(|| {
40-
let l: MaybeUninit<[u8; 2 * S]> = MaybeUninit::uninit();
41-
black_box(l.as_ptr() as u64);
42-
}).unwrap().join().unwrap();
43-
}
44-
fn silent() { let b = [0u8; 1000]; black_box(b); silent(); }
45-
fn main() {
46-
match env::args().nth(1).as_deref() {
47-
Some("child-recurse") => { thread::spawn(overflow_recurse).join().unwrap(); }
48-
Some("child-frame") => overflow_frame(),
49-
Some("silent-thread") => { thread::Builder::new().name("ferris".into())
50-
.spawn(silent).unwrap().join().ok(); }
51-
_ => panic!("need arg"),
52-
}
53-
}
54-
RS
55-
"$RUSTC" -Zcodegen-backend="$BACKEND" --sysroot "$SYSROOT" -Cprefer-dynamic -g -o "$D/a" "$D/repro.rs"
56-
echo "compiled repro: $(ls -l "$D/a" 2>/dev/null)"
57-
58-
debug_one() {
59-
local ARG="$1"
19+
# $1 = binary path, $2 = arg (the subprocess mode that overflows)
20+
debug_bin() {
21+
local BIN="$1" ARG="$2"
22+
[ -z "$BIN" ] || [ ! -x "$BIN" ] && { echo "SKIP (no binary): $BIN"; return; }
6023
echo ""
6124
echo "############################################################"
62-
echo "# DEBUG repro $ARG"
25+
echo "# DEBUG $BIN $ARG"
6326
echo "############################################################"
6427

6528
echo "----- reproduce (139=SIGSEGV/undetected-BUG, 134=SIGABRT/detected-ok) -----"
66-
"$D/a" "$ARG"; echo "exit=$?"
29+
"$BIN" "$ARG"; echo "exit=$?"
6730

6831
echo "----- strace: clone + sigaltstack per thread (does the SPAWNED thread set up its altstack?) -----"
69-
strace -f -e trace=clone,clone3,sigaltstack,rt_sigaction "$D/a" "$ARG" 2>"$D/strace.txt"
70-
grep -nE "clone|sigaltstack|rt_sigaction\((SIGSEGV|SIGBUS)" "$D/strace.txt"
71-
echo "sigaltstack total: $(grep -c 'sigaltstack(' "$D/strace.txt") clone total: $(grep -cE 'clone[3]?\(' "$D/strace.txt")"
32+
strace -f -e trace=clone,clone3,sigaltstack,rt_sigaction "$BIN" "$ARG" 2>/tmp/strace.txt
33+
grep -nE "clone|sigaltstack|rt_sigaction\((SIGSEGV|SIGBUS)" /tmp/strace.txt
34+
echo "sigaltstack total: $(grep -c 'sigaltstack(' /tmp/strace.txt) clone total: $(grep -cE 'clone[3]?\(' /tmp/strace.txt)"
7235

73-
echo "----- gdb: is make_handler / set_current_info reached by the SPAWNED thread? + NEED_ALTSTACK -----"
36+
echo "----- gdb: is make_handler / set_current_info reached by the SPAWNED thread? -----"
7437
gdb -q -batch -nx \
7538
-ex 'set pagination off' -ex 'set confirm off' \
7639
-ex 'rbreak stack_overflow.*imp.*make_handler' \
@@ -82,13 +45,30 @@ debug_one() {
8245
-ex 'printf "== HIT#4 thread=%d ==\n", $_thread' -ex 'bt 3' -ex 'continue' \
8346
-ex 'printf "== HIT#5 thread=%d ==\n", $_thread' -ex 'bt 3' -ex 'continue' \
8447
-ex 'printf "== end ==\n"' -ex 'info program' \
85-
--args "$D/a" "$ARG" 2>&1 \
86-
| grep -vE "Missing separate|Download failed|Reading symbols|warning: File" | head -150
48+
--args "$BIN" "$ARG" 2>&1 \
49+
| grep -vE "Missing separate|Download failed|Reading symbols|warning: File" | head -140
8750
}
8851

89-
debug_one "silent-thread"
90-
debug_one "child-recurse"
91-
debug_one "child-frame"
52+
echo "===================== REAL COMPILETEST BINARIES ====================="
53+
OO=$(find build/rust -type f -path '*out-of-stack/a' 2>/dev/null | head -1)
54+
SP=$(find build/rust -type f -path '*stack-probes*/a' 2>/dev/null | head -1)
55+
echo "out-of-stack: ${OO:-<none>}"
56+
echo "stack-probes: ${SP:-<none>}"
57+
debug_bin "$OO" "silent-thread"
58+
debug_bin "$SP" "child-recurse"
59+
debug_bin "$SP" "child-frame"
60+
61+
echo ""
62+
echo "===================== COMPARISON: freshly-built minimal repro ====================="
63+
D=$(mktemp -d)
64+
cat > "$D/repro.rs" <<'RS'
65+
use std::hint::black_box;
66+
use std::thread::Builder;
67+
fn silent() { let b = [0u8; 1000]; black_box(b); silent(); }
68+
fn main() { Builder::new().name("ferris".into()).spawn(silent).unwrap().join().ok(); }
69+
RS
70+
"$RUSTC" -Zcodegen-backend="$BACKEND" --sysroot "$SYSROOT" -Cprefer-dynamic -o "$D/a" "$D/repro.rs" 2>/dev/null
71+
debug_bin "$D/a" ""
9272

9373
echo ""
9474
echo "===================== OBJDUMP make_handler ====================="

.github/workflows/debug-so.yml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,7 @@ jobs:
5555
run: |
5656
./y.sh test --release --run-ui-tests -- \
5757
tests/ui/runtime/out-of-stack.rs \
58-
tests/ui/abi/stack-probes.rs \
59-
--force-rerun
58+
tests/ui/abi/stack-probes.rs
6059
6160
- name: Automated debug dump
6261
if: ${{ failure() }}

0 commit comments

Comments
 (0)