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