Bug 6832 - Crash while handling DW_AT_abstract_origin for a last comp unit
Summary: Crash while handling DW_AT_abstract_origin for a last comp unit
Status: RESOLVED FIXED
Alias: None
Product: binutils
Classification: Unclassified
Component: binutils (show other bugs)
Version: 2.18
: P2 normal
Target Milestone: ---
Assignee: Alan Modra
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2008-08-11 09:10 UTC by Dmitry Smirnov
Modified: 2010-01-11 09:31 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Last reconfirmed: 2009-01-21 08:10:32


Attachments
Stack of the crash (343 bytes, text/plain)
2008-08-11 09:13 UTC, Dmitry Smirnov
Details
DWARF info example for the last comp unit (480 bytes, text/plain)
2008-08-11 09:17 UTC, Dmitry Smirnov
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Dmitry Smirnov 2008-08-11 09:10:55 UTC
For this case I was using
http://www.kernel.org/pub/linux/devel/binutils/binutils-2.18.50.0.8.tar.bz2.

My application is using BFD library for handling ELF file generated by ADS 1.2.
Unfortunately, I cannot share this ELF file since it contains some proprietary
info. Nevertheless, I suppose I can describe the condition this ELF must to
conform. 

Application is crashing attempting to access the memory it is not allowed
(SIGSEGV). See stack (from Eclipse) attached.

After some debugging I found that problem is with find_line(), line 3143:

         if ((bfd_vma) (stash->info_ptr - stash->sec_info_ptr)
             == stash->sec->size)
           {
             stash->sec = find_debug_info (stash->bfd, stash->sec);
             stash->sec_info_ptr = stash->info_ptr;
           }

This code is changing stash->sec and stash->sec_info_ptr if this unit
was the last one. When find_abstract_instance_name() uses it later
(unit->stash->sec_info_ptr), it calculates the address that is over
the limits. This causes a crash.

