From owner-svn-src-all@FreeBSD.ORG Thu Feb 19 12:20:22 2015 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 9E8168A0; Thu, 19 Feb 2015 12:20:22 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 7F3F0CB2; Thu, 19 Feb 2015 12:20:22 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.9/8.14.9) with ESMTP id t1JCKMa8035791; Thu, 19 Feb 2015 12:20:22 GMT (envelope-from andrew@FreeBSD.org) Received: (from andrew@localhost) by svn.freebsd.org (8.14.9/8.14.9/Submit) id t1JCKMRA035789; Thu, 19 Feb 2015 12:20:22 GMT (envelope-from andrew@FreeBSD.org) Message-Id: <201502191220.t1JCKMRA035789@svn.freebsd.org> X-Authentication-Warning: svn.freebsd.org: andrew set sender to andrew@FreeBSD.org using -f From: Andrew Turner Date: Thu, 19 Feb 2015 12:20:22 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r278997 - in head/sys: cddl/dev/dtrace/arm conf X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 19 Feb 2015 12:20:22 -0000 Author: andrew Date: Thu Feb 19 12:20:21 2015 New Revision: 278997 URL: https://svnweb.freebsd.org/changeset/base/278997 Log: Use the ARM unwinder with dtrace to extract the stack when asked. With this dtrace is able to display a stack trace similar to the one below. # dtrace -p 603 -n 'tcp:kernel::receive { stack(); }' 0 70 :receive kernel`ip_input+0x140 kernel`netisr_dispatch_src+0xb8 kernel`ether_demux+0x1c4 kernel`ether_nh_input+0x3a8 kernel`netisr_dispatch_src+0xb8 kernel`ether_input+0x60 kernel`cpsw_intr_rx+0xac kernel`intr_event_execute_handlers+0x128 kernel`ithread_loop+0xb4 kernel`fork_exit+0x84 kernel`swi_exit kernel`swi_exit Tested by: gnn Sponsored by: ABT Systems Ltd Modified: head/sys/cddl/dev/dtrace/arm/dtrace_isa.c head/sys/conf/files.arm Modified: head/sys/cddl/dev/dtrace/arm/dtrace_isa.c ============================================================================== --- head/sys/cddl/dev/dtrace/arm/dtrace_isa.c Thu Feb 19 12:06:57 2015 (r278996) +++ head/sys/cddl/dev/dtrace/arm/dtrace_isa.c Thu Feb 19 12:20:21 2015 (r278997) @@ -69,9 +69,10 @@ void dtrace_getpcstack(pc_t *pcstack, int pcstack_limit, int aframes, uint32_t *intrpc) { - u_int32_t *frame, *lastframe; - int scp_offset; - int depth = 0; + struct unwind_state state; + register_t sp; + int scp_offset; + int depth = 0; pc_t caller = (pc_t) solaris_cpu[curcpu].cpu_dtrace_caller; if (intrpc != 0) @@ -79,23 +80,17 @@ dtrace_getpcstack(pc_t *pcstack, int pcs aframes++; - frame = (u_int32_t *)__builtin_frame_address(0);; - lastframe = NULL; - scp_offset = -(get_pc_str_offset() >> 2); - - while ((frame != NULL) && (depth < pcstack_limit)) { - db_addr_t scp; -#if 0 - u_int32_t savecode; - int r; - u_int32_t *rp; -#endif - - /* - * In theory, the SCP isn't guaranteed to be in the function - * that generated the stack frame. We hope for the best. - */ - scp = frame[FR_SCP]; + __asm __volatile("mov %0, sp" : "=&r" (sp)); + + state.registers[FP] = (uint32_t)__builtin_frame_address(0); + state.registers[SP] = sp; + state.registers[LR] = (uint32_t)__builtin_return_address(0); + state.registers[PC] = (uint32_t)dtrace_getpcstack; + + while (depth < pcstack_limit) { + int done; + + done = unwind_stack_one(&state, 1); if (aframes > 0) { aframes--; @@ -104,39 +99,10 @@ dtrace_getpcstack(pc_t *pcstack, int pcs } } else { - pcstack[depth++] = scp; + pcstack[depth++] = state.registers[PC]; } -#if 0 - savecode = ((u_int32_t *)scp)[scp_offset]; - if ((savecode & 0x0e100000) == 0x08000000) { - /* Looks like an STM */ - rp = frame - 4; - for (r = 10; r >= 0; r--) { - if (savecode & (1 << r)) { - /* register r == *rp-- */ - } - } - } -#endif - - /* - * Switch to next frame up - */ - if (frame[FR_RFP] == 0) - break; /* Top of stack */ - - lastframe = frame; - frame = (u_int32_t *)(frame[FR_RFP]); - - if (INKERNEL((int)frame)) { - /* staying in kernel */ - if (frame <= lastframe) { - /* bad frame pointer */ - break; - } - } - else + if (done) break; } @@ -176,55 +142,28 @@ dtrace_getarg(int arg, int aframes) int dtrace_getstackdepth(int aframes) { - u_int32_t *frame, *lastframe; - int scp_offset; - int depth = 1; - - frame = (u_int32_t *)__builtin_frame_address(0);; - lastframe = NULL; - scp_offset = -(get_pc_str_offset() >> 2); - - while (frame != NULL) { - db_addr_t scp; -#if 0 - u_int32_t savecode; - int r; - u_int32_t *rp; -#endif - - /* - * In theory, the SCP isn't guaranteed to be in the function - * that generated the stack frame. We hope for the best. - */ - scp = frame[FR_SCP]; + struct unwind_state state; + register_t sp; + int scp_offset; + int done = 0; + int depth = 1; + + __asm __volatile("mov %0, sp" : "=&r" (sp)); + + state.registers[FP] = (uint32_t)__builtin_frame_address(0); + state.registers[SP] = sp; + state.registers[LR] = (uint32_t)__builtin_return_address(0); + state.registers[PC] = (uint32_t)dtrace_getstackdepth; + do { + done = unwind_stack_one(&state, 1); depth++; - - /* - * Switch to next frame up - */ - if (frame[FR_RFP] == 0) - break; /* Top of stack */ - - lastframe = frame; - frame = (u_int32_t *)(frame[FR_RFP]); - - if (INKERNEL((int)frame)) { - /* staying in kernel */ - if (frame <= lastframe) { - /* bad frame pointer */ - break; - } - } - else - break; - } + } while (!done); if (depth < aframes) return 0; else return depth - aframes; - } ulong_t Modified: head/sys/conf/files.arm ============================================================================== --- head/sys/conf/files.arm Thu Feb 19 12:06:57 2015 (r278996) +++ head/sys/conf/files.arm Thu Feb 19 12:20:21 2015 (r278997) @@ -57,7 +57,7 @@ arm/arm/trap.c optional !armv6 arm/arm/trap-v6.c optional armv6 arm/arm/uio_machdep.c standard arm/arm/undefined.c standard -arm/arm/unwind.c optional ddb +arm/arm/unwind.c optional ddb | kdtrace_hooks arm/arm/vm_machdep.c standard arm/arm/vfp.c standard board_id.h standard \