diff options
author | jhaslam <none@none> | 2007-02-20 05:32:53 -0800 |
---|---|---|
committer | jhaslam <none@none> | 2007-02-20 05:32:53 -0800 |
commit | b8fac8e162eda7e98db13dfa3e439e43f90f41d9 (patch) | |
tree | 75caaa35cff008f601cf74f7a8b62bdd08b7143c /usr/src/uts/sparc | |
parent | dd566498928f08e7c9a79797a40db893c6a4b9fb (diff) | |
download | illumos-gate-b8fac8e162eda7e98db13dfa3e439e43f90f41d9.tar.gz |
6512250 dtrace_getustack_common() could be improved
Diffstat (limited to 'usr/src/uts/sparc')
-rw-r--r-- | usr/src/uts/sparc/dtrace/dtrace_isa.c | 33 |
1 files changed, 27 insertions, 6 deletions
diff --git a/usr/src/uts/sparc/dtrace/dtrace_isa.c b/usr/src/uts/sparc/dtrace/dtrace_isa.c index 627cef869e..50b1f49ea7 100644 --- a/usr/src/uts/sparc/dtrace/dtrace_isa.c +++ b/usr/src/uts/sparc/dtrace/dtrace_isa.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -21,7 +20,7 @@ */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -66,6 +65,8 @@ extern ulong_t dtrace_getreg_win(uint_t, uint_t); extern void dtrace_putreg_win(uint_t, ulong_t); extern int dtrace_fish(int, int, uintptr_t *); +int dtrace_ustackdepth_max = 2048; + /* * This is similar in principle to getpcstack(), but there are several marked * differences in implementation: @@ -361,8 +362,12 @@ dtrace_getustack_common(uint64_t *pcstack, int pcstack_limit, uintptr_t sp) { proc_t *p = curproc; int ret = 0; + uintptr_t oldsp; + volatile uint16_t *flags = + (volatile uint16_t *)&cpu_core[CPU->cpu_id].cpuc_dtrace_flags; ASSERT(pcstack == NULL || pcstack_limit > 0); + ASSERT(dtrace_ustackdepth_max > 0); if (p->p_model == DATAMODEL_NATIVE) { for (;;) { @@ -373,13 +378,23 @@ dtrace_getustack_common(uint64_t *pcstack, int pcstack_limit, uintptr_t sp) !IS_P2ALIGNED((uintptr_t)fr, STACK_ALIGN)) break; + oldsp = sp; + pc = dtrace_fulword(&fr->fr_savpc); sp = dtrace_fulword(&fr->fr_savfp); if (pc == 0) break; - ret++; + /* + * We limit the number of times we can go around this + * loop to account for a circular stack. + */ + if (sp == oldsp || ret++ >= dtrace_ustackdepth_max) { + *flags |= CPU_DTRACE_BADSTACK; + cpu_core[CPU->cpu_id].cpuc_dtrace_illval = sp; + break; + } if (pcstack != NULL) { *pcstack++ = pc; @@ -404,13 +419,19 @@ dtrace_getustack_common(uint64_t *pcstack, int pcstack_limit, uintptr_t sp) !IS_P2ALIGNED((uintptr_t)fr, STACK_ALIGN32)) break; + oldsp = sp; + pc = dtrace_fuword32(&fr->fr_savpc); sp = dtrace_fuword32(&fr->fr_savfp); if (pc == 0) break; - ret++; + if (sp == oldsp || ret++ >= dtrace_ustackdepth_max) { + *flags |= CPU_DTRACE_BADSTACK; + cpu_core[CPU->cpu_id].cpuc_dtrace_illval = sp; + break; + } if (pcstack != NULL) { *pcstack++ = pc; |