So, to be able to reproduce this test case, ELF file should contain compilation
unit that is the last unit in .debug_info section (it will be better to have
just one section as in my case). This unit should have DW_AT_abstract_origin for
some of its subtags (in my case this was DW_TAG_subprogram. I've attached the
example.

I was able to fix problem locally by moving the code above to the end of the
function (i.e. after the call to comp_unit_find_line). Not sure this is correct fix.

Dmitry
Comment 1 Dmitry Smirnov 2008-08-11 09:13:42 UTC
Created attachment 2900 [details]
Stack of the crash
Comment 2 Dmitry Smirnov 2008-08-11 09:17:00 UTC
Created attachment 2901 [details]
DWARF info example for the last comp unit
Comment 3 Dmitry Smirnov 2008-08-11 09:19:50 UTC
I forgot to say, that test case have to call find_line() for non-existing symbol
after BFD opening so the BFD try to create/parse ALL the comp units.
Comment 4 Dmitry Smirnov 2008-08-13 13:44:15 UTC
I've found one more test case for this crash.

For this case you need to have a comp unit with low and high PC specified in
DWARF info. It also should have DW_AT_abstract_origin for some of its attributes.

Symbol search should be performed in 2 steps:
1. Search for a symbol for address that does not fall into any debug info. More
exactly, this search should trigger all comp units of this debug section to be
created.
2. Search for a symbol for address that fall into comp unit with low/high PC
specified.

Dmitry
Comment 5 Nick Clifton 2008-08-14 09:20:56 UTC
Hi Dmitry,

> My application is using BFD library for handling ELF file generated
> by ADS 1.2.  Unfortunately, I cannot share this ELF file since it
> contains some proprietary info.

If you run your ELF binary through "readelf -w" does it report any
problems with the debug information ?

Without a test case and a procedure to follow to reproduce the bug, I
really do not think that we are going to be able to solve this
problem.  Are you sure that you cannot provide us with an ELF file ?
You could always zero out the proprietary information first before
uploading it.

> I was able to fix problem locally by moving the code above to the
> end of the function (i.e. after the call to
> comp_unit_find_line). Not sure this is correct fix

I think that would be the wrong way to fix the problem.  It would mean
that the stash pointer passed to comp_unit_find_line would be
incorrect.

Cheers
  Nick
Comment 6 Dmitry Smirnov 2008-08-14 10:10:06 UTC
(In reply to comment #5)
 
> If you run your ELF binary through "readelf -w" does it report any
> problems with the debug information ?

Yes, a lot of. Like this:
readelf: Warning: There is a hole [0xab1ea0 - 0xab2551] in .debug_loc section.
readelf: Warning: There is an overlap [0xab25ab - 0xab1ea0] in .debug_loc sectio
n.
 
> Without a test case and a procedure to follow to reproduce the bug, I
> really do not think that we are going to be able to solve this
> problem.  Are you sure that you cannot provide us with an ELF file ?
> You could always zero out the proprietary information first before
> uploading it.

I'm afraid I will need to remove whole debug info in order to remove this
proprietary info. 
I suppose, it is possible to generate such an ELF using GCC. I've described the
conditions it has to meet.
 
> I think that would be the wrong way to fix the problem.  It would mean
> that the stash pointer passed to comp_unit_find_line would be
> incorrect.
Maybe. Though, I believe it is also useless to pass the pointer above this
section. I think this value is not used at all except handling
DW_AT_abstract_origin. 

Dmitry
Comment 7 Nick Clifton 2008-08-14 10:42:00 UTC
Subject: Re:  Crash while handling DW_AT_abstract_origin
 for	a last comp unit

Hi Dmitry,

>> If you run your ELF binary through "readelf -w" does it report any
>> problems with the debug information ?
> 
> Yes, a lot of. Like this:
> readelf: Warning: There is a hole [0xab1ea0 - 0xab2551] in .debug_loc section.
> readelf: Warning: There is an overlap [0xab25ab - 0xab1ea0] in .debug_loc sectio
> n.

So the DWARF information in the ELF file is broken ?  That would explain 
why this problem has not been encountered by other people.

>> Without a test case and a procedure to follow to reproduce the bug, I
>> really do not think that we are going to be able to solve this
>> problem.  Are you sure that you cannot provide us with an ELF file ?
>> You could always zero out the proprietary information first before
>> uploading it.
> 
> I'm afraid I will need to remove whole debug info in order to remove this
> proprietary info. 

How can the debug info be proprietary ?  Maybe some of the symbol names, 
but you can always change those.

Cheers
   Nick

Comment 8 Sourceware Commits 2009-01-22 08:54:32 UTC
Subject: Bug 6832

CVSROOT:	/cvs/src
Module name:	src
Changes by:	amodra@sourceware.org	2009-01-22 08:54:20

Modified files:
	bfd            : ChangeLog dwarf2.c 

Log message:
	PR 6832
	* dwarf2.c (find_line): Don't update stash->sec_info_ptr until
	after comp_unit_find_line call.

Patches:
http://sources.redhat.com/cgi-bin/cvsweb.cgi/src/bfd/ChangeLog.diff?cvsroot=src&r1=1.4432&r2=1.4433
http://sources.redhat.com/cgi-bin/cvsweb.cgi/src/bfd/dwarf2.c.diff?cvsroot=src&r1=1.116&r2=1.117

Comment 9 Alan Modra 2009-01-22 09:01:37 UTC
.
Comment 10 Dmitry Smirnov 2009-12-11 14:19:11 UTC
Hi,

While running my program with BFD 2.20.51.20090916 (which I had grabbed from GDB 
7.0) I see there is still a possibility for the problem reported by this bug.

It does not crash but produces a message like 
Dwarf Error: Could not find abbrev number 

The problem, on my mind, is caused by the following sequence:
My program tries to locate an address and find the line number, function etc.
The ELF file has just one debug info section.
One of the comp unit was already loaded (by parse_comp_unit() I suppose) but 
scan_unit_for_symbols() was not yet called yet for it.
At some stage, all the comp units of this alone sections are loaded and parsed 
and stash->sec_info_ptr was advanced to the end of this section (line 3224 of 
dwarf2.c)
Finally, when find_line tries to find locate some address in this unit and 
scan_unit_for_symbols is called, it produces such an error message. This happens 
when find_abstract_instance_name() tries to read some attribute, referred by 
DW_FORM_ref_addr. It tries to read from beyond the scope of the debug info 
section due to line 1751:
  info_ptr = unit->stash->sec_info_ptr + die_ref;
As I said before, unit->stash->sec_info_ptr is pointing to the end if section.

Dmitry




Comment 11 Sourceware Commits 2010-01-11 08:36:34 UTC
Subject: Bug 6832

CVSROOT:	/cvs/src
Module name:	src
Changes by:	amodra@sourceware.org	2010-01-11 08:36:19

Modified files:
	bfd            : ChangeLog dwarf2.c 

Log message:
	PR 6832
	* dwarf2.c (struct comp_unit): Add sec_info_ptr.
	(find_abstract_instance_name): Use it.
	(parse_comp_unit): Set it.

Patches:
http://sources.redhat.com/cgi-bin/cvsweb.cgi/src/bfd/ChangeLog.diff?cvsroot=src&r1=1.4880&r2=1.4881
http://sources.redhat.com/cgi-bin/cvsweb.cgi/src/bfd/dwarf2.c.diff?cvsroot=src&r1=1.127&r2=1.128

Comment 12 Sourceware Commits 2010-01-11 08:37:32 UTC
Subject: Bug 6832

CVSROOT:	/cvs/src
Module name:	src
Branch: 	binutils-2_20-branch
Changes by:	amodra@sourceware.org	2010-01-11 08:37:17

Modified files:
	bfd            : ChangeLog dwarf2.c 

Log message:
	PR 6832
	* dwarf2.c (struct comp_unit): Add sec_info_ptr.
	(find_abstract_instance_name): Use it.
	(parse_comp_unit): Set it.

Patches:
http://sources.redhat.com/cgi-bin/cvsweb.cgi/src/bfd/ChangeLog.diff?cvsroot=src&only_with_tag=binutils-2_20-branch&r1=1.4761.2.36&r2=1.4761.2.37
http://sources.redhat.com/cgi-bin/cvsweb.cgi/src/bfd/dwarf2.c.diff?cvsroot=src&only_with_tag=binutils-2_20-branch&r1=1.122.4.2&r2=1.122.4.3

Comment 13 Alan Modra 2010-01-11 09:31:00 UTC
Should now be fixed.