events.c revision 63184be8c577f5799e44db2a4e312a8240ad7751
1d44c6b8b090b8b7aa9d971d9e0bfd848732a3071Juan Cespedes#if HAVE_CONFIG_H 2d44c6b8b090b8b7aa9d971d9e0bfd848732a3071Juan Cespedes#include "config.h" 3d44c6b8b090b8b7aa9d971d9e0bfd848732a3071Juan Cespedes#endif 4d44c6b8b090b8b7aa9d971d9e0bfd848732a3071Juan Cespedes 55e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes#define _GNU_SOURCE 1 61cd999a32728f41208dc30f38a125d7bb7063625Juan Cespedes#include <stdlib.h> 75e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes#include <sys/types.h> 85e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes#include <sys/wait.h> 95e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes#include <errno.h> 105e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes#include <signal.h> 115e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes#include <string.h> 125e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes 135e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes#include "ltrace.h" 145e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes#include "options.h" 15cac15c3f170b5ec2cc6304c8c0763a78103e1778Juan Cespedes#include "debug.h" 165e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes 175e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedesstatic struct event event; 185e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes 195e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes/* This should also update `current_process' */ 205e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes 212d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienandstatic struct process *pid2proc(int pid); 225e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes 232d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienandstruct event *wait_for_something(void) 242d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienand{ 255e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes pid_t pid; 265e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes int status; 275e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes int tmp; 28ef46b3e70e54059a7a8bf32af7361bb262ccc8d1Petr Machata int stop_signal; 295e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes 3028f60197b93b45422a73e5d1a6aa581584d6c4a5Juan Cespedes if (!list_of_processes) { 31cac15c3f170b5ec2cc6304c8c0763a78103e1778Juan Cespedes debug(1, "No more children"); 3228f60197b93b45422a73e5d1a6aa581584d6c4a5Juan Cespedes exit(0); 3328f60197b93b45422a73e5d1a6aa581584d6c4a5Juan Cespedes } 345e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes pid = wait(&status); 352d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienand if (pid == -1) { 362d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienand if (errno == ECHILD) { 37cac15c3f170b5ec2cc6304c8c0763a78103e1778Juan Cespedes debug(1, "No more children"); 385e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes exit(0); 392d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienand } else if (errno == EINTR) { 40cac15c3f170b5ec2cc6304c8c0763a78103e1778Juan Cespedes debug(1, "wait received EINTR ?"); 4128f60197b93b45422a73e5d1a6aa581584d6c4a5Juan Cespedes event.thing = LT_EV_NONE; 4228f60197b93b45422a73e5d1a6aa581584d6c4a5Juan Cespedes return &event; 435e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes } 445e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes perror("wait"); 455e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes exit(1); 465e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes } 475e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes event.proc = pid2proc(pid); 485e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes if (!event.proc) { 495e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes fprintf(stderr, "signal from wrong pid %u ?!?\n", pid); 505e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes exit(1); 515e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes } 525c3fe0697b202cc7d95e90459de0fb312b297b27Juan Cespedes get_arch_dep(event.proc); 5335d70634aacdf85a3cdf85792ce68989e27bc9c2Juan Cespedes event.proc->instruction_pointer = NULL; 54cac15c3f170b5ec2cc6304c8c0763a78103e1778Juan Cespedes debug(3, "signal from pid %u", pid); 555e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes if (event.proc->breakpoints_enabled == -1) { 565e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes enable_all_breakpoints(event.proc); 575e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes event.thing = LT_EV_NONE; 589a2ad351a1c3215dc596ff3e2e3fd4bc24445a6bIan Wienand trace_set_options(event.proc, event.proc->pid); 595e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes continue_process(event.proc->pid); 605e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes return &event; 615e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes } 6235d70634aacdf85a3cdf85792ce68989e27bc9c2Juan Cespedes if (opt_i) { 632d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienand event.proc->instruction_pointer = 642d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienand get_instruction_pointer(event.proc); 65f0fdae9e2444c2fb7764774088c574ab53c787f4Juan Cespedes } 662d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienand switch (syscall_p(event.proc, status, &tmp)) { 6763184be8c577f5799e44db2a4e312a8240ad7751Juan Cespedes case 1: 6863184be8c577f5799e44db2a4e312a8240ad7751Juan Cespedes event.thing = LT_EV_SYSCALL; 6963184be8c577f5799e44db2a4e312a8240ad7751Juan Cespedes event.e_un.sysnum = tmp; 7063184be8c577f5799e44db2a4e312a8240ad7751Juan Cespedes return &event; 7163184be8c577f5799e44db2a4e312a8240ad7751Juan Cespedes case 2: 7263184be8c577f5799e44db2a4e312a8240ad7751Juan Cespedes event.thing = LT_EV_SYSRET; 7363184be8c577f5799e44db2a4e312a8240ad7751Juan Cespedes event.e_un.sysnum = tmp; 7463184be8c577f5799e44db2a4e312a8240ad7751Juan Cespedes return &event; 7563184be8c577f5799e44db2a4e312a8240ad7751Juan Cespedes case 3: 7663184be8c577f5799e44db2a4e312a8240ad7751Juan Cespedes event.thing = LT_EV_ARCH_SYSCALL; 7763184be8c577f5799e44db2a4e312a8240ad7751Juan Cespedes event.e_un.sysnum = tmp; 7863184be8c577f5799e44db2a4e312a8240ad7751Juan Cespedes return &event; 7963184be8c577f5799e44db2a4e312a8240ad7751Juan Cespedes case 4: 8063184be8c577f5799e44db2a4e312a8240ad7751Juan Cespedes event.thing = LT_EV_ARCH_SYSRET; 8163184be8c577f5799e44db2a4e312a8240ad7751Juan Cespedes event.e_un.sysnum = tmp; 8263184be8c577f5799e44db2a4e312a8240ad7751Juan Cespedes return &event; 8363184be8c577f5799e44db2a4e312a8240ad7751Juan Cespedes case -1: 8463184be8c577f5799e44db2a4e312a8240ad7751Juan Cespedes event.thing = LT_EV_NONE; 8563184be8c577f5799e44db2a4e312a8240ad7751Juan Cespedes continue_process(event.proc->pid); 8663184be8c577f5799e44db2a4e312a8240ad7751Juan Cespedes return &event; 875e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes } 885e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes if (WIFEXITED(status)) { 895e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes event.thing = LT_EV_EXIT; 905e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes event.e_un.ret_val = WEXITSTATUS(status); 915e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes return &event; 925e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes } 935e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes if (WIFSIGNALED(status)) { 945e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes event.thing = LT_EV_EXIT_SIGNAL; 955e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes event.e_un.signum = WTERMSIG(status); 965e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes return &event; 975e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes } 985e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes if (!WIFSTOPPED(status)) { 995e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes event.thing = LT_EV_UNKNOWN; 1005e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes return &event; 1015e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes } 102ef46b3e70e54059a7a8bf32af7361bb262ccc8d1Petr Machata 103ef46b3e70e54059a7a8bf32af7361bb262ccc8d1Petr Machata stop_signal = WSTOPSIG(status); 104ef46b3e70e54059a7a8bf32af7361bb262ccc8d1Petr Machata 105ef46b3e70e54059a7a8bf32af7361bb262ccc8d1Petr Machata /* On some targets, breakpoints are signalled not using 106ef46b3e70e54059a7a8bf32af7361bb262ccc8d1Petr Machata SIGTRAP, but also with SIGILL, SIGSEGV or SIGEMT. Check 107ef46b3e70e54059a7a8bf32af7361bb262ccc8d1Petr Machata for these. */ 108ef46b3e70e54059a7a8bf32af7361bb262ccc8d1Petr Machata if (stop_signal == SIGSEGV 109ef46b3e70e54059a7a8bf32af7361bb262ccc8d1Petr Machata || stop_signal == SIGILL 110ef46b3e70e54059a7a8bf32af7361bb262ccc8d1Petr Machata#ifdef SIGEMT 111ef46b3e70e54059a7a8bf32af7361bb262ccc8d1Petr Machata || stop_signal == SIGEMT 112ef46b3e70e54059a7a8bf32af7361bb262ccc8d1Petr Machata#endif 113ef46b3e70e54059a7a8bf32af7361bb262ccc8d1Petr Machata ) { 114ef46b3e70e54059a7a8bf32af7361bb262ccc8d1Petr Machata // If we didn't need to know IP so far, get it now. 115ef46b3e70e54059a7a8bf32af7361bb262ccc8d1Petr Machata void * addr = opt_i 116ef46b3e70e54059a7a8bf32af7361bb262ccc8d1Petr Machata ? event.proc->instruction_pointer 117ef46b3e70e54059a7a8bf32af7361bb262ccc8d1Petr Machata : (event.proc->instruction_pointer = get_instruction_pointer (event.proc)); 118ef46b3e70e54059a7a8bf32af7361bb262ccc8d1Petr Machata 119ef46b3e70e54059a7a8bf32af7361bb262ccc8d1Petr Machata if (address2bpstruct(event.proc, addr)) 120ef46b3e70e54059a7a8bf32af7361bb262ccc8d1Petr Machata stop_signal = SIGTRAP; 121ef46b3e70e54059a7a8bf32af7361bb262ccc8d1Petr Machata } 122ef46b3e70e54059a7a8bf32af7361bb262ccc8d1Petr Machata 123ef46b3e70e54059a7a8bf32af7361bb262ccc8d1Petr Machata if (stop_signal != (SIGTRAP | event.proc->tracesysgood) 124ef46b3e70e54059a7a8bf32af7361bb262ccc8d1Petr Machata && stop_signal != SIGTRAP) { 1255e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes event.thing = LT_EV_SIGNAL; 126a413e5b8880de643a83ad124d078091c0956fe1dJuan Cespedes event.e_un.signum = stop_signal; 1275e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes return &event; 1285e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes } 12955ed83b24df9c6d671091a8c75caab33ffecd40ePetr Machata 13055ed83b24df9c6d671091a8c75caab33ffecd40ePetr Machata if (was_exec(event.proc, status)) { 13155ed83b24df9c6d671091a8c75caab33ffecd40ePetr Machata pid_t saved_pid; 13255ed83b24df9c6d671091a8c75caab33ffecd40ePetr Machata 13355ed83b24df9c6d671091a8c75caab33ffecd40ePetr Machata event.thing = LT_EV_NONE; 13455ed83b24df9c6d671091a8c75caab33ffecd40ePetr Machata event.e_un.signum = WSTOPSIG(status); 13555ed83b24df9c6d671091a8c75caab33ffecd40ePetr Machata debug(1, "Placing breakpoints for the new program"); 13655ed83b24df9c6d671091a8c75caab33ffecd40ePetr Machata event.proc->mask_32bit = 0; 13755ed83b24df9c6d671091a8c75caab33ffecd40ePetr Machata event.proc->personality = 0; 13855ed83b24df9c6d671091a8c75caab33ffecd40ePetr Machata event.proc->arch_ptr = NULL; 13955ed83b24df9c6d671091a8c75caab33ffecd40ePetr Machata event.proc->filename = pid2name(event.proc->pid); 14055ed83b24df9c6d671091a8c75caab33ffecd40ePetr Machata saved_pid = event.proc->pid; 14155ed83b24df9c6d671091a8c75caab33ffecd40ePetr Machata event.proc->pid = 0; 14255ed83b24df9c6d671091a8c75caab33ffecd40ePetr Machata breakpoints_init(event.proc); 14355ed83b24df9c6d671091a8c75caab33ffecd40ePetr Machata event.proc->pid = saved_pid; 14455ed83b24df9c6d671091a8c75caab33ffecd40ePetr Machata continue_process(event.proc->pid); 14555ed83b24df9c6d671091a8c75caab33ffecd40ePetr Machata return &event; 14655ed83b24df9c6d671091a8c75caab33ffecd40ePetr Machata } 14755ed83b24df9c6d671091a8c75caab33ffecd40ePetr Machata 1485e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes event.thing = LT_EV_BREAKPOINT; 14935d70634aacdf85a3cdf85792ce68989e27bc9c2Juan Cespedes if (!event.proc->instruction_pointer) { 1502d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienand event.proc->instruction_pointer = 1512d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienand get_instruction_pointer(event.proc); 15235d70634aacdf85a3cdf85792ce68989e27bc9c2Juan Cespedes } 1532d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienand event.e_un.brk_addr = 1542d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienand event.proc->instruction_pointer - DECR_PC_AFTER_BREAK; 1555e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes return &event; 1565e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes} 1575e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes 1582d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienandstatic struct process *pid2proc(pid_t pid) 1592d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienand{ 1602d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienand struct process *tmp; 1615e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes 1625e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes tmp = list_of_processes; 1632d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienand while (tmp) { 1645e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes if (pid == tmp->pid) { 1655e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes return tmp; 1665e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes } 1675e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes tmp = tmp->next; 1685e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes } 1695e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes return NULL; 1705e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes} 171