static void usage(FILE *out)
{
- fprintf(out, "usage: pstack [-h] PID\n");
+ fprintf(out, "usage: pstack [-hna] PID\n");
}
-static int dumpstack(pid_t pid)
+static int dumpstack(pid_t pid, int resolve)
{
int rv, s;
unw_addr_space_t rps;
ptd = _UPT_create(pid);
rv = 0;
if((s = unw_init_remote(&uw, rps, ptd)) != 0) {
- fprintf(stderr, "pstack: init_remote: %i\n", s);
+ fprintf(stderr, "pstack: init_remote: %s\n", unw_strerror(s));
rv = 1;
goto out;
}
do {
- if(!(s = unw_get_proc_name(&uw, pnm, sizeof(pnm), &pcoff)) || (s == -UNW_ENOMEM)) {
+ if(resolve && (!(s = unw_get_proc_name(&uw, pnm, sizeof(pnm), &pcoff)) || (s == -UNW_ENOMEM))) {
pnm[sizeof(pnm) - 1] = 0;
- printf("%s+%jx\n", pnm, (intmax_t)pcoff);
+ if(resolve == 2) {
+ unw_get_reg(&uw, UNW_REG_IP, ®);
+ printf("%s(%jx)+%jx\n", pnm, (intmax_t)(reg - pcoff), (intmax_t)pcoff);
+ } else {
+ printf("%s+%jx\n", pnm, (intmax_t)pcoff);
+ }
} else {
unw_get_reg(&uw, UNW_REG_IP, ®);
printf("%jx\n", (intmax_t)reg);
}
} while((s = unw_step(&uw)) > 0);
if(s < 0) {
- fprintf(stderr, "pstack: step: %i\n", s);
+ fprintf(stderr, "pstack: step: %s\n", unw_strerror(s));
}
out:
_UPT_destroy(ptd);
int main(int argc, char **argv)
{
- int c, s;
+ int c, s, res;
pid_t pid;
- while((c = getopt(argc, argv, "h")) != -1) {
+ res = 1;
+ while((c = getopt(argc, argv, "hna")) != -1) {
switch(c) {
case 'h':
usage(stdout);
exit(0);
+ case 'n':
+ res = 0;
+ break;
+ case 'a':
+ res = 2;
+ break;
default:
usage(stderr);
exit(1);
if(WIFSTOPPED(s))
break;
}
- dumpstack(pid);
+ dumpstack(pid, res);
if(ptrace(PTRACE_DETACH, pid, NULL, NULL)) {
fprintf(stderr, "pstack: detach: %s\n", strerror(errno));
}