summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Mustacchi <rm@joyent.com>2018-12-20 19:39:25 +0000
committerRobert Mustacchi <rm@joyent.com>2019-01-18 19:33:25 +0000
commit8f697f9a1a91761e318c95fdebf19480d38ce836 (patch)
tree9411875d5d693073eefffc8642470b28fae4d71d
parent30165b7f6753bc3d48c52319bed7ec7b3ea36b3c (diff)
downloadillumos-joyent-8f697f9a1a91761e318c95fdebf19480d38ce836.tar.gz
10220 libproc ia32 Pstack_iter() should leverage ctf
Reviewed by: Dan McDonald <danmcd@joyent.com> Reviewed by: Jason King <jason.king@joyent.com> Reviewed by: John Levon <john.levon@joyent.com> Approved by: Richard Lowe <richlowe@richlowe.net>
-rw-r--r--usr/src/lib/libproc/amd64/Pisadep.c37
-rw-r--r--usr/src/lib/libproc/i386/Pisadep.c36
2 files changed, 65 insertions, 8 deletions
diff --git a/usr/src/lib/libproc/amd64/Pisadep.c b/usr/src/lib/libproc/amd64/Pisadep.c
index 8ef8340b02..95064ae33a 100644
--- a/usr/src/lib/libproc/amd64/Pisadep.c
+++ b/usr/src/lib/libproc/amd64/Pisadep.c
@@ -21,6 +21,7 @@
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
+ * Copyright 2018, Joyent, Inc.
*/
#include <sys/stack.h>
@@ -158,6 +159,28 @@ Pissyscall_text(struct ps_prochandle *P, const void *buf, size_t buflen)
#define TR_ARG_MAX 6 /* Max args to print, same as SPARC */
+static boolean_t
+argcount_ctf(struct ps_prochandle *P, uint32_t pc, uint_t *countp)
+{
+ GElf_Sym sym;
+ ctf_file_t *ctfp;
+ ctf_funcinfo_t finfo;
+ prsyminfo_t si = { 0 };
+
+ if (Pxlookup_by_addr(P, pc, NULL, 0, &sym, &si) != 0)
+ return (B_FALSE);
+
+ if ((ctfp = Paddr_to_ctf(P, pc)) == NULL)
+ return (B_FALSE);
+
+ if (ctf_func_info(ctfp, si.prs_id, &finfo) == CTF_ERR)
+ return (B_FALSE);
+
+ *countp = finfo.ctc_argc;
+
+ return (B_TRUE);
+}
+
/*
* Given a return address, determine the likely number of arguments
* that were pushed on the stack prior to its execution. We do this by
@@ -247,7 +270,7 @@ Pstack_iter32(struct ps_prochandle *P, const prgregset_t regs,
uint_t argc;
ssize_t sz;
prgregset_t gregs;
- uint32_t fp, pfp, pc;
+ uint32_t fp, pfp, pc, ctf_pc;
long args[32];
int rv;
int i;
@@ -272,7 +295,7 @@ Pstack_iter32(struct ps_prochandle *P, const prgregset_t regs,
(void) memcpy(gregs, regs, sizeof (gregs));
fp = regs[R_FP];
- pc = regs[R_PC];
+ ctf_pc = pc = regs[R_PC];
while (fp != 0 || pc != 0) {
if (stack_loop(fp, &prevfp, &nfp, &pfpsize))
@@ -288,7 +311,12 @@ Pstack_iter32(struct ps_prochandle *P, const prgregset_t regs,
*/
if (frame.pc != -1L) {
sz -= 2* sizeof (uint32_t);
- argc = argcount(P, (uint32_t)frame.pc, sz);
+ if (argcount_ctf(P, ctf_pc, &argc)) {
+ argc = MIN(argc, 32);
+ } else {
+ argc = argcount(P, (uint32_t)frame.pc,
+ sz);
+ }
} else
argc = 3; /* sighandler(signo, sip, ucp) */
} else {
@@ -296,6 +324,7 @@ Pstack_iter32(struct ps_prochandle *P, const prgregset_t regs,
argc = 0;
}
+ ctf_pc = frame.pc;
gregs[R_FP] = fp;
gregs[R_PC] = pc;
@@ -465,7 +494,7 @@ read_args(struct ps_prochandle *P, uintptr_t fp, uintptr_t pc, prgreg_t *args,
int
Pstack_iter(struct ps_prochandle *P, const prgregset_t regs,
- proc_stack_f *func, void *arg)
+ proc_stack_f *func, void *arg)
{
struct {
uintptr_t fp;
diff --git a/usr/src/lib/libproc/i386/Pisadep.c b/usr/src/lib/libproc/i386/Pisadep.c
index e09b40bb73..855f50a5d4 100644
--- a/usr/src/lib/libproc/i386/Pisadep.c
+++ b/usr/src/lib/libproc/i386/Pisadep.c
@@ -21,6 +21,7 @@
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
+ * Copyright 2018, Joyent, Inc.
*/
#include <sys/stack.h>
@@ -118,6 +119,28 @@ Pissyscall_text(struct ps_prochandle *P, const void *buf, size_t buflen)
#define TR_ARG_MAX 6 /* Max args to print, same as SPARC */
+static boolean_t
+argcount_ctf(struct ps_prochandle *P, long pc, uint_t *countp)
+{
+ GElf_Sym sym;
+ ctf_file_t *ctfp;
+ ctf_funcinfo_t finfo;
+ prsyminfo_t si = { 0 };
+
+ if (Pxlookup_by_addr(P, pc, NULL, 0, &sym, &si) != 0)
+ return (B_FALSE);
+
+ if ((ctfp = Paddr_to_ctf(P, pc)) == NULL)
+ return (B_FALSE);
+
+ if (ctf_func_info(ctfp, si.prs_id, &finfo) == CTF_ERR)
+ return (B_FALSE);
+
+ *countp = finfo.ctc_argc;
+
+ return (B_TRUE);
+}
+
/*
* Given a return address, determine the likely number of arguments
* that were pushed on the stack prior to its execution. We do this by
@@ -172,7 +195,7 @@ ucontext_n_to_prgregs(const ucontext_t *src, prgregset_t dst)
int
Pstack_iter(struct ps_prochandle *P, const prgregset_t regs,
- proc_stack_f *func, void *arg)
+ proc_stack_f *func, void *arg)
{
prgreg_t *prevfp = NULL;
uint_t pfpsize = 0;
@@ -186,7 +209,7 @@ Pstack_iter(struct ps_prochandle *P, const prgregset_t regs,
ssize_t sz;
prgregset_t gregs;
prgreg_t fp, pfp;
- prgreg_t pc;
+ prgreg_t pc, ctf_pc;
int rv;
/*
@@ -209,7 +232,7 @@ Pstack_iter(struct ps_prochandle *P, const prgregset_t regs,
(void) memcpy(gregs, regs, sizeof (gregs));
fp = regs[R_FP];
- pc = regs[R_PC];
+ ctf_pc = pc = regs[R_PC];
while (fp != 0 || pc != 0) {
if (stack_loop(fp, &prevfp, &nfp, &pfpsize))
@@ -225,7 +248,11 @@ Pstack_iter(struct ps_prochandle *P, const prgregset_t regs,
*/
if (frame.pc != -1L) {
sz -= 2* sizeof (long);
- argc = argcount(P, (long)frame.pc, sz);
+ if (argcount_ctf(P, ctf_pc, &argc)) {
+ argc = MIN(argc, 32);
+ } else {
+ argc = argcount(P, (long)frame.pc, sz);
+ }
} else
argc = 3; /* sighandler(signo, sip, ucp) */
} else {
@@ -233,6 +260,7 @@ Pstack_iter(struct ps_prochandle *P, const prgregset_t regs,
argc = 0;
}
+ ctf_pc = frame.pc;
gregs[R_FP] = fp;
gregs[R_PC] = pc;