summaryrefslogtreecommitdiff
path: root/tools/stack-pid.c
blob: 8a03d4dd57e6c4f02d97b252ecb89dc3f50638d9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#include <sys/ptrace.h>
#include <stdio.h>
#include <stdlib.h>

#include <stdarg.h>

#include <libunwind-ptrace.h>

void die(const char *fmt, ...)
{
	va_list ap;

	va_start(ap, fmt);
	vfprintf(stderr, fmt, ap);
	va_end(ap);
	exit(1);
}


int main(int argc, char **argv)
{
	if (argc != 2)
		die("USAGE: unwind-pid <pid>\n");

	unw_addr_space_t as = unw_create_addr_space(&_UPT_accessors, 0);

	pid_t pid = atoi(argv[1]);
	if (ptrace(PTRACE_ATTACH, pid, 0, 0) != 0)
		die("ERROR: cannot attach to %d\n", pid);

	void *context = _UPT_create(pid);
	unw_cursor_t cursor;
	if (unw_init_remote(&cursor, as, context) != 0)
		die("ERROR: cannot initialize cursor for remote unwinding\n");

	do {
		unw_word_t offset, pc;
		char sym[4096];
		if (unw_get_reg(&cursor, UNW_REG_IP, &pc))
			die("ERROR: cannot read program counter\n");

		printf("0x%lx: ", pc);

		if (unw_get_proc_name(&cursor, sym, sizeof(sym), &offset) == 0)
			printf("(%s+0x%lx)\n", sym, offset);
		else
			printf("-- no symbol name found\n");
	} while (unw_step(&cursor) > 0);

	_UPT_destroy(context);
	(void) ptrace(PTRACE_DETACH, pid, 0, 0);

	return 0;
}