Skip to content

Commit 13b5ed9

Browse files
committed
Add debuglink tests
1 parent 9c5a666 commit 13b5ed9

File tree

7 files changed

+157
-2
lines changed

7 files changed

+157
-2
lines changed

.github/workflows/main.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,10 @@ jobs:
102102
env:
103103
RUSTFLAGS: "-C split-debuginfo=packed -Zunstable-options"
104104

105+
# Test that separate debug info works
106+
- run: ./ci/debuglink-docker.sh
107+
if: contains(matrix.os, 'ubuntu')
108+
105109
# Test that including as a submodule will still work
106110
- run: cargo build --manifest-path crates/as-if-std/Cargo.toml
107111

Cargo.toml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,12 @@ edition = "2018"
1717

1818
[workspace]
1919
members = ['crates/cpp_smoke_test', 'crates/as-if-std']
20-
exclude = ['crates/without_debuginfo', 'crates/macos_frames_test', 'crates/line-tables-only']
20+
exclude = [
21+
'crates/without_debuginfo',
22+
'crates/macos_frames_test',
23+
'crates/line-tables-only',
24+
'crates/debuglink',
25+
]
2126

2227
[dependencies]
2328
cfg-if = "1.0"

ci/debuglink-docker.sh

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# Small script to run debuglink tests inside a docker image.
2+
# Creates a writable mount on /usr/lib/debug.
3+
4+
set -ex
5+
6+
run() {
7+
docker build -t backtrace -f ci/docker/$1/Dockerfile ci
8+
mkdir -p target
9+
mkdir -p debug
10+
docker run \
11+
--user `id -u`:`id -g` \
12+
--rm \
13+
--init \
14+
--volume $(dirname $(dirname `which cargo`)):/cargo \
15+
--env CARGO_HOME=/cargo \
16+
--volume `rustc --print sysroot`:/rust:ro \
17+
--env TARGET=$1 \
18+
--volume `pwd`:/checkout:ro \
19+
--volume `pwd`/target:/checkout/crates/debuglink/target \
20+
--workdir /checkout \
21+
--volume `pwd`/debug:/usr/lib/debug \
22+
--privileged \
23+
--env RUSTFLAGS \
24+
backtrace \
25+
bash \
26+
-c 'PATH=$PATH:/rust/bin exec ci/debuglink.sh'
27+
}
28+
29+
run x86_64-unknown-linux-gnu

ci/debuglink.sh

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
#!/bin/bash
2+
3+
# Debuglink tests.
4+
# We build crates/debuglink and then move its debuginfo around
5+
# and test that it can still find the debuginfo.
6+
7+
set -ex
8+
9+
cratedir=`pwd`/crates/debuglink
10+
exefile=crates/debuglink/target/debug/debuglink
11+
12+
# Baseline; no separate debug
13+
cargo build --manifest-path crates/debuglink/Cargo.toml
14+
$exefile $cratedir
15+
16+
# Separate debug in same dir
17+
debugfile1=`dirname $exefile`/debuglink.debug
18+
objcopy --only-keep-debug $exefile $debugfile1
19+
strip -g $exefile
20+
(cd `dirname $exefile` && objcopy --add-gnu-debuglink=debuglink.debug debuglink)
21+
$exefile $cratedir
22+
23+
# Separate debug in .debug subdir
24+
debugfile2=`dirname $exefile`/.debug/debuglink.debug
25+
mkdir -p `dirname $debugfile2`
26+
mv $debugfile1 $debugfile2
27+
$exefile $cratedir
28+
29+
# Separate debug in /usr/lib/debug subdir
30+
debugfile3="/usr/lib/debug/$cratedir/target/debug/debuglink.debug"
31+
mkdir -p `dirname $debugfile3`
32+
mv $debugfile2 $debugfile3
33+
$exefile $cratedir
34+
35+
# Separate debug in /usr/lib/debug/.build-id subdir
36+
id=`readelf -n $exefile | grep '^ Build ID: [0-9a-f]' | cut -b 15-`
37+
idfile="/usr/lib/debug/.build-id/${id:0:2}/${id:2}.debug"
38+
mkdir -p `dirname $idfile`
39+
mv $debugfile3 $idfile
40+
$exefile $cratedir
41+
42+
# Replace idfile with a symlink (this is the usual arrangement)
43+
mv $idfile $debugfile3
44+
ln -s $debugfile3 $idfile
45+
$exefile $cratedir
46+
47+
# Supplementary object file using relative path
48+
dwzfile="/usr/lib/debug/.dwz/debuglink.debug"
49+
mkdir -p `dirname $dwzfile`
50+
cp $debugfile3 $debugfile3.copy
51+
dwz -m $dwzfile -rh $debugfile3 $debugfile3.copy
52+
rm $debugfile3.copy
53+
$exefile $cratedir
54+
55+
# Supplementary object file using build ID
56+
dwzid=`readelf -n $dwzfile | grep '^ Build ID: [0-9a-f]' | cut -b 15-`
57+
dwzidfile="/usr/lib/debug/.build-id/${dwzid:0:2}/${dwzid:2}.debug"
58+
mkdir -p `dirname $dwzidfile`
59+
mv $dwzfile $dwzidfile
60+
$exefile $cratedir
61+
mv $dwzidfile $dwzfile
62+
63+
# Missing debug should fail
64+
mv $debugfile3 $debugfile3.tmp
65+
! $exefile $cratedir
66+
mv $debugfile3.tmp $debugfile3
67+
68+
# Missing dwz should fail
69+
mv $dwzfile $dwzfile.tmp
70+
! $exefile $cratedir
71+
mv $dwzfile.tmp $dwzfile
72+
73+
# Cleanup
74+
rm $idfile $debugfile3 $dwzfile
75+
echo Success

ci/docker/x86_64-unknown-linux-gnu/Dockerfile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,5 @@ FROM ubuntu:20.04
22
RUN apt-get update && apt-get install -y --no-install-recommends \
33
gcc \
44
libc6-dev \
5-
ca-certificates
5+
ca-certificates \
6+
dwz

crates/debuglink/Cargo.toml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
[package]
2+
name = "debuglink"
3+
version = "0.1.0"
4+
edition = "2018"
5+
6+
[dependencies]
7+
backtrace = { path = "../.." }

crates/debuglink/src/main.rs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// Test that the debuginfo is being found by checking that the
2+
// backtrace contains `main` and that the source filename uses
3+
// the path given in the command line arguments.
4+
//
5+
// For dwz tests, this assumes that the path string will be moved into
6+
// the dwz file.
7+
fn main() {
8+
let crate_dir = std::env::args().skip(1).next().unwrap();
9+
let expect = std::path::Path::new(&crate_dir).join("src/main.rs");
10+
11+
let bt = backtrace::Backtrace::new();
12+
println!("{:?}", bt);
13+
14+
let mut found_main = false;
15+
16+
for frame in bt.frames() {
17+
let symbols = frame.symbols();
18+
if symbols.is_empty() {
19+
continue;
20+
}
21+
22+
if let Some(name) = symbols[0].name() {
23+
let name = format!("{:#}", name);
24+
if name == "debuglink::main" {
25+
found_main = true;
26+
let filename = symbols[0].filename().unwrap();
27+
assert_eq!(filename, expect);
28+
break;
29+
}
30+
}
31+
}
32+
33+
assert!(found_main);
34+
}

0 commit comments

Comments
 (0)