X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Fframe-unwind.c;h=3334c472d0202b546f5eea17e27ec6cbbabc7476;hb=b4991d292edd84c16bd2050bd071198ceae764fe;hp=e5ddeba90773b545092f74c3def5f98ede20832a;hpb=4de283e4b5f21207fe12f99913d1f28d4f07843c;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/frame-unwind.c b/gdb/frame-unwind.c index e5ddeba907..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. @@ -26,6 +26,8 @@ #include "regcache.h" #include "gdb_obstack.h" #include "target.h" +#include "gdbarch.h" +#include "dwarf2/frame-tailcall.h" static struct gdbarch_data *frame_unwind_data; @@ -42,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) { @@ -50,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; } @@ -101,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. */ @@ -120,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; @@ -305,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); }