Skip to content

Commit cb80619

Browse files
committed
Add nightly-only support for Cargo unremap trim-paths files in rust-gdb
1 parent 1b29cfd commit cb80619

3 files changed

Lines changed: 110 additions & 6 deletions

File tree

src/bootstrap/src/core/build_steps/dist.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -748,6 +748,9 @@ impl Step for DebuggerScripts {
748748
cp_debugger_script("gdb_load_rust_pretty_printers.py");
749749
cp_debugger_script("gdb_lookup.py");
750750
cp_debugger_script("gdb_providers.py");
751+
if builder.build.unstable_features() {
752+
cp_debugger_script("gdb_trim_paths.py");
753+
}
751754

752755
// lldb debugger scripts
753756
builder.install(

src/etc/gdb_trim_paths.py

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
# GDB Python script to handle Cargo `.trim-paths.jsonl` files from the trim-paths feature
2+
3+
import json
4+
import os
5+
import gdb
6+
7+
8+
def _process_v1_trim_paths(lines, trim_paths_path):
9+
for idx, line in enumerate(lines[2:], start=3):
10+
try:
11+
entry = json.loads(line)
12+
if "from" in entry and "to" in entry:
13+
# https://doc.guix.gnu.org/gdb/16.3/en/html_node/Source-Path.html#index-set-substitute_002dpath
14+
cmd = f'set substitute-path "{entry["from"]}" "{entry["to"]}"'
15+
gdb.execute(cmd)
16+
except json.JSONDecodeError:
17+
print(
18+
f"(rust-gdb) warning: invalid JSON on line {idx} of {trim_paths_path}"
19+
)
20+
21+
22+
def _load_trim_paths(filepath):
23+
trim_paths_path = f"{filepath}.trim-paths.jsonl"
24+
25+
if not os.path.isfile(trim_paths_path):
26+
return
27+
28+
try:
29+
# Load all the lines of the trim-paths file, max 10 lines
30+
with open(trim_paths_path, "r", encoding="utf-8") as f:
31+
lines = [line.strip() for line in f]
32+
33+
# Abort if we have less than 3 lines as that means that we cannot have any
34+
# substitutions (header + metadata is already 2 lines)
35+
if not lines or len(lines) < 3:
36+
return
37+
38+
# Try loading the header line, which contains the version (v) field
39+
try:
40+
header = json.loads(lines[0])
41+
ver = header["v"]
42+
except json.JSONDecodeError:
43+
print(
44+
f"(rust-gdb) warning: header line 1 of {trim_paths_path} is not valid JSON"
45+
)
46+
return
47+
48+
# We only handle version 1
49+
if ver == 1:
50+
_process_v1_trim_paths(lines, trim_paths_path)
51+
except Exception as e:
52+
print(
53+
f"(rust-gdb) warning: failed to process trim-paths mappings: {e} of {trim_paths_path}"
54+
)
55+
56+
57+
def _on_objfile(objfile):
58+
filepath = objfile.filename
59+
60+
if not filepath or not objfile.is_valid() or not os.path.isfile(filepath):
61+
return
62+
63+
_load_trim_paths(filepath)
64+
65+
66+
def _on_progspace(progspace):
67+
filepath = progspace.filename
68+
69+
if not filepath or not os.path.isfile(filepath):
70+
return
71+
72+
_load_trim_paths(filepath)
73+
74+
75+
def _on_new_objfile(event):
76+
_on_objfile(event.new_objfile)
77+
78+
79+
def _on_executable_changed(event):
80+
_on_progspace(event.progspace)
81+
82+
83+
# Setup the events for new objfile (so) and new executable
84+
# https://doc.guix.gnu.org/gdb/16.3/en/html_node/Events-In-Python.html
85+
#
86+
# FIXME: should we handle clear/free events?
87+
gdb.events.new_objfile.connect(_on_new_objfile)
88+
gdb.events.executable_changed.connect(_on_executable_changed)
89+
90+
# Load the trim-paths files for the already loaded objfiles
91+
for objfile in gdb.objfiles():
92+
_on_objfile(objfile)

src/etc/rust-gdb

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,18 @@ RUSTC_COMMIT_HASH="$("$RUSTC" -vV | sed -n 's/commit-hash: \([a-zA-Z0-9_]*\)/\1/
2020
# Set the environment variable `RUST_GDB` to overwrite the call to a
2121
# different/specific command (defaults to `gdb`).
2222
RUST_GDB="${RUST_GDB:-gdb}"
23-
PYTHONPATH="$PYTHONPATH:$GDB_PYTHON_MODULE_DIRECTORY" exec ${RUST_GDB} \
24-
--directory="$GDB_PYTHON_MODULE_DIRECTORY" \
25-
-iex "add-auto-load-safe-path $GDB_PYTHON_MODULE_DIRECTORY" \
26-
-iex "set substitute-path /rustc/$RUSTC_COMMIT_HASH $RUSTC_SYSROOT/lib/rustlib/src/rust" \
27-
"$@"
28-
23+
RUST_GDB_ARGS=(
24+
--directory="$GDB_PYTHON_MODULE_DIRECTORY"
25+
-iex "add-auto-load-safe-path $GDB_PYTHON_MODULE_DIRECTORY"
26+
-iex "set substitute-path /rustc/$RUSTC_COMMIT_HASH $RUSTC_SYSROOT/lib/rustlib/src/rust"
27+
)
28+
29+
# Unstable (nightly-only) trim-paths feature, activated only if
30+
# - RUST_GDB_TRIM_PATHS=unstable is set
31+
# - and if the python file is present (only shipped on nightly)
32+
GDB_TRIM_PATHS="$GDB_PYTHON_MODULE_DIRECTORY/gdb_trim_paths.py"
33+
if [ "${RUST_GDB_TRIM_PATHS:-}" = "unstable" ] && [ -f "$GDB_TRIM_PATHS" ]; then
34+
RUST_GDB_ARGS+=(-x "$GDB_TRIM_PATHS")
35+
fi
36+
37+
PYTHONPATH="$PYTHONPATH:$GDB_PYTHON_MODULE_DIRECTORY" exec ${RUST_GDB} "${RUST_GDB_ARGS[@]}" "$@"

0 commit comments

Comments
 (0)