From owner-freebsd-arm@FreeBSD.ORG Wed May 1 20:17:37 2013 Return-Path: Delivered-To: freebsd-arm@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by hub.freebsd.org (Postfix) with ESMTP id 3D8B5F25 for ; Wed, 1 May 2013 20:17:37 +0000 (UTC) (envelope-from ian@FreeBSD.org) Received: from mho-02-ewr.mailhop.org (mho-02-ewr.mailhop.org [204.13.248.72]) by mx1.freebsd.org (Postfix) with ESMTP id 157FE11DD for ; Wed, 1 May 2013 20:17:36 +0000 (UTC) Received: from c-24-8-230-52.hsd1.co.comcast.net ([24.8.230.52] helo=damnhippie.dyndns.org) by mho-02-ewr.mailhop.org with esmtpsa (TLSv1:AES256-SHA:256) (Exim 4.72) (envelope-from ) id 1UXdT5-0004VK-WA; Wed, 01 May 2013 20:17:36 +0000 Received: from [172.22.42.240] (revolution.hippie.lan [172.22.42.240]) by damnhippie.dyndns.org (8.14.3/8.14.3) with ESMTP id r41KHW6M008916; Wed, 1 May 2013 14:17:32 -0600 (MDT) (envelope-from ian@FreeBSD.org) X-Mail-Handler: Dyn Standard SMTP by Dyn X-Originating-IP: 24.8.230.52 X-Report-Abuse-To: abuse@dyndns.com (see http://www.dyndns.com/services/sendlabs/outbound_abuse.html for abuse reporting information) X-MHO-User: U2FsdGVkX1+pYlUasqUxmg7X0e5aTnoH Subject: A fix for the clang + eabi + kdb backtrace endless loop From: Ian Lepore To: freebsd-arm Content-Type: multipart/mixed; boundary="=-R74sECJmrSUq+3Vwtpin" Date: Wed, 01 May 2013 14:17:32 -0600 Message-ID: <1367439452.1180.92.camel@revolution.hippie.lan> Mime-Version: 1.0 X-Mailer: Evolution 2.32.1 FreeBSD GNOME Team Port X-BeenThere: freebsd-arm@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: Porting FreeBSD to the StrongARM Processor List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 01 May 2013 20:17:37 -0000 --=-R74sECJmrSUq+3Vwtpin Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit The attached patch fixes the problem where a kdb backtrace loops endlessly on an eabi kernel. I'm no expert on this stuff, so while this fixes the problem for me, I'm not sure it's right, especially the STOP_UNWINDING in exception_exit (which handles a test case of breaking into the debugger with the keyboard and typing 'bt'). I'm not going to commit this until it's been reviewed by someone who actually knows what they're doing. :) -- Ian --=-R74sECJmrSUq+3Vwtpin Content-Disposition: inline; filename="eabi_unwind_fixes.diff" Content-Type: text/x-patch; name="eabi_unwind_fixes.diff"; charset="us-ascii" Content-Transfer-Encoding: 7bit Index: sys/arm/arm/db_trace.c =================================================================== --- sys/arm/arm/db_trace.c (revision 248960) +++ sys/arm/arm/db_trace.c (working copy) @@ -354,7 +354,7 @@ index = db_find_index(state->start_pc); if (index->insn == EXIDX_CANTUNWIND) { - db_printf("Unable to unwind\n"); + db_printf("Unable to unwind further\n"); break; } else if (index->insn & (1 << 31)) { /* The data is within the instruction */ @@ -412,6 +412,23 @@ } } db_printf("\n"); + + /* Stop if we've unwound back to the thread entry point. */ + if (state->registers[FP] == 0) { + break; + } + + /* + * Stop if the unwind function didn't change the PC, to avoid + * getting stuck in this loop forever. If this happens, it's an + * indication that the unwind information is incorrect somehow + * for the function named in the last frame printed before you + * see this message. + */ + if (state->start_pc == state->registers[PC]) { + db_printf("Unwind failure (PC didn't change)\n"); + break; + } } } #endif Index: sys/arm/arm/exception.S =================================================================== --- sys/arm/arm/exception.S (revision 248960) +++ sys/arm/arm/exception.S (working copy) @@ -196,15 +196,19 @@ * Interrupts are disabled at suitable points to avoid ASTs * being posted between testing and exit to user mode. * - * This function uses PULLFRAMEFROMSVCANDEXIT and - * DO_AST - * only be called if the exception handler used PUSHFRAMEINSVC + * This function uses PULLFRAMEFROMSVCANDEXIT and DO_AST and can + * only be called if the exception handler used PUSHFRAMEINSVC. * + * For EABI, don't try to unwind any further than this, because the unwind + * info generated here is a single INSN_FINISH instruction. Nothing gets + * unwound (no registers change) so the unwind would loop here forever. */ -exception_exit: +ASENTRY_NP(exception_exit) + STOP_UNWINDING DO_AST PULLFRAMEFROMSVCANDEXIT +END(exception_exit) /* * undefined_entry: --=-R74sECJmrSUq+3Vwtpin--