This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
Re: [rfc/rfa] Use ARM exception tables as GDB unwinder
- From: Daniel Jacobowitz <dan at codesourcery dot com>
- To: Ulrich Weigand <uweigand at de dot ibm dot com>
- Cc: gdb-patches at sourceware dot org, rearnsha at arm dot com, matthew dot gretton-dann at arm dot com
- Date: Wed, 20 Oct 2010 09:26:57 -0400
- Subject: Re: [rfc/rfa] Use ARM exception tables as GDB unwinder
- References: <201010200000.o9K00u7j016909@d12av02.megacenter.de.ibm.com>
Thanks for doing this!
On Wed, Oct 20, 2010 at 02:00:56AM +0200, Ulrich Weigand wrote:
> In addition, one minor change was necessary to the prologue unwinder:
> the this_id routine no longer uses get_frame_func to retrieve the
> function start address; instead, this value is stored in the cache.
> This allows the exception unwinder to provide this information from
> the exception table, instead of having to rely on symbol data.
Like Matthew, I have some concern about this; unwind regions are not
1:1 with functions. Not only will the linker combine identical
regions, but hand-written code (or, hypothetically,
-fnon-call-exceptions) can have multiple regions in a function.
But we can probably ignore the latter case; the former can be handled
by using whichever is larger, the symbol or exception region address.
> + /* See if we have an ARM exception table entry covering this address. */
> + addr_in_block = get_frame_address_in_block (this_frame);
> + entry = arm_find_exidx_entry (addr_in_block, &func_exidx);
> + if (!entry)
> + return 0;
I assume you're deliberately treating can't-unwind and no-information
the same. We use can't-unwind to mark _start, but it also shows up in
exception handling in some cases.
> + /* The ARM exception index does not mark the *end* of the function
> + covered by the entry, and some functions will not have any entry.
> + Therefore, the entry we found above may not actually be correct
> + for this PC. As a sanity check, also try to determine the function
> + covering PC via the symbol table. If this finds a function start
> + address *closer* to PC than the one found via the exception table,
> + ignore the exception record, and fall back to prologue parsing.
> +
> + (Note that if we don't find a function via the symbol table, the
> + exception table may still be wrong. But in this case, prologue
> + parsing wouldn't work anyway, so we use the exception table and
> + hope for the best.) */
> + if (find_pc_partial_function (addr_in_block, NULL, &func_symtab, NULL)
> + && func_symtab > func_exidx)
> + return 0;
This doesn't go well with the discussion above about combined
exception regions... did you encounter this problem in practice? The
linker used to have this problem, but hasn't for a while (circa
2009-05-05).
The actual unwinder looks OK to me. If you want to handle C++ code
with exceptions (or C with cleanups), you'll need to check the name of
the referenced personality routine; it is __gxx_personality_v0 (et
cetera). Readelf has a sample of that. Code which doesn't throw or
catch uses the standard personality routines, as you've implemented.
--
Daniel Jacobowitz
CodeSourcery