@@ -323,7 +323,12 @@ fn run_debuginfo_gdb_test(config: &Config, props: &TestProps, testfile: &Path) {
323323 } ;
324324
325325 let config = & mut config;
326- let DebuggerCommands { commands, check_lines, .. } = parse_debugger_commands ( testfile, "gdb" ) ;
326+ let DebuggerCommands {
327+ commands,
328+ check_lines,
329+ use_gdb_pretty_printer,
330+ ..
331+ } = parse_debugger_commands ( testfile, "gdb" ) ;
327332 let mut cmds = commands. connect ( "\n " ) ;
328333
329334 // compile test file (it should have 'compile-flags:-g' in the header)
@@ -334,7 +339,6 @@ fn run_debuginfo_gdb_test(config: &Config, props: &TestProps, testfile: &Path) {
334339
335340 let exe_file = make_exe_name ( config, testfile) ;
336341
337- let mut proc_args;
338342 let debugger_run_result;
339343 match config. target . as_slice ( ) {
340344 "arm-linux-androideabi" => {
@@ -454,18 +458,65 @@ fn run_debuginfo_gdb_test(config: &Config, props: &TestProps, testfile: &Path) {
454458 }
455459
456460 _=> {
461+ let rust_src_root = find_rust_src_root ( config)
462+ . expect ( "Could not find Rust source root" ) ;
463+ let rust_pp_module_rel_path = Path :: new ( "./src/etc" ) ;
464+ let rust_pp_module_abs_path = rust_src_root. join ( rust_pp_module_rel_path)
465+ . as_str ( )
466+ . unwrap ( )
467+ . to_string ( ) ;
457468 // write debugger script
458- let script_str = [
459- "set charset UTF-8" . to_string ( ) ,
460- cmds,
461- "quit\n " . to_string ( )
462- ] . connect ( "\n " ) ;
469+ let mut script_str = String :: with_capacity ( 2048 ) ;
470+
471+ script_str. push_str ( "set charset UTF-8\n " ) ;
472+ script_str. push_str ( "show version\n " ) ;
473+
474+ match config. gdb_version {
475+ Some ( ref version) => {
476+ println ! ( "NOTE: compiletest thinks it is using GDB version {}" ,
477+ version. as_slice( ) ) ;
478+
479+ if header:: gdb_version_to_int ( version. as_slice ( ) ) >
480+ header:: gdb_version_to_int ( "7.4" ) {
481+ // Add the directory containing the pretty printers to
482+ // GDB's script auto loading safe path ...
483+ script_str. push_str (
484+ format ! ( "add-auto-load-safe-path {}\n " ,
485+ rust_pp_module_abs_path. as_slice( ) )
486+ . as_slice ( ) ) ;
487+ // ... and also the test directory
488+ script_str. push_str (
489+ format ! ( "add-auto-load-safe-path {}\n " ,
490+ config. build_base. as_str( ) . unwrap( ) )
491+ . as_slice ( ) ) ;
492+ }
493+ }
494+ _ => {
495+ println ! ( "NOTE: compiletest does not know which version of \
496+ GDB it is using") ;
497+ }
498+ }
499+
500+ // Load the target executable
501+ script_str. push_str ( format ! ( "file {}\n " ,
502+ exe_file. as_str( ) . unwrap( ) )
503+ . as_slice ( ) ) ;
504+
505+ script_str. push_str ( cmds. as_slice ( ) ) ;
506+ script_str. push_str ( "quit\n " ) ;
507+
463508 debug ! ( "script_str = {}" , script_str) ;
464509 dump_output_file ( config,
465510 testfile,
466511 script_str. as_slice ( ) ,
467512 "debugger.script" ) ;
468513
514+ if use_gdb_pretty_printer {
515+ // Only emit the gdb auto-loading script if pretty printers
516+ // should actually be loaded
517+ dump_gdb_autoload_script ( config, testfile) ;
518+ }
519+
469520 // run debugger script with gdb
470521 #[ cfg( windows) ]
471522 fn debugger ( ) -> String {
@@ -483,16 +534,19 @@ fn run_debuginfo_gdb_test(config: &Config, props: &TestProps, testfile: &Path) {
483534 vec ! ( "-quiet" . to_string( ) ,
484535 "-batch" . to_string( ) ,
485536 "-nx" . to_string( ) ,
486- format!( "-command={}" , debugger_script. as_str( ) . unwrap( ) ) ,
487- exe_file . as_str ( ) . unwrap ( ) . to_string ( ) ) ;
488- proc_args = ProcArgs {
537+ format!( "-command={}" , debugger_script. as_str( ) . unwrap( ) ) ) ;
538+
539+ let proc_args = ProcArgs {
489540 prog : debugger ( ) ,
490541 args : debugger_opts,
491542 } ;
543+
544+ let environment = vec ! [ ( "PYTHONPATH" . to_string( ) , rust_pp_module_abs_path) ] ;
545+
492546 debugger_run_result = compose_and_run ( config,
493547 testfile,
494548 proc_args,
495- Vec :: new ( ) ,
549+ environment ,
496550 config. run_lib_path . as_slice ( ) ,
497551 None ,
498552 None ) ;
@@ -504,6 +558,32 @@ fn run_debuginfo_gdb_test(config: &Config, props: &TestProps, testfile: &Path) {
504558 }
505559
506560 check_debugger_output ( & debugger_run_result, check_lines. as_slice ( ) ) ;
561+
562+ fn dump_gdb_autoload_script ( config : & Config , testfile : & Path ) {
563+ let mut script_path = output_base_name ( config, testfile) ;
564+ let mut script_file_name = script_path. filename ( ) . unwrap ( ) . to_vec ( ) ;
565+ script_file_name. push_all ( "-gdb.py" . as_bytes ( ) ) ;
566+ script_path. set_filename ( script_file_name. as_slice ( ) ) ;
567+
568+ let script_content = "import gdb_rust_pretty_printing\n \
569+ gdb_rust_pretty_printing.register_printers(gdb.current_objfile())\n "
570+ . as_bytes ( ) ;
571+
572+ File :: create ( & script_path) . write ( script_content) . unwrap ( ) ;
573+ }
574+ }
575+
576+ fn find_rust_src_root ( config : & Config ) -> Option < Path > {
577+ let mut path = config. src_base . clone ( ) ;
578+ let path_postfix = Path :: new ( "src/etc/lldb_batchmode.py" ) ;
579+
580+ while path. pop ( ) {
581+ if path. join ( path_postfix. clone ( ) ) . is_file ( ) {
582+ return Some ( path) ;
583+ }
584+ }
585+
586+ return None ;
507587}
508588
509589fn run_debuginfo_lldb_test ( config : & Config , props : & TestProps , testfile : & Path ) {
@@ -533,7 +613,8 @@ fn run_debuginfo_lldb_test(config: &Config, props: &TestProps, testfile: &Path)
533613 let DebuggerCommands {
534614 commands,
535615 check_lines,
536- breakpoint_lines
616+ breakpoint_lines,
617+ ..
537618 } = parse_debugger_commands ( testfile, "lldb" ) ;
538619
539620 // Write debugger script:
@@ -619,6 +700,7 @@ struct DebuggerCommands {
619700 commands : Vec < String > ,
620701 check_lines : Vec < String > ,
621702 breakpoint_lines : Vec < uint > ,
703+ use_gdb_pretty_printer : bool
622704}
623705
624706fn parse_debugger_commands ( file_path : & Path , debugger_prefix : & str )
@@ -631,6 +713,7 @@ fn parse_debugger_commands(file_path: &Path, debugger_prefix: &str)
631713 let mut breakpoint_lines = vec ! ( ) ;
632714 let mut commands = vec ! ( ) ;
633715 let mut check_lines = vec ! ( ) ;
716+ let mut use_gdb_pretty_printer = false ;
634717 let mut counter = 1 ;
635718 let mut reader = BufferedReader :: new ( File :: open ( file_path) . unwrap ( ) ) ;
636719 for line in reader. lines ( ) {
@@ -640,6 +723,10 @@ fn parse_debugger_commands(file_path: &Path, debugger_prefix: &str)
640723 breakpoint_lines. push ( counter) ;
641724 }
642725
726+ if line. as_slice ( ) . contains ( "gdb-use-pretty-printer" ) {
727+ use_gdb_pretty_printer = true ;
728+ }
729+
643730 header:: parse_name_value_directive (
644731 line. as_slice ( ) ,
645732 command_directive. as_slice ( ) ) . map ( |cmd| {
@@ -663,7 +750,8 @@ fn parse_debugger_commands(file_path: &Path, debugger_prefix: &str)
663750 DebuggerCommands {
664751 commands : commands,
665752 check_lines : check_lines,
666- breakpoint_lines : breakpoint_lines
753+ breakpoint_lines : breakpoint_lines,
754+ use_gdb_pretty_printer : use_gdb_pretty_printer,
667755 }
668756}
669757
0 commit comments