[llvm-dev] Question about debug information for global variables
Roman Levenstein via llvm-dev
llvm-dev at lists.llvm.org
Thu Mar 22 16:47:02 PDT 2018
Adrian,
Thanks for a quick reply!
On Thu, Mar 22, 2018 at 4:22 PM, Adrian Prantl <aprantl at apple.com> wrote:
>
>
>> 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?
This is what I see printed by llvm-dwarfdump using the command-line:
llvm-dwarfdump -verify-debug-info -debug-dump=all myobjectfile.o
The DW_AT_location values are different:
With deref:
0x00000032: DW_TAG_variable [2]
DW_AT_name [DW_FORM_strp] (
.debug_str[0x0000001d] = "var1")
DW_AT_type [DW_FORM_ref4] (cu + 0x0049 => {0x00000049})
DW_AT_external [DW_FORM_flag_present] (true)
DW_AT_location [DW_FORM_exprloc] (<0xd> 03 b0
2e 00 00 00 00 00 00 06 10 00 22 )
Without deref:
0x00000032: DW_TAG_variable [2]
DW_AT_name [DW_FORM_strp] (
.debug_str[0x0000001d] = "var1")
DW_AT_type [DW_FORM_ref4] (cu + 0x0048 => {0x00000048})
DW_AT_external [DW_FORM_flag_present] (true)
DW_AT_location [DW_FORM_exprloc] (<0xc> 03 a0
2e 00 00 00 00 00 00 10 00 22 )
Unfortunately, the llvm-dwarfdump output is not very descriptive when
it comes to expressions.
In LLVM IR, it is more understandable:
With deref:
!28 = !DIExpression(DW_OP_deref, DW_OP_constu, 2000, DW_OP_plus)
Without deref:
!28 = !DIExpression(DW_OP_constu, 2000, DW_OP_plus)
>>
>> 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 :-)
Yes, I was wondering if it could be an LLDB bug, because I'd also
expect different results.
That being said, does the overall approach I outlined seem correct?
I.e. should it be possible in principle to express the logical global
variables using the approach I outlined?
-Roman
>
> -- 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