[PATCH] DWARFv5: Handle location list for split dwarf.

nitachra Nitika.Achra@amd.com
Wed Mar 18 14:15:16 GMT 2020


Hi Simon,

Thanks for the review.

> @@ -332,7 +337,7 @@ dwarf2_find_location_expression (struct dwarf2_loclist_baton *baton,
>        enum debug_loc_kind kind;
>        const gdb_byte *new_ptr = NULL; /* init for gcc -Wall */
>
> -      if (baton->from_dwo)
> +      if (baton->per_cu->version () < 5 && baton->from_dwo)

>Can you please explain the rationale of this change?  It's hard to tell whether it is correct or not without an explanation (and I prefer not having to guess your intentions).

I made this change because clang and gcc are not generating the DW_LLE_GNU* entries with DWARFv5 and -gsplit-dwarf.
Instead they are generating DW_LLE_start* or DW_LLE_offset_pair with DW_LLE_base_addressx.



if (baton->from_dwo && kind != DEBUG_LOC_OFFSET_PAIR)
	{
	  low += base_offset;
	  high += base_offset;
	}
      else
	{
	  low += base_address;
	  high += base_address;
	}


I made the above change because clang is emitting DW_LLE_offset_pair and DW_LLE_base_addressx for DWARFv5 and -gsplit-dwarf.
So we need to add the base address in the case of dwo also, otherwise the low and high address will be incorrect
and gdb will give <optimized out> when printing the variable values.

These two changes combined will print the correct variable values. Overall the intent for this patch was to support the location
list for split dwarf and print the correct variable values.

>I am not able to reproduce to get this error message, there must be something else to trigger this bug:

To reproduce you have to apply the patch at https://sourceware.org/pipermail/gdb-patches/2020-January/164841.html
I updated the patch right now. Reapply the patch if you have already applied. You will be able to regenerate the error then.

>I don't really understand the patch. You add DEBUG_LOC_OFFSET_PAIR, but no function actually returns this kind.

My mistake. I sent the wrong patch before. 

Regards,
Nitika
---

GDB throws the error '<error reading variable: dwarf2_find_location_
expression: Corrupted DWARF expression.>' while printing the variable
value with executable file compiled with -gdwarf-5, -O1 and -gdwarf-split
flags. This patch fixes this error.

Tested by running the testsuite before and after the patch and there is
no increase in the number of test cases that fails. Tested with both
-gdwarf-4 and -gdwarf-5 flags. Also tested -gslit-dwarf along with -gdwarf-4
as well as -gdwarf-5 flags. Used clang version 10.0.0. This is the test case used-

int main()
{
    int arr[] = {1,2,3};
    for(int i = 0; i<3; i++)
        printf("%d",arr[i]);
    return 0;
}

clang -gdwarf-5 -O1 -gsplit-dwarf test.c -o test.out
gdb test.out
gdb> start
gdb> step
gdb> p i
dwarf2_find_location_expression: Corrupted DWARF expression.

gdb/ChangeLog:

   *dwarf2loc.c (enum debug_loc_kind): Added a new kind DEBUG_LOC_OFFSET_PAIR.
    (dwarf2_find_location_expression): Call the function decode_debug_loclists_
    addresses if DWARF version is 5 or more. Add applicable base address if the
    entry is DW_LLE_OFFSET_PAIR from DWO.
    (decode_debug_loclists_addresses): Return DEBUG_LOC_OFFSET_PAIR instead of
    DEBUG_LOC_START_END in case of DW_LLE_offset_pair.
---
 gdb/dwarf2/loc.c | 18 +++++++++++++-----
 1 file changed, 13 insertions(+), 5 deletions(-)

diff --git a/gdb/dwarf2/loc.c b/gdb/dwarf2/loc.c
index 5155cff60d..08c315a381 100644
--- a/gdb/dwarf2/loc.c
+++ b/gdb/dwarf2/loc.c
@@ -92,6 +92,11 @@ enum debug_loc_kind
      as in .debug_loc.  */
   DEBUG_LOC_START_LENGTH = 3,
 
+   /* This is followed by two unsigned LEB128 operands. The values of these
+      operands are the starting and ending offsets, respectively, relative to
+      the applicable base address. */
+  DEBUG_LOC_OFFSET_PAIR = 4,
+
   /* An internal value indicating there is insufficient data.  */
   DEBUG_LOC_BUFFER_OVERFLOW = -1,
 
@@ -232,7 +237,7 @@ decode_debug_loclists_addresses (struct dwarf2_per_cu_data *per_cu,
 	return DEBUG_LOC_BUFFER_OVERFLOW;
       *high = u64;
       *new_ptr = loc_ptr;
-      return DEBUG_LOC_START_END;
+      return DEBUG_LOC_OFFSET_PAIR;
     /* Following cases are not supported yet.  */
     case DW_LLE_startx_endx:
     case DW_LLE_start_end:
@@ -332,7 +337,7 @@ dwarf2_find_location_expression (struct dwarf2_loclist_baton *baton,
       enum debug_loc_kind kind;
       const gdb_byte *new_ptr = NULL; /* init for gcc -Wall */
 
-      if (baton->from_dwo)
+      if (baton->per_cu->version () < 5 && baton->from_dwo)
 	kind = decode_debug_loc_dwo_addresses (baton->per_cu,
 					       loc_ptr, buf_end, &new_ptr,
 					       &low, &high, byte_order);
@@ -358,6 +363,7 @@ dwarf2_find_location_expression (struct dwarf2_loclist_baton *baton,
 	  continue;
 	case DEBUG_LOC_START_END:
 	case DEBUG_LOC_START_LENGTH:
+	case DEBUG_LOC_OFFSET_PAIR:
 	  break;
 	case DEBUG_LOC_BUFFER_OVERFLOW:
 	case DEBUG_LOC_INVALID_ENTRY:
@@ -369,9 +375,11 @@ dwarf2_find_location_expression (struct dwarf2_loclist_baton *baton,
 
       /* Otherwise, a location expression entry.
 	 If the entry is from a DWO, don't add base address: the entry is from
-	 .debug_addr which already has the DWARF "base address".  We still add
-	 base_offset in case we're debugging a PIE executable.  */
-      if (baton->from_dwo)
+	 .debug_addr which already has the DWARF "base address". We still add
+	 base_offset in case we're debugging a PIE executable. However, if the
+	 entry is DW_LLE_offset_pair from a DWO, add the base address as the
+	 operands are offsets relative to the applicable base address. */
+      if (baton->from_dwo && kind != DEBUG_LOC_OFFSET_PAIR)
 	{
 	  low += base_offset;
 	  high += base_offset;
-- 
2.17.1



More information about the Gdb-patches mailing list