Bug 19999 - gdb not able to resolve argc, argv with fission when built as PIE
Summary: gdb not able to resolve argc, argv with fission when built as PIE
Status: RESOLVED FIXED
Alias: None
Product: gdb
Classification: Unclassified
Component: exp (show other bugs)
Version: HEAD
: P2 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
: 20405 (view as bug list)
Depends on:
Blocks:
 
Reported: 2016-04-26 17:01 UTC by Sriraman Tallam
Modified: 2016-07-25 14:29 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Sriraman Tallam 2016-04-26 17:01:56 UTC
Here is an example showing the problem:

foo.c
------

__attribute__((noinline)) 
int Init(int *b) { 
  return 0; 
} 

int main(int argc, char *argv[]) { 
  return Init(&argc); 
} 


$ gcc foo.c -gsplit-dwarf -fPIE  -pie -O1
$ gdb a.out
...
(gdb) start
Temporary breakpoint 1 at 0x73b: file foo.c, line 7.
Starting program: a.out 

Temporary breakpoint 1, main (argc=<optimized out>, argv=<optimized out>) at foo.c:7
7	int main(int argc, char *argv[]) {


argc and argv are optimized out.


Without linking as PIE,

$ gcc foo.c -gsplit-dwarf -fPIE -O1
$ gdb a.out
...
(gdb) start
Temporary breakpoint 1 at 0x4004f3: file foo.c, line 7.
Starting program: a.out 

Temporary breakpoint 1, main (argc=1, argv=0x7fffffffe188) at foo.c:7
7	int main(int argc, char *argv[]) {

argc and argv are fine.


The problem is in file dwarf2loc.c in function dwarf2_find_location_expression:

      if (! baton->from_dwo)
	{
	  low += base_address;
	  high += base_address;
	}

low and high are not updated to use the base_offset when it is from a dwo.

This is called from loclist_read_variable:

loclist_read_variable (struct symbol *symbol, struct frame_info *frame)
{
...
      size_t size;
      CORE_ADDR pc = frame ? get_frame_address_in_block (frame) : 0;

      data = dwarf2_find_location_expression (dlbaton, &size, pc);
...
}

size is 0 in the bad case which then creates an "optimized out" variable.
Comment 1 Paul Pluzhnikov 2016-04-26 17:05:26 UTC
Google ref: b/26218159

> The problem is in file dwarf2loc.c in function dwarf2_find_location_expression

We don't know that's the problem. But it definitely appears related,
and removing the "if (! baton->from_dwo)" condition makes GDB work.
Comment 2 dje 2016-04-26 19:07:15 UTC
I was probably trying to cope with a case where DW_AT_low_pc was non-zero (say 0x400410 or some such), and the addresses in .debug_addr also had low_pc (initial "base address") already added as well.

https://gcc.gnu.org/wiki/DebugFission

"Each location list entry in the .debug_loc section contains a beginning and ending address offset, which normally are relocated addresses. In the .debug_loc.dwo section, these offsets will be replaced by indices into the .debug_addr section. Each location list entry will begin with a single byte identifying the entry type: DW_LLE_end_of_list_entry (0) indicates an end-of-list entry, DW_LLE_base_address_selection_entry (1) indicates a base address selection entry, DW_LLE_start_end_entry (2) indicates a normal location list entry providing start and end addresses, DW_LLE_start_length_entry (3) indicates a normal location list entry providing a start address and a length, and DW_LLE_offset_pair_entry (4) indicates a normal location list entry providing start and end offsets relative to the base address given by a base address selection entry. An end-of-list entry has no further data. A base address selection entry contains a single unsigned LEB128 number following the entry type byte, which is an index into the .debug_addr section that selects the new base address for subsequent location list entries. A start/end entry contains two unsigned LEB128 numbers following the entry type byte, which are indices into the .debug_addr section that select the beginning and ending addresses. A start/length entry contains one unsigned LEB128 number and a 4-byte unsigned value (as would be represented by the form code DW_FORM_const4u). The first number is an index into the .debug_addr section that selects the beginning offset, and the second number is the length of the range. Addresses fetched from the .debug_addr section are not relative to the base address. An offset pair entry contains two 4-byte unsigned values (as would be represented by the form code DW_FORM_const4u), treated as the beginning and ending offsets, respectively, relative to the base address. As in the .debug_loc section, the base address is obtained either from the nearest preceding base address selection entry, or, if there is no such entry, from the compilation unit base address (see section 3.1.1 in the DWARF-4 spec). For the latter three types (start/end, start/length, and offset pair), the two operand values are followed by a location description as in a normal location list entry in the .debug_loc section."

In particular: "Addresses fetched from the .debug_addr section are not relative to the base address."

This might be the right fix (untested):

      if (baton->from_dwo)
        {
          low += base_offset
          high += base_offset
        }
      else
        {
          low += base_address;
          high += base_address;
        }
Comment 3 Sourceware Commits 2016-05-12 16:25:15 UTC
The master branch has been updated by Doug Evans <devans@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=8ddd5a6cd692ca8c4041d9fb64cbb4e0585d4aa1

commit 8ddd5a6cd692ca8c4041d9fb64cbb4e0585d4aa1
Author: Doug Evans <dje@google.com>
Date:   Thu May 12 09:20:57 2016 -0700

    PR symtab/19999 gdb unable to resolve vars with fission+PIE
    
    gdb/ChangeLog:
    
    	* dwarf2loc.c (dwarf2_find_location_expression): For DWO files still
    	add base_offset.
    
    gdb/testsuite/ChangeLog:
    
    	* lib/dwarf.exp (build_executable_from_fission_assembler): Pass
    	$options when building executable.
    	* gdb.dwarf2/fission-loclists-pie.c: New file.
    	* gdb.dwarf2/fission-loclists-pie.exp: New file.
Comment 4 dje 2016-05-12 16:29:10 UTC
patch committed
Comment 5 kmenc15 2016-07-25 14:29:30 UTC
*** Bug 20405 has been marked as a duplicate of this bug. ***