Skip to content

Commit 00426d6

Browse files
committed
Auto merge of #148685 - Zalathar:lldb-python, r=jieyouxu
compiletest: Run the `lldb_batchmode.py` script in LLDB's embedded Python Historically, LLDB debuginfo tests have used a Python script to control LLDB via its Python API, instead of invoking the `lldb` command directly. Unfortunately, this requires us to find and use a version of Python that is compatible with LLDB's Python bindings. However, it turns out that there is a simpler way to find a compatible Python interpreter: use the one that is embedded in LLDB itself, via the `script` command.
2 parents 5f666a6 + dca8be9 commit 00426d6

10 files changed

Lines changed: 108 additions & 110 deletions

File tree

‎bootstrap.example.toml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,7 @@
320320
#build.npm = "npm"
321321

322322
# Python interpreter to use for various tasks throughout the build, notably
323-
# rustdoc tests, the lldb python interpreter, and some dist bits and pieces.
323+
# rustdoc tests, and some dist bits and pieces.
324324
#
325325
# Defaults to the Python interpreter used to execute x.py.
326326
#build.python = "python"

‎src/bootstrap/src/core/build_steps/test.rs‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2094,11 +2094,11 @@ Please disable assertions with `rust.debug-assertions = false`.
20942094
cmd.arg("--gdb").arg(gdb);
20952095
}
20962096

2097-
ifletSome(debuggers::Lldb{lldb_version, lldb_python_dir}) =
2097+
ifletSome(debuggers::Lldb{lldb_exe, lldb_version}) =
20982098
debuggers::discover_lldb(builder)
20992099
{
2100+
cmd.arg("--lldb").arg(lldb_exe);
21002101
cmd.arg("--lldb-version").arg(lldb_version);
2101-
cmd.arg("--lldb-python-dir").arg(lldb_python_dir);
21022102
}
21032103
}
21042104

‎src/bootstrap/src/core/debuggers/lldb.rs‎

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ use crate::core::builder::Builder;
44
usecrate::utils::exec::command;
55

66
pub(crate)structLldb{
7+
pub(crate)lldb_exe:PathBuf,
78
pub(crate)lldb_version:String,
8-
pub(crate)lldb_python_dir:String,
99
}
1010

