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

Roman Levenstein via llvm-dev llvm-dev at lists.llvm.org
Thu Mar 22 16:08:10 PDT 2018


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.

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.
    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