blob: b5d88451e12ca82f9a7efbd5a4ca6a7a41b3fa75 [file] [log] [blame]
Juan Cespedes5e01f651998-03-08 22:31:44 +01001#define _GNU_SOURCE 1
2#include <sys/types.h>
3#include <sys/wait.h>
4#include <errno.h>
5#include <signal.h>
6#include <string.h>
7
8#include "ltrace.h"
9#include "options.h"
10#include "output.h"
11
12static struct event event;
13
14/* This should also update `current_process' */
15
16static struct process * pid2proc(int pid);
17
18struct event * wait_for_something(void)
19{
20 pid_t pid;
21 int status;
22 int tmp;
23
24 pid = wait(&status);
25 if (pid==-1) {
26 if (errno==ECHILD) {
27 if (opt_d) {
28 output_line(0, "No more children");
29 }
30 exit(0);
31 }
32 perror("wait");
33 exit(1);
34 }
35 event.proc = pid2proc(pid);
36 if (!event.proc) {
37 fprintf(stderr, "signal from wrong pid %u ?!?\n", pid);
38 exit(1);
39 }
Juan Cespedes35d70631998-03-15 14:05:40 +010040 event.proc->instruction_pointer = NULL;
Juan Cespedesf0fdae91998-03-11 00:03:00 +010041 if (opt_d>2) {
Juan Cespedes5e01f651998-03-08 22:31:44 +010042 output_line(0,"signal from pid %u", pid);
43 }
44 if (event.proc->breakpoints_enabled == -1) {
Juan Cespedes5e01f651998-03-08 22:31:44 +010045 enable_all_breakpoints(event.proc);
46 event.thing = LT_EV_NONE;
47 continue_process(event.proc->pid);
48 return &event;
49 }
Juan Cespedes35d70631998-03-15 14:05:40 +010050 if (opt_i) {
51 event.proc->instruction_pointer = get_instruction_pointer(pid);
Juan Cespedesf0fdae91998-03-11 00:03:00 +010052 }
Juan Cespedes35d70631998-03-15 14:05:40 +010053 switch(syscall_p(event.proc, status, &tmp)) {
54 case 1: event.thing = LT_EV_SYSCALL;
55 event.e_un.sysnum = tmp;
56 return &event;
57 case 2: event.thing = LT_EV_SYSRET;
58 event.e_un.sysnum = tmp;
59 return &event;
60 default:
Juan Cespedes5e01f651998-03-08 22:31:44 +010061 }
62 if (WIFEXITED(status)) {
63 event.thing = LT_EV_EXIT;
64 event.e_un.ret_val = WEXITSTATUS(status);
65 return &event;
66 }
67 if (WIFSIGNALED(status)) {
68 event.thing = LT_EV_EXIT_SIGNAL;
69 event.e_un.signum = WTERMSIG(status);
70 return &event;
71 }
72 if (!WIFSTOPPED(status)) {
73 event.thing = LT_EV_UNKNOWN;
74 return &event;
75 }
76 if (WSTOPSIG(status) != SIGTRAP) {
77 event.thing = LT_EV_SIGNAL;
78 event.e_un.signum = WSTOPSIG(status);
79 return &event;
80 }
81 event.thing = LT_EV_BREAKPOINT;
Juan Cespedes35d70631998-03-15 14:05:40 +010082 if (!event.proc->instruction_pointer) {
83 event.proc->instruction_pointer = get_instruction_pointer(pid);
84 }
Juan Cespedes5e01f651998-03-08 22:31:44 +010085 event.e_un.brk_addr = event.proc->instruction_pointer - DECR_PC_AFTER_BREAK;
86 return &event;
87}
88
89static struct process * pid2proc(int pid)
90{
91 struct process * tmp;
92
93 tmp = list_of_processes;
94 while(tmp) {
95 if (pid == tmp->pid) {
96 return tmp;
97 }
98 tmp = tmp->next;
99 }
100 return NULL;
101}
102