Skip to content

.debug_gdb_scripts is being loaded into memory #81028

Open
@jsgf

Description

@jsgf
Contributor

If I build:

fn main() {}

with rustc -g --crate-type bin --emit obj -o t.o t.rs, and look at the output of readelf -St t.o I see:

  [27] .debug_gdb_scripts
       PROGBITS               PROGBITS         0000000000000000  0000000000000270  0
       0000000000000022 0000000000000001  0                 1
       [0000000000000032]: ALLOC, MERGE, STRINGS

According to #41627, this is not supposed to be an alloc section (ie, loaded into memory), but only present in the object file.

Having this section loaded isn't a huge problem in itself, but when combined with --link-arg -Wl,--strip-all (or --strip-debug) it triggers a crash in lld: https://bugs.llvm.org//show_bug.cgi?id=44878

There are lld fixes pending (https://reviews.llvm.org/D74510, https://reviews.llvm.org/D91291) (lld is already fixed), but it still seems like making .debug_gdb_scripts alloc is unintended.

Meta

rustc --version --verbose:

rustc 1.49.0 (e1884a8e3 2020-12-29)
binary: rustc
commit-hash: e1884a8e3c3e813aada8254edfa120e85bf5ffca
commit-date: 2020-12-29
host: x86_64-unknown-linux-gnu
release: 1.49.0

cc @eddyb @ayermolo

Activity

jsgf

jsgf commented on Jan 15, 2021

@jsgf
ContributorAuthor

This is basically a regression of issue #41626
cc @whitequark

nagisa

nagisa commented on Jan 15, 2021

@nagisa
Member

somewhat relevant is #77961

I wouldn't be surprised if somebody went ahead and marked it as allocatable so that the linker preserves it in the final binary at all...

added
A-debuginfoArea: Debugging information in compiled programs (DWARF, PDB, etc.)
A-linkageArea: linking into static, shared libraries and binaries
I-heavyIssue: Problems and improvements with respect to binary size of generated code.
T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.
on Jan 16, 2021
bjorn3

bjorn3 commented on Apr 15, 2021

@bjorn3
Member

A symbol in this section is directly referenced in the main shim using read_volatile to prevent the linker from gc'ing it.

bx.insert_reference_to_gdb_debug_scripts_section_global();

/// 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(bx: &mut Builder<'_, '_, '_>) {
if needs_gdb_debug_scripts_section(bx) {
let gdb_debug_scripts_section = get_or_insert_gdb_debug_scripts_section_global(bx);
// Load just the first byte as that's all that's necessary to force
// LLVM to keep around the reference to the global.
let indices = [bx.const_i32(0), bx.const_i32(0)];
let element = bx.inbounds_gep(gdb_debug_scripts_section, &indices);
let volative_load_instruction = bx.volatile_load(element);
unsafe {
llvm::LLVMSetAlignment(volative_load_instruction, 1);
}
}
}

jsgf

jsgf commented on Apr 18, 2021

@jsgf
ContributorAuthor

OK, so it is supposed to be alloc then.

eddyb

eddyb commented on Apr 30, 2021

@eddyb
Member

That looks like an ancient way to emulate the #[used] attribute - could we maybe do that instead?

bjorn3

bjorn3 commented on Apr 30, 2021

@bjorn3
Member
#[used]
#[link_section = ".abc"]
#[no_mangle]
pub static FOO: u8 = 0;
fn main() {}

Does not result in an executable with an .abc section of FOO symbol. Executables never export any symbols except for main and certain symbols used by libc or created by the linker itself. Because of this --gc-sections will simply gc the .abc section.

$ readelf -sW rust_out | grep -v 0000000000000000 | grep "GLOBAL " | grep -v HIDDEN
    63: 0000000000001350     1 FUNC    GLOBAL DEFAULT   14 __libc_csu_fini
    65: 0000000000004010     0 NOTYPE  GLOBAL DEFAULT   24 _edata
    74: 00000000000012f0    93 FUNC    GLOBAL DEFAULT   14 __libc_csu_init
    75: 0000000000004018     0 NOTYPE  GLOBAL DEFAULT   25 _end
    76: 0000000000001050    43 FUNC    GLOBAL DEFAULT   14 _start
    78: 0000000000004010     0 NOTYPE  GLOBAL DEFAULT   25 __bss_start
    79: 00000000000012d0    29 FUNC    GLOBAL DEFAULT   14 main

From the linked rfc:

The part about the linker is not true (*): from the point of view of the linker static variables marked with #[used] look exactly the same as variables that have not been marked with that attribute -- those are the implemented LLVM semantics. Also ELF object files have no mechanism to prevent the linker from dropping its symbols if they are not referenced by other object files.

(*) unless "linker" is actually referring to llvm-link (?)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-debuginfoArea: Debugging information in compiled programs (DWARF, PDB, etc.)A-linkageArea: linking into static, shared libraries and binariesC-bugCategory: This is a bug.I-heavyIssue: Problems and improvements with respect to binary size of generated code.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @eddyb@jsgf@nagisa@jonas-schievink@bjorn3

        Issue actions

          .debug_gdb_scripts is being loaded into memory · Issue #81028 · rust-lang/rust