1111
pub(crate)fndiscover_lldb(builder:&Builder<'_>) -> Option<Lldb>{
@@ -21,12 +21,5 @@ pub(crate) fn discover_lldb(builder: &Builder<'_>) -> Option<Lldb> {
2121
.stdout_if_ok()
2222
.and_then(|v| if v.trim().is_empty(){None}else{Some(v)})?;
2323

24-
let lldb_python_dir = command(&lldb_exe)
25-
.allow_failure()
26-
.arg("-P")
27-
.run_capture_stdout(builder)
28-
.stdout_if_ok()
29-
.map(|p| p.lines().next().expect("lldb Python dir not found").to_string())?;
30-
31-
Some(Lldb{ lldb_version, lldb_python_dir })
24+
Some(Lldb{ lldb_exe, lldb_version })
3225
}

‎src/etc/lldb_batchmode.py‎

Lines changed: 68 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -176,77 +176,85 @@ def watchdog():
176176
watchdog_thread.start()
177177

178178

179+
defget_env_arg(name):
180+
value=os.environ.get(name)
181+
ifvalueisNone:
182+
print("must set %s"%name)
183+
sys.exit(1)
184+
returnvalue
185+
186+
179187
####################################################################################################
180188
# ~main
181189
####################################################################################################
182190

183191

184-
iflen(sys.argv) !=3:
185-
print("usage: python lldb_batchmode.py target-path script-path")
186-
sys.exit(1)
192+
defmain():
193+
target_path=get_env_arg("LLDB_BATCHMODE_TARGET_PATH")
194+
script_path=get_env_arg("LLDB_BATCHMODE_SCRIPT_PATH")
187195

188-
target_path=sys.argv[1]
189-
script_path=sys.argv[2]
196+
print("LLDB batch-mode script")
197+
print("----------------------")
198+
print("Debugger commands script is '%s'."%script_path)
199+
print("Target executable is '%s'."%target_path)
200+
print("Current working directory is '%s'"%os.getcwd())
190201

191-
print("LLDB batch-mode script")
192-
print("----------------------")
193-
print("Debugger commands script is '%s'."%script_path)
194-
print("Target executable is '%s'."%target_path)
195-
print("Current working directory is '%s'"%os.getcwd())
202+
# Start the timeout watchdog
203+
start_watchdog()
196204

197-
# Start the timeout watchdog
198-
start_watchdog()
205+
# Create a new debugger instance
206+
debugger=lldb.SBDebugger.Create()
199207

200-
# Create a new debugger instance
201-
debugger=lldb.SBDebugger.Create()
208+
# When we step or continue, don't return from the function until the process
209+
# stops. We do this by setting the async mode to false.
210+
debugger.SetAsync(False)
202211

203-
# When we step or continue, don't return from the function until the process
204-
# stops. We do this by setting the async mode to false.
205-
debugger.SetAsync(False)
212+
# Create a target from a file and arch
213+
print("Creating a target for '%s'"%target_path)
214+
target_error=lldb.SBError()
215+
target=debugger.CreateTarget(target_path, None, None, True, target_error)
206216

207-
# Create a target from a file and arch
208-
print("Creating a target for '%s'"%target_path)
209-
target_error=lldb.SBError()
210-
target=debugger.CreateTarget(target_path, None, None, True, target_error)
211-
212-
ifnottarget:
213-
print(
214-
"Could not create debugging target '"
215-
+target_path
216-
+"': "
217-
+str(target_error)
218-
+". Aborting.",
219-
file=sys.stderr,
220-
)
221-
sys.exit(1)
217+
ifnottarget:
218+
print(
219+
"Could not create debugging target '"
220+
+target_path
221+
+"': "
222+
+str(target_error)
223+
+". Aborting.",
224+
file=sys.stderr,
225+
)
226+
sys.exit(1)
222227

228+
# Register the breakpoint callback for every breakpoint
229+
start_breakpoint_listener(target)
223230

224-
# Register the breakpoint callback for every breakpoint
225-
start_breakpoint_listener(target)
231+
command_interpreter=debugger.GetCommandInterpreter()
226232

227-
command_interpreter=debugger.GetCommandInterpreter()
228-
229-
try:
230-
script_file=open(script_path, "r")
231-
232-
forlineinscript_file:
233-
command=line.strip()
234-
if (
235-
command=="run"
236-
orcommand=="r"
237-
orre.match(r"^process\s+launch.*", command)
238-
):
239-
# Before starting to run the program, let the thread sleep a bit, so all
240-
# breakpoint added events can be processed
241-
time.sleep(0.5)
242-
ifcommand!="":
243-
execute_command(command_interpreter, command)
244-
245-
exceptIOErrorase:
246-
print("Could not read debugging script '%s'."%script_path, file=sys.stderr)
247-
print(e, file=sys.stderr)
248-
print("Aborting.", file=sys.stderr)
249-
sys.exit(1)
250-
finally:
251-
debugger.Terminate()
252-
script_file.close()
233+
try:
234+
script_file=open(script_path, "r")
235+
236+
forlineinscript_file:
237+
command=line.strip()
238+
if (
239+
command=="run"
240+
orcommand=="r"
241+
orre.match(r"^process\s+launch.*", command)
242+
):
243+
# Before starting to run the program, let the thread sleep a bit, so all
244+
# breakpoint added events can be processed
245+
time.sleep(0.5)
246+
ifcommand!="":
247+
execute_command(command_interpreter, command)
248+
249+
exceptIOErrorase:
250+
print("Could not read debugging script '%s'."%script_path, file=sys.stderr)
251+
print(e, file=sys.stderr)
252+
print("Aborting.", file=sys.stderr)
253+
sys.exit(1)
254+
finally:
255+
debugger.Terminate()
256+
script_file.close()
257+
258+
259+
if__name__=="__main__":
260+
main()

‎src/tools/compiletest/src/common.rs‎

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -312,10 +312,7 @@ pub struct Config {
312312
/// Path to the `src/tools/coverage-dump/` bootstrap tool executable.
313313
pubcoverage_dump_path:Option<Utf8PathBuf>,
314314

315-
/// Path to the Python 3 executable to use for LLDB and htmldocck.
316-
///
317-
/// FIXME: the `lldb` setup currently requires I believe Python 3.10 **exactly**, it can't even
318-
/// be Python 3.11 or 3.9...
315+
/// Path to the Python 3 executable to use for htmldocck and some run-make tests.
319316
pubpython:String,
320317

321318
/// Path to the `src/tools/jsondocck/` bootstrap tool executable.
@@ -541,6 +538,9 @@ pub struct Config {
541538
/// FIXME: `gdb_version` is *derived* from gdb, but it's *not* technically a config!
542539
pubgdb_version:Option<u32>,
543540

541+
/// Path to or name of the LLDB executable to use for debuginfo tests.
542+
publldb:Option<Utf8PathBuf>,
543+
544544
/// Version of LLDB.
545545
///
546546
/// FIXME: `lldb_version` is *derived* from lldb, but it's *not* technically a config!
@@ -587,11 +587,6 @@ pub struct Config {
587587
/// FIXME: take a look at this; this also influences adb in gdb code paths in a strange way.
588588
pubadb_device_status:bool,
589589

590-
/// Path containing LLDB's Python module.
591-
///
592-
/// FIXME: `PYTHONPATH` takes precedence over this flag...? See `runtest::run_lldb`.
593-
publldb_python_dir:Option<String>,
594-
595590
/// Verbose dump a lot of info.
596591
///
597592
/// FIXME: this is *way* too coarse; the user can't select *which* info to verbosely dump.

‎src/tools/compiletest/src/debuggers.rs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ pub(crate) fn configure_gdb(config: &Config) -> Option<Arc<Config>> {
4949
}
5050

5151
pub(crate)fnconfigure_lldb(config:&Config) -> Option<Arc<Config>>{
52-
config.lldb_python_dir.as_ref()?;
52+
config.lldb.as_ref()?;
5353

5454
Some(Arc::new(Config{debugger:Some(Debugger::Lldb), ..config.clone()}))
5555
}

‎src/tools/compiletest/src/lib.rs‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -141,13 +141,13 @@ fn parse_config(args: Vec<String>) -> Config {
141141
.optopt("","host","the host to build for","HOST")
142142
.optopt("","cdb","path to CDB to use for CDB debuginfo tests","PATH")
143143
.optopt("","gdb","path to GDB to use for GDB debuginfo tests","PATH")
144+
.optopt("","lldb","path to LLDB to use for LLDB debuginfo tests","PATH")
144145
.optopt("","lldb-version","the version of LLDB used","VERSION STRING")
145146
.optopt("","llvm-version","the version of LLVM used","VERSION STRING")
146147
.optflag("","system-llvm","is LLVM the system LLVM")
147148
.optopt("","android-cross-path","Android NDK standalone path","PATH")
148149
.optopt("","adb-path","path to the android debugger","PATH")
149150
.optopt("","adb-test-dir","path to tests for the android debugger","PATH")
150-
.optopt("","lldb-python-dir","directory containing LLDB's python module","PATH")
151151
.reqopt("","cc","path to a C compiler","PATH")
152152
.reqopt("","cxx","path to a C++ compiler","PATH")
153153
.reqopt("","cflags","flags for the C compiler","FLAGS")
@@ -264,6 +264,7 @@ fn parse_config(args: Vec<String>) -> Config {
264264
let gdb = debuggers::discover_gdb(matches.opt_str("gdb"),&target,&android_cross_path);
265265
let gdb_version = gdb.as_deref().and_then(debuggers::query_gdb_version);
266266
// FIXME: `lldb_version` is *derived* from lldb, but it's *not* technically a config!
267+
let lldb = matches.opt_str("lldb").map(Utf8PathBuf::from);
267268
let lldb_version =
268269
matches.opt_str("lldb-version").as_deref().and_then(debuggers::extract_lldb_version);
269270
let color = match matches.opt_str("color").as_deref(){
@@ -435,6 +436,7 @@ fn parse_config(args: Vec<String>) -> Config {
435436
cdb_version,
436437
gdb,
437438
gdb_version,
439+
lldb,
438440
lldb_version,
439441
llvm_version,
440442
system_llvm: matches.opt_present("system-llvm"),
@@ -444,7 +446,6 @@ fn parse_config(args: Vec<String>) -> Config {
444446
adb_device_status:opt_str2(matches.opt_str("target")).contains("android")
445447
&& "(none)" != opt_str2(matches.opt_str("adb-test-dir"))
446448
&& !opt_str2(matches.opt_str("adb-test-dir")).is_empty(),
447-
lldb_python_dir: matches.opt_str("lldb-python-dir"),
448449
verbose: matches.opt_present("verbose"),
449450
only_modified: matches.opt_present("only-modified"),
450451
color,

‎src/tools/compiletest/src/runtest.rs‎

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -200,10 +200,11 @@ pub fn compute_stamp_hash(config: &Config) -> String {
200200
}
201201

202202
Some(Debugger::Lldb) => {
203-
config.python.hash(&mut hash);
204-
config.lldb_python_dir.hash(&mut hash);
203+
// LLDB debuginfo tests now use LLDB's embedded Python, with an
204+
// explicit PYTHONPATH, so they don't depend on `--python` or
205+
// the ambient PYTHONPATH.
206+
config.lldb.hash(&mut hash);
205207
env::var_os("PATH").hash(&mut hash);
206-
env::var_os("PYTHONPATH").hash(&mut hash);
207208
}
208209

209210
None => {}

‎src/tools/compiletest/src/runtest/debuginfo.rs‎

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -326,9 +326,9 @@ impl TestCx<'_> {
326326
}
327327

328328
fnrun_debuginfo_lldb_test(&self){
329-
ifself.config.lldb_python_dir.is_none(){
330-
self.fatal("Can't run LLDB test because LLDB's python path is not set.");
331-
}
329+
letSome(ref lldb) = self.config.lldbelse{
330+
self.fatal("Can't run LLDB test because LLDB's path is not set.");
331+
};
332332

333333
// compile test file (it should have 'compile-flags:-g' in the directive)
334334
let should_run = self.run_if_enabled();
@@ -434,7 +434,7 @@ impl TestCx<'_> {
434434
let debugger_script = self.make_out_name("debugger.script");
435435

436436
// Let LLDB execute the script via lldb_batchmode.py
437-
let debugger_run_result = self.run_lldb(&exe_file,&debugger_script);
437+
let debugger_run_result = self.run_lldb(lldb,&exe_file,&debugger_script);
438438

439439
if !debugger_run_result.status.success(){
440440
self.fatal_proc_rec("Error while running LLDB",&debugger_run_result);
@@ -445,23 +445,23 @@ impl TestCx<'_> {
445445
}
446446
}
447447

448-
fnrun_lldb(&self,test_executable:&Utf8Path,debugger_script:&Utf8Path) -> ProcRes{
449-
// Prepare the lldb_batchmode which executes the debugger script
450-
let lldb_script_path = self.config.src_root.join("src/etc/lldb_batchmode.py");
451-
452-
// FIXME: `PYTHONPATH` takes precedence over the flag...?
453-
let pythonpath = ifletOk(pp) = std::env::var("PYTHONPATH"){
454-
format!("{pp}:{}",self.config.lldb_python_dir.as_ref().unwrap())
455-
}else{
456-
self.config.lldb_python_dir.clone().unwrap()
457-
};
458-
self.run_command_to_procres(
459-
Command::new(&self.config.python)
460-
.arg(&lldb_script_path)
461-
.arg(test_executable)
462-
.arg(debugger_script)
463-
.env("PYTHONUNBUFFERED","1")// Help debugging #78665
464-
.env("PYTHONPATH", pythonpath),
465-
)
448+
fnrun_lldb(
449+
&self,
450+
lldb:&Utf8Path,
451+
test_executable:&Utf8Path,
452+
debugger_script:&Utf8Path,
453+
) -> ProcRes{
454+
// Path containing `lldb_batchmode.py`, so that the `script` command can import it.
455+
let pythonpath = self.config.src_root.join("src/etc");
456+
457+
letmut cmd = Command::new(lldb);
458+
cmd.arg("--one-line")
459+
.arg("script --language python -- import lldb_batchmode; lldb_batchmode.main()")
460+
.env("LLDB_BATCHMODE_TARGET_PATH", test_executable)
461+
.env("LLDB_BATCHMODE_SCRIPT_PATH", debugger_script)
462+
.env("PYTHONUNBUFFERED","1")// Help debugging #78665
463+
.env("PYTHONPATH",pythonpath);
464+
465+
self.run_command_to_procres(&mut cmd)
466466
}
467467
}

‎src/tools/compiletest/src/rustdoc_gui_test.rs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,14 +99,14 @@ fn incomplete_config_for_rustdoc_gui_test() -> Config {
9999
cdb_version:Default::default(),
100100
gdb:Default::default(),
101101
gdb_version:Default::default(),
102+
lldb:Default::default(),
102103
lldb_version:Default::default(),
103104
llvm_version:Default::default(),
104105
system_llvm:Default::default(),
105106
android_cross_path:Default::default(),
106107
adb_path:Default::default(),
107108
adb_test_dir:Default::default(),
108109
adb_device_status:Default::default(),
109-
lldb_python_dir:Default::default(),
110110
verbose:Default::default(),
111111
color:Default::default(),
112112
remote_test_client:Default::default(),

0 commit comments

Comments
 (0)
, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Auto merge of #148685 - Zalathar:lldb-python, r=jieyouxu · rust-lang/rust@00426d6 · GitHub
Skip to content

Commit 00426d6

Browse files
committed
Auto merge of #148685 - Zalathar:lldb-python, r=jieyouxu
compiletest: Run the `lldb_batchmode.py` script in LLDB's embedded Python Historically, LLDB debuginfo tests have used a Python script to control LLDB via its Python API, instead of invoking the `lldb` command directly. Unfortunately, this requires us to find and use a version of Python that is compatible with LLDB's Python bindings. However, it turns out that there is a simpler way to find a compatible Python interpreter: use the one that is embedded in LLDB itself, via the `script` command.
2 parents 5f666a6 + dca8be9 commit 00426d6

10 files changed

Lines changed: 108 additions & 110 deletions

File tree

‎bootstrap.example.toml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,7 @@
320320
#build.npm = "npm"
321321

322322
# Python interpreter to use for various tasks throughout the build, notably
323-
# rustdoc tests, the lldb python interpreter, and some dist bits and pieces.
323+
# rustdoc tests, and some dist bits and pieces.
324324
#
325325
# Defaults to the Python interpreter used to execute x.py.
326326
#build.python = "python"

‎src/bootstrap/src/core/build_steps/test.rs‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2094,11 +2094,11 @@ Please disable assertions with `rust.debug-assertions = false`.
20942094
cmd.arg("--gdb").arg(gdb);
20952095
}
20962096

2097-
ifletSome(debuggers::Lldb{lldb_version, lldb_python_dir}) =
2097+
ifletSome(debuggers::Lldb{lldb_exe, lldb_version}) =
20982098
debuggers::discover_lldb(builder)
20992099
{
2100+
cmd.arg("--lldb").arg(lldb_exe);
21002101
cmd.arg("--lldb-version").arg(lldb_version);
2101-
cmd.arg("--lldb-python-dir").arg(lldb_python_dir);
21022102
}
21032103
}
21042104

‎src/bootstrap/src/core/debuggers/lldb.rs‎

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ use crate::core::builder::Builder;
44
usecrate::utils::exec::command;
55

66
pub(crate)structLldb{
7+
pub(crate)lldb_exe:PathBuf,
78
pub(crate)lldb_version:String,
8-
pub(crate)lldb_python_dir:String,
99
}
1010

1111
pub(crate)fndiscover_lldb(builder:&Builder<'_>) -> Option<Lldb>{
@@ -21,12 +21,5 @@ pub(crate) fn discover_lldb(builder: &Builder<'_>) -> Option<Lldb> {
2121
.stdout_if_ok()
2222
.and_then(|v| if v.trim().is_empty(){None}else{Some(v)})?;
2323

24-
let lldb_python_dir = command(&lldb_exe)
25-
.allow_failure()
26-
.arg("-P")
27-
.run_capture_stdout(builder)
28-
.stdout_if_ok()
29-
.map(|p| p.lines().next().expect("lldb Python dir not found").to_string())?;
30-
31-
Some(Lldb{ lldb_version, lldb_python_dir })
24+
Some(Lldb{ lldb_exe, lldb_version })
3225
}

‎src/etc/lldb_batchmode.py‎

Lines changed: 68 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -176,77 +176,85 @@ def watchdog():
176176
watchdog_thread.start()
177177

178178

179+
defget_env_arg(name):
180+
value=os.environ.get(name)
181+
ifvalueisNone:
182+
print("must set %s"%name)
183+
sys.exit(1)
184+
returnvalue
185+
186+
179187
####################################################################################################
180188
# ~main
181189
####################################################################################################
182190

183191

184-
iflen(sys.argv) !=3:
185-
print("usage: python lldb_batchmode.py target-path script-path")
186-
sys.exit(1)
192+
defmain():
193+
target_path=get_env_arg("LLDB_BATCHMODE_TARGET_PATH")
194+
script_path=get_env_arg("LLDB_BATCHMODE_SCRIPT_PATH")
187195

188-
target_path=sys.argv[1]
189-
script_path=sys.argv[2]
196+
print("LLDB batch-mode script")
197+
print("----------------------")
198+
print("Debugger commands script is '%s'."%script_path)
199+
print("Target executable is '%s'."%target_path)
200+
print("Current working directory is '%s'"%os.getcwd())
190201

191-
print("LLDB batch-mode script")
192-
print("----------------------")
193-
print("Debugger commands script is '%s'."%script_path)
194-
print("Target executable is '%s'."%target_path)
195-
print("Current working directory is '%s'"%os.getcwd())
202+
# Start the timeout watchdog
203+
start_watchdog()
196204

197-
# Start the timeout watchdog
198-
start_watchdog()
205+
# Create a new debugger instance
206+
debugger=lldb.SBDebugger.Create()
199207

200-
# Create a new debugger instance
201-
debugger=lldb.SBDebugger.Create()
208+
# When we step or continue, don't return from the function until the process
209+
# stops. We do this by setting the async mode to false.
210+
debugger.SetAsync(False)
202211

203-
# When we step or continue, don't return from the function until the process
204-
# stops. We do this by setting the async mode to false.
205-
debugger.SetAsync(False)
212+
# Create a target from a file and arch
213+
print("Creating a target for '%s'"%target_path)
214+
target_error=lldb.SBError()
215+
target=debugger.CreateTarget(target_path, None, None, True, target_error)
206216

207-
# Create a target from a file and arch
208-
print("Creating a target for '%s'"%target_path)
209-
target_error=lldb.SBError()
210-
target=debugger.CreateTarget(target_path, None, None, True, target_error)
211-
212-
ifnottarget:
213-
print(
214-
"Could not create debugging target '"
215-
+target_path
216-
+"': "
217-
+str(target_error)
218-
+". Aborting.",
219-
file=sys.stderr,
220-
)
221-
sys.exit(1)
217+
ifnottarget:
218+
print(
219+
"Could not create debugging target '"
220+
+target_path
221+
+"': "
222+
+str(target_error)
223+
+". Aborting.",
224+
file=sys.stderr,
225+
)
226+
sys.exit(1)
222227

228+
# Register the breakpoint callback for every breakpoint
229+
start_breakpoint_listener(target)
223230

224-
# Register the breakpoint callback for every breakpoint
225-
start_breakpoint_listener(target)
231+
command_interpreter=debugger.GetCommandInterpreter()
226232

227-
command_interpreter=debugger.GetCommandInterpreter()
228-
229-
try:
230-
script_file=open(script_path, "r")
231-
232-
forlineinscript_file:
233-
command=line.strip()
234-
if (
235-
command=="run"
236-
orcommand=="r"
237-
orre.match(r"^process\s+launch.*", command)
238-
):
239-
# Before starting to run the program, let the thread sleep a bit, so all
240-
# breakpoint added events can be processed
241-
time.sleep(0.5)
242-
ifcommand!="":
243-
execute_command(command_interpreter, command)
244-
245-
exceptIOErrorase:
246-
print("Could not read debugging script '%s'."%script_path, file=sys.stderr)
247-
print(e, file=sys.stderr)
248-
print("Aborting.", file=sys.stderr)
249-
sys.exit(1)
250-
finally:
251-
debugger.Terminate()
252-
script_file.close()
233+
try:
234+
script_file=open(script_path, "r")
235+
236+
forlineinscript_file:
237+
command=line.strip()
238+
if (
239+
command=="run"
240+
orcommand=="r"
241+
orre.match(r"^process\s+launch.*", command)
242+
):
243+
# Before starting to run the program, let the thread sleep a bit, so all
244+
# breakpoint added events can be processed
245+
time.sleep(0.5)
246+
ifcommand!="":
247+
execute_command(command_interpreter, command)
248+
249+
exceptIOErrorase:
250+
print("Could not read debugging script '%s'."%script_path, file=sys.stderr)
251+
print(e, file=sys.stderr)
252+
print("Aborting.", file=sys.stderr)
253+
sys.exit(1)
254+
finally:
255+
debugger.Terminate()
256+
script_file.close()
257+
258+
259+
if__name__=="__main__":
260+
main()

‎src/tools/compiletest/src/common.rs‎

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -312,10 +312,7 @@ pub struct Config {
312312
/// Path to the `src/tools/coverage-dump/` bootstrap tool executable.
313313
pubcoverage_dump_path:Option<Utf8PathBuf>,
314314

315-
/// Path to the Python 3 executable to use for LLDB and htmldocck.
316-
///
317-
/// FIXME: the `lldb` setup currently requires I believe Python 3.10 **exactly**, it can't even
318-
/// be Python 3.11 or 3.9...
315+
/// Path to the Python 3 executable to use for htmldocck and some run-make tests.
319316
pubpython:String,
320317

321318
/// Path to the `src/tools/jsondocck/` bootstrap tool executable.
@@ -541,6 +538,9 @@ pub struct Config {
541538
/// FIXME: `gdb_version` is *derived* from gdb, but it's *not* technically a config!
542539
pubgdb_version:Option<u32>,
543540

541+
/// Path to or name of the LLDB executable to use for debuginfo tests.
542+
publldb:Option<Utf8PathBuf>,
543+
544544
/// Version of LLDB.
545545
///
546546
/// FIXME: `lldb_version` is *derived* from lldb, but it's *not* technically a config!
@@ -587,11 +587,6 @@ pub struct Config {
587587
/// FIXME: take a look at this; this also influences adb in gdb code paths in a strange way.
588588
pubadb_device_status:bool,
589589

590-
/// Path containing LLDB's Python module.
591-
///
592-
/// FIXME: `PYTHONPATH` takes precedence over this flag...? See `runtest::run_lldb`.
593-
publldb_python_dir:Option<String>,
594-
595590
/// Verbose dump a lot of info.
596591
///
597592
/// FIXME: this is *way* too coarse; the user can't select *which* info to verbosely dump.

‎src/tools/compiletest/src/debuggers.rs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ pub(crate) fn configure_gdb(config: &Config) -> Option<Arc<Config>> {
4949
}
5050

5151
pub(crate)fnconfigure_lldb(config:&Config) -> Option<Arc<Config>>{
52-
config.lldb_python_dir.as_ref()?;
52+
config.lldb.as_ref()?;
5353

5454
Some(Arc::new(Config{debugger:Some(Debugger::Lldb), ..config.clone()}))
5555
}

‎src/tools/compiletest/src/lib.rs‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -141,13 +141,13 @@ fn parse_config(args: Vec<String>) -> Config {
141141
.optopt("","host","the host to build for","HOST")
142142
.optopt("","cdb","path to CDB to use for CDB debuginfo tests","PATH")
143143
.optopt("","gdb","path to GDB to use for GDB debuginfo tests","PATH")
144+
.optopt("","lldb","path to LLDB to use for LLDB debuginfo tests","PATH")
144145
.optopt("","lldb-version","the version of LLDB used","VERSION STRING")
145146
.optopt("","llvm-version","the version of LLVM used","VERSION STRING")
146147
.optflag("","system-llvm","is LLVM the system LLVM")
147148
.optopt("","android-cross-path","Android NDK standalone path","PATH")
148149
.optopt("","adb-path","path to the android debugger","PATH")
149150
.optopt("","adb-test-dir","path to tests for the android debugger","PATH")
150-
.optopt("","lldb-python-dir","directory containing LLDB's python module","PATH")
151151
.reqopt("","cc","path to a C compiler","PATH")
152152
.reqopt("","cxx","path to a C++ compiler","PATH")
153153
.reqopt("","cflags","flags for the C compiler","FLAGS")
@@ -264,6 +264,7 @@ fn parse_config(args: Vec<String>) -> Config {
264264
let gdb = debuggers::discover_gdb(matches.opt_str("gdb"),&target,&android_cross_path);
265265
let gdb_version = gdb.as_deref().and_then(debuggers::query_gdb_version);
266266
// FIXME: `lldb_version` is *derived* from lldb, but it's *not* technically a config!
267+
let lldb = matches.opt_str("lldb").map(Utf8PathBuf::from);
267268
let lldb_version =
268269
matches.opt_str("lldb-version").as_deref().and_then(debuggers::extract_lldb_version);
269270
let color = match matches.opt_str("color").as_deref(){
@@ -435,6 +436,7 @@ fn parse_config(args: Vec<String>) -> Config {
435436
cdb_version,
436437
gdb,
437438
gdb_version,
439+
lldb,
438440
lldb_version,
439441
llvm_version,
440442
system_llvm: matches.opt_present("system-llvm"),
@@ -444,7 +446,6 @@ fn parse_config(args: Vec<String>) -> Config {
444446
adb_device_status:opt_str2(matches.opt_str("target")).contains("android")
445447
&& "(none)" != opt_str2(matches.opt_str("adb-test-dir"))
446448
&& !opt_str2(matches.opt_str("adb-test-dir")).is_empty(),
447-
lldb_python_dir: matches.opt_str("lldb-python-dir"),
448449
verbose: matches.opt_present("verbose"),
449450
only_modified: matches.opt_present("only-modified"),
450451
color,

‎src/tools/compiletest/src/runtest.rs‎

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -200,10 +200,11 @@ pub fn compute_stamp_hash(config: &Config) -> String {
200200
}
201201

202202
Some(Debugger::Lldb) => {
203-
config.python.hash(&mut hash);
204-
config.lldb_python_dir.hash(&mut hash);
203+
// LLDB debuginfo tests now use LLDB's embedded Python, with an
204+
// explicit PYTHONPATH, so they don't depend on `--python` or
205+
// the ambient PYTHONPATH.
206+
config.lldb.hash(&mut hash);
205207
env::var_os("PATH").hash(&mut hash);
206-
env::var_os("PYTHONPATH").hash(&mut hash);
207208
}
208209

209210
None => {}

‎src/tools/compiletest/src/runtest/debuginfo.rs‎

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -326,9 +326,9 @@ impl TestCx<'_> {
326326
}
327327

328328
fnrun_debuginfo_lldb_test(&self){
329-
ifself.config.lldb_python_dir.is_none(){
330-
self.fatal("Can't run LLDB test because LLDB's python path is not set.");
331-
}
329+
letSome(ref lldb) = self.config.lldbelse{
330+
self.fatal("Can't run LLDB test because LLDB's path is not set.");
331+
};
332332

333333
// compile test file (it should have 'compile-flags:-g' in the directive)
334334
let should_run = self.run_if_enabled();
@@ -434,7 +434,7 @@ impl TestCx<'_> {
434434
let debugger_script = self.make_out_name("debugger.script");
435435

436436
// Let LLDB execute the script via lldb_batchmode.py
437-
let debugger_run_result = self.run_lldb(&exe_file,&debugger_script);
437+
let debugger_run_result = self.run_lldb(lldb,&exe_file,&debugger_script);
438438

439439
if !debugger_run_result.status.success(){
440440
self.fatal_proc_rec("Error while running LLDB",&debugger_run_result);
@@ -445,23 +445,23 @@ impl TestCx<'_> {
445445
}
446446
}
447447

448-
fnrun_lldb(&self,test_executable:&Utf8Path,debugger_script:&Utf8Path) -> ProcRes{
449-
// Prepare the lldb_batchmode which executes the debugger script
450-
let lldb_script_path = self.config.src_root.join("src/etc/lldb_batchmode.py");
451-
452-
// FIXME: `PYTHONPATH` takes precedence over the flag...?
453-
let pythonpath = ifletOk(pp) = std::env::var("PYTHONPATH"){
454-
format!("{pp}:{}",self.config.lldb_python_dir.as_ref().unwrap())
455-
}else{
456-
self.config.lldb_python_dir.clone().unwrap()
457-
};
458-
self.run_command_to_procres(
459-
Command::new(&self.config.python)
460-
.arg(&lldb_script_path)
461-
.arg(test_executable)
462-
.arg(debugger_script)
463-
.env("PYTHONUNBUFFERED","1")// Help debugging #78665
464-
.env("PYTHONPATH", pythonpath),
465-
)
448+
fnrun_lldb(
449+
&self,
450+
lldb:&Utf8Path,
451+
test_executable:&Utf8Path,
452+
debugger_script:&Utf8Path,
453+
) -> ProcRes{
454+
// Path containing `lldb_batchmode.py`, so that the `script` command can import it.
455+
let pythonpath = self.config.src_root.join("src/etc");
456+
457+
letmut cmd = Command::new(lldb);
458+
cmd.arg("--one-line")
459+
.arg("script --language python -- import lldb_batchmode; lldb_batchmode.main()")
460+
.env("LLDB_BATCHMODE_TARGET_PATH", test_executable)
461+
.env("LLDB_BATCHMODE_SCRIPT_PATH", debugger_script)
462+
.env("PYTHONUNBUFFERED","1")// Help debugging #78665
463+
.env("PYTHONPATH",pythonpath);
464+
465+
self.run_command_to_procres(&mut cmd)
466466
}
467467
}

‎src/tools/compiletest/src/rustdoc_gui_test.rs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,14 +99,14 @@ fn incomplete_config_for_rustdoc_gui_test() -> Config {
9999
cdb_version:Default::default(),
100100
gdb:Default::default(),
101101
gdb_version:Default::default(),
102+
lldb:Default::default(),
102103
lldb_version:Default::default(),
103104
llvm_version:Default::default(),
104105
system_llvm:Default::default(),
105106
android_cross_path:Default::default(),
106107
adb_path:Default::default(),
107108
adb_test_dir:Default::default(),
108109
adb_device_status:Default::default(),
109-
lldb_python_dir:Default::default(),
110110
verbose:Default::default(),
111111
color:Default::default(),
112112
remote_test_client:Default::default(),

0 commit comments

Comments
 (0)
, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Auto merge of #148685 - Zalathar:lldb-python, r=jieyouxu · rust-lang/rust@00426d6 · GitHub
Skip to content

Commit 00426d6

Browse files
committed
Auto merge of #148685 - Zalathar:lldb-python, r=jieyouxu
compiletest: Run the `lldb_batchmode.py` script in LLDB's embedded Python Historically, LLDB debuginfo tests have used a Python script to control LLDB via its Python API, instead of invoking the `lldb` command directly. Unfortunately, this requires us to find and use a version of Python that is compatible with LLDB's Python bindings. However, it turns out that there is a simpler way to find a compatible Python interpreter: use the one that is embedded in LLDB itself, via the `script` command.
2 parents 5f666a6 + dca8be9 commit 00426d6

10 files changed

Lines changed: 108 additions & 110 deletions

File tree

‎bootstrap.example.toml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,7 @@
320320
#build.npm = "npm"
321321

322322
# Python interpreter to use for various tasks throughout the build, notably
323-
# rustdoc tests, the lldb python interpreter, and some dist bits and pieces.
323+
# rustdoc tests, and some dist bits and pieces.
324324
#
325325
# Defaults to the Python interpreter used to execute x.py.
326326
#build.python = "python"

‎src/bootstrap/src/core/build_steps/test.rs‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2094,11 +2094,11 @@ Please disable assertions with `rust.debug-assertions = false`.
20942094
cmd.arg("--gdb").arg(gdb);
20952095
}
20962096

2097-
ifletSome(debuggers::Lldb{lldb_version, lldb_python_dir}) =
2097+
ifletSome(debuggers::Lldb{lldb_exe, lldb_version}) =
20982098
debuggers::discover_lldb(builder)
20992099
{
2100+
cmd.arg("--lldb").arg(lldb_exe);
21002101
cmd.arg("--lldb-version").arg(lldb_version);
2101-
cmd.arg("--lldb-python-dir").arg(lldb_python_dir);
21022102
}
21032103
}
21042104

‎src/bootstrap/src/core/debuggers/lldb.rs‎

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ use crate::core::builder::Builder;
44
usecrate::utils::exec::command;
55

66
pub(crate)structLldb{
7+
pub(crate)lldb_exe:PathBuf,
78
pub(crate)lldb_version:String,
8-
pub(crate)lldb_python_dir:String,
99
}
1010

1111
pub(crate)fndiscover_lldb(builder:&Builder<'_>) -> Option<Lldb>{
@@ -21,12 +21,5 @@ pub(crate) fn discover_lldb(builder: &Builder<'_>) -> Option<Lldb> {
2121
.stdout_if_ok()
2222
.and_then(|v| if v.trim().is_empty(){None}else{Some(v)})?;
2323

24-
let lldb_python_dir = command(&lldb_exe)
25-
.allow_failure()
26-
.arg("-P")
27-
.run_capture_stdout(builder)
28-
.stdout_if_ok()
29-
.map(|p| p.lines().next().expect("lldb Python dir not found").to_string())?;
30-
31-
Some(Lldb{ lldb_version, lldb_python_dir })
24+
Some(Lldb{ lldb_exe, lldb_version })
3225
}

‎src/etc/lldb_batchmode.py‎

Lines changed: 68 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -176,77 +176,85 @@ def watchdog():
176176
watchdog_thread.start()
177177

178178

179+
defget_env_arg(name):
180+
value=os.environ.get(name)
181+
ifvalueisNone:
182+
print("must set %s"%name)
183+
sys.exit(1)
184+
returnvalue
185+
186+
179187
####################################################################################################
180188
# ~main
181189
####################################################################################################
182190

183191

184-
iflen(sys.argv) !=3:
185-
print("usage: python lldb_batchmode.py target-path script-path")
186-
sys.exit(1)
192+
defmain():
193+
target_path=get_env_arg("LLDB_BATCHMODE_TARGET_PATH")
194+
script_path=get_env_arg("LLDB_BATCHMODE_SCRIPT_PATH")
187195

188-
target_path=sys.argv[1]
189-
script_path=sys.argv[2]
196+
print("LLDB batch-mode script")
197+
print("----------------------")
198+
print("Debugger commands script is '%s'."%script_path)
199+
print("Target executable is '%s'."%target_path)
200+
print("Current working directory is '%s'"%os.getcwd())
190201

191-
print("LLDB batch-mode script")
192-
print("----------------------")
193-
print("Debugger commands script is '%s'."%script_path)
194-
print("Target executable is '%s'."%target_path)
195-
print("Current working directory is '%s'"%os.getcwd())
202+
# Start the timeout watchdog
203+
start_watchdog()
196204

197-
# Start the timeout watchdog
198-
start_watchdog()
205+
# Create a new debugger instance
206+
debugger=lldb.SBDebugger.Create()
199207

200-
# Create a new debugger instance
201-
debugger=lldb.SBDebugger.Create()
208+
# When we step or continue, don't return from the function until the process
209+
# stops. We do this by setting the async mode to false.
210+
debugger.SetAsync(False)
202211

203-
# When we step or continue, don't return from the function until the process
204-
# stops. We do this by setting the async mode to false.
205-
debugger.SetAsync(False)
212+
# Create a target from a file and arch
213+
print("Creating a target for '%s'"%target_path)
214+
target_error=lldb.SBError()
215+
target=debugger.CreateTarget(target_path, None, None, True, target_error)
206216

207-
# Create a target from a file and arch
208-
print("Creating a target for '%s'"%target_path)
209-
target_error=lldb.SBError()
210-
target=debugger.CreateTarget(target_path, None, None, True, target_error)
211-
212-
ifnottarget:
213-
print(
214-
"Could not create debugging target '"
215-
+target_path
216-
+"': "
217-
+str(target_error)
218-
+". Aborting.",
219-
file=sys.stderr,
220-
)
221-
sys.exit(1)
217+
ifnottarget:
218+
print(
219+
"Could not create debugging target '"
220+
+target_path
221+
+"': "
222+
+str(target_error)
223+
+". Aborting.",
224+
file=sys.stderr,
225+
)
226+
sys.exit(1)
222227

228+
# Register the breakpoint callback for every breakpoint
229+
start_breakpoint_listener(target)
223230

224-
# Register the breakpoint callback for every breakpoint
225-
start_breakpoint_listener(target)
231+
command_interpreter=debugger.GetCommandInterpreter()
226232

227-
command_interpreter=debugger.GetCommandInterpreter()
228-
229-
try:
230-
script_file=open(script_path, "r")
231-
232-
forlineinscript_file:
233-
command=line.strip()
234-
if (
235-
command=="run"
236-
orcommand=="r"
237-
orre.match(r"^process\s+launch.*", command)
238-
):
239-
# Before starting to run the program, let the thread sleep a bit, so all
240-
# breakpoint added events can be processed
241-
time.sleep(0.5)
242-
ifcommand!="":
243-
execute_command(command_interpreter, command)
244-
245-
exceptIOErrorase:
246-
print("Could not read debugging script '%s'."%script_path, file=sys.stderr)
247-
print(e, file=sys.stderr)
248-
print("Aborting.", file=sys.stderr)
249-
sys.exit(1)
250-
finally:
251-
debugger.Terminate()
252-
script_file.close()
233+
try:
234+
script_file=open(script_path, "r")
235+
236+
forlineinscript_file:
237+
command=line.strip()
238+
if (
239+
command=="run"
240+
orcommand=="r"
241+
orre.match(r"^process\s+launch.*", command)
242+
):
243+
# Before starting to run the program, let the thread sleep a bit, so all
244+
# breakpoint added events can be processed
245+
time.sleep(0.5)
246+
ifcommand!="":
247+
execute_command(command_interpreter, command)
248+
249+
exceptIOErrorase:
250+
print("Could not read debugging script '%s'."%script_path, file=sys.stderr)
251+
print(e, file=sys.stderr)
252+
print("Aborting.", file=sys.stderr)
253+
sys.exit(1)
254+
finally:
255+
debugger.Terminate()
256+
script_file.close()
257+
258+
259+
if__name__=="__main__":
260+
main()

‎src/tools/compiletest/src/common.rs‎

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -312,10 +312,7 @@ pub struct Config {
312312
/// Path to the `src/tools/coverage-dump/` bootstrap tool executable.
313313
pubcoverage_dump_path:Option<Utf8PathBuf>,
314314

315-
/// Path to the Python 3 executable to use for LLDB and htmldocck.
316-
///
317-
/// FIXME: the `lldb` setup currently requires I believe Python 3.10 **exactly**, it can't even
318-
/// be Python 3.11 or 3.9...
315+
/// Path to the Python 3 executable to use for htmldocck and some run-make tests.
319316
pubpython:String,
320317

321318
/// Path to the `src/tools/jsondocck/` bootstrap tool executable.
@@ -541,6 +538,9 @@ pub struct Config {
541538
/// FIXME: `gdb_version` is *derived* from gdb, but it's *not* technically a config!
542539
pubgdb_version:Option<u32>,
543540

541+
/// Path to or name of the LLDB executable to use for debuginfo tests.
542+
publldb:Option<Utf8PathBuf>,
543+
544544
/// Version of LLDB.
545545
///
546546
/// FIXME: `lldb_version` is *derived* from lldb, but it's *not* technically a config!
@@ -587,11 +587,6 @@ pub struct Config {
587587
/// FIXME: take a look at this; this also influences adb in gdb code paths in a strange way.
588588
pubadb_device_status:bool,
589589

590-
/// Path containing LLDB's Python module.
591-
///
592-
/// FIXME: `PYTHONPATH` takes precedence over this flag...? See `runtest::run_lldb`.
593-
publldb_python_dir:Option<String>,
594-
595590
/// Verbose dump a lot of info.
596591
///
597592
/// FIXME: this is *way* too coarse; the user can't select *which* info to verbosely dump.

‎src/tools/compiletest/src/debuggers.rs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ pub(crate) fn configure_gdb(config: &Config) -> Option<Arc<Config>> {
4949
}
5050

5151
pub(crate)fnconfigure_lldb(config:&Config) -> Option<Arc<Config>>{
52-
config.lldb_python_dir.as_ref()?;
52+
config.lldb.as_ref()?;
5353

5454
Some(Arc::new(Config{debugger:Some(Debugger::Lldb), ..config.clone()}))
5555
}

‎src/tools/compiletest/src/lib.rs‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -141,13 +141,13 @@ fn parse_config(args: Vec<String>) -> Config {
141141
.optopt("","host","the host to build for","HOST")
142142
.optopt("","cdb","path to CDB to use for CDB debuginfo tests","PATH")
143143
.optopt("","gdb","path to GDB to use for GDB debuginfo tests","PATH")
144+
.optopt("","lldb","path to LLDB to use for LLDB debuginfo tests","PATH")
144145
.optopt("","lldb-version","the version of LLDB used","VERSION STRING")
145146
.optopt("","llvm-version","the version of LLVM used","VERSION STRING")
146147
.optflag("","system-llvm","is LLVM the system LLVM")
147148
.optopt("","android-cross-path","Android NDK standalone path","PATH")
148149
.optopt("","adb-path","path to the android debugger","PATH")
149150
.optopt("","adb-test-dir","path to tests for the android debugger","PATH")
150-
.optopt("","lldb-python-dir","directory containing LLDB's python module","PATH")
151151
.reqopt("","cc","path to a C compiler","PATH")
152152
.reqopt("","cxx","path to a C++ compiler","PATH")
153153
.reqopt("","cflags","flags for the C compiler","FLAGS")
@@ -264,6 +264,7 @@ fn parse_config(args: Vec<String>) -> Config {
264264
let gdb = debuggers::discover_gdb(matches.opt_str("gdb"),&target,&android_cross_path);
265265
let gdb_version = gdb.as_deref().and_then(debuggers::query_gdb_version);
266266
// FIXME: `lldb_version` is *derived* from lldb, but it's *not* technically a config!
267+
let lldb = matches.opt_str("lldb").map(Utf8PathBuf::from);
267268
let lldb_version =
268269
matches.opt_str("lldb-version").as_deref().and_then(debuggers::extract_lldb_version);
269270
let color = match matches.opt_str("color").as_deref(){
@@ -435,6 +436,7 @@ fn parse_config(args: Vec<String>) -> Config {
435436
cdb_version,
436437
gdb,
437438
gdb_version,
439+
lldb,
438440
lldb_version,
439441
llvm_version,
440442
system_llvm: matches.opt_present("system-llvm"),
@@ -444,7 +446,6 @@ fn parse_config(args: Vec<String>) -> Config {
444446
adb_device_status:opt_str2(matches.opt_str("target")).contains("android")
445447
&& "(none)" != opt_str2(matches.opt_str("adb-test-dir"))
446448
&& !opt_str2(matches.opt_str("adb-test-dir")).is_empty(),
447-
lldb_python_dir: matches.opt_str("lldb-python-dir"),
448449
verbose: matches.opt_present("verbose"),
449450
only_modified: matches.opt_present("only-modified"),
450451
color,

‎src/tools/compiletest/src/runtest.rs‎

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -200,10 +200,11 @@ pub fn compute_stamp_hash(config: &Config) -> String {
200200
}
201201

202202
Some(Debugger::Lldb) => {
203-
config.python.hash(&mut hash);
204-
config.lldb_python_dir.hash(&mut hash);
203+
// LLDB debuginfo tests now use LLDB's embedded Python, with an
204+
// explicit PYTHONPATH, so they don't depend on `--python` or
205+
// the ambient PYTHONPATH.
206+
config.lldb.hash(&mut hash);
205207
env::var_os("PATH").hash(&mut hash);
206-
env::var_os("PYTHONPATH").hash(&mut hash);
207208
}
208209

209210
None => {}

‎src/tools/compiletest/src/runtest/debuginfo.rs‎

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -326,9 +326,9 @@ impl TestCx<'_> {
326326
}
327327

328328
fnrun_debuginfo_lldb_test(&self){
329-
ifself.config.lldb_python_dir.is_none(){
330-
self.fatal("Can't run LLDB test because LLDB's python path is not set.");
331-
}
329+
letSome(ref lldb) = self.config.lldbelse{
330+
self.fatal("Can't run LLDB test because LLDB's path is not set.");
331+
};
332332

333333
// compile test file (it should have 'compile-flags:-g' in the directive)
334334
let should_run = self.run_if_enabled();
@@ -434,7 +434,7 @@ impl TestCx<'_> {
434434
let debugger_script = self.make_out_name("debugger.script");
435435

436436
// Let LLDB execute the script via lldb_batchmode.py
437-
let debugger_run_result = self.run_lldb(&exe_file,&debugger_script);
437+
let debugger_run_result = self.run_lldb(lldb,&exe_file,&debugger_script);
438438

439439
if !debugger_run_result.status.success(){
440440
self.fatal_proc_rec("Error while running LLDB",&debugger_run_result);
@@ -445,23 +445,23 @@ impl TestCx<'_> {
445445
}
446446
}
447447

448-
fnrun_lldb(&self,test_executable:&Utf8Path,debugger_script:&Utf8Path) -> ProcRes{
449-
// Prepare the lldb_batchmode which executes the debugger script
450-
let lldb_script_path = self.config.src_root.join("src/etc/lldb_batchmode.py");
451-
452-
// FIXME: `PYTHONPATH` takes precedence over the flag...?
453-
let pythonpath = ifletOk(pp) = std::env::var("PYTHONPATH"){
454-
format!("{pp}:{}",self.config.lldb_python_dir.as_ref().unwrap())
455-
}else{
456-
self.config.lldb_python_dir.clone().unwrap()
457-
};
458-
self.run_command_to_procres(
459-
Command::new(&self.config.python)
460-
.arg(&lldb_script_path)
461-
.arg(test_executable)
462-
.arg(debugger_script)
463-
.env("PYTHONUNBUFFERED","1")// Help debugging #78665
464-
.env("PYTHONPATH", pythonpath),
465-
)
448+
fnrun_lldb(
449+
&self,
450+
lldb:&Utf8Path,
451+
test_executable:&Utf8Path,
452+
debugger_script:&Utf8Path,
453+
) -> ProcRes{
454+
// Path containing `lldb_batchmode.py`, so that the `script` command can import it.
455+
let pythonpath = self.config.src_root.join("src/etc");
456+
457+
letmut cmd = Command::new(lldb);
458+
cmd.arg("--one-line")
459+
.arg("script --language python -- import lldb_batchmode; lldb_batchmode.main()")
460+
.env("LLDB_BATCHMODE_TARGET_PATH", test_executable)
461+
.env("LLDB_BATCHMODE_SCRIPT_PATH", debugger_script)
462+
.env("PYTHONUNBUFFERED","1")// Help debugging #78665
463+
.env("PYTHONPATH",pythonpath);
464+
465+
self.run_command_to_procres(&mut cmd)
466466
}
467467
}

‎src/tools/compiletest/src/rustdoc_gui_test.rs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,14 +99,14 @@ fn incomplete_config_for_rustdoc_gui_test() -> Config {
9999
cdb_version:Default::default(),
100100
gdb:Default::default(),
101101
gdb_version:Default::default(),
102+
lldb:Default::default(),
102103
lldb_version:Default::default(),
103104
llvm_version:Default::default(),
104105
system_llvm:Default::default(),
105106
android_cross_path:Default::default(),
106107
adb_path:Default::default(),
107108
adb_test_dir:Default::default(),
108109
adb_device_status:Default::default(),
109-
lldb_python_dir:Default::default(),
110110
verbose:Default::default(),
111111
color:Default::default(),
112112
remote_test_client:Default::default(),

0 commit comments

Comments
 (0)
, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Auto merge of #148685 - Zalathar:lldb-python, r=jieyouxu · rust-lang/rust@00426d6 · GitHub
Skip to content

Commit 00426d6

Browse files
committed
Auto merge of #148685 - Zalathar:lldb-python, r=jieyouxu
compiletest: Run the `lldb_batchmode.py` script in LLDB's embedded Python Historically, LLDB debuginfo tests have used a Python script to control LLDB via its Python API, instead of invoking the `lldb` command directly. Unfortunately, this requires us to find and use a version of Python that is compatible with LLDB's Python bindings. However, it turns out that there is a simpler way to find a compatible Python interpreter: use the one that is embedded in LLDB itself, via the `script` command.
2 parents 5f666a6 + dca8be9 commit 00426d6

10 files changed

Lines changed: 108 additions & 110 deletions

File tree

‎bootstrap.example.toml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,7 @@
320320
#build.npm = "npm"
321321

322322
# Python interpreter to use for various tasks throughout the build, notably
323-
# rustdoc tests, the lldb python interpreter, and some dist bits and pieces.
323+
# rustdoc tests, and some dist bits and pieces.
324324
#
325325
# Defaults to the Python interpreter used to execute x.py.
326326
#build.python = "python"

‎src/bootstrap/src/core/build_steps/test.rs‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2094,11 +2094,11 @@ Please disable assertions with `rust.debug-assertions = false`.
20942094
cmd.arg("--gdb").arg(gdb);
20952095
}
20962096

2097-
ifletSome(debuggers::Lldb{lldb_version, lldb_python_dir}) =
2097+
ifletSome(debuggers::Lldb{lldb_exe, lldb_version}) =
20982098
debuggers::discover_lldb(builder)
20992099
{
2100+
cmd.arg("--lldb").arg(lldb_exe);
21002101
cmd.arg("--lldb-version").arg(lldb_version);
2101-
cmd.arg("--lldb-python-dir").arg(lldb_python_dir);
21022102
}
21032103
}
21042104

‎src/bootstrap/src/core/debuggers/lldb.rs‎

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ use crate::core::builder::Builder;
44
usecrate::utils::exec::command;
55

66
pub(crate)structLldb{
7+
pub(crate)lldb_exe:PathBuf,
78
pub(crate)lldb_version:String,
8-
pub(crate)lldb_python_dir:String,
99
}
1010

1111
pub(crate)fndiscover_lldb(builder:&Builder<'_>) -> Option<Lldb>{
@@ -21,12 +21,5 @@ pub(crate) fn discover_lldb(builder: &Builder<'_>) -> Option<Lldb> {
2121
.stdout_if_ok()
2222
.and_then(|v| if v.trim().is_empty(){None}else{Some(v)})?;
2323

24-
let lldb_python_dir = command(&lldb_exe)
25-
.allow_failure()
26-
.arg("-P")
27-
.run_capture_stdout(builder)
28-
.stdout_if_ok()
29-
.map(|p| p.lines().next().expect("lldb Python dir not found").to_string())?;
30-
31-
Some(Lldb{ lldb_version, lldb_python_dir })
24+
Some(Lldb{ lldb_exe, lldb_version })
3225
}

‎src/etc/lldb_batchmode.py‎

Lines changed: 68 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -176,77 +176,85 @@ def watchdog():
176176
watchdog_thread.start()
177177

178178

179+
defget_env_arg(name):
180+
value=os.environ.get(name)
181+
ifvalueisNone:
182+
print("must set %s"%name)
183+
sys.exit(1)
184+
returnvalue
185+
186+
179187
####################################################################################################
180188
# ~main
181189
####################################################################################################
182190

183191

184-
iflen(sys.argv) !=3:
185-
print("usage: python lldb_batchmode.py target-path script-path")
186-
sys.exit(1)
192+
defmain():
193+
target_path=get_env_arg("LLDB_BATCHMODE_TARGET_PATH")
194+
script_path=get_env_arg("LLDB_BATCHMODE_SCRIPT_PATH")
187195

188-
target_path=sys.argv[1]
189-
script_path=sys.argv[2]
196+
print("LLDB batch-mode script")
197+
print("----------------------")
198+
print("Debugger commands script is '%s'."%script_path)
199+
print("Target executable is '%s'."%target_path)
200+
print("Current working directory is '%s'"%os.getcwd())
190201

191-
print("LLDB batch-mode script")
192-
print("----------------------")
193-
print("Debugger commands script is '%s'."%script_path)
194-
print("Target executable is '%s'."%target_path)
195-
print("Current working directory is '%s'"%os.getcwd())
202+
# Start the timeout watchdog
203+
start_watchdog()
196204

197-
# Start the timeout watchdog
198-
start_watchdog()
205+
# Create a new debugger instance
206+
debugger=lldb.SBDebugger.Create()
199207

200-
# Create a new debugger instance
201-
debugger=lldb.SBDebugger.Create()
208+
# When we step or continue, don't return from the function until the process
209+
# stops. We do this by setting the async mode to false.
210+
debugger.SetAsync(False)
202211

203-
# When we step or continue, don't return from the function until the process
204-
# stops. We do this by setting the async mode to false.
205-
debugger.SetAsync(False)
212+
# Create a target from a file and arch
213+
print("Creating a target for '%s'"%target_path)
214+
target_error=lldb.SBError()
215+
target=debugger.CreateTarget(target_path, None, None, True, target_error)
206216

207-
# Create a target from a file and arch
208-
print("Creating a target for '%s'"%target_path)
209-
target_error=lldb.SBError()
210-
target=debugger.CreateTarget(target_path, None, None, True, target_error)
211-
212-
ifnottarget:
213-
print(
214-
"Could not create debugging target '"
215-
+target_path
216-
+"': "
217-
+str(target_error)
218-
+". Aborting.",
219-
file=sys.stderr,
220-
)
221-
sys.exit(1)
217+
ifnottarget:
218+
print(
219+
"Could not create debugging target '"
220+
+target_path
221+
+"': "
222+
+str(target_error)
223+
+". Aborting.",
224+
file=sys.stderr,
225+
)
226+
sys.exit(1)
222227

228+
# Register the breakpoint callback for every breakpoint
229+
start_breakpoint_listener(target)
223230

224-
# Register the breakpoint callback for every breakpoint
225-
start_breakpoint_listener(target)
231+
command_interpreter=debugger.GetCommandInterpreter()
226232

227-
command_interpreter=debugger.GetCommandInterpreter()
228-
229-
try:
230-
script_file=open(script_path, "r")
231-
232-
forlineinscript_file:
233-
command=line.strip()
234-
if (
235-
command=="run"
236-
orcommand=="r"
237-
orre.match(r"^process\s+launch.*", command)
238-
):
239-
# Before starting to run the program, let the thread sleep a bit, so all
240-
# breakpoint added events can be processed
241-
time.sleep(0.5)
242-
ifcommand!="":
243-
execute_command(command_interpreter, command)
244-
245-
exceptIOErrorase:
246-
print("Could not read debugging script '%s'."%script_path, file=sys.stderr)
247-
print(e, file=sys.stderr)
248-
print("Aborting.", file=sys.stderr)
249-
sys.exit(1)
250-
finally:
251-
debugger.Terminate()
252-
script_file.close()
233+
try:
234+
script_file=open(script_path, "r")
235+
236+
forlineinscript_file:
237+
command=line.strip()
238+
if (
239+
command=="run"
240+
orcommand=="r"
241+
orre.match(r"^process\s+launch.*", command)
242+
):
243+
# Before starting to run the program, let the thread sleep a bit, so all
244+
# breakpoint added events can be processed
245+
time.sleep(0.5)
246+
ifcommand!="":
247+
execute_command(command_interpreter, command)
248+
249+
exceptIOErrorase:
250+
print("Could not read debugging script '%s'."%script_path, file=sys.stderr)
251+
print(e, file=sys.stderr)
252+
print("Aborting.", file=sys.stderr)
253+
sys.exit(1)
254+
finally:
255+
debugger.Terminate()
256+
script_file.close()
257+
258+
259+
if__name__=="__main__":
260+
main()

‎src/tools/compiletest/src/common.rs‎

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -312,10 +312,7 @@ pub struct Config {
312312
/// Path to the `src/tools/coverage-dump/` bootstrap tool executable.
313313
pubcoverage_dump_path:Option<Utf8PathBuf>,
314314

315-
/// Path to the Python 3 executable to use for LLDB and htmldocck.
316-
///
317-
/// FIXME: the `lldb` setup currently requires I believe Python 3.10 **exactly**, it can't even
318-
/// be Python 3.11 or 3.9...
315+
/// Path to the Python 3 executable to use for htmldocck and some run-make tests.
319316
pubpython:String,
320317

321318
/// Path to the `src/tools/jsondocck/` bootstrap tool executable.
@@ -541,6 +538,9 @@ pub struct Config {
541538
/// FIXME: `gdb_version` is *derived* from gdb, but it's *not* technically a config!
542539
pubgdb_version:Option<u32>,
543540

541+
/// Path to or name of the LLDB executable to use for debuginfo tests.
542+
publldb:Option<Utf8PathBuf>,
543+
544544
/// Version of LLDB.
545545
///
546546
/// FIXME: `lldb_version` is *derived* from lldb, but it's *not* technically a config!
@@ -587,11 +587,6 @@ pub struct Config {
587587
/// FIXME: take a look at this; this also influences adb in gdb code paths in a strange way.
588588
pubadb_device_status:bool,
589589

590-
/// Path containing LLDB's Python module.
591-
///
592-
/// FIXME: `PYTHONPATH` takes precedence over this flag...? See `runtest::run_lldb`.
593-
publldb_python_dir:Option<String>,
594-
595590
/// Verbose dump a lot of info.
596591
///
597592
/// FIXME: this is *way* too coarse; the user can't select *which* info to verbosely dump.

‎src/tools/compiletest/src/debuggers.rs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ pub(crate) fn configure_gdb(config: &Config) -> Option<Arc<Config>> {
4949
}
5050

5151
pub(crate)fnconfigure_lldb(config:&Config) -> Option<Arc<Config>>{
52-
config.lldb_python_dir.as_ref()?;
52+
config.lldb.as_ref()?;
5353

5454
Some(Arc::new(Config{debugger:Some(Debugger::Lldb), ..config.clone()}))
5555
}

‎src/tools/compiletest/src/lib.rs‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -141,13 +141,13 @@ fn parse_config(args: Vec<String>) -> Config {
141141
.optopt("","host","the host to build for","HOST")
142142
.optopt("","cdb","path to CDB to use for CDB debuginfo tests","PATH")
143143
.optopt("","gdb","path to GDB to use for GDB debuginfo tests","PATH")
144+
.optopt("","lldb","path to LLDB to use for LLDB debuginfo tests","PATH")
144145
.optopt("","lldb-version","the version of LLDB used","VERSION STRING")
145146
.optopt("","llvm-version","the version of LLVM used","VERSION STRING")
146147
.optflag("","system-llvm","is LLVM the system LLVM")
147148
.optopt("","android-cross-path","Android NDK standalone path","PATH")
148149
.optopt("","adb-path","path to the android debugger","PATH")
149150
.optopt("","adb-test-dir","path to tests for the android debugger","PATH")
150-
.optopt("","lldb-python-dir","directory containing LLDB's python module","PATH")
151151
.reqopt("","cc","path to a C compiler","PATH")
152152
.reqopt("","cxx","path to a C++ compiler","PATH")
153153
.reqopt("","cflags","flags for the C compiler","FLAGS")
@@ -264,6 +264,7 @@ fn parse_config(args: Vec<String>) -> Config {
264264
let gdb = debuggers::discover_gdb(matches.opt_str("gdb"),&target,&android_cross_path);
265265
let gdb_version = gdb.as_deref().and_then(debuggers::query_gdb_version);
266266
// FIXME: `lldb_version` is *derived* from lldb, but it's *not* technically a config!
267+
let lldb = matches.opt_str("lldb").map(Utf8PathBuf::from);
267268
let lldb_version =
268269
matches.opt_str("lldb-version").as_deref().and_then(debuggers::extract_lldb_version);
269270
let color = match matches.opt_str("color").as_deref(){
@@ -435,6 +436,7 @@ fn parse_config(args: Vec<String>) -> Config {
435436
cdb_version,
436437
gdb,
437438
gdb_version,
439+
lldb,
438440
lldb_version,
439441
llvm_version,
440442
system_llvm: matches.opt_present("system-llvm"),
@@ -444,7 +446,6 @@ fn parse_config(args: Vec<String>) -> Config {
444446
adb_device_status:opt_str2(matches.opt_str("target")).contains("android")
445447
&& "(none)" != opt_str2(matches.opt_str("adb-test-dir"))
446448
&& !opt_str2(matches.opt_str("adb-test-dir")).is_empty(),
447-
lldb_python_dir: matches.opt_str("lldb-python-dir"),
448449
verbose: matches.opt_present("verbose"),
449450
only_modified: matches.opt_present("only-modified"),
450451
color,

‎src/tools/compiletest/src/runtest.rs‎

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -200,10 +200,11 @@ pub fn compute_stamp_hash(config: &Config) -> String {
200200
}
201201

202202
Some(Debugger::Lldb) => {
203-
config.python.hash(&mut hash);
204-
config.lldb_python_dir.hash(&mut hash);
203+
// LLDB debuginfo tests now use LLDB's embedded Python, with an
204+
// explicit PYTHONPATH, so they don't depend on `--python` or
205+
// the ambient PYTHONPATH.
206+
config.lldb.hash(&mut hash);
205207
env::var_os("PATH").hash(&mut hash);
206-
env::var_os("PYTHONPATH").hash(&mut hash);
207208
}
208209

209210
None => {}

‎src/tools/compiletest/src/runtest/debuginfo.rs‎

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -326,9 +326,9 @@ impl TestCx<'_> {
326326
}
327327

328328
fnrun_debuginfo_lldb_test(&self){
329-
ifself.config.lldb_python_dir.is_none(){
330-
self.fatal("Can't run LLDB test because LLDB's python path is not set.");
331-
}
329+
letSome(ref lldb) = self.config.lldbelse{
330+
self.fatal("Can't run LLDB test because LLDB's path is not set.");
331+
};
332332

333333
// compile test file (it should have 'compile-flags:-g' in the directive)
334334
let should_run = self.run_if_enabled();
@@ -434,7 +434,7 @@ impl TestCx<'_> {
434434
let debugger_script = self.make_out_name("debugger.script");
435435

436436
// Let LLDB execute the script via lldb_batchmode.py
437-
let debugger_run_result = self.run_lldb(&exe_file,&debugger_script);
437+
let debugger_run_result = self.run_lldb(lldb,&exe_file,&debugger_script);
438438

439439
if !debugger_run_result.status.success(){
440440
self.fatal_proc_rec("Error while running LLDB",&debugger_run_result);
@@ -445,23 +445,23 @@ impl TestCx<'_> {
445445
}
446446
}
447447

448-
fnrun_lldb(&self,test_executable:&Utf8Path,debugger_script:&Utf8Path) -> ProcRes{
449-
// Prepare the lldb_batchmode which executes the debugger script
450-
let lldb_script_path = self.config.src_root.join("src/etc/lldb_batchmode.py");
451-
452-
// FIXME: `PYTHONPATH` takes precedence over the flag...?
453-
let pythonpath = ifletOk(pp) = std::env::var("PYTHONPATH"){
454-
format!("{pp}:{}",self.config.lldb_python_dir.as_ref().unwrap())
455-
}else{
456-
self.config.lldb_python_dir.clone().unwrap()
457-
};
458-
self.run_command_to_procres(
459-
Command::new(&self.config.python)
460-
.arg(&lldb_script_path)
461-
.arg(test_executable)
462-
.arg(debugger_script)
463-
.env("PYTHONUNBUFFERED","1")// Help debugging #78665
464-
.env("PYTHONPATH", pythonpath),
465-
)
448+
fnrun_lldb(
449+
&self,
450+
lldb:&Utf8Path,
451+
test_executable:&Utf8Path,
452+
debugger_script:&Utf8Path,
453+
) -> ProcRes{
454+
// Path containing `lldb_batchmode.py`, so that the `script` command can import it.
455+
let pythonpath = self.config.src_root.join("src/etc");
456+
457+
letmut cmd = Command::new(lldb);
458+
cmd.arg("--one-line")
459+
.arg("script --language python -- import lldb_batchmode; lldb_batchmode.main()")
460+
.env("LLDB_BATCHMODE_TARGET_PATH", test_executable)
461+
.env("LLDB_BATCHMODE_SCRIPT_PATH", debugger_script)
462+
.env("PYTHONUNBUFFERED","1")// Help debugging #78665
463+
.env("PYTHONPATH",pythonpath);
464+
465+
self.run_command_to_procres(&mut cmd)
466466
}
467467
}

‎src/tools/compiletest/src/rustdoc_gui_test.rs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,14 +99,14 @@ fn incomplete_config_for_rustdoc_gui_test() -> Config {
9999
cdb_version:Default::default(),
100100
gdb:Default::default(),
101101
gdb_version:Default::default(),
102+
lldb:Default::default(),
102103
lldb_version:Default::default(),
103104
llvm_version:Default::default(),
104105
system_llvm:Default::default(),
105106
android_cross_path:Default::default(),
106107
adb_path:Default::default(),
107108
adb_test_dir:Default::default(),
108109
adb_device_status:Default::default(),
109-
lldb_python_dir:Default::default(),
110110
verbose:Default::default(),
111111
color:Default::default(),
112112
remote_test_client:Default::default(),

0 commit comments

Comments
 (0)
, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ' Auto merge of #148685 - Zalathar:lldb-python, r=jieyouxu · rust-lang/rust@00426d6 · GitHub
Skip to content

Commit 00426d6

Browse files
committed
Auto merge of #148685 - Zalathar:lldb-python, r=jieyouxu
compiletest: Run the `lldb_batchmode.py` script in LLDB's embedded Python Historically, LLDB debuginfo tests have used a Python script to control LLDB via its Python API, instead of invoking the `lldb` command directly. Unfortunately, this requires us to find and use a version of Python that is compatible with LLDB's Python bindings. However, it turns out that there is a simpler way to find a compatible Python interpreter: use the one that is embedded in LLDB itself, via the `script` command.
2 parents 5f666a6 + dca8be9 commit 00426d6

10 files changed

Lines changed: 108 additions & 110 deletions

File tree

‎bootstrap.example.toml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,7 @@
320320
#build.npm = "npm"
321321

322322
# Python interpreter to use for various tasks throughout the build, notably
323-
# rustdoc tests, the lldb python interpreter, and some dist bits and pieces.
323+
# rustdoc tests, and some dist bits and pieces.
324324
#
325325
# Defaults to the Python interpreter used to execute x.py.
326326
#build.python = "python"

‎src/bootstrap/src/core/build_steps/test.rs‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2094,11 +2094,11 @@ Please disable assertions with `rust.debug-assertions = false`.
20942094
cmd.arg("--gdb").arg(gdb);
20952095
}
20962096

2097-
ifletSome(debuggers::Lldb{lldb_version, lldb_python_dir}) =
2097+
ifletSome(debuggers::Lldb{lldb_exe, lldb_version}) =
20982098
debuggers::discover_lldb(builder)
20992099
{
2100+
cmd.arg("--lldb").arg(lldb_exe);
21002101
cmd.arg("--lldb-version").arg(lldb_version);
2101-
cmd.arg("--lldb-python-dir").arg(lldb_python_dir);
21022102
}
21032103
}
21042104

‎src/bootstrap/src/core/debuggers/lldb.rs‎

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ use crate::core::builder::Builder;
44
usecrate::utils::exec::command;
55

66
pub(crate)structLldb{
7+
pub(crate)lldb_exe:PathBuf,
78
pub(crate)lldb_version:String,
8-
pub(crate)lldb_python_dir:String,
99
}
1010

1111
pub(crate)fndiscover_lldb(builder:&Builder<'_>) -> Option<Lldb>{
@@ -21,12 +21,5 @@ pub(crate) fn discover_lldb(builder: &Builder<'_>) -> Option<Lldb> {
2121
.stdout_if_ok()
2222
.and_then(|v| if v.trim().is_empty(){None}else{Some(v)})?;
2323

24-
let lldb_python_dir = command(&lldb_exe)
25-
.allow_failure()
26-
.arg("-P")
27-
.run_capture_stdout(builder)
28-
.stdout_if_ok()
29-
.map(|p| p.lines().next().expect("lldb Python dir not found").to_string())?;
30-
31-
Some(Lldb{ lldb_version, lldb_python_dir })
24+
Some(Lldb{ lldb_exe, lldb_version })
3225
}

‎src/etc/lldb_batchmode.py‎

Lines changed: 68 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -176,77 +176,85 @@ def watchdog():
176176
watchdog_thread.start()
177177

178178

179+
defget_env_arg(name):
180+
value=os.environ.get(name)
181+
ifvalueisNone:
182+
print("must set %s"%name)
183+
sys.exit(1)
184+
returnvalue
185+
186+
179187
####################################################################################################
180188
# ~main
181189
####################################################################################################
182190

183191

184-
iflen(sys.argv) !=3:
185-
print("usage: python lldb_batchmode.py target-path script-path")
186-
sys.exit(1)
192+
defmain():
193+
target_path=get_env_arg("LLDB_BATCHMODE_TARGET_PATH")
194+
script_path=get_env_arg("LLDB_BATCHMODE_SCRIPT_PATH")
187195

188-
target_path=sys.argv[1]
189-
script_path=sys.argv[2]
196+
print("LLDB batch-mode script")
197+
print("----------------------")
198+
print("Debugger commands script is '%s'."%script_path)
199+
print("Target executable is '%s'."%target_path)
200+
print("Current working directory is '%s'"%os.getcwd())
190201

191-
print("LLDB batch-mode script")
192-
print("----------------------")
193-
print("Debugger commands script is '%s'."%script_path)
194-
print("Target executable is '%s'."%target_path)
195-
print("Current working directory is '%s'"%os.getcwd())
202+
# Start the timeout watchdog
203+
start_watchdog()
196204

197-
# Start the timeout watchdog
198-
start_watchdog()
205+
# Create a new debugger instance
206+
debugger=lldb.SBDebugger.Create()
199207

200-
# Create a new debugger instance
201-
debugger=lldb.SBDebugger.Create()
208+
# When we step or continue, don't return from the function until the process
209+
# stops. We do this by setting the async mode to false.
210+
debugger.SetAsync(False)
202211

203-
# When we step or continue, don't return from the function until the process
204-
# stops. We do this by setting the async mode to false.
205-
debugger.SetAsync(False)
212+
# Create a target from a file and arch
213+
print("Creating a target for '%s'"%target_path)
214+
target_error=lldb.SBError()
215+
target=debugger.CreateTarget(target_path, None, None, True, target_error)
206216

207-
# Create a target from a file and arch
208-
print("Creating a target for '%s'"%target_path)
209-
target_error=lldb.SBError()
210-
target=debugger.CreateTarget(target_path, None, None, True, target_error)
211-
212-
ifnottarget:
213-
print(
214-
"Could not create debugging target '"
215-
+target_path
216-
+"': "
217-
+str(target_error)
218-
+". Aborting.",
219-
file=sys.stderr,
220-
)
221-
sys.exit(1)
217+
ifnottarget:
218+
print(
219+
"Could not create debugging target '"
220+
+target_path
221+
+"': "
222+
+str(target_error)
223+
+". Aborting.",
224+
file=sys.stderr,
225+
)
226+
sys.exit(1)
222227

228+
# Register the breakpoint callback for every breakpoint
229+
start_breakpoint_listener(target)
223230

224-
# Register the breakpoint callback for every breakpoint
225-
start_breakpoint_listener(target)
231+
command_interpreter=debugger.GetCommandInterpreter()
226232

227-
command_interpreter=debugger.GetCommandInterpreter()
228-
229-
try:
230-
script_file=open(script_path, "r")
231-
232-
forlineinscript_file:
233-
command=line.strip()
234-
if (
235-
command=="run"
236-
orcommand=="r"
237-
orre.match(r"^process\s+launch.*", command)
238-
):
239-
# Before starting to run the program, let the thread sleep a bit, so all
240-
# breakpoint added events can be processed
241-
time.sleep(0.5)
242-
ifcommand!="":
243-
execute_command(command_interpreter, command)
244-
245-
exceptIOErrorase:
246-
print("Could not read debugging script '%s'."%script_path, file=sys.stderr)
247-
print(e, file=sys.stderr)
248-
print("Aborting.", file=sys.stderr)
249-
sys.exit(1)
250-
finally:
251-
debugger.Terminate()
252-
script_file.close()
233+
try:
234+
script_file=open(script_path, "r")
235+
236+
forlineinscript_file:
237+
command=line.strip()
238+
if (
239+
command=="run"
240+
orcommand=="r"
241+
orre.match(r"^process\s+launch.*", command)
242+
):
243+
# Before starting to run the program, let the thread sleep a bit, so all
244+
# breakpoint added events can be processed
245+
time.sleep(0.5)
246+
ifcommand!="":
247+
execute_command(command_interpreter, command)
248+
249+
exceptIOErrorase:
250+
print("Could not read debugging script '%s'."%script_path, file=sys.stderr)
251+
print(e, file=sys.stderr)
252+
print("Aborting.", file=sys.stderr)
253+
sys.exit(1)
254+
finally:
255+
debugger.Terminate()
256+
script_file.close()
257+
258+
259+
if__name__=="__main__":
260+
main()

‎src/tools/compiletest/src/common.rs‎

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -312,10 +312,7 @@ pub struct Config {
312312
/// Path to the `src/tools/coverage-dump/` bootstrap tool executable.
313313
pubcoverage_dump_path:Option<Utf8PathBuf>,
314314

315-
/// Path to the Python 3 executable to use for LLDB and htmldocck.
316-
///
317-
/// FIXME: the `lldb` setup currently requires I believe Python 3.10 **exactly**, it can't even
318-
/// be Python 3.11 or 3.9...
315+
/// Path to the Python 3 executable to use for htmldocck and some run-make tests.
319316
pubpython:String,
320317

321318
/// Path to the `src/tools/jsondocck/` bootstrap tool executable.
@@ -541,6 +538,9 @@ pub struct Config {
541538
/// FIXME: `gdb_version` is *derived* from gdb, but it's *not* technically a config!
542539
pubgdb_version:Option<u32>,
543540

541+
/// Path to or name of the LLDB executable to use for debuginfo tests.
542+
publldb:Option<Utf8PathBuf>,
543+
544544
/// Version of LLDB.
545545
///
546546
/// FIXME: `lldb_version` is *derived* from lldb, but it's *not* technically a config!
@@ -587,11 +587,6 @@ pub struct Config {
587587
/// FIXME: take a look at this; this also influences adb in gdb code paths in a strange way.
588588
pubadb_device_status:bool,
589589

590-
/// Path containing LLDB's Python module.
591-
///
592-
/// FIXME: `PYTHONPATH` takes precedence over this flag...? See `runtest::run_lldb`.
593-
publldb_python_dir:Option<String>,
594-
595590
/// Verbose dump a lot of info.
596591
///
597592
/// FIXME: this is *way* too coarse; the user can't select *which* info to verbosely dump.

‎src/tools/compiletest/src/debuggers.rs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ pub(crate) fn configure_gdb(config: &Config) -> Option<Arc<Config>> {
4949
}
5050

5151
pub(crate)fnconfigure_lldb(config:&Config) -> Option<Arc<Config>>{
52-
config.lldb_python_dir.as_ref()?;
52+
config.lldb.as_ref()?;
5353

5454
Some(Arc::new(Config{debugger:Some(Debugger::Lldb), ..config.clone()}))
5555
}

‎src/tools/compiletest/src/lib.rs‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -141,13 +141,13 @@ fn parse_config(args: Vec<String>) -> Config {
141141
.optopt("","host","the host to build for","HOST")
142142
.optopt("","cdb","path to CDB to use for CDB debuginfo tests","PATH")
143143
.optopt("","gdb","path to GDB to use for GDB debuginfo tests","PATH")
144+
.optopt("","lldb","path to LLDB to use for LLDB debuginfo tests","PATH")
144145
.optopt("","lldb-version","the version of LLDB used","VERSION STRING")
145146
.optopt("","llvm-version","the version of LLVM used","VERSION STRING")
146147
.optflag("","system-llvm","is LLVM the system LLVM")
147148
.optopt("","android-cross-path","Android NDK standalone path","PATH")
148149
.optopt("","adb-path","path to the android debugger","PATH")
149150
.optopt("","adb-test-dir","path to tests for the android debugger","PATH")
150-
.optopt("","lldb-python-dir","directory containing LLDB's python module","PATH")
151151
.reqopt("","cc","path to a C compiler","PATH")
152152
.reqopt("","cxx","path to a C++ compiler","PATH")
153153
.reqopt("","cflags","flags for the C compiler","FLAGS")
@@ -264,6 +264,7 @@ fn parse_config(args: Vec<String>) -> Config {
264264
let gdb = debuggers::discover_gdb(matches.opt_str("gdb"),&target,&android_cross_path);
265265
let gdb_version = gdb.as_deref().and_then(debuggers::query_gdb_version);
266266
// FIXME: `lldb_version` is *derived* from lldb, but it's *not* technically a config!
267+
let lldb = matches.opt_str("lldb").map(Utf8PathBuf::from);
267268
let lldb_version =
268269
matches.opt_str("lldb-version").as_deref().and_then(debuggers::extract_lldb_version);
269270
let color = match matches.opt_str("color").as_deref(){
@@ -435,6 +436,7 @@ fn parse_config(args: Vec<String>) -> Config {
435436
cdb_version,
436437
gdb,
437438
gdb_version,
439+
lldb,
438440
lldb_version,
439441
llvm_version,
440442
system_llvm: matches.opt_present("system-llvm"),
@@ -444,7 +446,6 @@ fn parse_config(args: Vec<String>) -> Config {
444446
adb_device_status:opt_str2(matches.opt_str("target")).contains("android")
445447
&& "(none)" != opt_str2(matches.opt_str("adb-test-dir"))
446448
&& !opt_str2(matches.opt_str("adb-test-dir")).is_empty(),
447-
lldb_python_dir: matches.opt_str("lldb-python-dir"),
448449
verbose: matches.opt_present("verbose"),
449450
only_modified: matches.opt_present("only-modified"),
450451
color,

‎src/tools/compiletest/src/runtest.rs‎

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -200,10 +200,11 @@ pub fn compute_stamp_hash(config: &Config) -> String {
200200
}
201201

202202
Some(Debugger::Lldb) => {
203-
config.python.hash(&mut hash);
204-
config.lldb_python_dir.hash(&mut hash);
203+
// LLDB debuginfo tests now use LLDB's embedded Python, with an
204+
// explicit PYTHONPATH, so they don't depend on `--python` or
205+
// the ambient PYTHONPATH.
206+
config.lldb.hash(&mut hash);
205207
env::var_os("PATH").hash(&mut hash);
206-
env::var_os("PYTHONPATH").hash(&mut hash);
207208
}
208209

209210
None => {}

‎src/tools/compiletest/src/runtest/debuginfo.rs‎

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -326,9 +326,9 @@ impl TestCx<'_> {
326326
}
327327

328328
fnrun_debuginfo_lldb_test(&self){
329-
ifself.config.lldb_python_dir.is_none(){
330-
self.fatal("Can't run LLDB test because LLDB's python path is not set.");
331-
}
329+
letSome(ref lldb) = self.config.lldbelse{
330+
self.fatal("Can't run LLDB test because LLDB's path is not set.");
331+
};
332332

333333
// compile test file (it should have 'compile-flags:-g' in the directive)
334334
let should_run = self.run_if_enabled();
@@ -434,7 +434,7 @@ impl TestCx<'_> {
434434
let debugger_script = self.make_out_name("debugger.script");
435435

436436
// Let LLDB execute the script via lldb_batchmode.py
437-
let debugger_run_result = self.run_lldb(&exe_file,&debugger_script);
437+
let debugger_run_result = self.run_lldb(lldb,&exe_file,&debugger_script);
438438

439439
if !debugger_run_result.status.success(){
440440
self.fatal_proc_rec("Error while running LLDB",&debugger_run_result);
@@ -445,23 +445,23 @@ impl TestCx<'_> {
445445
}
446446
}
447447

448-
fnrun_lldb(&self,test_executable:&Utf8Path,debugger_script:&Utf8Path) -> ProcRes{
449-
// Prepare the lldb_batchmode which executes the debugger script
450-
let lldb_script_path = self.config.src_root.join("src/etc/lldb_batchmode.py");
451-
452-
// FIXME: `PYTHONPATH` takes precedence over the flag...?
453-
let pythonpath = ifletOk(pp) = std::env::var("PYTHONPATH"){
454-
format!("{pp}:{}",self.config.lldb_python_dir.as_ref().unwrap())
455-
}else{
456-
self.config.lldb_python_dir.clone().unwrap()
457-
};
458-
self.run_command_to_procres(
459-
Command::new(&self.config.python)
460-
.arg(&lldb_script_path)
461-
.arg(test_executable)
462-
.arg(debugger_script)
463-
.env("PYTHONUNBUFFERED","1")// Help debugging #78665
464-
.env("PYTHONPATH", pythonpath),
465-
)
448+
fnrun_lldb(
449+
&self,
450+
lldb:&Utf8Path,
451+
test_executable:&Utf8Path,
452+
debugger_script:&Utf8Path,
453+
) -> ProcRes{
454+
// Path containing `lldb_batchmode.py`, so that the `script` command can import it.
455+
let pythonpath = self.config.src_root.join("src/etc");
456+
457+
letmut cmd = Command::new(lldb);
458+
cmd.arg("--one-line")
459+
.arg("script --language python -- import lldb_batchmode; lldb_batchmode.main()")
460+
.env("LLDB_BATCHMODE_TARGET_PATH", test_executable)
461+
.env("LLDB_BATCHMODE_SCRIPT_PATH", debugger_script)
462+
.env("PYTHONUNBUFFERED","1")// Help debugging #78665
463+
.env("PYTHONPATH",pythonpath);
464+
465+
self.run_command_to_procres(&mut cmd)
466466
}
467467
}

‎src/tools/compiletest/src/rustdoc_gui_test.rs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,14 +99,14 @@ fn incomplete_config_for_rustdoc_gui_test() -> Config {
9999
cdb_version:Default::default(),
100100
gdb:Default::default(),
101101
gdb_version:Default::default(),
102+
lldb:Default::default(),
102103
lldb_version:Default::default(),
103104
llvm_version:Default::default(),
104105
system_llvm:Default::default(),
105106
android_cross_path:Default::default(),
106107
adb_path:Default::default(),
107108
adb_test_dir:Default::default(),
108109
adb_device_status:Default::default(),
109-
lldb_python_dir:Default::default(),
110110
verbose:Default::default(),
111111
color:Default::default(),
112112
remote_test_client:Default::default(),

0 commit comments

Comments
 (0)
, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Auto merge of #148685 - Zalathar:lldb-python, r=jieyouxu · rust-lang/rust@00426d6 · GitHub
Skip to content

Commit 00426d6

Browse files
committed
Auto merge of #148685 - Zalathar:lldb-python, r=jieyouxu
compiletest: Run the `lldb_batchmode.py` script in LLDB's embedded Python Historically, LLDB debuginfo tests have used a Python script to control LLDB via its Python API, instead of invoking the `lldb` command directly. Unfortunately, this requires us to find and use a version of Python that is compatible with LLDB's Python bindings. However, it turns out that there is a simpler way to find a compatible Python interpreter: use the one that is embedded in LLDB itself, via the `script` command.
2 parents 5f666a6 + dca8be9 commit 00426d6

10 files changed

Lines changed: 108 additions & 110 deletions

File tree

‎bootstrap.example.toml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,7 @@
320320
#build.npm = "npm"
321321

322322
# Python interpreter to use for various tasks throughout the build, notably
323-
# rustdoc tests, the lldb python interpreter, and some dist bits and pieces.
323+
# rustdoc tests, and some dist bits and pieces.
324324
#
325325
# Defaults to the Python interpreter used to execute x.py.
326326
#build.python = "python"

‎src/bootstrap/src/core/build_steps/test.rs‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2094,11 +2094,11 @@ Please disable assertions with `rust.debug-assertions = false`.
20942094
cmd.arg("--gdb").arg(gdb);
20952095
}
20962096

2097-
ifletSome(debuggers::Lldb{lldb_version, lldb_python_dir}) =
2097+
ifletSome(debuggers::Lldb{lldb_exe, lldb_version}) =
20982098
debuggers::discover_lldb(builder)
20992099
{
2100+
cmd.arg("--lldb").arg(lldb_exe);
21002101
cmd.arg("--lldb-version").arg(lldb_version);
2101-
cmd.arg("--lldb-python-dir").arg(lldb_python_dir);
21022102
}
21032103
}
21042104

‎src/bootstrap/src/core/debuggers/lldb.rs‎

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ use crate::core::builder::Builder;
44
usecrate::utils::exec::command;
55

66
pub(crate)structLldb{
7+
pub(crate)lldb_exe:PathBuf,
78
pub(crate)lldb_version:String,
8-
pub(crate)lldb_python_dir:String,
99
}
1010

1111
pub(crate)fndiscover_lldb(builder:&Builder<'_>) -> Option<Lldb>{
@@ -21,12 +21,5 @@ pub(crate) fn discover_lldb(builder: &Builder<'_>) -> Option<Lldb> {
2121
.stdout_if_ok()
2222
.and_then(|v| if v.trim().is_empty(){None}else{Some(v)})?;
2323

24-
let lldb_python_dir = command(&lldb_exe)
25-
.allow_failure()
26-
.arg("-P")
27-
.run_capture_stdout(builder)
28-
.stdout_if_ok()
29-
.map(|p| p.lines().next().expect("lldb Python dir not found").to_string())?;
30-
31-
Some(Lldb{ lldb_version, lldb_python_dir })
24+
Some(Lldb{ lldb_exe, lldb_version })
3225
}

‎src/etc/lldb_batchmode.py‎

Lines changed: 68 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -176,77 +176,85 @@ def watchdog():
176176
watchdog_thread.start()
177177

178178

179+
defget_env_arg(name):
180+
value=os.environ.get(name)
181+
ifvalueisNone:
182+
print("must set %s"%name)
183+
sys.exit(1)
184+
returnvalue
185+
186+
179187
####################################################################################################
180188
# ~main
181189
####################################################################################################
182190

183191

184-
iflen(sys.argv) !=3:
185-
print("usage: python lldb_batchmode.py target-path script-path")
186-
sys.exit(1)
192+
defmain():
193+
target_path=get_env_arg("LLDB_BATCHMODE_TARGET_PATH")
194+
script_path=get_env_arg("LLDB_BATCHMODE_SCRIPT_PATH")
187195

188-
target_path=sys.argv[1]
189-
script_path=sys.argv[2]
196+
print("LLDB batch-mode script")
197+
print("----------------------")
198+
print("Debugger commands script is '%s'."%script_path)
199+
print("Target executable is '%s'."%target_path)
200+
print("Current working directory is '%s'"%os.getcwd())
190201

191-
print("LLDB batch-mode script")
192-
print("----------------------")
193-
print("Debugger commands script is '%s'."%script_path)
194-
print("Target executable is '%s'."%target_path)
195-
print("Current working directory is '%s'"%os.getcwd())
202+
# Start the timeout watchdog
203+
start_watchdog()
196204

197-
# Start the timeout watchdog
198-
start_watchdog()
205+
# Create a new debugger instance
206+
debugger=lldb.SBDebugger.Create()
199207

200-
# Create a new debugger instance
201-
debugger=lldb.SBDebugger.Create()
208+
# When we step or continue, don't return from the function until the process
209+
# stops. We do this by setting the async mode to false.
210+
debugger.SetAsync(False)
202211

203-
# When we step or continue, don't return from the function until the process
204-
# stops. We do this by setting the async mode to false.
205-
debugger.SetAsync(False)
212+
# Create a target from a file and arch
213+
print("Creating a target for '%s'"%target_path)
214+
target_error=lldb.SBError()
215+
target=debugger.CreateTarget(target_path, None, None, True, target_error)
206216

207-
# Create a target from a file and arch
208-
print("Creating a target for '%s'"%target_path)
209-
target_error=lldb.SBError()
210-
target=debugger.CreateTarget(target_path, None, None, True, target_error)
211-
212-
ifnottarget:
213-
print(
214-
"Could not create debugging target '"
215-
+target_path
216-
+"': "
217-
+str(target_error)
218-
+". Aborting.",
219-
file=sys.stderr,
220-
)
221-
sys.exit(1)
217+
ifnottarget:
218+
print(
219+
"Could not create debugging target '"
220+
+target_path
221+
+"': "
222+
+str(target_error)
223+
+". Aborting.",
224+
file=sys.stderr,
225+
)
226+
sys.exit(1)
222227

228+
# Register the breakpoint callback for every breakpoint
229+
start_breakpoint_listener(target)
223230

224-
# Register the breakpoint callback for every breakpoint
225-
start_breakpoint_listener(target)
231+
command_interpreter=debugger.GetCommandInterpreter()
226232

227-
command_interpreter=debugger.GetCommandInterpreter()
228-
229-
try:
230-
script_file=open(script_path, "r")
231-
232-
forlineinscript_file:
233-
command=line.strip()
234-
if (
235-
command=="run"
236-
orcommand=="r"
237-
orre.match(r"^process\s+launch.*", command)
238-
):
239-
# Before starting to run the program, let the thread sleep a bit, so all
240-
# breakpoint added events can be processed
241-
time.sleep(0.5)
242-
ifcommand!="":
243-
execute_command(command_interpreter, command)
244-
245-
exceptIOErrorase:
246-
print("Could not read debugging script '%s'."%script_path, file=sys.stderr)
247-
print(e, file=sys.stderr)
248-
print("Aborting.", file=sys.stderr)
249-
sys.exit(1)
250-
finally:
251-
debugger.Terminate()
252-
script_file.close()
233+
try:
234+
script_file=open(script_path, "r")
235+
236+
forlineinscript_file:
237+
command=line.strip()
238+
if (
239+
command=="run"
240+
orcommand=="r"
241+
orre.match(r"^process\s+launch.*", command)
242+
):
243+
# Before starting to run the program, let the thread sleep a bit, so all
244+
# breakpoint added events can be processed
245+
time.sleep(0.5)
246+
ifcommand!="":
247+
execute_command(command_interpreter, command)
248+
249+
exceptIOErrorase:
250+
print("Could not read debugging script '%s'."%script_path, file=sys.stderr)
251+
print(e, file=sys.stderr)
252+
print("Aborting.", file=sys.stderr)
253+
sys.exit(1)
254+
finally:
255+
debugger.Terminate()
256+
script_file.close()
257+
258+
259+
if__name__=="__main__":
260+
main()

‎src/tools/compiletest/src/common.rs‎

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -312,10 +312,7 @@ pub struct Config {
312312
/// Path to the `src/tools/coverage-dump/` bootstrap tool executable.
313313
pubcoverage_dump_path:Option<Utf8PathBuf>,
314314

315-
/// Path to the Python 3 executable to use for LLDB and htmldocck.
316-
///
317-
/// FIXME: the `lldb` setup currently requires I believe Python 3.10 **exactly**, it can't even
318-
/// be Python 3.11 or 3.9...
315+
/// Path to the Python 3 executable to use for htmldocck and some run-make tests.
319316
pubpython:String,
320317

321318
/// Path to the `src/tools/jsondocck/` bootstrap tool executable.
@@ -541,6 +538,9 @@ pub struct Config {
541538
/// FIXME: `gdb_version` is *derived* from gdb, but it's *not* technically a config!
542539
pubgdb_version:Option<u32>,
543540

541+
/// Path to or name of the LLDB executable to use for debuginfo tests.
542+
publldb:Option<Utf8PathBuf>,
543+
544544
/// Version of LLDB.
545545
///
546546
/// FIXME: `lldb_version` is *derived* from lldb, but it's *not* technically a config!
@@ -587,11 +587,6 @@ pub struct Config {
587587
/// FIXME: take a look at this; this also influences adb in gdb code paths in a strange way.
588588
pubadb_device_status:bool,
589589

590-
/// Path containing LLDB's Python module.
591-
///
592-
/// FIXME: `PYTHONPATH` takes precedence over this flag...? See `runtest::run_lldb`.
593-
publldb_python_dir:Option<String>,
594-
595590
/// Verbose dump a lot of info.
596591
///
597592
/// FIXME: this is *way* too coarse; the user can't select *which* info to verbosely dump.

‎src/tools/compiletest/src/debuggers.rs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ pub(crate) fn configure_gdb(config: &Config) -> Option<Arc<Config>> {
4949
}
5050

5151
pub(crate)fnconfigure_lldb(config:&Config) -> Option<Arc<Config>>{
52-
config.lldb_python_dir.as_ref()?;
52+
config.lldb.as_ref()?;
5353

5454
Some(Arc::new(Config{debugger:Some(Debugger::Lldb), ..config.clone()}))
5555
}

‎src/tools/compiletest/src/lib.rs‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -141,13 +141,13 @@ fn parse_config(args: Vec<String>) -> Config {
141141
.optopt("","host","the host to build for","HOST")
142142
.optopt("","cdb","path to CDB to use for CDB debuginfo tests","PATH")
143143
.optopt("","gdb","path to GDB to use for GDB debuginfo tests","PATH")
144+
.optopt("","lldb","path to LLDB to use for LLDB debuginfo tests","PATH")
144145
.optopt("","lldb-version","the version of LLDB used","VERSION STRING")
145146
.optopt("","llvm-version","the version of LLVM used","VERSION STRING")
146147
.optflag("","system-llvm","is LLVM the system LLVM")
147148
.optopt("","android-cross-path","Android NDK standalone path","PATH")
148149
.optopt("","adb-path","path to the android debugger","PATH")
149150
.optopt("","adb-test-dir","path to tests for the android debugger","PATH")
150-
.optopt("","lldb-python-dir","directory containing LLDB's python module","PATH")
151151
.reqopt("","cc","path to a C compiler","PATH")
152152
.reqopt("","cxx","path to a C++ compiler","PATH")
153153
.reqopt("","cflags","flags for the C compiler","FLAGS")
@@ -264,6 +264,7 @@ fn parse_config(args: Vec<String>) -> Config {
264264
let gdb = debuggers::discover_gdb(matches.opt_str("gdb"),&target,&android_cross_path);
265265
let gdb_version = gdb.as_deref().and_then(debuggers::query_gdb_version);
266266
// FIXME: `lldb_version` is *derived* from lldb, but it's *not* technically a config!
267+
let lldb = matches.opt_str("lldb").map(Utf8PathBuf::from);
267268
let lldb_version =
268269
matches.opt_str("lldb-version").as_deref().and_then(debuggers::extract_lldb_version);
269270
let color = match matches.opt_str("color").as_deref(){
@@ -435,6 +436,7 @@ fn parse_config(args: Vec<String>) -> Config {
435436
cdb_version,
436437
gdb,
437438
gdb_version,
439+
lldb,
438440
lldb_version,
439441
llvm_version,
440442
system_llvm: matches.opt_present("system-llvm"),
@@ -444,7 +446,6 @@ fn parse_config(args: Vec<String>) -> Config {
444446
adb_device_status:opt_str2(matches.opt_str("target")).contains("android")
445447
&& "(none)" != opt_str2(matches.opt_str("adb-test-dir"))
446448
&& !opt_str2(matches.opt_str("adb-test-dir")).is_empty(),
447-
lldb_python_dir: matches.opt_str("lldb-python-dir"),
448449
verbose: matches.opt_present("verbose"),
449450
only_modified: matches.opt_present("only-modified"),
450451
color,

‎src/tools/compiletest/src/runtest.rs‎

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -200,10 +200,11 @@ pub fn compute_stamp_hash(config: &Config) -> String {
200200
}
201201

202202
Some(Debugger::Lldb) => {
203-
config.python.hash(&mut hash);
204-
config.lldb_python_dir.hash(&mut hash);
203+
// LLDB debuginfo tests now use LLDB's embedded Python, with an
204+
// explicit PYTHONPATH, so they don't depend on `--python` or
205+
// the ambient PYTHONPATH.
206+
config.lldb.hash(&mut hash);
205207
env::var_os("PATH").hash(&mut hash);
206-
env::var_os("PYTHONPATH").hash(&mut hash);
207208
}
208209

209210
None => {}

‎src/tools/compiletest/src/runtest/debuginfo.rs‎

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -326,9 +326,9 @@ impl TestCx<'_> {
326326
}
327327

328328
fnrun_debuginfo_lldb_test(&self){
329-
ifself.config.lldb_python_dir.is_none(){
330-
self.fatal("Can't run LLDB test because LLDB's python path is not set.");
331-
}
329+
letSome(ref lldb) = self.config.lldbelse{
330+
self.fatal("Can't run LLDB test because LLDB's path is not set.");
331+
};
332332

333333
// compile test file (it should have 'compile-flags:-g' in the directive)
334334
let should_run = self.run_if_enabled();
@@ -434,7 +434,7 @@ impl TestCx<'_> {
434434
let debugger_script = self.make_out_name("debugger.script");
435435

436436
// Let LLDB execute the script via lldb_batchmode.py
437-
let debugger_run_result = self.run_lldb(&exe_file,&debugger_script);
437+
let debugger_run_result = self.run_lldb(lldb,&exe_file,&debugger_script);
438438

439439
if !debugger_run_result.status.success(){
440440
self.fatal_proc_rec("Error while running LLDB",&debugger_run_result);
@@ -445,23 +445,23 @@ impl TestCx<'_> {
445445
}
446446
}
447447

448-
fnrun_lldb(&self,test_executable:&Utf8Path,debugger_script:&Utf8Path) -> ProcRes{
449-
// Prepare the lldb_batchmode which executes the debugger script
450-
let lldb_script_path = self.config.src_root.join("src/etc/lldb_batchmode.py");
451-
452-
// FIXME: `PYTHONPATH` takes precedence over the flag...?
453-
let pythonpath = ifletOk(pp) = std::env::var("PYTHONPATH"){
454-
format!("{pp}:{}",self.config.lldb_python_dir.as_ref().unwrap())
455-
}else{
456-
self.config.lldb_python_dir.clone().unwrap()
457-
};
458-
self.run_command_to_procres(
459-
Command::new(&self.config.python)
460-
.arg(&lldb_script_path)
461-
.arg(test_executable)
462-
.arg(debugger_script)
463-
.env("PYTHONUNBUFFERED","1")// Help debugging #78665
464-
.env("PYTHONPATH", pythonpath),
465-
)
448+
fnrun_lldb(
449+
&self,
450+
lldb:&Utf8Path,
451+
test_executable:&Utf8Path,
452+
debugger_script:&Utf8Path,
453+
) -> ProcRes{
454+
// Path containing `lldb_batchmode.py`, so that the `script` command can import it.
455+
let pythonpath = self.config.src_root.join("src/etc");
456+
457+
letmut cmd = Command::new(lldb);
458+
cmd.arg("--one-line")
459+
.arg("script --language python -- import lldb_batchmode; lldb_batchmode.main()")
460+
.env("LLDB_BATCHMODE_TARGET_PATH", test_executable)
461+
.env("LLDB_BATCHMODE_SCRIPT_PATH", debugger_script)
462+
.env("PYTHONUNBUFFERED","1")// Help debugging #78665
463+
.env("PYTHONPATH",pythonpath);
464+
465+
self.run_command_to_procres(&mut cmd)
466466
}
467467
}

‎src/tools/compiletest/src/rustdoc_gui_test.rs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,14 +99,14 @@ fn incomplete_config_for_rustdoc_gui_test() -> Config {
9999
cdb_version:Default::default(),
100100
gdb:Default::default(),
101101
gdb_version:Default::default(),
102+
lldb:Default::default(),
102103
lldb_version:Default::default(),
103104
llvm_version:Default::default(),
104105
system_llvm:Default::default(),
105106
android_cross_path:Default::default(),
106107
adb_path:Default::default(),
107108
adb_test_dir:Default::default(),
108109
adb_device_status:Default::default(),
109-
lldb_python_dir:Default::default(),
110110
verbose:Default::default(),
111111
color:Default::default(),
112112
remote_test_client:Default::default(),

0 commit comments

Comments
 (0)
, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Auto merge of #148685 - Zalathar:lldb-python, r=jieyouxu · rust-lang/rust@00426d6 · GitHub
Skip to content

Commit 00426d6

Browse files
committed
Auto merge of #148685 - Zalathar:lldb-python, r=jieyouxu
compiletest: Run the `lldb_batchmode.py` script in LLDB's embedded Python Historically, LLDB debuginfo tests have used a Python script to control LLDB via its Python API, instead of invoking the `lldb` command directly. Unfortunately, this requires us to find and use a version of Python that is compatible with LLDB's Python bindings. However, it turns out that there is a simpler way to find a compatible Python interpreter: use the one that is embedded in LLDB itself, via the `script` command.
2 parents 5f666a6 + dca8be9 commit 00426d6

10 files changed

Lines changed: 108 additions & 110 deletions

File tree

‎bootstrap.example.toml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,7 @@
320320
#build.npm = "npm"
321321

322322
# Python interpreter to use for various tasks throughout the build, notably
323-
# rustdoc tests, the lldb python interpreter, and some dist bits and pieces.
323+
# rustdoc tests, and some dist bits and pieces.
324324
#
325325
# Defaults to the Python interpreter used to execute x.py.
326326
#build.python = "python"

‎src/bootstrap/src/core/build_steps/test.rs‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2094,11 +2094,11 @@ Please disable assertions with `rust.debug-assertions = false`.
20942094
cmd.arg("--gdb").arg(gdb);
20952095
}
20962096

2097-
ifletSome(debuggers::Lldb{lldb_version, lldb_python_dir}) =
2097+
ifletSome(debuggers::Lldb{lldb_exe, lldb_version}) =
20982098
debuggers::discover_lldb(builder)
20992099
{
2100+
cmd.arg("--lldb").arg(lldb_exe);
21002101
cmd.arg("--lldb-version").arg(lldb_version);
2101-
cmd.arg("--lldb-python-dir").arg(lldb_python_dir);
21022102
}
21032103
}
21042104

‎src/bootstrap/src/core/debuggers/lldb.rs‎

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ use crate::core::builder::Builder;
44
usecrate::utils::exec::command;
55

66
pub(crate)structLldb{
7+
pub(crate)lldb_exe:PathBuf,
78
pub(crate)lldb_version:String,
8-
pub(crate)lldb_python_dir:String,
99
}
1010

1111
pub(crate)fndiscover_lldb(builder:&Builder<'_>) -> Option<Lldb>{
@@ -21,12 +21,5 @@ pub(crate) fn discover_lldb(builder: &Builder<'_>) -> Option<Lldb> {
2121
.stdout_if_ok()
2222
.and_then(|v| if v.trim().is_empty(){None}else{Some(v)})?;
2323

24-
let lldb_python_dir = command(&lldb_exe)
25-
.allow_failure()
26-
.arg("-P")
27-
.run_capture_stdout(builder)
28-
.stdout_if_ok()
29-
.map(|p| p.lines().next().expect("lldb Python dir not found").to_string())?;
30-
31-
Some(Lldb{ lldb_version, lldb_python_dir })
24+
Some(Lldb{ lldb_exe, lldb_version })
3225
}

‎src/etc/lldb_batchmode.py‎

Lines changed: 68 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -176,77 +176,85 @@ def watchdog():
176176
watchdog_thread.start()
177177

178178

179+
defget_env_arg(name):
180+
value=os.environ.get(name)
181+
ifvalueisNone:
182+
print("must set %s"%name)
183+
sys.exit(1)
184+
returnvalue
185+
186+
179187
####################################################################################################
180188
# ~main
181189
####################################################################################################
182190

183191

184-
iflen(sys.argv) !=3:
185-
print("usage: python lldb_batchmode.py target-path script-path")
186-
sys.exit(1)
192+
defmain():
193+
target_path=get_env_arg("LLDB_BATCHMODE_TARGET_PATH")
194+
script_path=get_env_arg("LLDB_BATCHMODE_SCRIPT_PATH")
187195

188-
target_path=sys.argv[1]
189-
script_path=sys.argv[2]
196+
print("LLDB batch-mode script")
197+
print("----------------------")
198+
print("Debugger commands script is '%s'."%script_path)
199+
print("Target executable is '%s'."%target_path)
200+
print("Current working directory is '%s'"%os.getcwd())
190201

191-
print("LLDB batch-mode script")
192-
print("----------------------")
193-
print("Debugger commands script is '%s'."%script_path)
194-
print("Target executable is '%s'."%target_path)
195-
print("Current working directory is '%s'"%os.getcwd())
202+
# Start the timeout watchdog
203+
start_watchdog()
196204

197-
# Start the timeout watchdog
198-
start_watchdog()
205+
# Create a new debugger instance
206+
debugger=lldb.SBDebugger.Create()
199207

200-
# Create a new debugger instance
201-
debugger=lldb.SBDebugger.Create()
208+
# When we step or continue, don't return from the function until the process
209+
# stops. We do this by setting the async mode to false.
210+
debugger.SetAsync(False)
202211

203-
# When we step or continue, don't return from the function until the process
204-
# stops. We do this by setting the async mode to false.
205-
debugger.SetAsync(False)
212+
# Create a target from a file and arch
213+
print("Creating a target for '%s'"%target_path)
214+
target_error=lldb.SBError()
215+
target=debugger.CreateTarget(target_path, None, None, True, target_error)
206216

207-
# Create a target from a file and arch
208-
print("Creating a target for '%s'"%target_path)
209-
target_error=lldb.SBError()
210-
target=debugger.CreateTarget(target_path, None, None, True, target_error)
211-
212-
ifnottarget:
213-
print(
214-
"Could not create debugging target '"
215-
+target_path
216-
+"': "
217-
+str(target_error)
218-
+". Aborting.",
219-
file=sys.stderr,
220-
)
221-
sys.exit(1)
217+
ifnottarget:
218+
print(
219+
"Could not create debugging target '"
220+
+target_path
221+
+"': "
222+
+str(target_error)
223+
+". Aborting.",
224+
file=sys.stderr,
225+
)
226+
sys.exit(1)
222227

228+
# Register the breakpoint callback for every breakpoint
229+
start_breakpoint_listener(target)
223230

224-
# Register the breakpoint callback for every breakpoint
225-
start_breakpoint_listener(target)
231+
command_interpreter=debugger.GetCommandInterpreter()
226232

227-
command_interpreter=debugger.GetCommandInterpreter()
228-
229-
try:
230-
script_file=open(script_path, "r")
231-
232-
forlineinscript_file:
233-
command=line.strip()
234-
if (
235-
command=="run"
236-
orcommand=="r"
237-
orre.match(r"^process\s+launch.*", command)
238-
):
239-
# Before starting to run the program, let the thread sleep a bit, so all
240-
# breakpoint added events can be processed
241-
time.sleep(0.5)
242-
ifcommand!="":
243-
execute_command(command_interpreter, command)
244-
245-
exceptIOErrorase:
246-
print("Could not read debugging script '%s'."%script_path, file=sys.stderr)
247-
print(e, file=sys.stderr)
248-
print("Aborting.", file=sys.stderr)
249-
sys.exit(1)
250-
finally:
251-
debugger.Terminate()
252-
script_file.close()
233+
try:
234+
script_file=open(script_path, "r")
235+
236+
forlineinscript_file:
237+
command=line.strip()
238+
if (
239+
command=="run"
240+
orcommand=="r"
241+
orre.match(r"^process\s+launch.*", command)
242+
):
243+
# Before starting to run the program, let the thread sleep a bit, so all
244+
# breakpoint added events can be processed
245+
time.sleep(0.5)
246+
ifcommand!="":
247+
execute_command(command_interpreter, command)
248+
249+
exceptIOErrorase:
250+
print("Could not read debugging script '%s'."%script_path, file=sys.stderr)
251+
print(e, file=sys.stderr)
252+
print("Aborting.", file=sys.stderr)
253+
sys.exit(1)
254+
finally:
255+
debugger.Terminate()
256+
script_file.close()
257+
258+
259+
if__name__=="__main__":
260+
main()

‎src/tools/compiletest/src/common.rs‎

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -312,10 +312,7 @@ pub struct Config {
312312
/// Path to the `src/tools/coverage-dump/` bootstrap tool executable.
313313
pubcoverage_dump_path:Option<Utf8PathBuf>,
314314

315-
/// Path to the Python 3 executable to use for LLDB and htmldocck.
316-
///
317-
/// FIXME: the `lldb` setup currently requires I believe Python 3.10 **exactly**, it can't even
318-
/// be Python 3.11 or 3.9...
315+
/// Path to the Python 3 executable to use for htmldocck and some run-make tests.
319316
pubpython:String,
320317

321318
/// Path to the `src/tools/jsondocck/` bootstrap tool executable.
@@ -541,6 +538,9 @@ pub struct Config {
541538
/// FIXME: `gdb_version` is *derived* from gdb, but it's *not* technically a config!
542539
pubgdb_version:Option<u32>,
543540

541+
/// Path to or name of the LLDB executable to use for debuginfo tests.
542+
publldb:Option<Utf8PathBuf>,
543+
544544
/// Version of LLDB.
545545
///
546546
/// FIXME: `lldb_version` is *derived* from lldb, but it's *not* technically a config!
@@ -587,11 +587,6 @@ pub struct Config {
587587
/// FIXME: take a look at this; this also influences adb in gdb code paths in a strange way.
588588
pubadb_device_status:bool,
589589

590-
/// Path containing LLDB's Python module.
591-
///
592-
/// FIXME: `PYTHONPATH` takes precedence over this flag...? See `runtest::run_lldb`.
593-
publldb_python_dir:Option<String>,
594-
595590
/// Verbose dump a lot of info.
596591
///
597592
/// FIXME: this is *way* too coarse; the user can't select *which* info to verbosely dump.

‎src/tools/compiletest/src/debuggers.rs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ pub(crate) fn configure_gdb(config: &Config) -> Option<Arc<Config>> {
4949
}
5050

5151
pub(crate)fnconfigure_lldb(config:&Config) -> Option<Arc<Config>>{
52-
config.lldb_python_dir.as_ref()?;
52+
config.lldb.as_ref()?;
5353

5454
Some(Arc::new(Config{debugger:Some(Debugger::Lldb), ..config.clone()}))
5555
}

‎src/tools/compiletest/src/lib.rs‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -141,13 +141,13 @@ fn parse_config(args: Vec<String>) -> Config {
141141
.optopt("","host","the host to build for","HOST")
142142
.optopt("","cdb","path to CDB to use for CDB debuginfo tests","PATH")
143143
.optopt("","gdb","path to GDB to use for GDB debuginfo tests","PATH")
144+
.optopt("","lldb","path to LLDB to use for LLDB debuginfo tests","PATH")
144145
.optopt("","lldb-version","the version of LLDB used","VERSION STRING")
145146
.optopt("","llvm-version","the version of LLVM used","VERSION STRING")
146147
.optflag("","system-llvm","is LLVM the system LLVM")
147148
.optopt("","android-cross-path","Android NDK standalone path","PATH")
148149
.optopt("","adb-path","path to the android debugger","PATH")
149150
.optopt("","adb-test-dir","path to tests for the android debugger","PATH")
150-
.optopt("","lldb-python-dir","directory containing LLDB's python module","PATH")
151151
.reqopt("","cc","path to a C compiler","PATH")
152152
.reqopt("","cxx","path to a C++ compiler","PATH")
153153
.reqopt("","cflags","flags for the C compiler","FLAGS")
@@ -264,6 +264,7 @@ fn parse_config(args: Vec<String>) -> Config {
264264
let gdb = debuggers::discover_gdb(matches.opt_str("gdb"),&target,&android_cross_path);
265265
let gdb_version = gdb.as_deref().and_then(debuggers::query_gdb_version);
266266
// FIXME: `lldb_version` is *derived* from lldb, but it's *not* technically a config!
267+
let lldb = matches.opt_str("lldb").map(Utf8PathBuf::from);
267268
let lldb_version =
268269
matches.opt_str("lldb-version").as_deref().and_then(debuggers::extract_lldb_version);
269270
let color = match matches.opt_str("color").as_deref(){
@@ -435,6 +436,7 @@ fn parse_config(args: Vec<String>) -> Config {
435436
cdb_version,
436437
gdb,
437438
gdb_version,
439+
lldb,
438440
lldb_version,
439441
llvm_version,
440442
system_llvm: matches.opt_present("system-llvm"),
@@ -444,7 +446,6 @@ fn parse_config(args: Vec<String>) -> Config {
444446
adb_device_status:opt_str2(matches.opt_str("target")).contains("android")
445447
&& "(none)" != opt_str2(matches.opt_str("adb-test-dir"))
446448
&& !opt_str2(matches.opt_str("adb-test-dir")).is_empty(),
447-
lldb_python_dir: matches.opt_str("lldb-python-dir"),
448449
verbose: matches.opt_present("verbose"),
449450
only_modified: matches.opt_present("only-modified"),
450451
color,

‎src/tools/compiletest/src/runtest.rs‎

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -200,10 +200,11 @@ pub fn compute_stamp_hash(config: &Config) -> String {
200200
}
201201

202202
Some(Debugger::Lldb) => {
203-
config.python.hash(&mut hash);
204-
config.lldb_python_dir.hash(&mut hash);
203+
// LLDB debuginfo tests now use LLDB's embedded Python, with an
204+
// explicit PYTHONPATH, so they don't depend on `--python` or
205+
// the ambient PYTHONPATH.
206+
config.lldb.hash(&mut hash);
205207
env::var_os("PATH").hash(&mut hash);
206-
env::var_os("PYTHONPATH").hash(&mut hash);
207208
}
208209

209210
None => {}

‎src/tools/compiletest/src/runtest/debuginfo.rs‎

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -326,9 +326,9 @@ impl TestCx<'_> {
326326
}
327327

328328
fnrun_debuginfo_lldb_test(&self){
329-
ifself.config.lldb_python_dir.is_none(){
330-
self.fatal("Can't run LLDB test because LLDB's python path is not set.");
331-
}
329+
letSome(ref lldb) = self.config.lldbelse{
330+
self.fatal("Can't run LLDB test because LLDB's path is not set.");
331+
};
332332

333333
// compile test file (it should have 'compile-flags:-g' in the directive)
334334
let should_run = self.run_if_enabled();
@@ -434,7 +434,7 @@ impl TestCx<'_> {
434434
let debugger_script = self.make_out_name("debugger.script");
435435

436436
// Let LLDB execute the script via lldb_batchmode.py
437-
let debugger_run_result = self.run_lldb(&exe_file,&debugger_script);
437+
let debugger_run_result = self.run_lldb(lldb,&exe_file,&debugger_script);
438438

439439
if !debugger_run_result.status.success(){
440440
self.fatal_proc_rec("Error while running LLDB",&debugger_run_result);
@@ -445,23 +445,23 @@ impl TestCx<'_> {
445445
}
446446
}
447447

448-
fnrun_lldb(&self,test_executable:&Utf8Path,debugger_script:&Utf8Path) -> ProcRes{
449-
// Prepare the lldb_batchmode which executes the debugger script
450-
let lldb_script_path = self.config.src_root.join("src/etc/lldb_batchmode.py");
451-
452-
// FIXME: `PYTHONPATH` takes precedence over the flag...?
453-
let pythonpath = ifletOk(pp) = std::env::var("PYTHONPATH"){
454-
format!("{pp}:{}",self.config.lldb_python_dir.as_ref().unwrap())
455-
}else{
456-
self.config.lldb_python_dir.clone().unwrap()
457-
};
458-
self.run_command_to_procres(
459-
Command::new(&self.config.python)
460-
.arg(&lldb_script_path)
461-
.arg(test_executable)
462-
.arg(debugger_script)
463-
.env("PYTHONUNBUFFERED","1")// Help debugging #78665
464-
.env("PYTHONPATH", pythonpath),
465-
)
448+
fnrun_lldb(
449+
&self,
450+
lldb:&Utf8Path,
451+
test_executable:&Utf8Path,
452+
debugger_script:&Utf8Path,
453+
) -> ProcRes{
454+
// Path containing `lldb_batchmode.py`, so that the `script` command can import it.
455+
let pythonpath = self.config.src_root.join("src/etc");
456+
457+
letmut cmd = Command::new(lldb);
458+
cmd.arg("--one-line")
459+
.arg("script --language python -- import lldb_batchmode; lldb_batchmode.main()")
460+
.env("LLDB_BATCHMODE_TARGET_PATH", test_executable)
461+
.env("LLDB_BATCHMODE_SCRIPT_PATH", debugger_script)
462+
.env("PYTHONUNBUFFERED","1")// Help debugging #78665
463+
.env("PYTHONPATH",pythonpath);
464+
465+
self.run_command_to_procres(&mut cmd)
466466
}
467467
}

‎src/tools/compiletest/src/rustdoc_gui_test.rs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,14 +99,14 @@ fn incomplete_config_for_rustdoc_gui_test() -> Config {
9999
cdb_version:Default::default(),
100100
gdb:Default::default(),
101101
gdb_version:Default::default(),
102+
lldb:Default::default(),
102103
lldb_version:Default::default(),
103104
llvm_version:Default::default(),
104105
system_llvm:Default::default(),
105106
android_cross_path:Default::default(),
106107
adb_path:Default::default(),
107108
adb_test_dir:Default::default(),
108109
adb_device_status:Default::default(),
109-
lldb_python_dir:Default::default(),
110110
verbose:Default::default(),
111111
color:Default::default(),
112112
remote_test_client:Default::default(),

0 commit comments

Comments
 (0)
, 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })(); Auto merge of #148685 - Zalathar:lldb-python, r=jieyouxu · rust-lang/rust@00426d6 · GitHub
Skip to content

Commit 00426d6

Browse files
committed
Auto merge of #148685 - Zalathar:lldb-python, r=jieyouxu
compiletest: Run the `lldb_batchmode.py` script in LLDB's embedded Python Historically, LLDB debuginfo tests have used a Python script to control LLDB via its Python API, instead of invoking the `lldb` command directly. Unfortunately, this requires us to find and use a version of Python that is compatible with LLDB's Python bindings. However, it turns out that there is a simpler way to find a compatible Python interpreter: use the one that is embedded in LLDB itself, via the `script` command.
2 parents 5f666a6 + dca8be9 commit 00426d6

10 files changed

Lines changed: 108 additions & 110 deletions

File tree

‎bootstrap.example.toml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,7 @@
320320
#build.npm = "npm"
321321

322322
# Python interpreter to use for various tasks throughout the build, notably
323-
# rustdoc tests, the lldb python interpreter, and some dist bits and pieces.
323+
# rustdoc tests, and some dist bits and pieces.
324324
#
325325
# Defaults to the Python interpreter used to execute x.py.
326326
#build.python = "python"

‎src/bootstrap/src/core/build_steps/test.rs‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2094,11 +2094,11 @@ Please disable assertions with `rust.debug-assertions = false`.
20942094
cmd.arg("--gdb").arg(gdb);
20952095
}
20962096

2097-
ifletSome(debuggers::Lldb{lldb_version, lldb_python_dir}) =
2097+
ifletSome(debuggers::Lldb{lldb_exe, lldb_version}) =
20982098
debuggers::discover_lldb(builder)
20992099
{
2100+
cmd.arg("--lldb").arg(lldb_exe);
21002101
cmd.arg("--lldb-version").arg(lldb_version);
2101-
cmd.arg("--lldb-python-dir").arg(lldb_python_dir);
21022102
}
21032103
}
21042104

‎src/bootstrap/src/core/debuggers/lldb.rs‎

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ use crate::core::builder::Builder;
44
usecrate::utils::exec::command;
55

66
pub(crate)structLldb{
7+
pub(crate)lldb_exe:PathBuf,
78
pub(crate)lldb_version:String,
8-
pub(crate)lldb_python_dir:String,
99
}
1010

1111
pub(crate)fndiscover_lldb(builder:&Builder<'_>) -> Option<Lldb>{
@@ -21,12 +21,5 @@ pub(crate) fn discover_lldb(builder: &Builder<'_>) -> Option<Lldb> {
2121
.stdout_if_ok()
2222
.and_then(|v| if v.trim().is_empty(){None}else{Some(v)})?;
2323

24-
let lldb_python_dir = command(&lldb_exe)
25-
.allow_failure()
26-
.arg("-P")
27-
.run_capture_stdout(builder)
28-
.stdout_if_ok()
29-
.map(|p| p.lines().next().expect("lldb Python dir not found").to_string())?;
30-
31-
Some(Lldb{ lldb_version, lldb_python_dir })
24+
Some(Lldb{ lldb_exe, lldb_version })
3225
}

‎src/etc/lldb_batchmode.py‎

Lines changed: 68 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -176,77 +176,85 @@ def watchdog():
176176
watchdog_thread.start()
177177

178178

179+
defget_env_arg(name):
180+
value=os.environ.get(name)
181+
ifvalueisNone:
182+
print("must set %s"%name)
183+
sys.exit(1)
184+
returnvalue
185+
186+
179187
####################################################################################################
180188
# ~main
181189
####################################################################################################
182190

183191

184-
iflen(sys.argv) !=3:
185-
print("usage: python lldb_batchmode.py target-path script-path")
186-
sys.exit(1)
192+
defmain():
193+
target_path=get_env_arg("LLDB_BATCHMODE_TARGET_PATH")
194+
script_path=get_env_arg("LLDB_BATCHMODE_SCRIPT_PATH")
187195

188-
target_path=sys.argv[1]
189-
script_path=sys.argv[2]
196+
print("LLDB batch-mode script")
197+
print("----------------------")
198+
print("Debugger commands script is '%s'."%script_path)
199+
print("Target executable is '%s'."%target_path)
200+
print("Current working directory is '%s'"%os.getcwd())
190201

191-
print("LLDB batch-mode script")
192-
print("----------------------")
193-
print("Debugger commands script is '%s'."%script_path)
194-
print("Target executable is '%s'."%target_path)
195-
print("Current working directory is '%s'"%os.getcwd())
202+
# Start the timeout watchdog
203+
start_watchdog()
196204

197-
# Start the timeout watchdog
198-
start_watchdog()
205+
# Create a new debugger instance
206+
debugger=lldb.SBDebugger.Create()
199207

200-
# Create a new debugger instance
201-
debugger=lldb.SBDebugger.Create()
208+
# When we step or continue, don't return from the function until the process
209+
# stops. We do this by setting the async mode to false.
210+
debugger.SetAsync(False)
202211

203-
# When we step or continue, don't return from the function until the process
204-
# stops. We do this by setting the async mode to false.
205-
debugger.SetAsync(False)
212+
# Create a target from a file and arch
213+
print("Creating a target for '%s'"%target_path)
214+
target_error=lldb.SBError()
215+
target=debugger.CreateTarget(target_path, None, None, True, target_error)
206216

207-
# Create a target from a file and arch
208-
print("Creating a target for '%s'"%target_path)
209-
target_error=lldb.SBError()
210-
target=debugger.CreateTarget(target_path, None, None, True, target_error)
211-
212-
ifnottarget:
213-
print(
214-
"Could not create debugging target '"
215-
+target_path
216-
+"': "
217-
+str(target_error)
218-
+". Aborting.",
219-
file=sys.stderr,
220-
)
221-
sys.exit(1)
217+
ifnottarget:
218+
print(
219+
"Could not create debugging target '"
220+
+target_path
221+
+"': "
222+
+str(target_error)
223+
+". Aborting.",
224+
file=sys.stderr,
225+
)
226+
sys.exit(1)
222227

228+
# Register the breakpoint callback for every breakpoint
229+
start_breakpoint_listener(target)
223230

224-
# Register the breakpoint callback for every breakpoint
225-
start_breakpoint_listener(target)
231+
command_interpreter=debugger.GetCommandInterpreter()
226232

227-
command_interpreter=debugger.GetCommandInterpreter()
228-
229-
try:
230-
script_file=open(script_path, "r")
231-
232-
forlineinscript_file:
233-
command=line.strip()
234-
if (
235-
command=="run"
236-
orcommand=="r"
237-
orre.match(r"^process\s+launch.*", command)
238-
):
239-
# Before starting to run the program, let the thread sleep a bit, so all
240-
# breakpoint added events can be processed
241-
time.sleep(0.5)
242-
ifcommand!="":
243-
execute_command(command_interpreter, command)
244-
245-
exceptIOErrorase:
246-
print("Could not read debugging script '%s'."%script_path, file=sys.stderr)
247-
print(e, file=sys.stderr)
248-
print("Aborting.", file=sys.stderr)
249-
sys.exit(1)
250-
finally:
251-
debugger.Terminate()
252-
script_file.close()
233+
try:
234+
script_file=open(script_path, "r")
235+
236+
forlineinscript_file:
237+
command=line.strip()
238+
if (
239+
command=="run"
240+
orcommand=="r"
241+
orre.match(r"^process\s+launch.*", command)
242+
):
243+
# Before starting to run the program, let the thread sleep a bit, so all
244+
# breakpoint added events can be processed
245+
time.sleep(0.5)
246+
ifcommand!="":
247+
execute_command(command_interpreter, command)
248+
249+
exceptIOErrorase:
250+
print("Could not read debugging script '%s'."%script_path, file=sys.stderr)
251+
print(e, file=sys.stderr)
252+
print("Aborting.", file=sys.stderr)
253+
sys.exit(1)
254+
finally:
255+
debugger.Terminate()
256+
script_file.close()
257+
258+
259+
if__name__=="__main__":
260+
main()

‎src/tools/compiletest/src/common.rs‎

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -312,10 +312,7 @@ pub struct Config {
312312
/// Path to the `src/tools/coverage-dump/` bootstrap tool executable.
313313
pubcoverage_dump_path:Option<Utf8PathBuf>,
314314

315-
/// Path to the Python 3 executable to use for LLDB and htmldocck.
316-
///
317-
/// FIXME: the `lldb` setup currently requires I believe Python 3.10 **exactly**, it can't even
318-
/// be Python 3.11 or 3.9...
315+
/// Path to the Python 3 executable to use for htmldocck and some run-make tests.
319316
pubpython:String,
320317

321318
/// Path to the `src/tools/jsondocck/` bootstrap tool executable.
@@ -541,6 +538,9 @@ pub struct Config {
541538
/// FIXME: `gdb_version` is *derived* from gdb, but it's *not* technically a config!
542539
pubgdb_version:Option<u32>,
543540

541+
/// Path to or name of the LLDB executable to use for debuginfo tests.
542+
publldb:Option<Utf8PathBuf>,
543+
544544
/// Version of LLDB.
545545
///
546546
/// FIXME: `lldb_version` is *derived* from lldb, but it's *not* technically a config!
@@ -587,11 +587,6 @@ pub struct Config {
587587
/// FIXME: take a look at this; this also influences adb in gdb code paths in a strange way.
588588
pubadb_device_status:bool,
589589

590-
/// Path containing LLDB's Python module.
591-
///
592-
/// FIXME: `PYTHONPATH` takes precedence over this flag...? See `runtest::run_lldb`.
593-
publldb_python_dir:Option<String>,
594-
595590
/// Verbose dump a lot of info.
596591
///
597592
/// FIXME: this is *way* too coarse; the user can't select *which* info to verbosely dump.

‎src/tools/compiletest/src/debuggers.rs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ pub(crate) fn configure_gdb(config: &Config) -> Option<Arc<Config>> {
4949
}
5050

5151
pub(crate)fnconfigure_lldb(config:&Config) -> Option<Arc<Config>>{
52-
config.lldb_python_dir.as_ref()?;
52+
config.lldb.as_ref()?;
5353

5454
Some(Arc::new(Config{debugger:Some(Debugger::Lldb), ..config.clone()}))
5555
}

‎src/tools/compiletest/src/lib.rs‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -141,13 +141,13 @@ fn parse_config(args: Vec<String>) -> Config {
141141
.optopt("","host","the host to build for","HOST")
142142
.optopt("","cdb","path to CDB to use for CDB debuginfo tests","PATH")
143143
.optopt("","gdb","path to GDB to use for GDB debuginfo tests","PATH")
144+
.optopt("","lldb","path to LLDB to use for LLDB debuginfo tests","PATH")
144145
.optopt("","lldb-version","the version of LLDB used","VERSION STRING")
145146
.optopt("","llvm-version","the version of LLVM used","VERSION STRING")
146147
.optflag("","system-llvm","is LLVM the system LLVM")
147148
.optopt("","android-cross-path","Android NDK standalone path","PATH")
148149
.optopt("","adb-path","path to the android debugger","PATH")
149150
.optopt("","adb-test-dir","path to tests for the android debugger","PATH")
150-
.optopt("","lldb-python-dir","directory containing LLDB's python module","PATH")
151151
.reqopt("","cc","path to a C compiler","PATH")
152152
.reqopt("","cxx","path to a C++ compiler","PATH")
153153
.reqopt("","cflags","flags for the C compiler","FLAGS")
@@ -264,6 +264,7 @@ fn parse_config(args: Vec<String>) -> Config {
264264
let gdb = debuggers::discover_gdb(matches.opt_str("gdb"),&target,&android_cross_path);
265265
let gdb_version = gdb.as_deref().and_then(debuggers::query_gdb_version);
266266
// FIXME: `lldb_version` is *derived* from lldb, but it's *not* technically a config!
267+
let lldb = matches.opt_str("lldb").map(Utf8PathBuf::from);
267268
let lldb_version =
268269
matches.opt_str("lldb-version").as_deref().and_then(debuggers::extract_lldb_version);
269270
let color = match matches.opt_str("color").as_deref(){
@@ -435,6 +436,7 @@ fn parse_config(args: Vec<String>) -> Config {
435436
cdb_version,
436437
gdb,
437438
gdb_version,
439+
lldb,
438440
lldb_version,
439441
llvm_version,
440442
system_llvm: matches.opt_present("system-llvm"),
@@ -444,7 +446,6 @@ fn parse_config(args: Vec<String>) -> Config {
444446
adb_device_status:opt_str2(matches.opt_str("target")).contains("android")
445447
&& "(none)" != opt_str2(matches.opt_str("adb-test-dir"))
446448
&& !opt_str2(matches.opt_str("adb-test-dir")).is_empty(),
447-
lldb_python_dir: matches.opt_str("lldb-python-dir"),
448449
verbose: matches.opt_present("verbose"),
449450
only_modified: matches.opt_present("only-modified"),
450451
color,

‎src/tools/compiletest/src/runtest.rs‎

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -200,10 +200,11 @@ pub fn compute_stamp_hash(config: &Config) -> String {
200200
}
201201

202202
Some(Debugger::Lldb) => {
203-
config.python.hash(&mut hash);
204-
config.lldb_python_dir.hash(&mut hash);
203+
// LLDB debuginfo tests now use LLDB's embedded Python, with an
204+
// explicit PYTHONPATH, so they don't depend on `--python` or
205+
// the ambient PYTHONPATH.
206+
config.lldb.hash(&mut hash);
205207
env::var_os("PATH").hash(&mut hash);
206-
env::var_os("PYTHONPATH").hash(&mut hash);
207208
}
208209

209210
None => {}

‎src/tools/compiletest/src/runtest/debuginfo.rs‎

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -326,9 +326,9 @@ impl TestCx<'_> {
326326
}
327327

328328
fnrun_debuginfo_lldb_test(&self){
329-
ifself.config.lldb_python_dir.is_none(){
330-
self.fatal("Can't run LLDB test because LLDB's python path is not set.");
331-
}
329+
letSome(ref lldb) = self.config.lldbelse{
330+
self.fatal("Can't run LLDB test because LLDB's path is not set.");
331+
};
332332

333333
// compile test file (it should have 'compile-flags:-g' in the directive)
334334
let should_run = self.run_if_enabled();
@@ -434,7 +434,7 @@ impl TestCx<'_> {
434434
let debugger_script = self.make_out_name("debugger.script");
435435

436436
// Let LLDB execute the script via lldb_batchmode.py
437-
let debugger_run_result = self.run_lldb(&exe_file,&debugger_script);
437+
let debugger_run_result = self.run_lldb(lldb,&exe_file,&debugger_script);
438438

439439
if !debugger_run_result.status.success(){
440440
self.fatal_proc_rec("Error while running LLDB",&debugger_run_result);
@@ -445,23 +445,23 @@ impl TestCx<'_> {
445445
}
446446
}
447447

448-
fnrun_lldb(&self,test_executable:&Utf8Path,debugger_script:&Utf8Path) -> ProcRes{
449-
// Prepare the lldb_batchmode which executes the debugger script
450-
let lldb_script_path = self.config.src_root.join("src/etc/lldb_batchmode.py");
451-
452-
// FIXME: `PYTHONPATH` takes precedence over the flag...?
453-
let pythonpath = ifletOk(pp) = std::env::var("PYTHONPATH"){
454-
format!("{pp}:{}",self.config.lldb_python_dir.as_ref().unwrap())
455-
}else{
456-
self.config.lldb_python_dir.clone().unwrap()
457-
};
458-
self.run_command_to_procres(
459-
Command::new(&self.config.python)
460-
.arg(&lldb_script_path)
461-
.arg(test_executable)
462-
.arg(debugger_script)
463-
.env("PYTHONUNBUFFERED","1")// Help debugging #78665
464-
.env("PYTHONPATH", pythonpath),
465-
)
448+
fnrun_lldb(
449+
&self,
450+
lldb:&Utf8Path,
451+
test_executable:&Utf8Path,
452+
debugger_script:&Utf8Path,
453+
) -> ProcRes{
454+
// Path containing `lldb_batchmode.py`, so that the `script` command can import it.
455+
let pythonpath = self.config.src_root.join("src/etc");
456+
457+
letmut cmd = Command::new(lldb);
458+
cmd.arg("--one-line")
459+
.arg("script --language python -- import lldb_batchmode; lldb_batchmode.main()")
460+
.env("LLDB_BATCHMODE_TARGET_PATH", test_executable)
461+
.env("LLDB_BATCHMODE_SCRIPT_PATH", debugger_script)
462+
.env("PYTHONUNBUFFERED","1")// Help debugging #78665
463+
.env("PYTHONPATH",pythonpath);
464+
465+
self.run_command_to_procres(&mut cmd)
466466
}
467467
}

‎src/tools/compiletest/src/rustdoc_gui_test.rs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,14 +99,14 @@ fn incomplete_config_for_rustdoc_gui_test() -> Config {
9999
cdb_version:Default::default(),
100100
gdb:Default::default(),
101101
gdb_version:Default::default(),
102+
lldb:Default::default(),
102103
lldb_version:Default::default(),
103104
llvm_version:Default::default(),
104105
system_llvm:Default::default(),
105106
android_cross_path:Default::default(),
106107
adb_path:Default::default(),
107108
adb_test_dir:Default::default(),
108109
adb_device_status:Default::default(),
109-
lldb_python_dir:Default::default(),
110110
verbose:Default::default(),
111111
color:Default::default(),
112112
remote_test_client:Default::default(),

0 commit comments

Comments
 (0)