Skip to content

Commit 5193d1f

Browse files
committed
Add gdb to the build
This optionally adds gdb to the Rust build, allowing gdb to be installed via rustup. This makes it simpler to make debuginfo changes, as gdb updates can now be shipped immediately. If gdb is not checked out, nothing changes. The build is perhaps a bit chatty, as gdb's "make" and "make install" are run each time, even if they do nothing. rust-gdb is modified to prefer the gdb installed by rustup. This is analogous to what was done for rust-lldb. The built gdb requires Python 2.7 as a shared library (other dependencies are statically linked). This is a least-common-denominator Python that is widely available and stable; dynamic linking is used to avoid breaking existing gdb Python code that might load shared libraries that themselves require a dynamic libpython. To avoid problems here, a small wrapper program is used that attemps to dlopen libpython; with failures being reported to the user in an intelligible way. Two of the Linux dist builds are updated to build gdb. More could be added if need be. If gdb is built as part of the build, and if no other gdb was specified in config.toml, then the just-built gdb will be used for debuginfo testing. Closes #34457
1 parent cb84844 commit 5193d1f

File tree

17 files changed

+227
-5
lines changed

17 files changed

+227
-5
lines changed

.gitmodules

+4
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,10 @@
5252
path = src/tools/clang
5353
url = https://github.com/rust-lang-nursery/clang.git
5454
branch = rust-release-80-v2
55+
[submodule "src/tools/gdb"]
56+
path = src/tools/gdb
57+
url = https://github.com/rust-dev-tools/gdb.git
58+
branch = rust-8.2
5559
[submodule "src/doc/rustc-guide"]
5660
path = src/doc/rustc-guide
5761
url = https://github.com/rust-lang/rustc-guide.git

config.toml.example

+3
Original file line numberDiff line numberDiff line change
@@ -383,6 +383,9 @@
383383
# This is only built if LLVM is also being built.
384384
#lldb = false
385385

386+
# Indicates whether GDB will also be built.
387+
#build-gdb = false
388+
386389
# Whether to deny warnings in crates
387390
#deny-warnings = true
388391

src/bootstrap/bootstrap.py

+4
Original file line numberDiff line numberDiff line change
@@ -723,6 +723,10 @@ def update_submodules(self):
723723
config = self.get_toml('lldb')
724724
if config is None or config == 'false':
725725
continue
726+
if module.endswith("gdb"):
727+
config = self.get_toml('build-gdb')
728+
if config is None or config == 'false':
729+
continue
726730
check = self.check_submodule(module, slow_submodules)
727731
filtered_submodules.append((module, check))
728732
submodules_names.append(module)

src/bootstrap/builder.rs

