Added pstack program.
authorFredrik Tolf <fredrik@dolda2000.com>
Sun, 19 Feb 2017 18:32:03 +0000 (19:32 +0100)
committerFredrik Tolf <fredrik@dolda2000.com>
Sun, 19 Feb 2017 18:32:03 +0000 (19:32 +0100)
pstack.c [new file with mode: 0644]

diff --git a/pstack.c b/pstack.c
new file mode 100644 (file)
index 0000000..055bcf4
--- /dev/null
+++ b/pstack.c
@@ -0,0 +1,89 @@
+#include <stdlib.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/ptrace.h>
+#include <sys/wait.h>
+#include <libunwind.h>
+#include <libunwind-ptrace.h>
+
+static void usage(FILE *out)
+{
+    fprintf(out, "usage: pstack [-h] PID\n");
+}
+
+static int dumpstack(pid_t pid)
+{
+    int rv, s;
+    unw_addr_space_t rps;
+    unw_cursor_t uw;
+    unw_word_t reg, pcoff;
+    void *ptd;
+    char pnm[64];
+    
+    rps = unw_create_addr_space(&_UPT_accessors, 0);
+    ptd = _UPT_create(pid);
+    rv = 0;
+    if((s = unw_init_remote(&uw, rps, ptd)) != 0) {
+       fprintf(stderr, "pstack: init_remote: %i\n", s);
+       rv = 1;
+       goto out;
+    }
+    do {
+       if(!(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);
+       } else {
+           unw_get_reg(&uw, UNW_REG_IP, &reg);
+           printf("%jx\n", (intmax_t)reg);
+       }
+    } while((s = unw_step(&uw)) > 0);
+    if(s < 0) {
+       fprintf(stderr, "pstack: step: %i\n", s);
+    }
+out:
+    _UPT_destroy(ptd);
+    unw_destroy_addr_space(rps);
+    return(rv);
+}
+
+int main(int argc, char **argv)
+{
+    int c, s;
+    pid_t pid;
+    
+    while((c = getopt(argc, argv, "h")) != -1) {
+       switch(c) {
+       case 'h':
+           usage(stdout);
+           exit(0);
+       default:
+           usage(stderr);
+           exit(1);
+       }
+    }
+    if(argc - optind < 1) {
+       usage(stderr);
+       exit(1);
+    }
+    pid = atoi(argv[optind]);
+    if(ptrace(PTRACE_ATTACH, pid, NULL, NULL)) {
+       fprintf(stderr, "pstack: attach %i: %s\n", pid, strerror(errno));
+       exit(1);
+    }
+    while(1) {
+       if(waitpid(pid, &s, 0) < 0) {
+           fprintf(stderr, "pstack: wait: %s\n", strerror(errno));
+           exit(1);
+       }
+       if(WIFSTOPPED(s))
+           break;
+    }
+    dumpstack(pid);
+    if(ptrace(PTRACE_DETACH, pid, NULL, NULL)) {
+       fprintf(stderr, "pstack: detach: %s\n", strerror(errno));
+    }
+    return(0);
+}