diff options
| author | ahl <none@none> | 2005-07-20 01:15:45 -0700 |
|---|---|---|
| committer | ahl <none@none> | 2005-07-20 01:15:45 -0700 |
| commit | 0b38a8bdfd75ac6144f9d462bb38d0c1b3f0ca50 (patch) | |
| tree | b1914d8b26048f30b052b54b9625a9f6f8d153ca /usr/src/uts/intel/dtrace/dtrace_isa.c | |
| parent | b52a2671b74561fd8e88284bba4b0b834687951e (diff) | |
| download | illumos-joyent-0b38a8bdfd75ac6144f9d462bb38d0c1b3f0ca50.tar.gz | |
4970475 There should be a stackdepth equivalent for userland
5084954 value of dip can be incorrect in autovec
6181505 dtrace sysinfo:::modload probe does not fire when using 'modload'
6265417 schedctl-yield isn't listed in sdt_subr.c
6272558 gcc and dtrace don't get along
6276101 dtrace -G behaves strangely with multiple scripts
6284880 intrstat can leak dynamic variable state
6295662 plockstat needs more characters for stack addresses
6296903 invalid memory accesses clear other DTrace error bits
Diffstat (limited to 'usr/src/uts/intel/dtrace/dtrace_isa.c')
| -rw-r--r-- | usr/src/uts/intel/dtrace/dtrace_isa.c | 146 |
1 files changed, 102 insertions, 44 deletions
diff --git a/usr/src/uts/intel/dtrace/dtrace_isa.c b/usr/src/uts/intel/dtrace/dtrace_isa.c index 04a1279829..9177d135fd 100644 --- a/usr/src/uts/intel/dtrace/dtrace_isa.c +++ b/usr/src/uts/intel/dtrace/dtrace_isa.c @@ -117,35 +117,19 @@ dtrace_getpcstack(pc_t *pcstack, int pcstack_limit, int aframes, } } -void -dtrace_getupcstack(uint64_t *pcstack, int pcstack_limit) +static int +dtrace_getustack_common(uint64_t *pcstack, int pcstack_limit, uintptr_t pc, + uintptr_t sp) { klwp_t *lwp = ttolwp(curthread); - proc_t *p = ttoproc(curthread); - struct regs *rp; - uintptr_t pc, sp, oldcontext; - volatile uint8_t *flags = - (volatile uint8_t *)&cpu_core[CPU->cpu_id].cpuc_dtrace_flags; + proc_t *p = curproc; + uintptr_t oldcontext = lwp->lwp_oldcontext; + volatile uint16_t *flags = + (volatile uint16_t *)&cpu_core[CPU->cpu_id].cpuc_dtrace_flags; size_t s1, s2; + int ret = 0; - if (lwp == NULL || p == NULL || (rp = lwp->lwp_regs) == NULL) - return; - - if (*flags & CPU_DTRACE_FAULT) - return; - - if (pcstack_limit <= 0) - return; - - *pcstack++ = (uint64_t)p->p_pid; - pcstack_limit--; - - if (pcstack_limit <= 0) - return; - - pc = rp->r_pc; - sp = rp->r_fp; - oldcontext = lwp->lwp_oldcontext; + ASSERT(pcstack == NULL || pcstack_limit > 0); if (p->p_model == DATAMODEL_NATIVE) { s1 = sizeof (struct frame) + 2 * sizeof (long); @@ -155,23 +139,14 @@ dtrace_getupcstack(uint64_t *pcstack, int pcstack_limit) s2 = s1 + sizeof (siginfo32_t); } - if (DTRACE_CPUFLAG_ISSET(CPU_DTRACE_ENTRY)) { - *pcstack++ = (uint64_t)pc; - pcstack_limit--; - if (pcstack_limit <= 0) - return; - - if (p->p_model == DATAMODEL_NATIVE) - pc = dtrace_fulword((void *)rp->r_sp); - else - pc = dtrace_fuword32((void *)rp->r_sp); - } - while (pc != 0 && sp != 0) { - *pcstack++ = (uint64_t)pc; - pcstack_limit--; - if (pcstack_limit <= 0) - break; + ret++; + if (pcstack != NULL) { + *pcstack++ = (uint64_t)pc; + pcstack_limit--; + if (pcstack_limit <= 0) + break; + } if (oldcontext == sp + s1 || oldcontext == sp + s2) { if (p->p_model == DATAMODEL_NATIVE) { @@ -216,20 +191,103 @@ dtrace_getupcstack(uint64_t *pcstack, int pcstack_limit) } } + return (ret); +} + +void +dtrace_getupcstack(uint64_t *pcstack, int pcstack_limit) +{ + klwp_t *lwp = ttolwp(curthread); + proc_t *p = curproc; + struct regs *rp; + uintptr_t pc, sp; + volatile uint16_t *flags = + (volatile uint16_t *)&cpu_core[CPU->cpu_id].cpuc_dtrace_flags; + int n; + + if (lwp == NULL || p == NULL || (rp = lwp->lwp_regs) == NULL) + return; + + if (*flags & CPU_DTRACE_FAULT) + return; + + if (pcstack_limit <= 0) + return; + + *pcstack++ = (uint64_t)p->p_pid; + pcstack_limit--; + + if (pcstack_limit <= 0) + return; + + pc = rp->r_pc; + sp = rp->r_fp; + + if (DTRACE_CPUFLAG_ISSET(CPU_DTRACE_ENTRY)) { + *pcstack++ = (uint64_t)pc; + pcstack_limit--; + if (pcstack_limit <= 0) + return; + + if (p->p_model == DATAMODEL_NATIVE) + pc = dtrace_fulword((void *)rp->r_sp); + else + pc = dtrace_fuword32((void *)rp->r_sp); + } + + n = dtrace_getustack_common(pcstack, pcstack_limit, pc, sp); + ASSERT(n >= 0); + ASSERT(n <= pcstack_limit); + + pcstack += n; + pcstack_limit -= n; + while (pcstack_limit-- > 0) *pcstack++ = NULL; } +int +dtrace_getustackdepth(void) +{ + klwp_t *lwp = ttolwp(curthread); + proc_t *p = curproc; + struct regs *rp; + uintptr_t pc, sp; + int n = 0; + + if (lwp == NULL || p == NULL || (rp = lwp->lwp_regs) == NULL) + return (0); + + if (DTRACE_CPUFLAG_ISSET(CPU_DTRACE_FAULT)) + return (-1); + + pc = rp->r_pc; + sp = rp->r_fp; + + if (DTRACE_CPUFLAG_ISSET(CPU_DTRACE_ENTRY)) { + n++; + + if (p->p_model == DATAMODEL_NATIVE) + pc = dtrace_fulword((void *)rp->r_sp); + else + pc = dtrace_fuword32((void *)rp->r_sp); + } + + n += dtrace_getustack_common(NULL, 0, pc, sp); + + return (n); +} + /*ARGSUSED*/ void dtrace_getufpstack(uint64_t *pcstack, uint64_t *fpstack, int pcstack_limit) { klwp_t *lwp = ttolwp(curthread); - proc_t *p = ttoproc(curthread); + proc_t *p = curproc; struct regs *rp; uintptr_t pc, sp, oldcontext; - volatile uint8_t *flags = - (volatile uint8_t *)&cpu_core[CPU->cpu_id].cpuc_dtrace_flags; + volatile uint16_t *flags = + (volatile uint16_t *)&cpu_core[CPU->cpu_id].cpuc_dtrace_flags; size_t s1, s2; if (lwp == NULL || p == NULL || (rp = lwp->lwp_regs) == NULL) |
