arm_addr_bits_remove

Pedro Alves pedro@codesourcery.com
Tue Jan 22 21:17:00 GMT 2008


[long speech, small patch]

Hi,

arm-eabi/-mthumb currently has a couple of failures on the break.exp test:

break marker4
Breakpoint 2 at 0x1e8
(gdb) FAIL: gdb.base/break.exp: breakpoint small function, optimized file

The test is failing because a filename and a line number is expected after
the breakpoint address.

What's happening is that when we're building the line table, we call
buildsym.c:record_line, which means we call gdbarch_addr_bits_remove
on every address of the line table, eventually calling it on the
end-of-sequence marker address, just past the last address of
the last function in the testcase's object file where function
"marker4" is defined.

arm uses an encoding in the minimal symbols to distinguish between
arm and thumb code.  A lookup_minimal_symbol_by_pc is needed
in arm_pc_is_thumb to get at the minimal symbol of the address in
question.  If this address we're looking up isn't part of any
real function, this lookup_minimal_symbol_by_pc returns NULL,
which has the effect of arm_pc_is_thumb returning false
(defaulting to non-thumb), which triggers arm_addr_bits_remove
to remove the 2 lower bits from the address -- it thinks this is
a 32-bit arm address).  This is thumb code we're testing, so bit
1 is important to keep.  The bug is then visible because when
we're handling the end of sequence marker in record_line, and
the address has bit 1 set:

          pc = gdbarch_addr_bits_remove (current_gdbarch, pc);  <<= trims more
                                                                <<= than it should

          if (line == 0 && subfile->line_vector->nitems > 0)
            {
              e = subfile->line_vector->item + subfile->line_vector->nitems - 1;
              while (subfile->line_vector->nitems > 0 && e->pc == pc)
	{
	  e--;
	  subfile->line_vector->nitems--;
	}
            }

... the pc is trimmed back by 2 bytes.  If the last function in the
object happens to be empty, it will have two line entries with
the same address as this "broken" marker.  Now the "broken" marker
is no longer the last address in the line vector, so, the while
loop shown above will cut off the wrong lines -- effectively
removing all line info for this last function in the object file.

When we issue a break marker4, gdb will not be able to find its line
info, and will just print:

Breakpoint 2 at 0x1e8

The easy fix is to never strip the 0x2 from the address.  0x1
is used to mark thumb addresses, but 0x2 should never appear, and
should never need to be stripped.

Attached is a testcase, based on break.exp, and the fix for the bug.
I'm not sure if we should add the testcase or not.  On one hand, this was
already caught by a failure; on the other hand, this is not what the
break.exp test is testing -- any change to it may hide a similar
future bug; (on the other (third) hand, the test is sensible.)

Tested on arm-eabi, arm and thumb.

So... ,
OK ?

-- 
Pedro Alves



-------------- next part --------------
A non-text attachment was scrubbed...
Name: addr_bits_remove.diff
Type: text/x-diff
Size: 722 bytes
Desc: not available
URL: <http://sourceware.org/pipermail/gdb-patches/attachments/20080122/134e6647/attachment.bin>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: addr_bits_rem_test.diff
Type: text/x-diff
Size: 3417 bytes
Desc: not available
URL: <http://sourceware.org/pipermail/gdb-patches/attachments/20080122/134e6647/attachment-0001.bin>


More information about the Gdb-patches mailing list