anndl: Fixed a couple of bugs.
[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{
14 fprintf(out, "usage: pstack [-h] PID\n");
15}
16
17static int dumpstack(pid_t pid)
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) {
30 fprintf(stderr, "pstack: init_remote: %i\n", s);
31 rv = 1;
32 goto out;
33 }
34 do {
35 if(!(s = unw_get_proc_name(&uw, pnm, sizeof(pnm), &pcoff)) || (s == -UNW_ENOMEM)) {
36 pnm[sizeof(pnm) - 1] = 0;
37 printf("%s+%jx\n", pnm, (intmax_t)pcoff);
38 } else {
39 unw_get_reg(&uw, UNW_REG_IP, &reg);
40 printf("%jx\n", (intmax_t)reg);
41 }
42 } while((s = unw_step(&uw)) > 0);
43 if(s < 0) {
44 fprintf(stderr, "pstack: step: %i\n", s);
45 }
46out:
47 _UPT_destroy(ptd);
48 unw_destroy_addr_space(rps);
49 return(rv);
50}
51
52int main(int argc, char **argv)
53{
54 int c, s;
55 pid_t pid;
56
57 while((c = getopt(argc, argv, "h")) != -1) {
58 switch(c) {
59 case 'h':
60 usage(stdout);
61 exit(0);
62 default:
63 usage(stderr);
64 exit(1);
65 }
66 }
67 if(argc - optind < 1) {
68 usage(stderr);
69 exit(1);
70 }
71 pid = atoi(argv[optind]);
72 if(ptrace(PTRACE_ATTACH, pid, NULL, NULL)) {
73 fprintf(stderr, "pstack: attach %i: %s\n", pid, strerror(errno));
74 exit(1);
75 }
76 while(1) {
77 if(waitpid(pid, &s, 0) < 0) {
78 fprintf(stderr, "pstack: wait: %s\n", strerror(errno));
79 exit(1);
80 }
81 if(WIFSTOPPED(s))
82 break;
83 }
84 dumpstack(pid);
85 if(ptrace(PTRACE_DETACH, pid, NULL, NULL)) {
86 fprintf(stderr, "pstack: detach: %s\n", strerror(errno));
87 }
88 return(0);
89}
338cc72b
FT
90
91/*
92 * Local Variables:
93 * compile-command: "gcc -Wall -g -o pstack pstack.c -lunwind-ptrace -lunwind-x86_64"
94 * End:
95 */