summaryrefslogtreecommitdiff
path: root/usr/src/uts/intel/dtrace/dtrace_isa.c
diff options
context:
space:
mode:
authorjhaslam <none@none>2007-02-20 05:32:53 -0800
committerjhaslam <none@none>2007-02-20 05:32:53 -0800
commitb8fac8e162eda7e98db13dfa3e439e43f90f41d9 (patch)
tree75caaa35cff008f601cf74f7a8b62bdd08b7143c /usr/src/uts/intel/dtrace/dtrace_isa.c
parentdd566498928f08e7c9a79797a40db893c6a4b9fb (diff)
downloadillumos-joyent-b8fac8e162eda7e98db13dfa3e439e43f90f41d9.tar.gz
6512250 dtrace_getustack_common() could be improved
Diffstat (limited to 'usr/src/uts/intel/dtrace/dtrace_isa.c')
-rw-r--r--usr/src/uts/intel/dtrace/dtrace_isa.c23
1 files changed, 22 insertions, 1 deletions
diff --git a/usr/src/uts/intel/dtrace/dtrace_isa.c b/usr/src/uts/intel/dtrace/dtrace_isa.c
index 4baf88c31f..afed21d7b2 100644
--- a/usr/src/uts/intel/dtrace/dtrace_isa.c
+++ b/usr/src/uts/intel/dtrace/dtrace_isa.c
@@ -35,6 +35,8 @@
extern uintptr_t kernelbase;
+int dtrace_ustackdepth_max = 2048;
+
void
dtrace_getpcstack(pc_t *pcstack, int pcstack_limit, int aframes,
uint32_t *intrpc)
@@ -113,12 +115,14 @@ dtrace_getustack_common(uint64_t *pcstack, int pcstack_limit, uintptr_t pc,
klwp_t *lwp = ttolwp(curthread);
proc_t *p = curproc;
uintptr_t oldcontext = lwp->lwp_oldcontext;
+ uintptr_t oldsp;
volatile uint16_t *flags =
(volatile uint16_t *)&cpu_core[CPU->cpu_id].cpuc_dtrace_flags;
size_t s1, s2;
int ret = 0;
ASSERT(pcstack == NULL || pcstack_limit > 0);
+ ASSERT(dtrace_ustackdepth_max > 0);
if (p->p_model == DATAMODEL_NATIVE) {
s1 = sizeof (struct frame) + 2 * sizeof (long);
@@ -129,7 +133,16 @@ dtrace_getustack_common(uint64_t *pcstack, int pcstack_limit, uintptr_t pc,
}
while (pc != 0) {
- ret++;
+ /*
+ * We limit the number of times we can go around this
+ * loop to account for a circular stack.
+ */
+ if (ret++ >= dtrace_ustackdepth_max) {
+ *flags |= CPU_DTRACE_BADSTACK;
+ cpu_core[CPU->cpu_id].cpuc_dtrace_illval = sp;
+ break;
+ }
+
if (pcstack != NULL) {
*pcstack++ = (uint64_t)pc;
pcstack_limit--;
@@ -140,6 +153,8 @@ dtrace_getustack_common(uint64_t *pcstack, int pcstack_limit, uintptr_t pc,
if (sp == 0)
break;
+ oldsp = sp;
+
if (oldcontext == sp + s1 || oldcontext == sp + s2) {
if (p->p_model == DATAMODEL_NATIVE) {
ucontext_t *ucp = (ucontext_t *)oldcontext;
@@ -172,6 +187,12 @@ dtrace_getustack_common(uint64_t *pcstack, int pcstack_limit, uintptr_t pc,
}
}
+ if (sp == oldsp) {
+ *flags |= CPU_DTRACE_BADSTACK;
+ cpu_core[CPU->cpu_id].cpuc_dtrace_illval = sp;
+ break;
+ }
+
/*
* This is totally bogus: if we faulted, we're going to clear
* the fault and break. This is to deal with the apparently