-
Notifications
You must be signed in to change notification settings - Fork 1
/
callstack.c
55 lines (40 loc) · 1.47 KB
/
callstack.c
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
55
#include "callstack.h"
#include "log.h"
#include <sys/ptrace.h>
#include <libunwind-ptrace.h>
void callstack_unwind_log(Process *proc){
pid_t pid = proc->pid;
log_open();
if (ptrace(PTRACE_ATTACH, pid, 0, 0) != 0){
syslog(LOG_ERR, LOG_PREFIX"cannot log process(PID=%d) call stack due to ptrace ATTACH failed", pid);
goto end;
}
unw_addr_space_t as = unw_create_addr_space(&_UPT_accessors, 0);
void *context = _UPT_create(pid);
unw_cursor_t cursor;
if (unw_init_remote(&cursor, as, context) != 0){
syslog(LOG_ERR, LOG_PREFIX"cannot log process(PID=%d, exe=%s) call stack due to stack cursor initilization failed", pid, proc->exe);
goto end;
}
syslog(LOG_ERR, LOG_PREFIX"process(PID=%d, exe=%s) call stack prologue(bottom up)\n", pid, proc->exe);
unw_word_t offset, ip;
char sym[BUF_SIZE];
while(unw_step(&cursor) > 0){
memset(sym, 0, BUF_SIZE);
if (unw_get_reg(&cursor, UNW_REG_IP, &ip)){
syslog(LOG_ERR, LOG_PREFIX"call stack broken due to read instruction pointer failed");
goto epi;
}
if (unw_get_proc_name(&cursor, sym, sizeof(sym), &offset) == 0)
syslog(LOG_ERR, LOG_PREFIX"(%s+0x%lx)\n", sym, offset);
else
syslog(LOG_ERR, LOG_PREFIX"?? no symbol found\n");
}
_UPT_destroy(context);
(void) ptrace(PTRACE_DETACH, pid, 0, 0);
epi:
syslog(LOG_ERR, LOG_PREFIX"process(PID=%d, exe=%s) call stack epilogue\n", pid, proc->exe);
end:
log_close();
return;
}