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/intel/dtrace/dtrace_isa.c | |
| parent | dd566498928f08e7c9a79797a40db893c6a4b9fb (diff) | |
| download | illumos-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.c | 23 |
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 |
