summaryrefslogtreecommitdiff
path: root/usr/src/uts/intel/dtrace/dtrace_isa.c
diff options
context:
space:
mode:
authorahl <none@none>2005-07-20 01:15:45 -0700
committerahl <none@none>2005-07-20 01:15:45 -0700
commit0b38a8bdfd75ac6144f9d462bb38d0c1b3f0ca50 (patch)
treeb1914d8b26048f30b052b54b9625a9f6f8d153ca /usr/src/uts/intel/dtrace/dtrace_isa.c
parentb52a2671b74561fd8e88284bba4b0b834687951e (diff)
downloadillumos-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.c146
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)