-name '*.dll' -o \
-name '*.def' -o \
-name '*.py' -o \
+ -name '*.pyc' -o \
-name '*.bc' \
\) \
| xargs rm -f
clean$(1)_H_$(2): \
$$(foreach crate,$$(CRATES),clean$(1)_H_$(2)-lib-$$(crate)) \
- $$(foreach tool,$$(TOOLS) $$(DEBUGGER_BIN_SCRIPTS),clean$(1)_H_$(2)-tool-$$(tool))
+ $$(foreach tool,$$(TOOLS) $$(DEBUGGER_BIN_SCRIPTS_ALL),clean$(1)_H_$(2)-tool-$$(tool))
$$(Q)rm -fr $(2)/rt/libbacktrace
clean$(1)_H_$(2)-tool-%:
clean$(1)_T_$(2)_H_$(3): \
$$(foreach crate,$$(CRATES),clean$(1)_T_$(2)_H_$(3)-lib-$$(crate)) \
- $$(foreach tool,$$(TOOLS) $$(DEBUGGER_BIN_SCRIPTS),clean$(1)_T_$(2)_H_$(3)-tool-$$(tool))
+ $$(foreach tool,$$(TOOLS) $$(DEBUGGER_BIN_SCRIPTS_ALL),clean$(1)_T_$(2)_H_$(3)-tool-$$(tool))
$$(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/libmorestack.a
$$(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/libcompiler-rt.a
$(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/librun_pass_stage* # For unix
# Copy debugger related scripts
######################################################################
-DEBUGGER_RUSTLIB_ETC_SCRIPTS=lldb_rust_formatters.py
-DEBUGGER_BIN_SCRIPTS=rust-lldb
-DEBUGGER_RUSTLIB_ETC_SCRIPTS_ABS=$(foreach script,$(DEBUGGER_RUSTLIB_ETC_SCRIPTS), \
- $(CFG_SRC_DIR)src/etc/$(script))
-DEBUGGER_BIN_SCRIPTS_ABS=$(foreach script,$(DEBUGGER_BIN_SCRIPTS), \
- $(CFG_SRC_DIR)src/etc/$(script))
+## GDB ##
+DEBUGGER_RUSTLIB_ETC_SCRIPTS_GDB=gdb_load_rust_pretty_printers.py \
+ gdb_rust_pretty_printing.py
+DEBUGGER_RUSTLIB_ETC_SCRIPTS_GDB_ABS=\
+ $(foreach script,$(DEBUGGER_RUSTLIB_ETC_SCRIPTS_GDB), \
+ $(CFG_SRC_DIR)src/etc/$(script))
+
+DEBUGGER_BIN_SCRIPTS_GDB=rust-gdb
+DEBUGGER_BIN_SCRIPTS_GDB_ABS=\
+ $(foreach script,$(DEBUGGER_BIN_SCRIPTS_GDB), \
+ $(CFG_SRC_DIR)src/etc/$(script))
+
+
+## LLDB ##
+DEBUGGER_RUSTLIB_ETC_SCRIPTS_LLDB=lldb_rust_formatters.py
+DEBUGGER_RUSTLIB_ETC_SCRIPTS_LLDB_ABS=\
+ $(foreach script,$(DEBUGGER_RUSTLIB_ETC_SCRIPTS_LLDB), \
+ $(CFG_SRC_DIR)src/etc/$(script))
+
+DEBUGGER_BIN_SCRIPTS_LLDB=rust-lldb
+DEBUGGER_BIN_SCRIPTS_LLDB_ABS=\
+ $(foreach script,$(DEBUGGER_BIN_SCRIPTS_LLDB), \
+ $(CFG_SRC_DIR)src/etc/$(script))
+
+
+## ALL ##
+DEBUGGER_RUSTLIB_ETC_SCRIPTS_ALL=$(DEBUGGER_RUSTLIB_ETC_SCRIPTS_GDB) \
+ $(DEBUGGER_RUSTLIB_ETC_SCRIPTS_LLDB)
+DEBUGGER_RUSTLIB_ETC_SCRIPTS_ALL_ABS=$(DEBUGGER_RUSTLIB_ETC_SCRIPTS_GDB_ABS) \
+ $(DEBUGGER_RUSTLIB_ETC_SCRIPTS_LLDB_ABS)
+DEBUGGER_BIN_SCRIPTS_ALL=$(DEBUGGER_BIN_SCRIPTS_GDB) \
+ $(DEBUGGER_BIN_SCRIPTS_LLDB)
+DEBUGGER_BIN_SCRIPTS_ALL_ABS=$(DEBUGGER_BIN_SCRIPTS_GDB_ABS) \
+ $(DEBUGGER_BIN_SCRIPTS_LLDB_ABS)
-DEBUGGER_SCRIPTS_ALL=$(DEBUGGER_RUSTLIB_ETC_SCRIPTS_ABS) $(DEBUGGER_BIN_SCRIPTS_ABS)
# $(1) - the stage to copy to
# $(2) - the host triple
define DEF_INSTALL_DEBUGGER_SCRIPTS_HOST
-tmp/install-debugger-scripts$(1)_H_$(2).done: $$(DEBUGGER_SCRIPTS_ALL)
+tmp/install-debugger-scripts$(1)_H_$(2)-gdb.done: \
+ $$(DEBUGGER_RUSTLIB_ETC_SCRIPTS_GDB_ABS) \
+ $$(DEBUGGER_BIN_SCRIPTS_GDB_ABS)
+ $(Q)mkdir -p $$(HBIN$(1)_H_$(2))
+ $(Q)mkdir -p $$(HLIB$(1)_H_$(2))/rustlib/etc
+ $(Q)install $$(DEBUGGER_BIN_SCRIPTS_GDB_ABS) $$(HBIN$(1)_H_$(2))
+ $(Q)install $$(DEBUGGER_RUSTLIB_ETC_SCRIPTS_GDB_ABS) $$(HLIB$(1)_H_$(2))/rustlib/etc
+ $(Q)touch $$@
+
+tmp/install-debugger-scripts$(1)_H_$(2)-lldb.done: \
+ $$(DEBUGGER_RUSTLIB_ETC_SCRIPTS_LLDB_ABS) \
+ $$(DEBUGGER_BIN_SCRIPTS_LLDB_ABS)
+ $(Q)mkdir -p $$(HBIN$(1)_H_$(2))
+ $(Q)mkdir -p $$(HLIB$(1)_H_$(2))/rustlib/etc
+ $(Q)install $$(DEBUGGER_BIN_SCRIPTS_LLDB_ABS) $$(HBIN$(1)_H_$(2))
+ $(Q)install $$(DEBUGGER_RUSTLIB_ETC_SCRIPTS_LLDB_ABS) $$(HLIB$(1)_H_$(2))/rustlib/etc
+ $(Q)touch $$@
+
+tmp/install-debugger-scripts$(1)_H_$(2)-all.done: \
+ $$(DEBUGGER_RUSTLIB_ETC_SCRIPTS_ALL_ABS) \
+ $$(DEBUGGER_BIN_SCRIPTS_ALL_ABS)
$(Q)mkdir -p $$(HBIN$(1)_H_$(2))
$(Q)mkdir -p $$(HLIB$(1)_H_$(2))/rustlib/etc
- $(Q)install $(DEBUGGER_BIN_SCRIPTS_ABS) $$(HBIN$(1)_H_$(2))
- $(Q)install $(DEBUGGER_RUSTLIB_ETC_SCRIPTS_ABS) $$(HLIB$(1)_H_$(2))/rustlib/etc
+ $(Q)install $$(DEBUGGER_BIN_SCRIPTS_ALL_ABS) $$(HBIN$(1)_H_$(2))
+ $(Q)install $$(DEBUGGER_RUSTLIB_ETC_SCRIPTS_ALL_ABS) $$(HLIB$(1)_H_$(2))/rustlib/etc
$(Q)touch $$@
+
+tmp/install-debugger-scripts$(1)_H_$(2)-none.done:
+ $(Q)touch $$@
+
endef
# Expand host make-targets for all stages
# $(3) is the host triple
define DEF_INSTALL_DEBUGGER_SCRIPTS_TARGET
-tmp/install-debugger-scripts$(1)_T_$(2)_H_$(3).done: $$(DEBUGGER_SCRIPTS_ALL)
+tmp/install-debugger-scripts$(1)_T_$(2)_H_$(3)-gdb.done: \
+ $$(DEBUGGER_RUSTLIB_ETC_SCRIPTS_GDB_ABS) \
+ $$(DEBUGGER_BIN_SCRIPTS_GDB_ABS)
+ $(Q)mkdir -p $$(TBIN$(1)_T_$(2)_H_$(3))
+ $(Q)mkdir -p $$(TLIB$(1)_T_$(2)_H_$(3))/rustlib/etc
+ $(Q)install $(DEBUGGER_BIN_SCRIPTS_GDB_ABS) $$(TBIN$(1)_T_$(2)_H_$(3))
+ $(Q)install $(DEBUGGER_RUSTLIB_ETC_SCRIPTS_GDB_ABS) $$(TLIB$(1)_T_$(2)_H_$(3))/rustlib/etc
+ $(Q)touch $$@
+
+tmp/install-debugger-scripts$(1)_T_$(2)_H_$(3)-lldb.done: \
+ $$(DEBUGGER_RUSTLIB_ETC_SCRIPTS_LLDB_ABS) \
+ $$(DEBUGGER_BIN_SCRIPTS_LLDB_ABS)
$(Q)mkdir -p $$(TBIN$(1)_T_$(2)_H_$(3))
$(Q)mkdir -p $$(TLIB$(1)_T_$(2)_H_$(3))/rustlib/etc
- $(Q)install $(DEBUGGER_BIN_SCRIPTS_ABS) $$(TBIN$(1)_T_$(2)_H_$(3))
- $(Q)install $(DEBUGGER_RUSTLIB_ETC_SCRIPTS_ABS) $$(TLIB$(1)_T_$(2)_H_$(3))/rustlib/etc
+ $(Q)install $(DEBUGGER_BIN_SCRIPTS_LLDB_ABS) $$(TBIN$(1)_T_$(2)_H_$(3))
+ $(Q)install $(DEBUGGER_RUSTLIB_ETC_SCRIPTS_LLDB_ABS) $$(TLIB$(1)_T_$(2)_H_$(3))/rustlib/etc
$(Q)touch $$@
+
+tmp/install-debugger-scripts$(1)_T_$(2)_H_$(3)-all.done: \
+ $$(DEBUGGER_RUSTLIB_ETC_SCRIPTS_ALL_ABS) \
+ $$(DEBUGGER_BIN_SCRIPTS_ALL_ABS)
+ $(Q)mkdir -p $$(TBIN$(1)_T_$(2)_H_$(3))
+ $(Q)mkdir -p $$(TLIB$(1)_T_$(2)_H_$(3))/rustlib/etc
+ $(Q)install $(DEBUGGER_BIN_SCRIPTS_ALL_ABS) $$(TBIN$(1)_T_$(2)_H_$(3))
+ $(Q)install $(DEBUGGER_RUSTLIB_ETC_SCRIPTS_ALL_ABS) $$(TLIB$(1)_T_$(2)_H_$(3))/rustlib/etc
+ $(Q)touch $$@
+
+tmp/install-debugger-scripts$(1)_T_$(2)_H_$(3)-none.done:
+ $(Q)touch $$@
+
endef
# Expand target make-targets for all stages
# Per-stage targets and runner
######################################################################
+# Valid setting-strings are 'all', 'none', 'gdb', 'lldb'
+# This 'function' will determine which debugger scripts to copy based on a
+# target triple. See debuggers.mk for more information.
+TRIPLE_TO_DEBUGGER_SCRIPT_SETTING=\
+ $(if $(findstring windows,$(1)),none,$(if $(findstring darwin,$(1)),lldb,gdb))
+
STAGES = 0 1 2 3
define SREQ
HSREQ$(1)_H_$(3) = \
$$(HBIN$(1)_H_$(3))/rustc$$(X_$(3)) \
$$(MKFILE_DEPS) \
- tmp/install-debugger-scripts$(1)_H_$(3).done
+ tmp/install-debugger-scripts$(1)_H_$(3)-$$(call TRIPLE_TO_DEBUGGER_SCRIPT_SETTING,$(3)).done
endif
# Prerequisites for using the stageN compiler to build target artifacts
$$(TSREQ$(1)_T_$(2)_H_$(3)) \
$$(foreach dep,$$(TARGET_CRATES), \
$$(TLIB$(1)_T_$(2)_H_$(3))/stamp.$$(dep)) \
- tmp/install-debugger-scripts$(1)_T_$(2)_H_$(3).done
+ tmp/install-debugger-scripts$(1)_T_$(2)_H_$(3)-$$(call TRIPLE_TO_DEBUGGER_SCRIPT_SETTING,$(2)).done
# Prerequisites for a working stageN compiler and complete set of target
# libraries
$$(call PREPARE_LIB,libcompiler-rt.a),),),)
endef
+define INSTALL_GDB_DEBUGGER_SCRIPTS_COMMANDS
+ $(Q)$(PREPARE_BIN_CMD) $(DEBUGGER_BIN_SCRIPTS_GDB_ABS) $(PREPARE_DEST_BIN_DIR)
+ $(Q)$(PREPARE_LIB_CMD) $(DEBUGGER_RUSTLIB_ETC_SCRIPTS_GDB_ABS) $(PREPARE_DEST_LIB_DIR)/rustlib/etc
+endef
+
+define INSTALL_LLDB_DEBUGGER_SCRIPTS_COMMANDS
+ $(Q)$(PREPARE_BIN_CMD) $(DEBUGGER_BIN_SCRIPTS_LLDB_ABS) $(PREPARE_DEST_BIN_DIR)
+ $(Q)$(PREPARE_LIB_CMD) $(DEBUGGER_RUSTLIB_ETC_SCRIPTS_LLDB_ABS) $(PREPARE_DEST_LIB_DIR)/rustlib/etc
+endef
+
+define INSTALL_NO_DEBUGGER_SCRIPTS_COMMANDS
+ $(Q)echo "No debugger scripts will be installed for host $(PREPARE_HOST)"
+endef
+
+# $(1) is PREPARE_HOST
+INSTALL_DEBUGGER_SCRIPT_COMMANDS=$(if $(findstring windows,$(1)),\
+ $(INSTALL_NO_DEBUGGER_SCRIPTS_COMMANDS),\
+ $(if $(findstring darwin,$(1)),\
+ $(INSTALL_LLDB_DEBUGGER_SCRIPTS_COMMANDS),\
+ $(INSTALL_GDB_DEBUGGER_SCRIPTS_COMMANDS)))
+
define DEF_PREPARE
prepare-base-$(1): PREPARE_SOURCE_DIR=$$(PREPARE_HOST)/stage$$(PREPARE_STAGE)
$$(call PREPARE_DIR,$$(PREPARE_DEST_LIB_DIR)/rustlib/etc)
$$(call PREPARE_DIR,$$(PREPARE_DEST_MAN_DIR))
-prepare-debugger-scripts-$(1): prepare-host-dirs-$(1) $(DEBUGGER_SCRIPTS_ALL)
- $$(Q)$$(PREPARE_BIN_CMD) $(DEBUGGER_BIN_SCRIPTS_ABS) $$(PREPARE_DEST_BIN_DIR)
- $$(Q)$$(PREPARE_LIB_CMD) $(DEBUGGER_RUSTLIB_ETC_SCRIPTS_ABS) $$(PREPARE_DEST_LIB_DIR)/rustlib/etc
+prepare-debugger-scripts-$(1): prepare-host-dirs-$(1) \
+ $$(DEBUGGER_BIN_SCRIPTS_ALL_ABS) \
+ $$(DEBUGGER_RUSTLIB_ETC_SCRIPTS_ALL_ABS)
+ $$(call INSTALL_DEBUGGER_SCRIPT_COMMANDS,$$(PREPARE_HOST))
$$(foreach tool,$$(PREPARE_TOOLS), \
$$(foreach host,$$(CFG_HOST), \
let DebuggerCommands {
commands,
check_lines,
- use_gdb_pretty_printer,
breakpoint_lines
} = parse_debugger_commands(testfile, "gdb");
let mut cmds = commands.connect("\n");
if header::gdb_version_to_int(version.as_slice()) >
header::gdb_version_to_int("7.4") {
// Add the directory containing the pretty printers to
- // GDB's script auto loading safe path ...
+ // GDB's script auto loading safe path
script_str.push_str(
format!("add-auto-load-safe-path {}\n",
rust_pp_module_abs_path.replace("\\", "\\\\").as_slice())
.as_slice());
- // ... and also the test directory
- script_str.push_str(
- format!("add-auto-load-safe-path {}\n",
- config.build_base.as_str().unwrap().replace("\\", "\\\\"))
- .as_slice());
}
}
_ => {
// pretty printing, it just tells GDB to print values on one line:
script_str.push_str("set print pretty off\n");
+ // Add the pretty printer directory to GDB's source-file search path
+ script_str.push_str(format!("directory {}\n", rust_pp_module_abs_path)[]);
+
// Load the target executable
script_str.push_str(format!("file {}\n",
exe_file.as_str().unwrap().replace("\\", "\\\\"))
script_str.as_slice(),
"debugger.script");
- if use_gdb_pretty_printer {
- // Only emit the gdb auto-loading script if pretty printers
- // should actually be loaded
- dump_gdb_autoload_script(config, testfile);
- }
-
// run debugger script with gdb
#[cfg(windows)]
fn debugger() -> String {
}
check_debugger_output(&debugger_run_result, check_lines.as_slice());
-
- fn dump_gdb_autoload_script(config: &Config, testfile: &Path) {
- let mut script_path = output_base_name(config, testfile);
- let mut script_file_name = script_path.filename().unwrap().to_vec();
- script_file_name.push_all("-gdb.py".as_bytes());
- script_path.set_filename(script_file_name.as_slice());
-
- let script_content = "import gdb_rust_pretty_printing\n\
- gdb_rust_pretty_printing.register_printers(gdb.current_objfile())\n"
- .as_bytes();
-
- File::create(&script_path).write(script_content).unwrap();
- }
}
fn find_rust_src_root(config: &Config) -> Option<Path> {
commands: Vec<String>,
check_lines: Vec<String>,
breakpoint_lines: Vec<uint>,
- use_gdb_pretty_printer: bool
}
fn parse_debugger_commands(file_path: &Path, debugger_prefix: &str)
let mut breakpoint_lines = vec!();
let mut commands = vec!();
let mut check_lines = vec!();
- let mut use_gdb_pretty_printer = false;
let mut counter = 1;
let mut reader = BufferedReader::new(File::open(file_path).unwrap());
for line in reader.lines() {
breakpoint_lines.push(counter);
}
- if line.as_slice().contains("gdb-use-pretty-printer") {
- use_gdb_pretty_printer = true;
- }
-
header::parse_name_value_directive(
line.as_slice(),
command_directive.as_slice()).map(|cmd| {
commands: commands,
check_lines: check_lines,
breakpoint_lines: breakpoint_lines,
- use_gdb_pretty_printer: use_gdb_pretty_printer,
}
}
--- /dev/null
+# Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+# file at the top-level directory of this distribution and at
+# http://rust-lang.org/COPYRIGHT.
+#
+# Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+# http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+# <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+# option. This file may not be copied, modified, or distributed
+# except according to those terms.
+
+import gdb_rust_pretty_printing
+gdb_rust_pretty_printing.register_printers(gdb.current_objfile())
--- /dev/null
+#!/bin/sh
+# Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+# file at the top-level directory of this distribution and at
+# http://rust-lang.org/COPYRIGHT.
+#
+# Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+# http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+# <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+# option. This file may not be copied, modified, or distributed
+# except according to those terms.
+
+# Exit if anything fails
+set -e
+
+# Find out where the pretty printer Python module is
+RUSTC_SYSROOT=`rustc --print=sysroot`
+GDB_PYTHON_MODULE_DIRECTORY="$RUSTC_SYSROOT/lib/rustlib/etc"
+
+# Run GDB with the additional arguments that load the pretty printers
+PYTHONPATH="$PYTHONPATH:$GDB_PYTHON_MODULE_DIRECTORY" gdb \
+ -d "$GDB_PYTHON_MODULE_DIRECTORY" \
+ -iex "add-auto-load-safe-path $GDB_PYTHON_MODULE_DIRECTORY" \
+ "$@"
"static_assert",
"thread_local",
"no_debug",
+ "omit_gdb_pretty_printer_section",
"unsafe_no_drop_flag",
// used in resolve
isOptimized: bool,
Flags: *const c_char,
RuntimeVer: c_uint,
- SplitName: *const c_char);
+ SplitName: *const c_char)
+ -> DIDescriptor;
pub fn LLVMDIBuilderCreateFile(Builder: DIBuilderRef,
Filename: *const c_char,
unsafe {
llvm::LLVMPositionBuilderAtEnd(bld, llbb);
+ debuginfo::insert_reference_to_gdb_debug_scripts_section_global(ccx);
+
let (start_fn, args) = if use_start_lang_item {
let start_def_id = match ccx.tcx().lang_items.require(StartFnLangItem) {
Ok(id) => id,
use std::rc::{Rc, Weak};
use syntax::util::interner::Interner;
use syntax::codemap::{Span, Pos};
-use syntax::{ast, codemap, ast_util, ast_map};
+use syntax::{ast, codemap, ast_util, ast_map, attr};
use syntax::ast_util::PostExpansionMethod;
use syntax::parse::token::{mod, special_idents};
}
debug!("finalize");
- compile_unit_metadata(cx);
+ let _ = compile_unit_metadata(cx);
+
+ if needs_gdb_debug_scripts_section(cx) {
+ // Add a .debug_gdb_scripts section to this compile-unit. This will
+ // cause GDB to try and load the gdb_load_rust_pretty_printers.py file,
+ // which activates the Rust pretty printers for binary this section is
+ // contained in.
+ get_or_insert_gdb_debug_scripts_section_global(cx);
+ }
+
unsafe {
llvm::LLVMDIBuilderFinalize(DIB(cx));
llvm::LLVMDIBuilderDispose(DIB(cx));
};
}
-fn compile_unit_metadata(cx: &CrateContext) {
+fn compile_unit_metadata(cx: &CrateContext) -> DIDescriptor {
let work_dir = &cx.sess().working_dir;
let compile_unit_name = match cx.sess().local_crate_source_file {
None => fallback_path(cx),
(option_env!("CFG_VERSION")).expect("CFG_VERSION"));
let compile_unit_name = compile_unit_name.as_ptr();
- work_dir.as_vec().with_c_str(|work_dir| {
+ return work_dir.as_vec().with_c_str(|work_dir| {
producer.with_c_str(|producer| {
"".with_c_str(|flags| {
"".with_c_str(|split_name| {
cx.sess().opts.optimize != config::No,
flags,
0,
- split_name);
+ split_name)
}
})
})
}
})
}
+
+
+//=-----------------------------------------------------------------------------
+// .debug_gdb_scripts binary section
+//=-----------------------------------------------------------------------------
+
+/// Inserts a side-effect free instruction sequence that makes sure that the
+/// .debug_gdb_scripts global is referenced, so it isn't removed by the linker.
+pub fn insert_reference_to_gdb_debug_scripts_section_global(ccx: &CrateContext) {
+ if needs_gdb_debug_scripts_section(ccx) {
+ let empty = b"".to_c_str();
+ let gdb_debug_scripts_section_global =
+ get_or_insert_gdb_debug_scripts_section_global(ccx);
+ unsafe {
+ let volative_load_instruction =
+ llvm::LLVMBuildLoad(ccx.raw_builder(),
+ gdb_debug_scripts_section_global,
+ empty.as_ptr());
+ llvm::LLVMSetVolatile(volative_load_instruction, llvm::True);
+ }
+ }
+}
+
+/// Allocates the global variable responsible for the .debug_gdb_scripts binary
+/// section.
+fn get_or_insert_gdb_debug_scripts_section_global(ccx: &CrateContext)
+ -> llvm::ValueRef {
+ let section_var_name = b"__rustc_debug_gdb_scripts_section__".to_c_str();
+
+ let section_var = unsafe {
+ llvm::LLVMGetNamedGlobal(ccx.llmod(), section_var_name.as_ptr())
+ };
+
+ if section_var == ptr::null_mut() {
+ let section_name = b".debug_gdb_scripts".to_c_str();
+ let section_contents = b"\x01gdb_load_rust_pretty_printers.py\0";
+
+ unsafe {
+ let llvm_type = Type::array(&Type::i8(ccx),
+ section_contents.len() as u64);
+ let section_var = llvm::LLVMAddGlobal(ccx.llmod(),
+ llvm_type.to_ref(),
+ section_var_name.as_ptr());
+ llvm::LLVMSetSection(section_var, section_name.as_ptr());
+ llvm::LLVMSetInitializer(section_var, C_bytes(ccx, section_contents));
+ llvm::LLVMSetGlobalConstant(section_var, llvm::True);
+ llvm::LLVMSetUnnamedAddr(section_var, llvm::True);
+ llvm::SetLinkage(section_var, llvm::Linkage::LinkOnceODRLinkage);
+ // This should make sure that the whole section is not larger than
+ // the string it contains. Otherwise we get a warning from GDB.
+ llvm::LLVMSetAlignment(section_var, 1);
+ section_var
+ }
+ } else {
+ section_var
+ }
+}
+
+fn needs_gdb_debug_scripts_section(ccx: &CrateContext) -> bool {
+ let omit_gdb_pretty_printer_section =
+ attr::contains_name(ccx.tcx()
+ .map
+ .krate()
+ .attrs
+ .as_slice(),
+ "omit_gdb_pretty_printer_section");
+
+ !omit_gdb_pretty_printer_section &&
+ !ccx.sess().target.target.options.is_like_osx &&
+ !ccx.sess().target.target.options.is_like_windows &&
+ ccx.sess().opts.debuginfo != NoDebugInfo
+}
+
Builder->finalize();
}
-extern "C" void LLVMDIBuilderCreateCompileUnit(
+extern "C" LLVMValueRef LLVMDIBuilderCreateCompileUnit(
DIBuilderRef Builder,
unsigned Lang,
const char* File,
const char* Flags,
unsigned RuntimeVer,
const char* SplitName) {
- Builder->createCompileUnit(Lang, File, Dir, Producer, isOptimized,
- Flags, RuntimeVer, SplitName);
+ return wrap(Builder->createCompileUnit(Lang,
+ File,
+ Dir,
+ Producer,
+ isOptimized,
+ Flags,
+ RuntimeVer,
+ SplitName));
}
extern "C" LLVMValueRef LLVMDIBuilderCreateFile(
#![allow(unused_variables)]
#![allow(dead_code)]
+#![omit_gdb_pretty_printer_section]
static B: bool = false;
// gdb-command:continue
#![allow(unused_variables)]
+#![omit_gdb_pretty_printer_section]
static B: bool = false;
static I: int = -1;
// gdb-command:continue
#![allow(unused_variables)]
+#![omit_gdb_pretty_printer_section]
fn main() {
let unit: () = ();
// gdb-check:$28 = 9.25
#![allow(unused_variables)]
+#![omit_gdb_pretty_printer_section]
static mut B: bool = false;
static mut I: int = -1;
// lldb-check:[...]$12 = 3.5
#![allow(unused_variables)]
+#![omit_gdb_pretty_printer_section]
fn main() {
let b: bool = false;
// lldb-check:[...]$12 = 3.5
#![allow(unused_variables)]
+#![omit_gdb_pretty_printer_section]
fn main() {
let bool_val: bool = true;
// lldb-check:[...]$2 = TheC
#![allow(unused_variables)]
+#![omit_gdb_pretty_printer_section]
enum ABC { TheA, TheB, TheC }
// lldb-check:[...]$2 = TheOnlyCase(4820353753753434)
#![allow(unused_variables)]
+#![omit_gdb_pretty_printer_section]
// The first element is to ensure proper alignment, irrespective of the machines word size. Since
// the size of the discriminant value is machine dependent, this has be taken into account when
// lldb-check:[...]$6 = 26.5
#![allow(unused_variables)]
+#![omit_gdb_pretty_printer_section]
struct SomeStruct {
x: int,
#![allow(unused_variables)]
+#![omit_gdb_pretty_printer_section]
fn main() {
let stack_val: (i16, f32) = (-14, -19f32);
// lldb-check:[...]$12 = 3.5
#![allow(unused_variables)]
-
+#![omit_gdb_pretty_printer_section]
fn main() {
let bool_box: Box<bool> = box true;
// lldb-check:[...]$1 = (2, 3.5)
#![allow(unused_variables)]
+#![omit_gdb_pretty_printer_section]
fn main() {
let a = box 1i;
// lldb-check:[...]$1 = StructWithDestructor { x: 77, y: 777, z: 7777, w: 77777 }
#![allow(unused_variables)]
+#![omit_gdb_pretty_printer_section]
struct StructWithSomePadding {
x: i16,
// lldb-check:[...]$6 = Case1 { x: 0, y: 8970181431921507452 }
// lldb-command:continue
+#![omit_gdb_pretty_printer_section]
+
#[deriving(Clone)]
struct Struct {
a: int,
// lldb-check:[...]$2 = (4444.5, 5555, 6666, 7777.5)
// lldb-command:continue
+#![omit_gdb_pretty_printer_section]
+
trait Trait {
fn method(self) -> Self;
}
// lldb-check:[...]$6 = (StructWithDrop { a: OneHundred, b: Vienna }, 9)
#![allow(unused_variables)]
+#![omit_gdb_pretty_printer_section]
use self::AnEnum::{OneHundred, OneThousand, OneMillion};
use self::AnotherEnum::{MountainView, Toronto, Vienna};
#![allow(unused_variables)]
#![allow(dead_code)]
+#![omit_gdb_pretty_printer_section]
use self::AutoDiscriminant::{One, Two, Three};
use self::ManualDiscriminant::{OneHundred, OneThousand, OneMillion};
// lldb-check:[...]$3 = 110
// lldb-command:continue
+#![omit_gdb_pretty_printer_section]
+
fn some_generic_fun<T1, T2>(a: T1, b: T2) -> (T2, T1) {
let closure = |x, y| {
// lldb-command:continue
#![allow(unused_variables)]
+#![omit_gdb_pretty_printer_section]
use self::Univariant::Unit;
// lldb-check:[...]$23 = (34903493, 232323)
// lldb-command:continue
+#![allow(unused_variables)]
+#![omit_gdb_pretty_printer_section]
+
struct Struct {
x: i16,
y: f32,
#![allow(unused_variables)]
+#![omit_gdb_pretty_printer_section]
use self::Univariant::Unit;
// lldb-check:[...]$4 = StructPaddedAtEnd { x: [22, 23], y: [24, 25] }
#![allow(unused_variables)]
+#![omit_gdb_pretty_printer_section]
struct NoPadding1 {
x: [u32; 3],
// lldb-command:continue
-
#![allow(unused_variables)]
-
-
+#![omit_gdb_pretty_printer_section]
fn immediate_args(a: int, b: bool, c: f64) {
::std::io::print("") // #break
// lldb-check:[...]$3 = 3000
// lldb-command:continue
+
+#![omit_gdb_pretty_printer_section]
+
fn main() {
fun(111102, true);
// lldb-command:continue
#![allow(unused_variables)]
+#![omit_gdb_pretty_printer_section]
#[no_stack_check]
fn immediate_args(a: int, b: bool, c: f64) {
// lldb-command:continue
#![allow(unused_variables)]
+#![omit_gdb_pretty_printer_section]
fn immediate_args(a: int, b: bool, c: f64) {
()
// ignore-lldb
// ignore-android: FIXME(#10381)
// compile-flags:-g
-// gdb-use-pretty-printer
// gdb-command: run
// ignore-lldb
// ignore-android: FIXME(#10381)
// compile-flags:-g
-// gdb-use-pretty-printer
// This test uses some GDB Python API features (e.g. accessing anonymous fields)
// which are only available in newer GDB version. The following directive will
// lldb-check:[...]$8 = ((5, Struct { a: 6, b: 7.5 }), (Struct { a: 6, b: 7.5 }, 5))
// lldb-command:continue
+#![omit_gdb_pretty_printer_section]
#[deriving(Clone)]
struct Struct {
// lldb-check:[...]$7 = 2.5
// lldb-command:continue
+
+#![omit_gdb_pretty_printer_section]
+
fn outer<TA: Clone>(a: TA) {
inner(a.clone(), 1i);
inner(a.clone(), 2.5f64);
// lldb-check:[...]$14 = -10.5
// lldb-command:continue
+#![omit_gdb_pretty_printer_section]
struct Struct<T> {
x: T
// gdb-check:$5 = 5
// gdb-command:continue
+
+#![omit_gdb_pretty_printer_section]
+
struct Struct {
x: int
}
// gdb-command:print univariant
// gdb-check:$4 = {{a = -1}}
+
+#![omit_gdb_pretty_printer_section]
+
use self::Regular::{Case1, Case2, Case3};
use self::Univariant::TheOnlyCase;
// lldb-command:print float_int_float
// lldb-check:[...]$3 = AGenericStruct<f64, generic-struct::AGenericStruct<int, f64>> { key: 6.5, value: AGenericStruct<int, f64> { key: 7, value: 8.5 } }
+
+#![omit_gdb_pretty_printer_section]
+
struct AGenericStruct<TKey, TValue> {
key: TKey,
value: TValue
// gdb-check:$4 = {3.5, {4, 5, 6}}
// gdb-command:continue
+#![omit_gdb_pretty_printer_section]
struct Struct {
x: int
// lldb-command:print univariant
// lldb-check:[...]$3 = TheOnlyCase(-1)
+#![omit_gdb_pretty_printer_section]
+
use self::Regular::{Case1, Case2, Case3};
use self::Univariant::TheOnlyCase;
// lldb-command:continue
#![allow(unused_variables)]
+#![omit_gdb_pretty_printer_section]
// This test case makes sure that debug info does not ICE when include_str is
// used multiple times (see issue #11322).
// gdb-command:run
// gdb-command:next
-// gdb-check:[...]32[...]s
+// gdb-check:[...]34[...]s
// gdb-command:continue
+#![omit_gdb_pretty_printer_section]
+
// IF YOU MODIFY THIS FILE, BE CAREFUL TO ADAPT THE LINE NUMBERS IN THE DEBUGGER COMMANDS
// This test makes sure that gdb does not set unwanted breakpoints in inlined functions. If a
// lldb-check:[...]$6 = 1000000
// lldb-command:continue
+#![omit_gdb_pretty_printer_section]
+
fn main() {
let range = [1i, 2, 3];
// lldb-check:[...]$15 = -1
// lldb-command:continue
+#![omit_gdb_pretty_printer_section]
fn main() {
// lldb-check:[...]$17 = 232
// lldb-command:continue
+#![omit_gdb_pretty_printer_section]
struct Struct {
x: int,
// lldb-check:[...]$5 = false
// lldb-command:continue
+#![omit_gdb_pretty_printer_section]
+
fn main() {
let x = false;
// lldb-check:[...]$12 = 2
// lldb-command:continue
+#![omit_gdb_pretty_printer_section]
+
fn main() {
let mut x = 0i;
// lldb-check:[...]$5 = false
// lldb-command:continue
+
+#![omit_gdb_pretty_printer_section]
+
fn main() {
let x = false;
// lldb-check:[...]$12 = 2
// lldb-command:continue
+#![omit_gdb_pretty_printer_section]
fn main() {
#![feature(macro_rules)]
+#![omit_gdb_pretty_printer_section]
macro_rules! trivial {
($e1:expr) => ($e1)
#![allow(unused_variables)]
#![allow(unused_assignments)]
+#![omit_gdb_pretty_printer_section]
static mut MUT_INT: int = 0;
#![allow(unused_variables)]
+#![omit_gdb_pretty_printer_section]
struct Struct {
a: i64,
// lldb-check:[...]$14 = -10
// lldb-command:continue
+#![omit_gdb_pretty_printer_section]
+
enum Enum {
Variant1 { x: u16, y: u16 },
Variant2 (u32)
// lldb-command:continue
+#![omit_gdb_pretty_printer_section]
+
struct Struct<T> {
x: T
}
// lldb-check:[...]$14 = -10
// lldb-command:continue
+
+#![omit_gdb_pretty_printer_section]
+
struct Struct {
x: int
}
// lldb-check:[...]$14 = -10
// lldb-command:continue
+
+#![omit_gdb_pretty_printer_section]
+
struct Struct {
x: int
}
// lldb-check:[...]$14 = -10
// lldb-command:continue
+
+#![omit_gdb_pretty_printer_section]
+
struct TupleStruct(int, f64);
impl TupleStruct {
// lldb-check:[...]$2 = 30303
#![allow(unused_variables)]
+#![omit_gdb_pretty_printer_section]
fn function_one() {
let abc = 10101i;
// lldb-check:[...]$2 = 30303
#![allow(unused_variables)]
+#![omit_gdb_pretty_printer_section]
fn function_one() {
let a = 10101i;
// lldb-check:[...]$11 = 20
// lldb-command:continue
+#![omit_gdb_pretty_printer_section]
+
fn main() {
let x = false;
let y = true;
// gdb-check:$2 = {<No data fields>}
#![allow(unused_variables)]
+#![omit_gdb_pretty_printer_section]
enum ANilEnum {}
enum AnotherNilEnum {}
// gdb-command:continue
#![allow(unused_variables)]
+#![omit_gdb_pretty_printer_section]
fn function_with_debuginfo() {
let abc = 10u;
// lldb-check:[...]$7 = None
+#![omit_gdb_pretty_printer_section]
+
// If a struct has exactly two variants, one of them is empty, and the other one
// contains a non-nullable pointer, then this value is used as the discriminator.
// The test cases in this file make sure that something readable is generated for
#![allow(unused_variables)]
+#![omit_gdb_pretty_printer_section]
#[repr(packed)]
struct Packed {
// lldb-check:[...]$5 = 40
#![allow(unused_variables)]
+#![omit_gdb_pretty_printer_section]
#[repr(packed)]
struct Packed {
// is taken from issue #11083.
#![allow(unused_variables)]
+#![omit_gdb_pretty_printer_section]
pub struct Window<'a> {
callbacks: WindowCallbacks<'a>
// gdb-command:continue
#![allow(unused_variables)]
+#![omit_gdb_pretty_printer_section]
use self::Opt::{Empty, Val};
// lldb-check:[...]$14 = -10
// lldb-command:continue
+#![omit_gdb_pretty_printer_section]
struct Struct {
x: int
// lldb-check:[...]$14 = -10.5
// lldb-command:continue
+#![omit_gdb_pretty_printer_section]
struct Struct {
x: int
// lldb-check:[...]$5 = 20
// lldb-command:continue
+
+#![omit_gdb_pretty_printer_section]
+
fn a_function(x: bool, y: bool) {
zzz(); // #break
sentinel();
// lldb-check:[...]$5 = 20
// lldb-command:continue
+#![omit_gdb_pretty_printer_section]
+
fn main() {
let x = false;
let y = true;
#![allow(experimental)]
#![allow(unused_variables)]
+#![omit_gdb_pretty_printer_section]
use std::simd::{i8x16, i16x8,i32x4,i64x2,u8x16,u16x8,u32x4,u64x2,f32x4,f64x2};
// lldb-check:[...]$6 = false
// lldb-command:continue
+
+#![omit_gdb_pretty_printer_section]
+
fn main() {
let x = false;
// lldb-command:print padding_at_end
// lldb-check:[...]$5 = PaddingAtEnd { x: -10014, y: 10015 }
-#![allow(unused_variables)];
-#![allow(dead_code)];
+#![allow(unused_variables)]
+#![allow(dead_code)]
+#![omit_gdb_pretty_printer_section]
struct NoPadding16 {
x: u16,
#![allow(unused_variables)]
#![allow(dead_code)]
+#![omit_gdb_pretty_printer_section]
static mut NO_PADDING_8: (i8, u8) = (-50, 50);
static mut NO_PADDING_16: (i16, i16, u16) = (-1, 2, 3);
// lldb-check:[...]$4 = 5
// lldb-command:continue
+#![omit_gdb_pretty_printer_section]
+
struct Struct {
x: int
}
// lldb-check:[...]$2 = TheOnlyCase(Struct { x: 123, y: 456, z: 789 })
#![allow(unused_variables)]
+#![omit_gdb_pretty_printer_section]
use self::Regular::{Case1, Case2};
use self::Univariant::TheOnlyCase;
// lldb-check:[...]$7 = Tree { x: Simple { x: 25 }, y: InternalPaddingParent { x: InternalPadding { x: 26, y: 27 }, y: InternalPadding { x: 28, y: 29 }, z: InternalPadding { x: 30, y: 31 } }, z: BagInBag { x: Bag { x: Simple { x: 32 } } } }
#![allow(unused_variables)]
+#![omit_gdb_pretty_printer_section]
struct Simple {
x: i32
// lldb-check:[...]$3 = TheOnlyCase { a: -1 }
#![allow(unused_variables)]
+#![omit_gdb_pretty_printer_section]
use self::Regular::{Case1, Case2, Case3};
use self::Univariant::TheOnlyCase;
// lldb-check:[...]$3 = NestedOuter { a: NestedInner { a: WithDestructor { x: 7890, y: 9870 } } }
#![allow(unused_variables)]
+#![omit_gdb_pretty_printer_section]
struct NoDestructor {
x: i32,
// lldb-check:[...]$3 = (1, 2, 3)
// lldb-command:continue
+#![omit_gdb_pretty_printer_section]
+
struct Struct {
x: int
}
// lldb-command:run
#![allow(unused_variables)]
+#![omit_gdb_pretty_printer_section]
trait Trait {
fn method(&self) -> int { 0 }
// gdb-check:$10 = {x = {{40, 41, 42}, {43, 44}}, y = {45, 46, 47, 48}}
#![allow(unused_variables)]
+#![omit_gdb_pretty_printer_section]
struct NoPadding1 {
x: (i32, i32),
// lldb-check:[...]$6 = ((21, 22), 23)
#![allow(unused_variables)]
+#![omit_gdb_pretty_printer_section]
fn main() {
let no_padding1: ((u32, u32), u32, u32) = ((0, 1), 2, 3);
// to all fields having the name "<unnamed_field>"). Otherwise they are handled the same a normal
// structs.
+
+#![omit_gdb_pretty_printer_section]
+
struct NoPadding16(u16, i16);
struct NoPadding32(i32, f32, u32);
struct NoPadding64(f64, i64, u64);
// lldb-check:[...]$3 = TheOnlyCase(-1)
#![allow(unused_variables)]
+#![omit_gdb_pretty_printer_section]
use self::Regular::{Case1, Case2, Case3};
use self::Univariant::TheOnlyCase;
// gdb-command:whatis stack_closure2
// gdb-check:type = struct (&mut|i8, f32| -> f32, uint)
+#![omit_gdb_pretty_printer_section]
+
use self::Enum1::{Variant1_1, Variant1_2};
use std::ptr;
// lldb-check:[...]$2 = TheOnlyCase(123234)
#![allow(unused_variables)]
+#![omit_gdb_pretty_printer_section]
// The first element is to ensure proper alignment, irrespective of the machines word size. Since
// the size of the discriminant value is machine dependent, this has be taken into account when
// lldb-command:continue
#![allow(unused_variables)]
+#![omit_gdb_pretty_printer_section]
struct Struct {
a: int,
#![allow(unused_variables)]
#![feature(unboxed_closures)]
+#![omit_gdb_pretty_printer_section]
struct Struct {
a: int,
#![feature(unboxed_closures)]
#![allow(unused_variables)]
+#![omit_gdb_pretty_printer_section]
struct Struct {
a: int,
#![allow(unused_variables)]
#![feature(slicing_syntax)]
+#![omit_gdb_pretty_printer_section]
struct AStruct {
x: i16,
// lldb-check:[...]$0 = [1, 2, 3]
#![allow(unused_variables)]
+#![omit_gdb_pretty_printer_section]
static mut VECT: [i32; 3] = [1, 2, 3];