X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Fframe-unwind.c;h=3334c472d0202b546f5eea17e27ec6cbbabc7476;hb=b4991d292edd84c16bd2050bd071198ceae764fe;hp=46096c212b473d226de488007e53a9764ff10fb0;hpb=d55e5aa6b29906346c51ad00e6a9b112590aa294;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/frame-unwind.c b/gdb/frame-unwind.c index 46096c212b..3334c472d0 100644 --- a/gdb/frame-unwind.c +++ b/gdb/frame-unwind.c @@ -1,6 +1,6 @@ /* Definitions for frame unwinder, for GDB, the GNU debugger. - Copyright (C) 2003-2019 Free Software Foundation, Inc. + Copyright (C) 2003-2020 Free Software Foundation, Inc. This file is part of GDB. @@ -18,16 +18,16 @@ along with this program. If not, see . */ #include "defs.h" - -/* Local non-gdb includes. */ -#include "dummy-frame.h" -#include "frame-unwind.h" #include "frame.h" -#include "gdb_obstack.h" +#include "frame-unwind.h" +#include "dummy-frame.h" #include "inline-frame.h" +#include "value.h" #include "regcache.h" +#include "gdb_obstack.h" #include "target.h" -#include "value.h" +#include "gdbarch.h" +#include "dwarf2/frame-tailcall.h" static struct gdbarch_data *frame_unwind_data; @@ -44,6 +44,18 @@ struct frame_unwind_table struct frame_unwind_table_entry **osabi_head; }; +/* A helper function to add an unwinder to a list. LINK says where to + install the new unwinder. The new link is returned. */ + +static struct frame_unwind_table_entry ** +add_unwinder (struct obstack *obstack, const struct frame_unwind *unwinder, + struct frame_unwind_table_entry **link) +{ + *link = OBSTACK_ZALLOC (obstack, struct frame_unwind_table_entry); + (*link)->unwinder = unwinder; + return &(*link)->next; +} + static void * frame_unwind_init (struct obstack *obstack) { @@ -52,13 +64,21 @@ frame_unwind_init (struct obstack *obstack) /* Start the table out with a few default sniffers. OSABI code can't override this. */ - table->list = OBSTACK_ZALLOC (obstack, struct frame_unwind_table_entry); - table->list->unwinder = &dummy_frame_unwind; - table->list->next = OBSTACK_ZALLOC (obstack, - struct frame_unwind_table_entry); - table->list->next->unwinder = &inline_frame_unwind; + struct frame_unwind_table_entry **link = &table->list; + + link = add_unwinder (obstack, &dummy_frame_unwind, link); + /* The DWARF tailcall sniffer must come before the inline sniffer. + Otherwise, we can end up in a situation where a DWARF frame finds + tailcall information, but then the inline sniffer claims a frame + before the tailcall sniffer, resulting in confusion. This is + safe to do always because the tailcall sniffer can only ever be + activated if the newer frame was created using the DWARF + unwinder, and it also found tailcall information. */ + link = add_unwinder (obstack, &dwarf2_tailcall_frame_unwind, link); + link = add_unwinder (obstack, &inline_frame_unwind, link); + /* The insertion point for OSABI sniffers. */ - table->osabi_head = &table->list->next->next; + table->osabi_head = link; return table; } @@ -103,11 +123,11 @@ frame_unwind_try_unwinder (struct frame_info *this_frame, void **this_cache, frame_prepare_for_sniffer (this_frame, unwinder); - TRY + try { res = unwinder->sniffer (unwinder, this_frame, this_cache); } - CATCH (ex, RETURN_MASK_ALL) + catch (const gdb_exception &ex) { /* Catch all exceptions, caused by either interrupt or error. Reset *THIS_CACHE. */ @@ -122,9 +142,8 @@ frame_unwind_try_unwinder (struct frame_info *this_frame, void **this_cache, should always accept the frame. */ return 0; } - throw_exception (ex); + throw; } - END_CATCH if (res) return 1; @@ -307,8 +326,9 @@ frame_unwind_got_address (struct frame_info *frame, int regnum, return reg_val; } +void _initialize_frame_unwind (); void -_initialize_frame_unwind (void) +_initialize_frame_unwind () { frame_unwind_data = gdbarch_data_register_pre_init (frame_unwind_init); }