[PATCH] Output debug information for structure members only referenced by a pointer or typedef

Keith Walker Keith.Walker at arm.com
Thu Jun 20 04:48:26 PDT 2013


> On Wed, Jun 19, 2013 at 5:34 AM, Keith Walker <keith.walker at arm.com>
> wrote:
> > This patch addresses an issue introduced by r183296 that means that
> the
> > members of a structure are no longer output in the DWARF debugging
> > information if the structure is only referenced by a pointer or
> typedef
> > (reported in PR16214).
>
> Does r184252 address your issue?

Unfortunately no.

> What's the particular regression you're trying to fix related to
> pointers without typedefs? I'm pretty sure even pre-r183296 a simple

Actually it appears I simplified my example program I was using to investigate the problem too much.

The problem is actually to do with a typdef'ed pointer to a structure as mentioned in PR16214.

This program when compiled with "-g -O0" demonstrates the problem that the member i of struct s in not output (unless you use -fno-limit-debug-info).

-----------------------------------
#include <stdlib.h>

struct s {
    int i;
};

typedef struct s *sptr;

int main()
{
    sptr sp = (sptr)malloc(sizeof(struct s));
    sp->i = 1;
    return sp->i;
}
-----------------------------------

Unfortunately during my investigation I had taken one step further and simplified it to ....

-----------------------------------
#include <stdlib.h>

struct s {
    int i;
};


int main()
{
    struct s *sp = (struct s*)malloc(sizeof(struct s));
    sp->i = 1;
}
-----------------------------------

Which generated the same debugging information so I mistakenly thought the problem was not due to the typedef.

However, upon further investigation adding back the return statement so there is a read of the member sp->i and hey-presto the expected member information is generated.

So actually the problem I was attempting to fix is that which is mentioned it PR16214.

> piece of code involving a struct definition and the declaration of a
> variable that is a pointer to that type would've only emitted the
> declaration of that type. Did you observe different behavior?

Previously to r183296 the member information was generated .... but I guess that is actually because the -flimit-debug-info was not limiting the generated information in all cases.

