blob: 13ce5777e183bfb84603b57aa3f23ba8076b2e91 [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
Juan Cespedes28f60191998-04-12 00:04:39 +020024 if (!list_of_processes) {
25 if (opt_d) {
26 output_line(0, "No more children");
27 }
28 exit(0);
29 }
Juan Cespedes5e01f651998-03-08 22:31:44 +010030 pid = wait(&status);
31 if (pid==-1) {
32 if (errno==ECHILD) {
33 if (opt_d) {
34 output_line(0, "No more children");
35 }
36 exit(0);
Juan Cespedes28f60191998-04-12 00:04:39 +020037 } else if (errno==EINTR) {
38 if (opt_d) {
39 output_line(0, "wait received EINTR ?");
40 }
41 event.thing = LT_EV_NONE;
42 return &event;
Juan Cespedes5e01f651998-03-08 22:31:44 +010043 }
44 perror("wait");
45 exit(1);
46 }
47 event.proc = pid2proc(pid);
48 if (!event.proc) {
49 fprintf(stderr, "signal from wrong pid %u ?!?\n", pid);
50 exit(1);
51 }
Juan Cespedes35d70631998-03-15 14:05:40 +010052 event.proc->instruction_pointer = NULL;
Juan Cespedesf0fdae91998-03-11 00:03:00 +010053 if (opt_d>2) {
Juan Cespedes5e01f651998-03-08 22:31:44 +010054 output_line(0,"signal from pid %u", pid);
55 }
56 if (event.proc->breakpoints_enabled == -1) {
Juan Cespedes5e01f651998-03-08 22:31:44 +010057 enable_all_breakpoints(event.proc);
58 event.thing = LT_EV_NONE;
59 continue_process(event.proc->pid);
60 return &event;
61 }
Juan Cespedes35d70631998-03-15 14:05:40 +010062 if (opt_i) {
63 event.proc->instruction_pointer = get_instruction_pointer(pid);
Juan Cespedesf0fdae91998-03-11 00:03:00 +010064 }
Juan Cespedes35d70631998-03-15 14:05:40 +010065 switch(syscall_p(event.proc, status, &tmp)) {
66 case 1: event.thing = LT_EV_SYSCALL;
67 event.e_un.sysnum = tmp;
68 return &event;
69 case 2: event.thing = LT_EV_SYSRET;
70 event.e_un.sysnum = tmp;
71 return &event;
72 default:
Juan Cespedes5e01f651998-03-08 22:31:44 +010073 }
74 if (WIFEXITED(status)) {
75 event.thing = LT_EV_EXIT;
76 event.e_un.ret_val = WEXITSTATUS(status);
77 return &event;
78 }
79 if (WIFSIGNALED(status)) {
80 event.thing = LT_EV_EXIT_SIGNAL;
81 event.e_un.signum = WTERMSIG(status);
82 return &event;
83 }
84 if (!WIFSTOPPED(status)) {
85 event.thing = LT_EV_UNKNOWN;
86 return &event;
87 }
88 if (WSTOPSIG(status) != SIGTRAP) {
89 event.thing = LT_EV_SIGNAL;
90 event.e_un.signum = WSTOPSIG(status);
91 return &event;
92 }
93 event.thing = LT_EV_BREAKPOINT;
Juan Cespedes35d70631998-03-15 14:05:40 +010094 if (!event.proc->instruction_pointer) {
95 event.proc->instruction_pointer = get_instruction_pointer(pid);
96 }
Juan Cespedes5e01f651998-03-08 22:31:44 +010097 event.e_un.brk_addr = event.proc->instruction_pointer - DECR_PC_AFTER_BREAK;
98 return &event;
99}
100
101static struct process * pid2proc(int pid)
102{
103 struct process * tmp;
104
105 tmp = list_of_processes;
106 while(tmp) {
107 if (pid == tmp->pid) {
108 return tmp;
109 }
110 tmp = tmp->next;
111 }
112 return NULL;
113}
114