trace.c revision 8cc1b9d456c8f41e3a8cc0d3ec0d77eb779cb7bb
1#include <stdio.h>
2#include <string.h>
3#include <errno.h>
4#include <sys/types.h>
5#include <sys/ptrace.h>
6#include <asm/unistd.h>
7
8#include "ltrace.h"
9#include "options.h"
10
11/* Returns 1 if the sysnum may make a new child to be created
12 * (ie, with fork() or clone())
13 * Returns 0 otherwise.
14 */
15int
16fork_p(int sysnum) {
17	return 0
18#if defined(__NR_fork)
19		|| (sysnum == __NR_fork)
20#endif
21#if defined(__NR_clone)
22		|| (sysnum == __NR_clone)
23#endif
24#if defined(__NR_vfork)
25		|| (sysnum == __NR_vfork)
26#endif
27		;
28}
29
30/* Returns 1 if the sysnum may make the process exec other program
31 */
32int
33exec_p(int sysnum) {
34	return (sysnum == __NR_execve);
35}
36
37void
38trace_me(void) {
39	if (ptrace(PTRACE_TRACEME, 0, 1, 0)<0) {
40		perror("PTRACE_TRACEME");
41		exit(1);
42	}
43}
44
45int
46trace_pid(pid_t pid) {
47	if (ptrace(PTRACE_ATTACH, pid, 1, 0) < 0) {
48		return -1;
49	}
50	return 0;
51}
52
53void
54untrace_pid(pid_t pid) {
55	ptrace(PTRACE_DETACH, pid, 1, 0);
56}
57
58void
59continue_after_signal(pid_t pid, int signum) {
60	/* We should always trace syscalls to be able to control fork(), clone(), execve()... */
61	ptrace(PTRACE_SYSCALL, pid, 0, signum);
62}
63
64void
65continue_process(pid_t pid) {
66	continue_after_signal(pid, 0);
67}
68
69void
70continue_enabling_breakpoint(pid_t pid, struct breakpoint * sbp) {
71	enable_breakpoint(pid, sbp);
72	continue_process(pid);
73}
74
75int
76umovestr(struct process * proc, void * addr, int len, void * laddr) {
77	long a;
78	int i;
79	int offset=0;
80
81	while(offset<len) {
82		a = ptrace(PTRACE_PEEKTEXT, proc->pid, addr+offset, 0);
83		for(i=0; i<sizeof(long); i++) {
84			if (((char*)&a)[i] && offset+i < len) {
85				*(char *)(laddr+offset+i) = ((char*)&a)[i];
86			} else {
87				*(char *)(laddr+offset+i) = '\0';
88				return 0;
89			}
90		}
91		offset += sizeof(long);
92	}
93	*(char *)(laddr+offset) = '\0';
94	return 0;
95}
96