>
> > Files:
> >   test/CodeGenCXX/debug-info-namespace.cpp
> >   test/CodeGenCXX/debug-info.cpp
> >   lib/CodeGen/CGDebugInfo.cpp
> >
> > Index: test/CodeGenCXX/debug-info-namespace.cpp
> > ===================================================================
> > --- test/CodeGenCXX/debug-info-namespace.cpp    (revision 184291)
> > +++ test/CodeGenCXX/debug-info-namespace.cpp    (working copy)
> > @@ -57,7 +57,7 @@
> >  // CHECK: [[M6]] = metadata !{i32 {{[0-9]*}}, metadata [[FUNC]],
> metadata
> > [[FOO:![0-9]*]], i32 21} ; [ DW_TAG_imported_declaration ]
> >  // CHECK: [[FOO]] {{.*}} ; [ DW_TAG_structure_type ] [foo] [line 5,
> size 0,
> > align 0, offset 0] [fwd] [from ]
> >  // CHECK: [[M7]] = metadata !{i32 {{[0-9]*}}, metadata [[FUNC]],
> metadata
> > [[BAR:![0-9]*]], i32 22} ; [ DW_TAG_imported_declaration ]
> > -// CHECK: [[BAR]] {{.*}} ; [ DW_TAG_structure_type ] [bar] [line 6,
> {{.*}}]
> > [fwd] [from ]
> > +// CHECK: [[BAR]] {{.*}} ; [ DW_TAG_structure_type ] [bar] [line 6,
> {{.*}}]
> > [from ]
> >  // CHECK: [[M8]] = metadata !{i32 {{[0-9]*}}, metadata [[FUNC]],
> metadata
> > [[F1]], i32 23} ; [ DW_TAG_imported_declaration ]
> >  // CHECK: [[M9]] = metadata !{i32 {{[0-9]*}}, metadata [[FUNC]],
> metadata
> > [[I]], i32 24} ; [ DW_TAG_imported_declaration ]
> >  // CHECK: [[M10]] = metadata !{i32 {{[0-9]*}}, metadata [[FUNC]],
> metadata
> > [[BAZ:![0-9]*]], i32 25} ; [ DW_TAG_imported_declaration ]
> > Index: test/CodeGenCXX/debug-info.cpp
> > ===================================================================
> > --- test/CodeGenCXX/debug-info.cpp      (revision 184291)
> > +++ test/CodeGenCXX/debug-info.cpp      (working copy)
> > @@ -102,18 +102,26 @@
> >  typedef a at;
> >
> >  struct b {
> > +  int j;
> >  };
> >
> > +struct c;
> > +
> >  typedef b bt;
> > +typedef c ct;
> >
> >  void func() {
> >    at a_inst;
> >    bt *b_ptr_inst;
> >    const bt *b_cnst_ptr_inst;
> > +  ct *c_ptr_inst;
> >  }
> >
> >  // CHECK: metadata [[A_MEM:![0-9]*]], i32 0, null, null} ; [
> > DW_TAG_structure_type ] [a]
> >  // CHECK: [[A_MEM]] = metadata !{metadata [[A_I:![0-9]*]], metadata
> > !{{[0-9]*}}}
> >  // CHECK: [[A_I]] = {{.*}} ; [ DW_TAG_member ] [i] {{.*}} [from int]
> > -// CHECK: ; [ DW_TAG_structure_type ] [b] {{.*}}[fwd]
> > +// CHECK: metadata [[B_MEM:![0-9]*]], i32 0, null, null} ; [
> > DW_TAG_structure_type ] [b]
> > +// CHECK: [[B_MEM]] = metadata !{metadata [[B_J:![0-9]*]]}
> > +// CHECK: [[B_J]] = {{.*}} ; [ DW_TAG_member ] [j] {{.*}} [from int]
> > +// CHECK: ; [ DW_TAG_structure_type ] [c] {{.*}}[fwd]
> >  }
> > Index: lib/CodeGen/CGDebugInfo.cpp
> > ===================================================================
> > --- lib/CodeGen/CGDebugInfo.cpp (revision 184291)
> > +++ lib/CodeGen/CGDebugInfo.cpp (working copy)
> > @@ -615,7 +615,8 @@
> >                                                       llvm::DIFile
> Unit) {
> >    if (DebugKind > CodeGenOptions::LimitedDebugInfo)
> >      return getOrCreateType(PointeeTy, Unit);
> > -  return getOrCreateType(PointeeTy, Unit, true);
> > +  bool Declaration = isa<RecordType>(PointeeTy);
> > +  return getOrCreateType(PointeeTy, Unit, Declaration);
>
> This is not the right fix - we don't want to always emit definitions
> for types referenced via pointers or typedefs in all cases.
>
> Limited debug info (r184252 probably addresses your issue when
> building with -fno-limit-debug-info) is intended to reduce debug info
> by taking steps including emitting only the declaration of types that
> are only used in ways that a definition would not be needed.
>
> In your test case there's no use of the concrete type 'b' - only some
> pointers to 'b' that are never dereferenced. (the test here is "if a
> struct definition were replaced with a declaration, would the code
> still compile" - if that condition is met, then the intent is that
> Clang emit only a declaration for that type when building with
> -flimit-debug-info (which is the default))

I hadn't realised -flimit-debug-info was the default ...silly me!

> Does that make sense?

Yes.

> As for how to fix it - we'd have to look at how to plumb in hooks for
> the debug info to be invoked (to request the full definition of a
> type) when we visit expressions that require the full definition (eg
> in Adrian's r184252 the commented line in the test case that
> dereferences the pointer).

Yes .... this look exactly like the problem that I was wanting to fix .... unfortunately it looks like my attempted fix was a sledge hammer approach. :-)

>
> >  }
> >
> >  llvm::DIType CGDebugInfo::CreatePointerLikeType(unsigned Tag,


-- IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium.  Thank you.





More information about the cfe-commits mailing list