[lldb-dev] Reading eValueTypeLoadAddress with missing compiler type

Leonardo Bianconi via lldb-dev lldb-dev at lists.llvm.org
Tue Sep 19 04:10:27 PDT 2017


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?

Thanks!



> -----Original Message-----
> From: Greg Clayton [mailto:clayborg at gmail.com]
> Sent: segunda-feira, 18 de setembro de 2017 17:24
> To: Leonardo Bianconi <leonardo.bianconi at eldorado.org.br>
> Cc: lldb-dev at 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 <clayborg at 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-
> dev at 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 at lists.llvm.org
> >> http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-dev
> >



More information about the lldb-dev mailing list