So you need to fix "DW_OP_call_frame_cfa" so it creates the same kind of value
on the expression stack as "DW_OP_reg31" does. I am guessing that "DW_OP_reg31"
will have a Value that whose value is "eValueTypeScalar". Verify this and
change "DW_OP_call_frame_cfa" to match. We want the Scalar gotten by:
Scalar value;
if (frame->GetFrameBaseValue(value, error_ptr)) {
To be the same kind of value. Seems the expression parsing code that uses
"DW_OP_call_frame_cfa" is doing the wrong thing by setting the value to a load
address type.
> On Sep 19, 2017, at 10:51 AM, Leonardo Bianconi
> <[email protected]> wrote:
>
>
>
>> -----Original Message-----
>> From: Greg Clayton [mailto:[email protected]]
>> Sent: terça-feira, 19 de setembro de 2017 12:33
>> To: Leonardo Bianconi <[email protected]>
>> Cc: [email protected]
>> Subject: Re: [lldb-dev] Reading eValueTypeLoadAddress with missing compiler
>> type
>>
>>
>>> On Sep 19, 2017, at 4:10 AM, Leonardo Bianconi
>> <[email protected]> wrote:
>>>
>>> Some more details:
>>>
>>> I'm part of the team that is working in LLDB to enable PPC64le
>>> architecture, so
>> I'm running my test in a Power8 machine.
>>> When compiling the code with clang, it works, the issue happen when
>>> compiling
>> with gcc, which generates a different debug information content.
>>>
>>> Talking a bit about the power stack frame, it is organized this way:
>>>
>>> Suppose that you have two functions a() and b() and a calls b, then the
>>> frames
>> will be like this:
>>>
>>> high address
>>> +-----------------+
>>> | ... | // frame of a
>>> | ... |
>>> | ... |
>>> | ... |
>>> | ... |
>>> | back chain | // r31 and r1 points here when running function a
>>> +-----------------+
>>> | ... | // frame of b
>>> |variable address |
>>> | ... |
>>> | ... |
>>> | ... |
>>> | back chain | // r31 and r1 points here when running function b
>>> +-----------------+
>>> low address
>>>
>>> The debug information related to find the variable with clang is:
>>> <2><6ce>: Abbrev Number: 27 (DW_TAG_variable)
>>> <6cf> DW_AT_location : 3 byte block: 91 f0 0 (DW_OP_fbreg: 112)
>>> <6d3> DW_AT_name : (indirect string, offset: 0x1cf): a
>>> <6d7> DW_AT_decl_file : 5
>>> <6d8> DW_AT_decl_line : 6
>>> <6d9> DW_AT_type : <0x1bf>
>>> <2><6dd>: Abbrev Number: 0
>>> <1><6de>: Abbrev Number: 0
>>> <1><6b5>: Abbrev Number: 26 (DW_TAG_subprogram)
>>> <6b6> DW_AT_low_pc : 0x10000630
>>> <6be> DW_AT_high_pc : 0x88
>>> <6c2> DW_AT_frame_base : 1 byte block: 6f (DW_OP_reg31 (r31))
>>> <6c4> DW_AT_name : (indirect string, offset: 0x1ca): main
>>> <6c8> DW_AT_decl_file : 5
>>> <6c9> DW_AT_decl_line : 5
>>> <6ca> DW_AT_type : <0x1bf>
>>> <6ce> DW_AT_external : 1
>>>
>>> Which uses the r31 (DW_OP_reg31) and a positive offset (112) to find it,
>>> which
>> is ok, as it does not need to read the memory using the address in the r31
>> register.
>>>
>>> The issue happen when using the debug information generated by gcc, which
>> is:
>>> <2><9e>: Abbrev Number: 5 (DW_TAG_variable)
>>> <9f> DW_AT_name : a
>>> <a1> DW_AT_decl_file : 1
>>> <a2> DW_AT_decl_line : 6
>>> <a3> DW_AT_type : <0x3b>
>>> <a7> DW_AT_location : 2 byte block: 91 5c (DW_OP_fbreg: -36)
>>> <1><81>: Abbrev Number: 4 (DW_TAG_subprogram)
>>> <82> DW_AT_external : 1
>>> <82> DW_AT_name : (indirect string, offset: 0xe): main
>>> <86> DW_AT_decl_file : 1
>>> <87> DW_AT_decl_line : 5
>>> <88> DW_AT_type : <0x3b>
>>> <8c> DW_AT_low_pc : 0x840
>>> <94> DW_AT_high_pc : 0xf8
>>> <9c> DW_AT_frame_base : 1 byte block: 9c (DW_OP_call_frame_cfa)
>>> <9e> DW_AT_GNU_all_tail_call_sites: 1
>>>
>>> Here, it says to use the "DW_OP_call_frame_cfa", that is correctly executed
>>> in
>> the LLDB, obtaining the content of r31 and setting it as "
>> lldb_private::Value::eValueTypeLoadAddress", which means the data it is
>> looking
>> for is located in the address obtained in the r31, and it need to be read
>> from
>> memory. If the address was correctly read, it would point to the back chain
>> of the
>> previous frame, and the variable would be found, as the offset is negative
>> (-36),
>> so ("previous back chain address" - 36) is the correct variable address.
>>>
>>> My code is very simple:
>>> =====================================
>>> #include <stdlib.h>
>>> #include <stdio.h>
>>>
>>> int main(void) {
>>> int a = 2;
>>> printf("a address: %p \n", (void*)&a);
>>> printf("a = %d \n", a);
>>> return 0;
>>> }
>>> =====================================
>>>
>>> And I'm using the commands:
>>> gcc -O0 -ggdb stest.cpp (gcc version 5.4.1 20170304)
>>> clang -O0 -ggdb stest.cpp
>>>
>>>
>>> I think it is not related with the variable type, right?
>>
>> It might be, can you show the DWARF for the 0x3b type? This was in your GCC
>> variable's DWARF:
>>
>>> <a3> DW_AT_type : <0x3b>
>
> It is a 4 byte signed integer:
>
> <1><3b>: Abbrev Number: 3 (DW_TAG_base_type)
> <3c> DW_AT_byte_size : 4
> <3d> DW_AT_encoding : 5 (signed)
> <3e> DW_AT_name : int
>
>>
>> There should be nothing wrong with that as long as LLDB is correctly setting
>> r31
>> into the expression stack in response to the DW_OP_call_frame_cfa opcode. It
>> should grab r31 - 36 and push the result onto the expression stack with
>> eValueTypeLoadAddress as the type. Then we just need to read the type from
>> memory. Since the type is so simple (int), I don't see the type failing
>> here. I am
>> guessing the DW_OP_call_frame_cfa is messing up the expression somehow.
>> Can you step through and make sure that "r31 - 36" is correctly being pushed
>> onto the expression stack?
>
> I think I was not clear when I referenced the " DW_OP_call_frame_cfa", sorry
> for that. I mean it is trying to resolve the frame base value, not the
> variable yet, the issue is before trying to get the variable address.
>
> I will do some steps to clarify it:
>
> * Using gcc binary
> - On the prompt I type the command "p a" to print the variable value.
> - LLDB needs the base frame, which must be found using the debug info "
> DW_AT_frame_base : 1 byte block: 9c (DW_OP_call_frame_cfa)".
> - The value of r31 is read, and it is set to "
> lldb_private::Value::eValueTypeLoadAddress", which means that beyond read the
> r31 value, this value is an address that must be read as well, in order to
> point to the previous frame:
>
> +-----------+
> | | // frame of a
> |back chain | //previous r31' and r1'
> +-----------+
> | | // frame of b
> |back chain | //current r31 and r1
> +-----------+
>
> Issue: It should get the r31' as address of frame base to apply the offset,
> and read the variable value that is inside the "frame of b", as the offset is
> negative. Instead of that, as the compiler type is invalid, the address
> obtained from r31 value is not being read, no error is shown, and the frame
> base value keeps as r31, which is incorrect. When using this value, the
> variable address is located in the red zone "r31 - 28 (offset)"
> (DW_AT_location : 2 byte block: 91 64 (DW_OP_fbreg: -28)).
>
>
> * Using Clang binary:
> - On the prompt I type the command "p a" to print the variable value.
> - LLDB needs the base frame, which must be found using the debug info
> "DW_AT_frame_base : 1 byte block: 6f (DW_OP_reg31 (r31))".
> - The value of r31 is read, and the memory of the address found in r31 is not
> read from memory, when running the case " DW_OP_reg31".
>
> +-----------+
> | | // frame of a
> |back chain | //previous r31' and r1'
> +-----------+
> | | // frame of b
> |back chain | //current r31 and r1
> +-----------+
>
> Result: It gets the r31 value, which points to the back chain of the "frame
> b", as expected, because the offset is positive, so "r31 + 112" (<6cf>
> DW_AT_location : 3 byte block: 91 f0 0 (DW_OP_fbreg: 112)).
>
>
>
> It is visible that gcc and lldb generates different debug info, gcc
> calculates the variable offset from the beginning of the frame, while lldb
> from the end of the frame. I saw in the code that LLDB is getting the correct
> information about the frame, but as the compiler type is invalid, the memory
> is not read, if it was valid, it would work correctly, that is why I'm trying
> to set the correct compiler type. I need to know what compiler type to use
> when reading the previous frame.
>
> I placed the full output from the binaries in the pastbin:
> Clang debug info: https://pastebin.com/tyXp5C9g
> Gcc debug info: https://pastebin.com/00b0SiKm
> Disassembly of gcc binary: https://pastebin.com/06UakF24
>
>
>>
>>>
>>> Thanks!
>>>
>>>
>>>
>>>> -----Original Message-----
>>>> From: Greg Clayton [mailto:[email protected]]
>>>> Sent: segunda-feira, 18 de setembro de 2017 17:24
>>>> To: Leonardo Bianconi <[email protected]>
>>>> Cc: [email protected]
>>>> Subject: Re: [lldb-dev] Reading eValueTypeLoadAddress with missing compiler
>>>> type
>>>>
>>>> If you have the binary and the function that this is happening in and can
>>>> share
>> the
>>>> binary that contains debug info and also share which file and function and
>>>> variable is causing the issue, I might be able to tell you why this is
>>>> happening.
>>>>
>>>> Greg
>>>>
>>>>> On Sep 18, 2017, at 1:23 PM, Greg Clayton <[email protected]> wrote:
>>>>>
>>>>> A DW_TAG_subprogram's usually has a DW_AT_frame_base DWARF
>>>> expression that describes where the frame is. That evaluates to something
>> and
>>>> doesn't require any type. I am guessing you now have a variable that is
>> relative to
>>>> that frame base and that variable's type is not valid. This can be due to
>>>> many
>>>> reasons, most likely is the compiler may have redacted your type when
>>>> trying
>> to
>>>> save space. Can you confirm this is what is happening?
>>>>>
>>>>>
>>>>>> On Sep 18, 2017, at 12:25 PM, Leonardo Bianconi via lldb-dev <lldb-
>>>> [email protected]> wrote:
>>>>>>
>>>>>> Hi all!
>>>>>>
>>>>>> I'm facing an issue with a value of
>>>> lldb_private::Value::eValueTypeLoadAddress type, which cannot be loaded
>> from
>>>> memory because the compiler type was not filled.
>>>>>> That happens obtaining the fame base, which is based on
>>>> "DW_OP_call_frame_cfa" case (DWARFExpression.cpp:2825).
>>>>>> After obtain the base frame, when resolving the value (Value.cpp:612), as
>> the
>>>> compiler type is invalid, the value is not read from memory, and the frame
>> base
>>>> keep as its address.
>>>>>>
>>>>>> How can I solve this issue?
>>>>>> I looked in many files, and couldn't find how to fill the compiler type
>>>>>> in the
>>>> "DWARFExpression::Evaluate" method.
>>>>>>
>>>>>>
>>>>>> Thanks,
>>>>>> Leonardo Bianconi.
>>>>>> _______________________________________________
>>>>>> lldb-dev mailing list
>>>>>> [email protected]
>>>>>> http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-dev
>>>>>
>>>
>
_______________________________________________
lldb-dev mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-dev