Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gdb needs to know what traits a type implements #33014

Open
tromey opened this issue Apr 15, 2016 · 5 comments
Open

gdb needs to know what traits a type implements #33014

tromey opened this issue Apr 15, 2016 · 5 comments
Labels
A-debuginfo Area: Debugging information in compiled programs (DWARF, PDB, etc.) A-trait-system Area: Trait system C-feature-request Category: A feature request, i.e: not implemented / a PR. P-low Low priority T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@tromey
Copy link
Contributor

tromey commented Apr 15, 2016

I'd like to make operator overloading work for Rust in gdb. That is, I'd like something like print x+y to call the appropriate method on the Add trait. I'd also like to make ordinary method calls work, where the method is defined in some trait that is impl'd for the concrete type of the object.

Right now I think this can't be done. There is no information in the debug info about what traits are implemented by a type.

Consider:

pub trait What {
    fn what(&self);
}

impl What for i32 {
    fn what(&self) {
        println!("{}", self);
    }
}

fn main() {
    let v = 23;
    let x = &v as &What;

    x.what();
    ()
}

Here i32 is described as just a base type:

 <1><5e7>: Abbrev Number: 16 (DW_TAG_base_type)
    <5e8>   DW_AT_name        : (indirect string, offset: 0x46a): i32
    <5ec>   DW_AT_encoding    : 5   (signed)
    <5ed>   DW_AT_byte_size   : 4

I think this might be a good spot to list all the impl'd traits. Perhaps they can be represented as DWARF interfaces; or maybe some Rust extension to DWARF would be preferable.

i32.What is emitted as a namespace:

 <2><2f>: Abbrev Number: 2 (DW_TAG_namespace)
    <30>   DW_AT_name        : (indirect string, offset: 0x48): i32.What

... but this isn't directly useful as it would require an iteration over all the namespace DIEs looking for matches. Maybe I could do this; but I'd rather not as it is very inefficient.

@tromey
Copy link
Contributor Author

tromey commented Apr 18, 2016

It occurred to me later that for operator overloading, I could perhaps just compute the method name directly in gdb. For example, impl Add for S might result in a method crate::S.Add::add.

However, there doesn't seem to be a way to tell whether this is std::ops::Add or some other trait that happens to have the same name. For this, rustc would have to emit some extra debuginfo.

I think it is still necessary to have information about traits attached to types, for other calls via traits.

@sanxiyn sanxiyn added the A-debuginfo Area: Debugging information in compiled programs (DWARF, PDB, etc.) label Apr 19, 2016
@Mark-Simulacrum Mark-Simulacrum added C-enhancement Category: An issue proposing an enhancement or a PR with one. C-bug Category: This is a bug. C-feature-request Category: A feature request, i.e: not implemented / a PR. and removed C-enhancement Category: An issue proposing an enhancement or a PR with one. C-bug Category: This is a bug. labels Jul 25, 2017
@tromey
Copy link
Contributor Author

tromey commented Jan 11, 2019

I thought I would write up a plan here; I probably am going to stop working on this, but this can serve as a guide to anyone picking it up in the future.

The basic idea is to represent a concrete impl of a trait for some type using the existing DW_TAG_interface_type (and not namespace as is curently done). This would then be attached to the type using DW_TAG_inheritance.

I started on an LLVM patch here: https://github.com/tromey/llvm/tree/interface-type. However, this patch is incomplete, as it does not allow interfaces to be attached to subroutine types, pointer types, or scalar types. Adding those would require a bigger change. Maybe the cleanest way would be to let the type base class hold any interface types. However, this is a pain due to the way this part of LLVM has been written. So perhaps handling this case-by-case on the concrete subclasses is simpler in practice.

This approach will also require a small DWARF extension. DWARF 5, section 5.7.3, says:

A class type or interface type entry that describes a derived, extended or
implementing class or interface owns debugging information entries describing
each of the classes or interfaces it is derived from, extending or implementing,
respectively, ordered as they were in the source program. Each such entry has the
tag DW_TAG_inheritance.

This language is specific to class/structure/interface types. However, for Rust, this restriction should be lifted.

It would make sense to file this as a DWARF issue; however, it may be best to wait until any patches have landed in LLVM first.

@Grunthos
Copy link

Grunthos commented Oct 3, 2024

Not sure why this is a low priority item: I came across it as a result of trying to inspect x.is_some() in RustRover.

Being able to debug basic variables is kind of a critical feature for any language, I would have thought. Or am I missing something? Is this bug report very narrow and is there another issue relating to the broader requirement to inspect variables in a debugger?

@bjorn3
Copy link
Member

bjorn3 commented Oct 3, 2024

This issue is specifically about traits. x.is_some() doesn't use any traits. For x.is_some() maybe is_some was never called on this specific type and thus never codegened?

@Grunthos
Copy link

Grunthos commented Oct 3, 2024

Thanks for the quick reply:

        if self.parent.is_some() {
            println!("Not an orphan");
        }
        // Break point on next IF statement
        if let Some(parent) = &self.parent {

Examining self.parent.is_some() results in the error.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-debuginfo Area: Debugging information in compiled programs (DWARF, PDB, etc.) A-trait-system Area: Trait system C-feature-request Category: A feature request, i.e: not implemented / a PR. P-low Low priority T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

7 participants