pstack: Add some name resolution options.
[utils.git] / pstack.c
CommitLineData
c094f988
FT
1#include <stdlib.h>
2#include <stdint.h>
3#include <stdio.h>
4#include <unistd.h>
5#include <string.h>
6#include <errno.h>
7#include <sys/ptrace.h>
8#include <sys/wait.h>
9#include <libunwind.h>
10#include <libunwind-ptrace.h>
11
12static void usage(FILE *out)
13{
a6edb3d9 14 fprintf(out, "usage: pstack [-hna] PID\n");
c094f988
FT
15}
16
a6edb3d9 17static int dumpstack(pid_t pid, int resolve)
c094f988
FT
18{
19 int rv, s;
20 unw_addr_space_t rps;
21 unw_cursor_t uw;
22 unw_word_t reg, pcoff;
23 void *ptd;
24 char pnm[64];
25
26 rps = unw_create_addr_space(&_UPT_accessors, 0);
27 ptd = _UPT_create(pid);
28 rv = 0;
29 if((s = unw_init_remote(&uw, rps, ptd)) != 0) {
a6edb3d9 30 fprintf(stderr, "pstack: init_remote: %s\n", unw_strerror(s));
c094f988
FT
31 rv = 1;
32 goto out;
33 }
34 do {
a6edb3d9 35 if(resolve && (!(s = unw_get_proc_name(&uw, pnm, sizeof(pnm), &pcoff)) || (s == -UNW_ENOMEM))) {
c094f988 36 pnm[sizeof(pnm) - 1] = 0;
a6edb3d9
FT
37 if(resolve == 2) {
38 unw_get_reg(&uw, UNW_REG_IP, &reg);
39 printf("%s(%jx)+%jx\n", pnm, (intmax_t)(reg - pcoff), (intmax_t)pcoff);
40 } else {
41 printf("%s+%jx\n", pnm, (intmax_t)pcoff);
42 }
c094f988
FT
43 } else {
44 unw_get_reg(&uw, UNW_REG_IP, &reg);
45 printf("%jx\n", (intmax_t)reg);
46 }
47 } while((s = unw_step(&uw)) > 0);
48 if(s < 0) {
a6edb3d9 49 fprintf(stderr, "pstack: step: %s\n", unw_strerror(s));
c094f988
FT
50 }
51out:
52 _UPT_destroy(ptd);
53 unw_destroy_addr_space(rps);
54 return(rv);
55}
56
57int main(int argc, char **argv)
58{
a6edb3d9 59 int c, s, res;
c094f988
FT
60 pid_t pid;
61
a6edb3d9
FT
62 res = 1;
63 while((c = getopt(argc, argv, "hna")) != -1) {
c094f988
FT
64 switch(c) {
65 case 'h':
66 usage(stdout);
67 exit(0);
a6edb3d9
FT
68 case 'n':
69 res = 0;
70 break;
71 case 'a':
72 res = 2;
73 break;
c094f988
FT
74 default:
75 usage(stderr);
76 exit(1);
77 }
78 }
79 if(argc - optind < 1) {
80 usage(stderr);
81 exit(1);
82 }
83 pid = atoi(argv[optind]);
84 if(ptrace(PTRACE_ATTACH, pid, NULL, NULL)) {
85 fprintf(stderr, "pstack: attach %i: %s\n", pid, strerror(errno));
86 exit(1);
87 }
88 while(1) {
89 if(waitpid(pid, &s, 0) < 0) {
90 fprintf(stderr, "pstack: wait: %s\n", strerror(errno));
91 exit(1);
92 }
93 if(WIFSTOPPED(s))
94 break;
95 }
a6edb3d9 96 dumpstack(pid, res);
c094f988
FT
97 if(ptrace(PTRACE_DETACH, pid, NULL, NULL)) {
98 fprintf(stderr, "pstack: detach: %s\n", strerror(errno));
99 }
100 return(0);
101}
338cc72b
FT
102
103/*
104 * Local Variables:
105 * compile-command: "gcc -Wall -g -o pstack pstack.c -lunwind-ptrace -lunwind-x86_64"
106 * End:
107 */