/* See LICENSE file for copyright and license details. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #if defined(__clang__) # define FALL_THROUGH __attribute__((fallthrough)); #else # define FALL_THROUGH #endif #if defined(__clang__) # pragma clang diagnostic ignored "-Wdisabled-macro-expansion" # pragma clang diagnostic ignored "-Wpadded" #elif defined(__GNUC__) # pragma GCC diagnostic ignored "-Wpadded" # pragma GCC diagnostic ignored "-Wsuggest-attribute=pure" # pragma GCC diagnostic ignored "-Wsuggest-attribute=format" #endif #if defined(__linux__) # include "linux/os.h" #else # error "This program is only implemented for Linux" #endif /* #define signals that may appear in list-signums.h but may be missing in */ #if !defined(SIGCLD) && defined(SIGCHLD) # define SIGCLD SIGCHLD #endif #include "arg.h" #include "list-errnos.h" #include "list-signums.h" struct process; enum type { Unknown, Void, Int, UInt, OInt, XInt, Long, ULong, OLong, XLong, LLong, ULLong, OLLong, XLLong, Ptr }; enum state { Normal, Syscall, CloneChild, ForkChild, VforkChild, CloneParent, ForkParent, VforkParent, Exec }; struct output { int ells; char fmt; unsigned long long int size; void (*func)(struct process *, size_t); }; struct process { pid_t pid; pid_t thread_leader; struct process *next; struct process *prev; enum state state; int silent_until_execed; /* 2 until exec, 1 until "= 0", 0 afterwards */ /* Syscall data */ unsigned long long int scall; unsigned long long int args[6]; unsigned long long int save[6]; unsigned long long int ret; enum type ret_type; struct output outputs[6]; /* multiarch support */ unsigned long long int scall_xor; int long_is_int; int ptr_is_int; int mode; /* vfork(2) data */ struct process *continue_on_exit; struct process *vfork_waiting_on; }; /* consts.c */ const char *get_errno_name(int err); const char *get_signum_name(int sig); /* memory.c */ extern size_t abbreviate_memory; char *get_string(pid_t pid, unsigned long int addr, size_t *lenp, const char **errorp); int get_struct(pid_t pid, unsigned long int addr, void *out, size_t size, const char **errorp); char *get_memory(pid_t pid, unsigned long int addr, size_t n, const char **errorp); char *escape_memory(const char *str, size_t m); char *escape_string(const char *str, size_t m); char *get_escaped_string(pid_t pid, unsigned long int addr, size_t *lenp, const char **errorp); char *get_escaped_memory(pid_t pid, unsigned long int addr, size_t n, const char **errorp); /* print.c */ void print_systemcall(struct process *proc); void print_systemcall_exit(struct process *proc); /* process.c */ void init_process_list(void); struct process *find_process(pid_t pid); struct process *add_process(pid_t pid, unsigned long int trace_options); void remove_process(struct process *proc); /* util.c */ void setup_trace_output(FILE *fp, int multiprocess); void tprintf(struct process *proc, const char *fmt, ...); void weprintf(const char *fmt, ...); #define eprintf(...) (weprintf(__VA_ARGS__), exit(1)) #define eprintf_and_kill(PID, ...) (weprintf(__VA_ARGS__), kill((PID), SIGKILL), exit(1)) FILE *xfopen(const char *file, const char *mode);