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 
> <leonardo.bianc...@eldorado.org.br> wrote:
> 
> 
> 
>> -----Original Message-----
>> From: Greg Clayton [mailto:clayb...@gmail.com]
>> Sent: terça-feira, 19 de setembro de 2017 12:33
>> To: Leonardo Bianconi <leonardo.bianc...@eldorado.org.br>
>> Cc: lldb-dev@lists.llvm.org
>> Subject: Re: [lldb-dev] Reading eValueTypeLoadAddress with missing compiler
>> type
>> 
>> 
>>> On Sep 19, 2017, at 4:10 AM, Leonardo Bianconi
>> <leonardo.bianc...@eldorado.org.br> 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:clayb...@gmail.com]
>>>> Sent: segunda-feira, 18 de setembro de 2017 17:24
>>>> To: Leonardo Bianconi <leonardo.bianc...@eldorado.org.br>
>>>> Cc: lldb-dev@lists.llvm.org
>>>> 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 <clayb...@gmail.com> 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-
>>>> d...@lists.llvm.org> 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
>>>>>> lldb-dev@lists.llvm.org
>>>>>> http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-dev
>>>>> 
>>> 
> 

_______________________________________________
lldb-dev mailing list
lldb-dev@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-dev

Reply via email to