[llvm-dev] RFC: Supporting all entities declared in lexical scope in LLVM debug info
David Blaikie via llvm-dev
llvm-dev at lists.llvm.org
Wed Jan 20 14:26:06 PST 2016
On Wed, Jan 20, 2016 at 9:10 AM, Aboud, Amjad <amjad.aboud at intel.com> wrote:
> Hi David,
>
> 1. Yes, when I say that GDB 7.10 does the right thing, I meant that
> when stepping in inlined subroutine, it can find the direct children of the
> local scope based on the information appears in the correlated abstract
> block.
>
> 2. When I did my previous (initial) check, I was using an older
> version of GDB (7.6), so I am not sure when exactly this change/fix was
> applied between 7.6 and 7.10.
>
>
>
> Adrian can use the patches from these code review:
>
> http://reviews.llvm.org/D15976
>
> http://reviews.llvm.org/D15977
>
>
>
> I would like to hear from Adrian how far LLDB is from supporting this
> feature.
>
> If you think that it would take time before LLDB is fixed, we may consider
> committing the workaround solution first, and keep the final solution
> commented out.
>
> Once again, the difference between both solutions is few lines.
>
Thanks for mentioning this ^ again, I must've missed it the first
time/haven't looked closely enough at the patches. If that's the case, I
don't mind so much - possibly even include it under a flag or the like.
I'll have to see what it looks like in the code when I get to that.
> The above patches contain only the final solution as proposed below.
>
>
>
> Thanks,
>
> Amjad
>
>
>
> *From:* David Blaikie [mailto:dblaikie at gmail.com]
> *Sent:* Wednesday, January 20, 2016 01:48
> *To:* Aboud, Amjad; Adrian Prantl
> *Cc:* llvm-dev at lists.llvm.org; Merritt, Steve; Wyma, Brock
> *Subject:* Re: [llvm-dev] RFC: Supporting all entities declared in
> lexical scope in LLVM debug info
>
>
>
>
>
>
>
> On Mon, Dec 14, 2015 at 7:01 AM, Aboud, Amjad via llvm-dev <
> llvm-dev at lists.llvm.org> wrote:
>
> Hi,
>
> I verified that GDB 7.10 does support “DW_AT_abstract_origin” attribute on
> “DW_TAG_lexical_block”.
>
>
>
> I take it you mean that it does the right thing, finding the direct
> children of the abstract block when stepping into the inlined subroutine,
> etc?
>
> & this was a recent change/fix - because you'd verified that this did not
> work previously/in recent past GDB versions?
>
>
>
> This means, that we can implement the proposal I suggested below, and
> there is no need to open a change request for GDB.
>
>
>
> However, I am not sure about LLDB.
>
> My understanding is that LLDB does not support declarations inside lexical
> block properly.
>
> In the below example, the following command on LLDB:
>
> Ø ptype A
>
> Will print two suggestions for “A”:
>
> 1. float
>
> 2. int
>
>
>
> Adrian - want to test this sort of thing on LLDB? (Amjad - do you have a
> quick hack/patch Adrian could apply to generate a simple example on MacOS
> to test with LLDB there?) Would you want us to consider this a bug in LLDB
> & just forge ahead fixing this the right way? Or implement a fallback that
> duplicates local types/using declarations/static variables into the inlined
> subroutines rather than only emitting them in the abstract definition?
>
> - Dave
>
>
>
>
>
> Letting the user decide what is the proper type from the list of possible
> answers.
>
>
>
> Unless there are any real concerns regarding this proposal, I intend to
> start uploading the implementation soon.
>
> Please, let me know if you have any comment or feedback.
>
>
>
> Thanks,
>
> Amjad
>
>
>
>
>
> *From:* llvm-dev [mailto:llvm-dev-bounces at lists.llvm.org] *On Behalf Of *Aboud,
> Amjad via llvm-dev
> *Sent:* Wednesday, November 18, 2015 16:58
> *To:* llvm-dev at lists.llvm.org
> *Cc:* Merritt, Steve; Wyma, Brock
> *Subject:* [llvm-dev] RFC: Supporting all entities declared in lexical
> scope in LLVM debug info
>
>
>
> Hi,
>
> I would like to implement a fix to how LLVM handles/creates debug info for
> entities declared inside a basic block.
>
> Below you will find 5 parts:
>
> 1. Motivation for this fix.
>
> 2. Background explaining the cases that need to be fixed.
>
> 3. An example for each case.
>
> 4. Proposal on how to represent each case in dwarf.
>
> 5. Secondary (workaround) proposal which might be needed in the
> short term until applying a fix in GDB debugger.
>
>
>
> Please, let me know if you have any comment or feedback on this approach.
>
>
>
> Thanks,
>
> Amjad
>
>
>
> *Motivation*
>
> Current implementation causes loss of debug info, even when optimizations
> are disabled.
>
>
>
> For example:
>
>
>
> int foo(bool b) {
>
> if (b) {
>
> typedef int A;
>
> class B { public: int x; };
>
> B y;
>
> static A z = 0;
>
> return y.x + z++;
>
> } else {
>
> typedef float A;
>
> class B { public: float x; };
>
> B y;
>
> static A z = 0.0;
>
> return (int)(y.x + z++);
>
> }
>
> }
>
>
>
> In the above example, debugger will not be able to fetch the correct value
> for types "A" and "B" and for local static variable "z", however it will
> work fine with local variable "y".
>
>
>
> The local static variable has an open ticket in LLVM Bugzilla:
>
> https://llvm.org/bugs/show_bug.cgi?id=19238
>
>
>
> *Background*
>
> These are all the entities that can be declared inside a lexical scope
> (i.e. function or basic block):
>
> 1. Local variable
>
> 2. Local static variable
>
> 3. Imported Entity
>
> a. Imported declaration
>
> b. Imported module
>
> 4. Type
>
> a. Record (structure, class, union)
>
> b. Typedef
>
>
>
> In the current LLVM implementation only (1) the local variables are
> handled correctly.
>
> (2) local static variables and (4) Types are associated in clang-FE to the
> function lexical scope even when they are declared in an internal basic
> block.
>
> (3) Imported Entity is handled differently depends on where it is
> declared, in function lexical scope or in basic block scope.
>
>
>
> There are two interesting cases where we should consider the
> representation in dwarf for the above entities:
>
> a. Function was not inlined - has one concrete entry.
>
> b. Function was inlined - has one abstract entry, one or more
> inlined entries, and possibly one concrete entry.
>
>
>
> The goal is to be able to debug all the above entities in case (a) - which
> is the common case when compile with no optimizations. But also, we would
> like to be able to debug as many entities as we can also in case (b), the
> optimized mode.
>
>
>
> *Example*
>
> These are two examples that represent cases (a) and (b) with all the
> entities mentioned above.
>
>
>
> // (Case a)
>
> namespace N {
>
> class D;
>
> };
>
> int foo() {
>
> {
>
> using namespace N;
>
> using N::D;
>
> typedef int A;
>
> class B { public: int x; };
>
> B y;
>
> static A z = 0;
>
> return y.x + z++;
>
> }
>
> }
>
>
>
> // (Case b)
>
> __attribute__(always_inline)
>
> int foo(bool b) {
>
> // same as case (a)
>
> }
>
>
>
> int bar() {
>
> return foo();
>
> }
>
>
>
> *Proposed representation in dwarf*
>
> Case (a) - There is only one concrete function with one lexical block
> (DW_TAG_lexical_block) entry. Each entity will have a dwarf entry placed
> under the lexical block scope the same as appear in the source.
>
>
>
> (1) DW_TAG_subprogram (concrete)
>
> DW_AT_name (= "foo")
>
> DW_AT_low_pc
>
> DW_AT_low_high
>
>
>
> (2) LexicalBlock
>
> DW_AT_low_pc
>
> DW_AT_low_high
>
>
>
> (3) DW_TAG_imported_module
>
> DW_AT_import (=> N)
>
>
>
> (3) DW_TAG_imported_declaration
>
> DW_AT_import (=> N::D)
>
>
>
> (3) DW_TAG_typedef
>
> DW_AT_name (= "A")
>
> DW_AT_type (=> int)
>
>
>
> (3) DW_TAG_class_type
>
> DW_AT_name (= "B")
>
>
>
> (4) DW_TAG_variable
>
> DW_AT_name (= "x")
>
> DW_AT_type (= int)
>
>
>
> (3) DW_TAG_variable
>
> DW_AT_name (= "y")
>
> DW_AT_type (=> B)
>
> DW_AT_location
>
>
>
> (3) DW_TAG_variable
>
> DW_AT_name (= "z")
>
> DW_AT_type (= A)
>
> DW_AT_location
>
>
>
>
>
> Case (b) - There is one abstract function, one inline function
> (DW_TAG_inlined_subroutine) and one concrete function, each has one
> lexical block entry.
>
> Each entity will have a dwarf entry placed under the lexical block scope
> of the abstract function. Where these entries will contain all the debug
> info attributes for the represented entity, except for the local variable
> that will be missing the location attribute (DW_AT_location), as it is not
> common to all inline/concrete functions.
>
> In addition, under each lexical block entry in the inline/concrete
> function entry there will be:
>
> 1. Abstract origin attribute (DW_AT_abstract_origin) pointing to the
> equivalent lexical block entry in the abstract function.
>
> 2. Local variable entry - with abstract origin attribute pointing to
> the one in the abstract function, and also the location attribute.
>
>
>
> (1) DW_TAG_subprogram (abstract)
>
> DW_AT_name (= "foo")
>
> DW_AT_inline
>
>
>
> (2) LexicalBlock
>
>
>
> (3) DW_TAG_imported_module
>
> DW_AT_import (=> N)
>
>
>
> (3) DW_TAG_imported_declaration
>
> DW_AT_import (=> N::D)
>
>
>
> (3) DW_TAG_typedef
>
> DW_AT_name (= "A")
>
> DW_AT_type (=> int)
>
>
>
> (3) DW_TAG_class_type
>
> DW_AT_name (= "B")
>
>
>
> (4) DW_TAG_variable
>
> DW_AT_name (= "x")
>
> DW_AT_type (= int)
>
>
>
> (3) DW_TAG_variable
>
> DW_AT_name (= "y")
>
> DW_AT_type (=> B)
>
>
>
> (3) DW_TAG_variable
>
> DW_AT_name (= "z")
>
> DW_AT_type (=> A)
>
> DW_AT_location
>
>
>
>
>
> (1) DW_TAG_subprogram (concrete)
>
> DW_AT_abstract_origin (=> abstract function "foo")
>
> DW_AT_low_pc
>
> DW_AT_low_high
>
>
>
> (2) LexicalBlock
>
> DW_AT_abstract_origin (=> abstract lexical block)
>
> DW_AT_low_pc
>
> DW_AT_low_high
>
>
>
> (3) DW_TAG_variable
>
> DW_AT_abstract_origin (=> abstract variable "y")
>
> DW_AT_location
>
>
>
>
>
> (1) DW_TAG_subprogram
>
> DW_AT_name (= "bar")
>
> DW_AT_low_pc
>
> DW_AT_low_high
>
>
>
> (2) DW_TAG_inlined_subroutine (inline)
>
> DW_AT_abstract_origin (=> abstract function "foo")
>
> DW_AT_low_pc
>
> DW_AT_low_high
>
>
>
> (3) LexicalBlock
>
> DW_AT_abstract_origin (=> abstract lexical block)
>
> DW_AT_low_pc
>
> DW_AT_low_high
>
>
>
> (4) DW_TAG_variable
>
> DW_AT_abstract_origin (=> abstract variable "y")
>
> DW_AT_location
>
>
>
>
>
> This would be the optimal solution if GDB would support the
> "DW_AT_abstract_origin" attribute on lexical block.
>
> The idea of having this variable on lexical block is to inform the
> debugger that all attributes and (direct) children of the abstract lexical
> block are available for the inline/concrete lexical block as well.
>
>
>
> GDB does not support the above proposal and I suggest to open a bug on GDB
> debugger to support this.
>
> Do you think otherwise?
>
>
>
> *Workaround solution*
>
> In the meanwhile and till GDB implement the above requirement, we can
> implement a different approach for case (b), that will allows GDB to
> provide information on all entities in the inline/concrete function (except
> for types).
>
> The abstract function will still be the same, however the inline/concrete
> functions will be changed as follow:
>
>
>
> (1) DW_TAG_subprogram (concrete)
>
> DW_AT_abstract_origin (=> abstract function "foo")
>
> DW_AT_low_pc
>
> DW_AT_low_high
>
>
>
> (2) LexicalBlock
>
> DW_AT_low_pc
>
> DW_AT_low_high
>
>
>
> (3) DW_TAG_imported_module
>
> DW_AT_import (=> N)
>
>
>
> (3) DW_TAG_imported_declaration
>
> DW_AT_import (=> N::D)
>
>
>
> (3) DW_TAG_variable
>
> DW_AT_abstract_origin (=> abstract variable "y")
>
> DW_AT_location
>
>
>
> (3) DW_TAG_variable
>
> DW_AT_abstract_origin (=> abstract static variable "z")
>
>
>
>
>
> (1) DW_TAG_subprogram
>
> DW_AT_name (= "bar")
>
> DW_AT_low_pc
>
> DW_AT_low_high
>
>
>
> (2) DW_TAG_inlined_subroutine (inline)
>
> DW_AT_abstract_origin (=> abstract function "foo")
>
> DW_AT_low_pc
>
> DW_AT_low_high
>
>
>
> (3) LexicalBlock
>
> DW_AT_low_pc
>
> DW_AT_low_high
>
>
>
> (4) DW_TAG_imported_module
>
> DW_AT_import (=> N)
>
>
>
> (4) DW_TAG_imported_declaration
>
> DW_AT_import (=> N::D)
>
>
>
> (4) DW_TAG_variable
>
> DW_AT_abstract_origin (=> abstract variable "y")
>
> DW_AT_location
>
>
>
> (4) DW_TAG_variable
>
> DW_AT_abstract_origin (=> abstract static variable "z")
>
>
>
>
>
> I already have an implementation for this proposal and the changes between
> the optimal solution, which needs support from GDB, and the workaround
> solution is minimal.
>
>
>
>
>
> ---------------------------------------------------------------------
> Intel Israel (74) Limited
>
> This e-mail and any attachments may contain confidential material for
> the sole use of the intended recipient(s). Any review or distribution
> by others is strictly prohibited. If you are not the intended
> recipient, please contact the sender and delete all copies.
>
> ---------------------------------------------------------------------
> Intel Israel (74) Limited
>
> This e-mail and any attachments may contain confidential material for
> the sole use of the intended recipient(s). Any review or distribution
> by others is strictly prohibited. If you are not the intended
> recipient, please contact the sender and delete all copies.
>
>
> _______________________________________________
> LLVM Developers mailing list
> llvm-dev at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
>
>
>
> ---------------------------------------------------------------------
> Intel Israel (74) Limited
>
> This e-mail and any attachments may contain confidential material for
> the sole use of the intended recipient(s). Any review or distribution
> by others is strictly prohibited. If you are not the intended
> recipient, please contact the sender and delete all copies.
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20160120/ccb4ed43/attachment-0001.html>
More information about the llvm-dev
mailing list