+2
Original file line numberDiff line numberDiff line change
@@ -363,6 +363,7 @@ impl<'a> Builder<'a> {
363363
tool::Rustdoc,
364364
tool::Clippy,
365365
native::Llvm,
366+
native::Gdb,
366367
tool::Rustfmt,
367368
tool::Miri,
368369
native::Lld
@@ -461,6 +462,7 @@ impl<'a> Builder<'a> {
461462
dist::Clippy,
462463
dist::LlvmTools,
463464
dist::Lldb,
465+
dist::Gdb,
464466
dist::Extended,
465467
dist::HashSign
466468
),

src/bootstrap/config.rs

+4
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,8 @@ pub struct Config {
9292
pub lldb_enabled: bool,
9393
pub llvm_tools_enabled: bool,
9494

95+
pub gdb_enabled: bool,
96+
9597
// rust codegen options
9698
pub rust_optimize: bool,
9799
pub rust_codegen_units: Option<u32>,
@@ -320,6 +322,7 @@ struct Rust {
320322
wasm_syscall: Option<bool>,
321323
lld: Option<bool>,
322324
lldb: Option<bool>,
325+
build_gdb: Option<bool>,
323326
llvm_tools: Option<bool>,
324327
deny_warnings: Option<bool>,
325328
backtrace_on_ice: Option<bool>,
@@ -552,6 +555,7 @@ impl Config {
552555
set(&mut config.wasm_syscall, rust.wasm_syscall);
553556
set(&mut config.lld_enabled, rust.lld);
554557
set(&mut config.lldb_enabled, rust.lldb);
558+
set(&mut config.gdb_enabled, rust.build_gdb);
555559
set(&mut config.llvm_tools_enabled, rust.llvm_tools);
556560
config.rustc_parallel_queries = rust.experimental_parallel_queries.unwrap_or(false);
557561
config.rustc_default_linker = rust.default_linker.clone();

src/bootstrap/configure.py

+1
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ def v(*args):
7070
o("full-tools", None, "enable all tools")
7171
o("lld", "rust.lld", "build lld")
7272
o("lldb", "rust.lldb", "build lldb")
73+
o("gdb", "rust.build-gdb", "build gdb")
7374
o("missing-tools", "dist.missing-tools", "allow failures when building tools")
7475

7576
# Optimization and debugging options. These may be overridden by the release

src/bootstrap/dist.rs

+99
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,11 @@ use crate::tool::{self, Tool};
3535
use crate::cache::{INTERNER, Interned};
3636
use time;
3737

38+
#[cfg(unix)]
39+
use std::os::unix::fs::symlink as symlink_file;
40+
#[cfg(windows)]
41+
use std::os::windows::fs::symlink_file;
42+
3843
pub fn pkgname(builder: &Builder, component: &str) -> String {
3944
if component == "cargo" {
4045
format!("{}-{}", component, builder.cargo_package_vers())
@@ -48,6 +53,8 @@ pub fn pkgname(builder: &Builder, component: &str) -> String {
4853
format!("{}-{}", component, builder.llvm_tools_package_vers())
4954
} else if component == "lldb" {
5055
format!("{}-{}", component, builder.lldb_package_vers())
56+
} else if component == "gdb" {
57+
format!("{}-{}", component, builder.gdb_package_vers())
5158
} else {
5259
assert!(component.starts_with("rust"));
5360
format!("{}-{}", component, builder.rust_package_vers())
@@ -1400,6 +1407,7 @@ impl Step for Extended {
14001407
let llvm_tools_installer = builder.ensure(LlvmTools { stage, target });
14011408
let clippy_installer = builder.ensure(Clippy { stage, target });
14021409
let lldb_installer = builder.ensure(Lldb { target });
1410+
let gdb_installer = builder.ensure(Gdb { target });
14031411
let mingw_installer = builder.ensure(Mingw { host: target });
14041412
let analysis_installer = builder.ensure(Analysis {
14051413
compiler: builder.compiler(stage, self.host),
@@ -1440,6 +1448,7 @@ impl Step for Extended {
14401448
tarballs.extend(rustfmt_installer.clone());
14411449
tarballs.extend(llvm_tools_installer);
14421450
tarballs.extend(lldb_installer);
1451+
tarballs.extend(gdb_installer);
14431452
tarballs.push(analysis_installer);
14441453
tarballs.push(std_installer);
14451454
if builder.config.docs {
@@ -1873,6 +1882,7 @@ impl Step for HashSign {
18731882
cmd.arg(builder.package_vers(&builder.release_num("rustfmt")));
18741883
cmd.arg(builder.llvm_tools_package_vers());
18751884
cmd.arg(builder.lldb_package_vers());
1885+
cmd.arg(builder.gdb_package_vers());
18761886
cmd.arg(addr);
18771887

18781888
builder.create_dir(&distdir(builder));
@@ -2121,3 +2131,92 @@ impl Step for Lldb {
21212131
Some(distdir(builder).join(format!("{}-{}.tar.gz", name, target)))
21222132
}
21232133
}
2134+
2135+
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
2136+
pub struct Gdb {
2137+
pub target: Interned<String>,
2138+
}
2139+
2140+
impl Step for Gdb {
2141+
type Output = Option<PathBuf>;
2142+
const DEFAULT: bool = true;
2143+
const ONLY_HOSTS: bool = false;
2144+
2145+
fn should_run(run: ShouldRun) -> ShouldRun {
2146+
let builder = run.builder;
2147+
run.path("src/tools/gdb").default_condition(builder.config.gdb_enabled)
2148+
}
2149+
2150+
fn make_run(run: RunConfig) {
2151+
run.builder.ensure(Gdb {
2152+
target: run.target,
2153+
});
2154+
}
2155+
2156+
fn run(self, builder: &Builder) -> Option<PathBuf> {
2157+
let target = self.target;
2158+
2159+
if builder.config.dry_run {
2160+
return None;
2161+
}
2162+
2163+
let gdb_install = builder.gdb_out(target).join("install");
2164+
let bindir = gdb_install.join("bin");
2165+
let gdb_exe = bindir.join(exe("gdb", &target));
2166+
if !gdb_exe.exists() {
2167+
return None;
2168+
}
2169+
2170+
builder.info(&format!("Dist Gdb ({})", target));
2171+
let src = builder.src.join("src/tools/gdb");
2172+
let name = pkgname(builder, "gdb");
2173+
2174+
let tmp = tmpdir(builder);
2175+
let image = tmp.join("gdb-image");
2176+
drop(fs::remove_dir_all(&image));
2177+
2178+
// Prepare the image directory
2179+
let root = image.join("lib/rustlib").join(&*target);
2180+
let dst = root.join("bin");
2181+
t!(fs::create_dir_all(&dst));
2182+
// Install gdb as real-gdb, and run-gdb as gdb.
2183+
let filename = bindir.join(exe("gdb", &target));
2184+
builder.copy(&filename, &dst.join(exe("real-gdb", &target)));
2185+
let filename = bindir.join(exe("run-gdb", &target));
2186+
builder.copy(&filename, &dst.join(exe("gdb", &target)));
2187+
2188+
// gdb "share" files.
2189+
let sharedir = gdb_install.join("share/gdb");
2190+
let dst = root.join("share/gdb");
2191+
t!(fs::create_dir_all(&dst));
2192+
builder.cp_r(&sharedir, &dst);
2193+
2194+
// We want to pick up the system auto-loads.
2195+
t!(symlink_file(&Path::new("/usr/share/gdb/auto-load"), &dst.join("auto-load")));
2196+
2197+
// Prepare the overlay
2198+
let overlay = tmp.join("gdb-overlay");
2199+
drop(fs::remove_dir_all(&overlay));
2200+
builder.create_dir(&overlay);
2201+
builder.install(&src.join("COPYING3"), &overlay, 0o644);
2202+
builder.create(&overlay.join("version"), &builder.gdb_vers());
2203+
2204+
// Generate the installer tarball
2205+
let mut cmd = rust_installer(builder);
2206+
cmd.arg("generate")
2207+
.arg("--product-name=Rust")
2208+
.arg("--rel-manifest-dir=rustlib")
2209+
.arg("--success-message=gdb-installed.")
2210+
.arg("--image-dir").arg(&image)
2211+
.arg("--work-dir").arg(&tmpdir(builder))
2212+
.arg("--output-dir").arg(&distdir(builder))
2213+
.arg("--non-installed-overlay").arg(&overlay)
2214+
.arg(format!("--package-name={}-{}", name, target))
2215+
.arg("--legacy-manifest-dirs=rustlib,cargo")
2216+
.arg("--component-name=gdb");
2217+
2218+
2219+
builder.run(&mut cmd);
2220+
Some(distdir(builder).join(format!("{}-{}.tar.gz", name, target)))
2221+
}
2222+
}

src/bootstrap/lib.rs

+13
Original file line numberDiff line numberDiff line change
@@ -594,6 +594,11 @@ impl Build {
594594
self.out.join(&*target).join("lld")
595595
}
596596

597+
/// Output directory for gdb build.
598+
fn gdb_out(&self, target: Interned<String>) -> PathBuf {
599+
self.out.join(&*target).join("gdb")
600+
}
601+
597602
/// Output directory for all documentation for a target
598603
fn doc_out(&self, target: Interned<String>) -> PathBuf {
599604
self.out.join(&*target).join("doc")
@@ -1047,6 +1052,14 @@ impl Build {
10471052
self.rust_version()
10481053
}
10491054

1055+
fn gdb_package_vers(&self) -> String {
1056+
self.package_vers(&self.rust_version())
1057+
}
1058+
1059+
fn gdb_vers(&self) -> String {
1060+
self.rust_version()
1061+
}
1062+
10501063
fn llvm_link_tools_dynamically(&self, target: Interned<String>) -> bool {
10511064
(target.contains("linux-gnu") || target.contains("apple-darwin"))
10521065
}

src/bootstrap/native.rs

+42
Original file line numberDiff line numberDiff line change
@@ -473,6 +473,48 @@ impl Step for Lld {
473473
}
474474
}
475475

476+
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
477+
pub struct Gdb {
478+
pub target: Interned<String>,
479+
}
480+
481+
impl Step for Gdb {
482+
type Output = ();
483+
const DEFAULT: bool = true;
484+
const ONLY_HOSTS: bool = false;
485+
486+
fn should_run(run: ShouldRun) -> ShouldRun {
487+
let builder = run.builder;
488+
run.path("src/tools/gdb").default_condition(builder.config.gdb_enabled)
489+
}
490+
491+
fn make_run(run: RunConfig) {
492+
run.builder.ensure(Gdb {
493+
target: run.target
494+
});
495+
}
496+
497+
fn run(self, builder: &Builder) {
498+
if builder.config.dry_run {
499+
return;
500+
}
501+
502+
let root = builder.gdb_out(self.target);
503+
let build = root.join("build");
504+
let install = root.join("install");
505+
let src = builder.src.join("src/tools/gdb");
506+
t!(fs::create_dir_all(&build));
507+
t!(fs::create_dir_all(&install));
508+
509+
let mut cmd = Command::new(&src.join("build-for-rust.sh"));
510+
cmd.arg(&src)
511+
.arg(&build)
512+
.arg(&install);
513+
514+
builder.run(&mut cmd);
515+
}
516+
}
517+
476518
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
477519
pub struct TestHelpers {
478520
pub target: Interned<String>,

src/bootstrap/sanity.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -126,8 +126,7 @@ pub fn check(build: &mut Build) {
126126
.or_else(|| cmd_finder.maybe_have("node"))
127127
.or_else(|| cmd_finder.maybe_have("nodejs"));
128128

129-
build.config.gdb = build.config.gdb.take().map(|p| cmd_finder.must_have(p))
130-
.or_else(|| cmd_finder.maybe_have("gdb"));
129+
build.config.gdb = build.config.gdb.take().map(|p| cmd_finder.must_have(p));
131130

132131
// We're gonna build some custom C code here and there, host triples
133132
// also build some C++ shims for LLVM so we need a C++ compiler.

src/bootstrap/test.rs

+6
Original file line numberDiff line numberDiff line change
@@ -1111,8 +1111,14 @@ impl Step for Compiletest {
11111111
cmd.arg("--lldb-python").arg(builder.python());
11121112
}
11131113

1114+
// If config.toml specifies a gdb, use it; otherwise, if we
1115+
// built a gdb, prefer that.
11141116
if let Some(ref gdb) = builder.config.gdb {
11151117
cmd.arg("--gdb").arg(gdb);
1118+
} else if builder.config.gdb_enabled {
1119+
cmd.arg("--gdb").arg(builder.gdb_out(target).join("install/bin/gdb"));
1120+
} else {
1121+
cmd.arg("--gdb").arg("gdb");
11161122
}
11171123

11181124
let run = |cmd: &mut Command| {

src/ci/docker/dist-i686-linux/Dockerfile

+8-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,13 @@ RUN yum upgrade -y && yum install -y \
2323
pkgconfig \
2424
wget \
2525
autoconf \
26-
gettext
26+
gettext \
27+
xz-static \
28+
xz-devel \
29+
expat-static \
30+
expat-devel \
31+
ncurses-static \
32+
ncurses-devel
2733

2834
ENV PATH=/rustroot/bin:$PATH
2935
ENV LD_LIBRARY_PATH=/rustroot/lib64:/rustroot/lib
@@ -95,6 +101,7 @@ ENV HOSTS=i686-unknown-linux-gnu
95101

96102
ENV RUST_CONFIGURE_ARGS \
97103
--enable-full-tools \
104+
--enable-gdb \
98105
--enable-sanitizers \
99106
--enable-profiler \
100107
--set target.i686-unknown-linux-gnu.linker=clang \

src/ci/docker/dist-x86_64-linux/Dockerfile

+8-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,13 @@ RUN yum upgrade -y && yum install -y \
2323
pkgconfig \
2424
wget \
2525
autoconf \
26-
gettext
26+
gettext \
27+
xz-static \
28+
xz-devel \
29+
expat-static \
30+
expat-devel \
31+
ncurses-static \
32+
ncurses-devel
2733

2834
ENV PATH=/rustroot/bin:$PATH
2935
ENV LD_LIBRARY_PATH=/rustroot/lib64:/rustroot/lib
@@ -95,6 +101,7 @@ ENV HOSTS=x86_64-unknown-linux-gnu
95101

96102
ENV RUST_CONFIGURE_ARGS \
97103
--enable-full-tools \
104+
--enable-gdb \
98105
--enable-sanitizers \
99106
--enable-profiler \
100107
--enable-compiler-docs \

src/etc/rust-gdb

+13-1
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,22 @@ set -e
1616
RUSTC_SYSROOT=`rustc --print=sysroot`
1717
GDB_PYTHON_MODULE_DIRECTORY="$RUSTC_SYSROOT/lib/rustlib/etc"
1818

19+
if [ -z "$RUST_GDB" ]; then
20+
# Find the host triple so we can find lldb in rustlib.
21+
host=`rustc -vV | sed -n -e 's/^host: //p'`
22+
RUST_GDB=gdb
23+
if [ -f "$RUSTC_SYSROOT/lib/rustlib/$host/bin/gdb" ]; then
24+
bin="$RUSTC_SYSROOT/lib/rustlib/$host/bin"
25+
# Pass the path to real-gdb to the wrapper. This avoids
26+
# having to modify PATH here, which might possibly be
27+
# confusing inside gdb.
28+
RUST_GDB="$bin/gdb $bin/real-gdb"
29+
fi
30+
fi
31+
1932
# Run GDB with the additional arguments that load the pretty printers
2033
# Set the environment variable `RUST_GDB` to overwrite the call to a
2134
# different/specific command (defaults to `gdb`).
22-
RUST_GDB="${RUST_GDB:-gdb}"
2335
PYTHONPATH="$PYTHONPATH:$GDB_PYTHON_MODULE_DIRECTORY" exec ${RUST_GDB} \
2436
--directory="$GDB_PYTHON_MODULE_DIRECTORY" \
2537
-iex "add-auto-load-safe-path $GDB_PYTHON_MODULE_DIRECTORY" \

0 commit comments

Comments
 (0)