[LLVMdev] More DIFactory questions - still stumped

Talin viridia at gmail.com
Sun Sep 5 11:32:36 PDT 2010


I hate to be a nag, but after several days of working on this I am still
utterly stumped.

Let me recap the situation as it currently stands: I'm trying to write code
that generates DWARF debugging information for my compiler using DIFactory
and friends. Unfortunately the information I am generating appears to be
invalid, but I can't figure out the cause.

Based on the advice in the earlier thread, I've been using dwarfdump to try
and isolate the problem. This was helpful in solving the earlier problem,
but isn't helping me with the current problem.

When I run dwarfdump -a, it prints a couple hundred pages of debug info, and
then segfaults. The last few lines before the segfault look like this:

.debug_inlined contents:
< EMPTY >
.debug_frame contents:

0x00000000: CIE
        length: 0x00000010
        CIE_id: 0xffffffff
       version: 0x01
  augmentation: ""
    code_align: 1
    data_align: -4
   ra_register: 0x08
                DW_CFA_def_cfa (esp, 4)
                DW_CFA_offset (eip, 0)
                DW_CFA_nop
                DW_CFA_nop
  Instructions: Init State: CFA=esp+4     eip=[esp+4]


0x00000014: FDE
        length: 0x00000028
   CIE_pointer: 0x00000000
Segmentation fault


If I grep through the output of dwarfdump, there are no other CIE or FDE
definitions that occur before this point, so I assume that the problem isn't
just this particular FDE.

One difficulty here is that I don't know which calls to DIFactory produce
these data structures. Usually my solution of last resort when dealing with
intractable debugging problems like this is to start commenting out code
until the problem goes away, but in this case I don't know where to even
start. If I comment out *all* the DWARF-generating code, then obviously the
problem goes away. :)

I did in fact discover that if I comment out all calls to
DIFactory::CreateSubprogram, the problem disappears - but then I don't have
any debugging info. (Well, I still have all the DINodes for my data
structures, just not functions.) I've also commented out all of the
declarations of parameters and local variables, which doesn't prevent the
problem from occurring. (Since my current understanding is that CIE and FDE
are used to describe the call frame, I'm trying to simplify the problem as
much as possible.)

I've carefully studied the source code of CGDebugInfo in clang as a working
example. One puzzlement is that there's a discrepancy between what the
"source level debugging with LLVM" docs say and what clang does: According
to the docs, DW_TAG_formal_parameter is used to specify a formal parameter
in a function type descriptor, but according to a code search, the name
"DW_TAG_formal_parameter" does not appear anywhere in the clang source code.
Instead, the argument array that is used when creating a function type
descriptor contains only the bare types, not types wrapped in a formal
parameter DIE.

However, since I've tried it both ways (wrapped and unwrapped) and the
dwarfdump crash occurs either way, this latter issue is of lesser concern.

At the moment I'm experimenting with the parameters to CreateSubprogram,
trying every possible permutation of inputs that I can think of in hope of
stumbling on the right answer. I can't think of what else to do.

Note that I am calling assert(diNode.Verify()) on every DINode after it's
created, so I know that it's valid up to that point at least. However, the
checks in Verify() aren't very extensive. (Also, I've observed in the past
that it's kind of inconvenient that Verify() only returns a boolean result
when it fails, with no indication of what you did wrong.)

All of this is with the current LLVM head, although I was getting the same
problems with the version from about 2 months ago.

On Thu, Sep 2, 2010 at 11:43 PM, Talin <viridia at gmail.com> wrote:

> OK here's another question along these lines: According to the LLVM source
> level debugging manual:
>
>  The first member of subroutine (tag = DW_TAG_subroutine_type) type
> elements is the return type for the subroutine. The remaining elements are
> the formal arguments to the subroutine.
>
>
> Now, when I read "formal arguments" I'm assuming we're talking about DIEs
> of type DW_TAG_formal_parameter. However, when I look in the code in
> CGDebugInfo.cpp in clang, I see that the arguments are in fact the bare
> types, not the formal parameter declarations.
>
> Here's what my code looks like:
>
>   const ParameterList & params = type->params();
>   for (ParameterList::const_iterator it = params.begin(); it !=
> params.end(); ++it) {
>     const ParameterDefn * param = *it;
>     DIType ptype = genDIParameterType(param->type());
>     ptype = dbgFactory_.CreateDerivedTypeEx(
>         dwarf::DW_TAG_formal_parameter,
>         dbgCompileUnit_,
>         param->name() != NULL ? param->name() : "",
>         genDIFile(param),
>         getSourceLineNumber(param->location()),
>         getSizeOfInBits(param->internalType()->irParameterType()),
>         getInt64Val(0),
>         getInt64Val(0), 0,
>         ptype);
>     DASSERT(ptype.Verify());
>     args.push_back(ptype);
>   }
>
>
> However, if I go by what's in clang, it seems that the
> DW_TAG_formal_parameter is unnecessary. Is this correct?
>
> And I'd still like to see some of these questions addressed in the actual
> HTML documentation, as opposed to just responding here on the mailing list.
> :)
>
> On Tue, Aug 31, 2010 at 10:32 AM, Devang Patel <dpatel at apple.com> wrote:
>
>>
>> On Aug 31, 2010, at 9:03 AM, Talin wrote:
>>
>> > 4) What is the meaning of the "inlinedAt" argument for DebugLoc::get()?
>> Does it mean the location where the inlined code was defined, or the
>> location where it was expanded?
>>
>> the location where it was expanded
>> -
>> Devang
>
>
>
>
> --
> -- Talin
>



-- 
-- Talin
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20100905/8e2458cf/attachment.html>


More information about the llvm-dev mailing list