diff options
author | Robert Mustacchi <rm@joyent.com> | 2018-12-20 19:39:25 +0000 |
---|---|---|
committer | Robert Mustacchi <rm@joyent.com> | 2019-01-18 19:33:25 +0000 |
commit | 8f697f9a1a91761e318c95fdebf19480d38ce836 (patch) | |
tree | 9411875d5d693073eefffc8642470b28fae4d71d | |
parent | 30165b7f6753bc3d48c52319bed7ec7b3ea36b3c (diff) | |
download | illumos-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.c | 37 | ||||
-rw-r--r-- | usr/src/lib/libproc/i386/Pisadep.c | 36 |
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; |