[llvm-dev] Question about debug information for global variables

Adrian Prantl via llvm-dev llvm-dev at lists.llvm.org
Thu Mar 22 16:22:03 PDT 2018



> On Mar 22, 2018, at 4:08 PM, Roman Levenstein <romixlev at gmail.com> wrote:
> 
> Hi,
> 
> I'm trying to achieve the following:
> 
> - I have a global variable BaseAddress that holds the base address of
> a contiguous dynamically allocated memory block.
> 
> - I have a number of logical variables of different types that are
> mapped on certain address ranges inside the memory block pointed to by
> BaseAddress. The offset and the size of each such logical variable
> inside the memory block are known constants.
> 
> - I'd like to make it possible to access these logical variables
> inside the debugger as if they are normal global variables.
> 
> My idea was to create the debug information for each of these logical
> variables by using DIBuilder::createGlobalVariableExpression called
> GVE and provide a DIExpression called DIE that should basically take
> the value of the global variable GVE is added to, i.e. the value of
> BaseAddress, and add a constant offset corresponding to the logical
> variable. This should be the address of the logical variable.
> 
> So, the DIExpression  DIE would look something like:
> DW_OP_deref, DW_OP_constu, offset, DW_OP_plus
> 
> But this does not work. I tried the variants with and without
> DW_OP_deref, but I always get the same wrong result when I test with
> LLDB. The offset is always added to the address of BaseAddress and not
> to its value.

Can you share the final expression as printed by llvm-dwarfdump?

> 
> The code for creating logical variables looks roughly like:
> 
>    llvm::SmallVector<uint64_t, 4> ops;
>    size_t offset = getOffset(logicalVariable);
>    // Get the value of the global variable that contains a pointer to
> the memory block.
>    // NOTE: Even if DW_OP_deref is omitted, the results under LLDB
> are the same.

Have you considered that this might be a bug in LLDB? You really shouldn't get the same result with and without the DW_OP_deref (unless you are pointing to a self-referential pointer :-)

-- adrian

>    ops.push_back(llvm::dwarf::DW_OP_deref);
>    // Add a constant offset to the value of the global variable.
>    ops.push_back(llvm::dwarf::DW_OP_constu);
>    ops.push_back(offset);
>    ops.push_back(llvm::dwarf::DW_OP_plus);
>    llvm::DIExpression *DIexpr{nullptr};
>    auto *DIE = DIBuilder_->createExpression(ops);
>    auto *GVE = DIBuilder_->createGlobalVariableExpression(
>        cu, name, "", file, 0, type,
>        /* isLocalToUnit */ false, DIE);
>    // Add GVE as debug info to BaseAddress.
>    baseAddress->addDebugInfo(GVE);
> 
> I guess I'm doing something wrong, but I cannot see what it is.
> 
> Interestingly enough, when I tried a similar approach, where
> BaseAddress would be a function argument and logical variables would
> be created by means of insertDeclare, everything seems to work just
> fine under LLDB. I use the following code for this approach:
> 
>   llvm::SmallVector<uint64_t, 4> ops;
>   llvm::DIExpression::appendOffset(ops, getOffset(logicalVariable));
>   auto *DIE = DIBuilder_->createExpression(ops);
>   builder.insertDeclare(baseAddress, var, DIE,
>                                llvm::DebugLoc::get(lineNo, 0, currentScope),
>                                insertionPoint);
> 
> Can anyone provide an insight regarding how to achieve the desired
> results using global variables and what I'm doing wrong? Or may be
> there are simpler ways to achieve the same effect?
> 
> Thanks,
>  Roman



More information about the llvm-dev mailing list