Bug 12528 - Should we handle constructors that are garbage collected but their debug info isn't?
Summary: Should we handle constructors that are garbage collected but their debug info...
Status: RESOLVED FIXED
Alias: None
Product: gdb
Classification: Unclassified
Component: breakpoints (show other bugs)
Version: HEAD
: P2 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
: 12568 (view as bug list)
Depends on:
Blocks:
 
Reported: 2011-03-01 22:18 UTC by dje
Modified: 2018-06-27 15:14 UTC (History)
1 user (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 dje 2011-03-01 22:18:38 UTC
This is a general problem which normally isn't significant (YMMV).
But in the case of constructors it can happen in real world code.

GCC can emit two copies of a constructor, and then with -ffunction-sections -Wl,--gc-sections one copy may get thrown away.  However the associated debug info won't get thrown away, leading to gdb lossage.

$ cat c1c2.cc

class foo
{
 public:
  foo (int x);
  int _x;
};

class foo2 : public foo
{
 public:
  foo2 (int x);
};

foo::foo (int x)
  : _x (x)
{
}

foo2::foo2 (int x)
  : foo (x)
{ // line 21
}

int
main ()
{
  foo2 bar (3);
  return 0;
}
$ g++ -g -ffunction-sections -Wl,--gc-sections c1c2.cc
$ gdb a.out
[...]
(gdb) b 21
Breakpoint 1 at 0x20: file c1c2.cc, line 22. (2 locations)
(gdb) i b
Num     Type           Disp Enb Address            What
1       breakpoint     keep y   <MULTIPLE>
1.1                         y     0x0000000000000020 c1c2.cc:22
1.2                         y     0x00000000004005c8 in foo2::foo2(int)
                                               at c1c2.cc:22
(gdb) r
Starting program: /home/dje/src/play/a.out
Warning:
Cannot insert breakpoint 1.
Error accessing memory address 0x20: Input/output error.

(gdb)
Comment 1 dje 2011-03-11 08:11:32 UTC
*** Bug 12568 has been marked as a duplicate of this bug. ***
Comment 2 Sourceware Commits 2011-03-16 18:15:27 UTC
CVSROOT:	/cvs/src
Module name:	src
Changes by:	ppluzhnikov@sourceware.org	2011-03-16 18:15:20

Modified files:
	gdb            : dwarf2read.c ChangeLog 
	gdb/testsuite  : ChangeLog 
Added files:
	gdb/testsuite/gdb.base: break-on-linker-gcd-function.cc 
	                        break-on-linker-gcd-function.exp 

Log message:
	ChangeLog:
	
	2011-03-16  Paul Pluzhnikov  <ppluzhnikov@google.com>
	
	PR gdb/12528
	* dwarf2read.c (noop_record_line): New function.
	(dwarf_decode_lines): Ignore line tables for GCd functions.
	
	testsuite/ChangeLog:
	
	2011-03-16  Paul Pluzhnikov  <ppluzhnikov@google.com>
	
	PR gdb/12528
	* gdb.base/Makefile.in: Adjust EXECUTABLES.
	* gdb.base/break-on-linker-gcd-function.exp: New test.
	* gdb.base/break-on-linker-gcd-function.cc: New file.

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/src/gdb/dwarf2read.c.diff?cvsroot=src&r1=1.509&r2=1.510
http://sourceware.org/cgi-bin/cvsweb.cgi/src/gdb/ChangeLog.diff?cvsroot=src&r1=1.12822&r2=1.12823
http://sourceware.org/cgi-bin/cvsweb.cgi/src/gdb/testsuite/ChangeLog.diff?cvsroot=src&r1=1.2635&r2=1.2636
http://sourceware.org/cgi-bin/cvsweb.cgi/src/gdb/testsuite/gdb.base/break-on-linker-gcd-function.cc.diff?cvsroot=src&r1=NONE&r2=1.1
http://sourceware.org/cgi-bin/cvsweb.cgi/src/gdb/testsuite/gdb.base/break-on-linker-gcd-function.exp.diff?cvsroot=src&r1=NONE&r2=1.1
Comment 3 Sourceware Commits 2011-03-16 18:16:35 UTC
CVSROOT:	/cvs/src
Module name:	src
Changes by:	ppluzhnikov@sourceware.org	2011-03-16 18:16:26

Modified files:
	gdb/testsuite/gdb.base: Makefile.in 

Log message:
	ChangeLog:
	
	2011-03-16  Paul Pluzhnikov  <ppluzhnikov@google.com>
	
	PR gdb/12528
	* dwarf2read.c (noop_record_line): New function.
	(dwarf_decode_lines): Ignore line tables for GCd functions.
	
	testsuite/ChangeLog:
	
	2011-03-16  Paul Pluzhnikov  <ppluzhnikov@google.com>
	
	PR gdb/12528
	* gdb.base/Makefile.in: Adjust EXECUTABLES.
	* gdb.base/break-on-linker-gcd-function.exp: New test.
	* gdb.base/break-on-linker-gcd-function.cc: New file.

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/src/gdb/testsuite/gdb.base/Makefile.in.diff?cvsroot=src&r1=1.9&r2=1.10
Comment 4 Paul Pluzhnikov 2011-03-16 18:22:29 UTC
Verified original test case is fixed as well.
Comment 5 Sourceware Commits 2014-09-19 08:59:51 UTC
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "gdb and binutils".

The branch, master has been updated
       via  00ba3162ed1633f9b27f3fdd450e076d3a3f2e90 (commit)
       via  c3b7b696c231416ac90fd9cb7d5ce735b3683356 (commit)
      from  8e635c209bd7dbccd410953334a55ff5fc91e81b (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=00ba3162ed1633f9b27f3fdd450e076d3a3f2e90

commit 00ba3162ed1633f9b27f3fdd450e076d3a3f2e90
Author: Yao Qi <yao@codesourcery.com>
Date:   Mon Aug 18 09:57:40 2014 +0800

    Run dw2-var-zero-addr.exp with --readnow
    
    This patch is to extend dw2-var-zero-add.exp to cover the case that
    partial symtabl is not used while full symtab is used, in order to
    cover the changes in patch 2/3.  This patch restarts GDB with
    --readnow and does the same test again.
    
    gdb/testsuite:
    
    2014-09-19  Yao Qi  <yao@codesourcery.com>
    
    	* gdb.dwarf2/dw2-var-zero-addr.exp: Move test into new proc test.
    	Invoke test.  Restart GDB with --readnow and invoke test again.

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

commit c3b7b696c231416ac90fd9cb7d5ce735b3683356
Author: Yao Qi <yao@codesourcery.com>
Date:   Mon Aug 4 14:57:22 2014 +0800

    Check function is GC'ed
    
    I see the following fail on arm-none-eabi target,
    
    (gdb) b 24^M
    Breakpoint 1 at 0x4: file
    ../../../../git/gdb/testsuite/gdb.base/break-on-linker-gcd-function.cc,
    line 24.^M
    (gdb) FAIL: gdb.base/break-on-linker-gcd-function.exp: b 24
    
    Currently, we are using flag has_section_at_zero to determine whether
    address zero in debug info means the corresponding code has been
    GC'ed, like this:
    
    	case DW_LNE_set_address:
    	  address = read_address (abfd, line_ptr, cu, &bytes_read);
    
    	  if (address == 0 && !dwarf2_per_objfile->has_section_at_zero)
    	    {
    	      /* This line table is for a function which has been
    		 GCd by the linker.  Ignore it.  PR gdb/12528 */
    
    However, this is incorrect on some bare metal targets, as .text
    section is located at 0x0, so dwarf2_per_objfile->has_section_at_zero
    is true.  If a function is GC'ed by linker, the address is zero.  GDB
    thinks address zero is a function's address rather than this function
    is GC'ed.
    
    In this patch, we choose 'lowpc' got in read_file_scope to check
    whether 'lowpc' is greater than zero.  If it isn't, address zero really
    means the function is GC'ed.  In this patch, we pass 'lowpc' in
    read_file_scope through handle_DW_AT_stmt_list and dwarf_decode_lines,
    and to dwarf_decode_lines_1 finally.
    
    This patch fixes the fail above. This patch also covers the path that
    partial symbol isn't used, which is tested by starting gdb with
    --readnow option.
    
    It is regression tested on x86-linux with
    target_board=dwarf4-gdb-index, and arm-none-eabi.  OK to apply?
    
    gdb:
    
    2014-09-19  Yao Qi  <yao@codesourcery.com>
    
    	* dwarf2read.c (dwarf_decode_lines): Update declaration.
    	(handle_DW_AT_stmt_list): Add argument 'lowpc'.  Update
    	comments.  Callers update.
    	(dwarf_decode_lines): Likewise.
    	(dwarf_decode_lines_1): Add argument 'lowpc'.  Update
    	comments.  Skip the line table if  'lowpc' is greater than
    	'address'.  Don't check
    	dwarf2_per_objfile->has_section_at_zero.
    
    gdb/testsuite:
    
    2014-09-19  Yao Qi  <yao@codesourcery.com>
    
    	* gdb.base/break-on-linker-gcd-function.exp: Move test into new
    	proc set_breakpoint_on_gcd_function.  Invoke
    	set_breakpoint_on_gcd_function.  Restart GDB with --readnow and
    	invoke set_breakpoint_on_gcd_function again.

-----------------------------------------------------------------------

Summary of changes:
 gdb/ChangeLog                                      |   11 ++++++
 gdb/dwarf2read.c                                   |   33 +++++++++++++------
 gdb/testsuite/ChangeLog                            |   12 +++++++
 .../gdb.base/break-on-linker-gcd-function.exp      |   24 +++++++++++---
 gdb/testsuite/gdb.dwarf2/dw2-var-zero-addr.exp     |   19 +++++++++--
 5 files changed, 80 insertions(+), 19 deletions(-)
Comment 6 Sourceware Commits 2018-06-27 15:14:01 UTC
The master branch has been updated by Omair Javaid <omjavaid@sourceware.org>:

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

commit 7ab6656f274b450942deb8800257c0d2e060fa84
Author: Omair Javaid <omair.javaid@linaro.org>
Date:   Tue May 15 19:04:21 2018 +0500

    Fix lost line info for symbol at addr zero
    
    This patch fixes a unique condition where GDB fails to provide line
    information of symbol at address zero when code is compiled with text
    address zero but loaded at an offset > 0.
    
    For example lets compile following code snippet:
    
    int main() {
      return 0;
    }
    
    gcc -O0 -g3 -nostdlib -emain -Wl,-Ttext=0x00 -o file.out file.c
    
    Start gdb and run:
    
    add-symbol-file file.out 0xffff0000
    info line main
    
    GDB will return error saying no line info is available for the symbol.
    
    This is a direct consequence of the fix for PR 12528 where GDB tries to ignore
    line table for a function which has been garbage collected by the linker.
    
    As the garbage collected symbols are sent to address zero GDB assumes a symbol
    actually placed at address zero as garbage collected.
    
    This was fixed with an additional check address < lowpc. But when symbol is
    loaded at an offset lowpc becomes lowpc + offset while no offset is added to
    address rather final symbol address is calculated based on baseaddr and address
    added together. So in case where symbols are loaded at an offset the condition
    address < lowpc will always return true.
    
    This patch fixes this by comparing address against a non offset lowpc.
    
    This patch also adds a GDB test case to replicate this behavior.
    
    gdb:
    
    2018-06-27  Omair Javaid  <omair.javaid@linaro.org>
    
    	PR gdb/21695
    	* dwarf2read.c (lnp_state_machine::check_line_address): Update declaration.
    	(dwarf_decode_lines_1): Adjust.
    
    gdb/testsuite:
    
    2018-06-27  Omair Javaid  <omair.javaid@linaro.org>
    
    	PR gdb/21695
    	* gdb.base/infoline-reloc-main-from-zero.exp: New test.
    	* gdb.base/infoline-reloc-main-from-zero.c: New file.