From patchwork Tue Jul 7 12:51:55 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pierre Langlois X-Patchwork-Id: 7560 Received: (qmail 50826 invoked by alias); 7 Jul 2015 12:53:15 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 50709 invoked by uid 89); 7 Jul 2015 12:53:14 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.1 required=5.0 tests=AWL, BAYES_00, SPF_PASS autolearn=ham version=3.3.2 X-HELO: eu-smtp-delivery-143.mimecast.com Received: from eu-smtp-delivery-143.mimecast.com (HELO eu-smtp-delivery-143.mimecast.com) (207.82.80.143) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 07 Jul 2015 12:53:12 +0000 Received: from cam-owa1.Emea.Arm.com (fw-tnat.cambridge.arm.com [217.140.96.140]) by eu-smtp-1.mimecast.com with ESMTP id uk-mta-14-6rjXeVxORliQSuWYr42dVQ-11 Received: from e105615-lin.cambridge.arm.com ([10.1.2.79]) by cam-owa1.Emea.Arm.com with Microsoft SMTPSVC(6.0.3790.3959); Tue, 7 Jul 2015 13:52:00 +0100 From: Pierre Langlois To: gdb-patches@sourceware.org Cc: Pierre Langlois Subject: [PATCH 5/8] [AArch64] Teach stub unwinder to terminate gracefully Date: Tue, 7 Jul 2015 13:51:55 +0100 Message-Id: <1436273518-5959-6-git-send-email-pierre.langlois@arm.com> In-Reply-To: <1436273518-5959-1-git-send-email-pierre.langlois@arm.com> References: <1436273518-5959-1-git-send-email-pierre.langlois@arm.com> X-MC-Unique: 6rjXeVxORliQSuWYr42dVQ-11 X-IsSubscribed: yes The stub unwinder is used on AArch64 if the target's memory is not readable at the current PC. If we purposely kill the inferior before examining the trace then we get the following issue: ~~~ ... (gdb) trace f Tracepoint 3 at 0x7fb7fc28c0 (gdb) tstart (gdb) continue ... (gdb) tstop (gdb) tsave /tmp/trace (gdb) kill ... (gdb) target tfile /tmp/trace ... (gdb) tfind Register 31 is not available. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Found trace frame 0, tracepoint 3 #-1 0x0000007fb7fc28c0 in f () ... ^^^ ~~~ This patch teaches the stub unwinder to report to the core frame code with UNWIND_UNAVAILABLE when either the stack pointer of the return address are unavailable to read from the target. The following test cases now pass when enabling tracepoints: PASS: gdb.trace/pending.exp: trace works: tfind test frame 0 PASS: gdb.trace/pending.exp: trace resolved_in_trace: tfind test frame 0 PASS: gdb.trace/pending.exp: trace installed_in_trace: tfind test frame 0 PASS: gdb.trace/mi-tracepoint-changed.exp: pending resolved: -trace-find frame-number 0 gdb/ChangeLog: * aarch64-tdep.c (aarch64_make_stub_cache): Set available_p and swallow NOT_AVAILABLE_ERROR. (aarch64_stub_this_id): Call frame_id_build_unavailable_stack if available_p is not set. (aarch64_stub_frame_unwind_stop_reason): New function. (aarch64_stub_unwind): Install it. --- gdb/aarch64-tdep.c | 36 +++++++++++++++++++++++++++++++----- 1 file changed, 31 insertions(+), 5 deletions(-) diff --git a/gdb/aarch64-tdep.c b/gdb/aarch64-tdep.c index 87a6d61..57976b7 100644 --- a/gdb/aarch64-tdep.c +++ b/gdb/aarch64-tdep.c @@ -1109,13 +1109,36 @@ aarch64_make_stub_cache (struct frame_info *this_frame, void **this_cache) cache->saved_regs = trad_frame_alloc_saved_regs (this_frame); *this_cache = cache; - cache->prev_sp - = get_frame_register_unsigned (this_frame, AARCH64_SP_REGNUM); - cache->prev_pc = get_frame_pc (this_frame); + TRY + { + cache->prev_sp + = get_frame_register_unsigned (this_frame, AARCH64_SP_REGNUM); + cache->prev_pc = get_frame_pc (this_frame); + cache->available_p = 1; + } + CATCH (ex, RETURN_MASK_ERROR) + { + if (ex.error != NOT_AVAILABLE_ERROR) + throw_exception (ex); + } + END_CATCH return cache; } +static enum unwind_stop_reason +aarch64_stub_frame_unwind_stop_reason (struct frame_info *this_frame, + void **this_cache) +{ + struct aarch64_prologue_cache *cache + = aarch64_make_stub_cache (this_frame, this_cache); + + if (!cache->available_p) + return UNWIND_UNAVAILABLE; + + return UNWIND_NO_REASON; +} + /* Our frame ID for a stub frame is the current SP and LR. */ static void @@ -1125,7 +1148,10 @@ aarch64_stub_this_id (struct frame_info *this_frame, struct aarch64_prologue_cache *cache = aarch64_make_stub_cache (this_frame, this_cache); - *this_id = frame_id_build (cache->prev_sp, cache->prev_pc); + if (cache->available_p) + *this_id = frame_id_build (cache->prev_sp, cache->prev_pc); + else + *this_id = frame_id_build_unavailable_stack (cache->prev_pc); } /* Implement the "sniffer" frame_unwind method. */ @@ -1152,7 +1178,7 @@ aarch64_stub_unwind_sniffer (const struct frame_unwind *self, struct frame_unwind aarch64_stub_unwind = { NORMAL_FRAME, - default_frame_unwind_stop_reason, + aarch64_stub_frame_unwind_stop_reason, aarch64_stub_this_id, aarch64_prologue_prev_register, NULL,