[2/2] Check function is GC'ed

Message ID 1407307813-5321-2-git-send-email-yao@codesourcery.com
State New, archived
Headers

Commit Message

Yao Qi Aug. 6, 2014, 6:50 a.m. UTC
  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.  In this patch, we choose 'textlow' field
of partial symtabl.  This patch fixes the fail above.  It is
regression tested on x86_64-linux, arm-none-eabi,
arm-none-linux-gnueabi.  OK to apply?

gdb:

2014-08-06  Yao Qi  <yao@codesourcery.com>

	* dwarf2read.c (dwarf_decode_lines_1): Skip the line table if
	PST->textlow is greater than zero.
---
 gdb/dwarf2read.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)
  

Comments

Doug Evans Aug. 15, 2014, 4:40 a.m. UTC | #1
Yao Qi writes:
 > 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.  In this patch, we choose 'textlow' field
 > of partial symtabl.  This patch fixes the fail above.  It is
 > regression tested on x86_64-linux, arm-none-eabi,
 > arm-none-linux-gnueabi.  OK to apply?

Something in this explanation doesn't feel right.
If .text is at zero then has_section_at_zero should be true.
Perhaps the explanation just needs more elaboration,
but looking at break-on-linker-gcd-function.exp
the problem seems to be more that the test is invalid
when .text begins at 0x0.
If the testcase is invalid in this context (and
we can discuss ways in which to cope with that),
is there still a real bug here?

 > 
 > gdb:
 > 
 > 2014-08-06  Yao Qi  <yao@codesourcery.com>
 > 
 > 	* dwarf2read.c (dwarf_decode_lines_1): Skip the line table if
 > 	PST->textlow is greater than zero.
 > ---
 >  gdb/dwarf2read.c | 9 ++++++++-
 >  1 file changed, 8 insertions(+), 1 deletion(-)
 > 
 > diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
 > index 8011e4e..5e292f2 100644
 > --- a/gdb/dwarf2read.c
 > +++ b/gdb/dwarf2read.c
 > @@ -17229,6 +17229,8 @@ dwarf_decode_lines_1 (struct line_header *lh, const char *comp_dir,
 >        /* Decode the table.  */
 >        while (!end_sequence)
 >  	{
 > +	  struct partial_symtab *pst = NULL;
 > +
 >  	  op_code = read_1_byte (abfd, line_ptr);
 >  	  line_ptr += 1;
 >  	  if (line_ptr > line_end)
 > @@ -17291,7 +17293,12 @@ dwarf_decode_lines_1 (struct line_header *lh, const char *comp_dir,
 >  		case DW_LNE_set_address:
 >  		  address = read_address (abfd, line_ptr, cu, &bytes_read);
 >  
 > -		  if (address == 0 && !dwarf2_per_objfile->has_section_at_zero)
 > +		  if (!decode_for_pst_p)
 > +		    pst = cu->per_cu->v.psymtab;

I believe this is incorrect: .gdb_index may be in use and thus we're not using partial syms.

 > +
 > +		  if (address == 0
 > +		      && (!dwarf2_per_objfile->has_section_at_zero
 > +			  || (pst != NULL && pst->textlow > address)))
 >  		    {
 >  		      /* This line table is for a function which has been
 >  			 GCd by the linker.  Ignore it.  PR gdb/12528 */
  
Yao Qi Aug. 15, 2014, 6:15 a.m. UTC | #2
On 08/15/2014 12:40 PM, Doug Evans wrote:
> Something in this explanation doesn't feel right.
> If .text is at zero then has_section_at_zero should be true.

Right.  Under this situation, if a function is GC'ed by linker,
the address is zero.  GDB thinks address zero is about a function's
address, rather than this function is GC'ed.

> Perhaps the explanation just needs more elaboration,

OK, I'll improve the explanation.

> but looking at break-on-linker-gcd-function.exp
> the problem seems to be more that the test is invalid
> when .text begins at 0x0.
> If the testcase is invalid in this context (and
> we can discuss ways in which to cope with that),
> is there still a real bug here?

AFAICS, the test is still valid when .text begins at 0x0.
  
Pedro Alves Aug. 20, 2014, 3:40 p.m. UTC | #3
On 08/06/2014 07:50 AM, Yao Qi wrote:
> @@ -17291,7 +17293,12 @@ dwarf_decode_lines_1 (struct line_header *lh, const char *comp_dir,
>  		case DW_LNE_set_address:
>  		  address = read_address (abfd, line_ptr, cu, &bytes_read);
>  
> -		  if (address == 0 && !dwarf2_per_objfile->has_section_at_zero)
> +		  if (!decode_for_pst_p)
> +		    pst = cu->per_cu->v.psymtab;
> +
> +		  if (address == 0
> +		      && (!dwarf2_per_objfile->has_section_at_zero
> +			  || (pst != NULL && pst->textlow > address)))
>  		    {
>  		      /* This line table is for a function which has been
>  			 GCd by the linker.  Ignore it.  PR gdb/12528 */

Does this still work when we have .gdb_index sections?
ISTR we don't have psymtabs in that case?

Thanks,
Pedro Alves
  

Patch

diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index 8011e4e..5e292f2 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -17229,6 +17229,8 @@  dwarf_decode_lines_1 (struct line_header *lh, const char *comp_dir,
       /* Decode the table.  */
       while (!end_sequence)
 	{
+	  struct partial_symtab *pst = NULL;
+
 	  op_code = read_1_byte (abfd, line_ptr);
 	  line_ptr += 1;
 	  if (line_ptr > line_end)
@@ -17291,7 +17293,12 @@  dwarf_decode_lines_1 (struct line_header *lh, const char *comp_dir,
 		case DW_LNE_set_address:
 		  address = read_address (abfd, line_ptr, cu, &bytes_read);
 
-		  if (address == 0 && !dwarf2_per_objfile->has_section_at_zero)
+		  if (!decode_for_pst_p)
+		    pst = cu->per_cu->v.psymtab;
+
+		  if (address == 0
+		      && (!dwarf2_per_objfile->has_section_at_zero
+			  || (pst != NULL && pst->textlow > address)))
 		    {
 		      /* This line table is for a function which has been
 			 GCd by the linker.  Ignore it.  PR gdb/12528 */