blob: 417ca6772590ddd2ea95b04c890dab808e1213ae [file] [log] [blame]
Juan Cespedesd44c6b81998-09-25 14:48:42 +02001#if HAVE_CONFIG_H
2#include "config.h"
3#endif
4
Juan Cespedes5e01f651998-03-08 22:31:44 +01005#define _GNU_SOURCE 1
Juan Cespedes1cd999a2001-07-03 00:46:04 +02006#include <stdlib.h>
Juan Cespedes5e01f651998-03-08 22:31:44 +01007#include <sys/types.h>
8#include <sys/wait.h>
9#include <errno.h>
10#include <signal.h>
11#include <string.h>
12
13#include "ltrace.h"
14#include "options.h"
15#include "output.h"
16
17static struct event event;
18
19/* This should also update `current_process' */
20
21static struct process * pid2proc(int pid);
22
23struct event * wait_for_something(void)
24{
25 pid_t pid;
26 int status;
27 int tmp;
28
Juan Cespedes28f60191998-04-12 00:04:39 +020029 if (!list_of_processes) {
30 if (opt_d) {
31 output_line(0, "No more children");
32 }
33 exit(0);
34 }
Juan Cespedes5e01f651998-03-08 22:31:44 +010035 pid = wait(&status);
36 if (pid==-1) {
37 if (errno==ECHILD) {
38 if (opt_d) {
39 output_line(0, "No more children");
40 }
41 exit(0);
Juan Cespedes28f60191998-04-12 00:04:39 +020042 } else if (errno==EINTR) {
43 if (opt_d) {
44 output_line(0, "wait received EINTR ?");
45 }
46 event.thing = LT_EV_NONE;
47 return &event;
Juan Cespedes5e01f651998-03-08 22:31:44 +010048 }
49 perror("wait");
50 exit(1);
51 }
52 event.proc = pid2proc(pid);
53 if (!event.proc) {
54 fprintf(stderr, "signal from wrong pid %u ?!?\n", pid);
55 exit(1);
56 }
Juan Cespedes35d70631998-03-15 14:05:40 +010057 event.proc->instruction_pointer = NULL;
Juan Cespedesf0fdae91998-03-11 00:03:00 +010058 if (opt_d>2) {
Juan Cespedes5e01f651998-03-08 22:31:44 +010059 output_line(0,"signal from pid %u", pid);
60 }
61 if (event.proc->breakpoints_enabled == -1) {
Juan Cespedes5e01f651998-03-08 22:31:44 +010062 enable_all_breakpoints(event.proc);
63 event.thing = LT_EV_NONE;
64 continue_process(event.proc->pid);
65 return &event;
66 }
Juan Cespedes35d70631998-03-15 14:05:40 +010067 if (opt_i) {
68 event.proc->instruction_pointer = get_instruction_pointer(pid);
Juan Cespedesf0fdae91998-03-11 00:03:00 +010069 }
Juan Cespedes35d70631998-03-15 14:05:40 +010070 switch(syscall_p(event.proc, status, &tmp)) {
71 case 1: event.thing = LT_EV_SYSCALL;
72 event.e_un.sysnum = tmp;
73 return &event;
74 case 2: event.thing = LT_EV_SYSRET;
75 event.e_un.sysnum = tmp;
76 return &event;
Juan Cespedes5e01f651998-03-08 22:31:44 +010077 }
78 if (WIFEXITED(status)) {
79 event.thing = LT_EV_EXIT;
80 event.e_un.ret_val = WEXITSTATUS(status);
81 return &event;
82 }
83 if (WIFSIGNALED(status)) {
84 event.thing = LT_EV_EXIT_SIGNAL;
85 event.e_un.signum = WTERMSIG(status);
86 return &event;
87 }
88 if (!WIFSTOPPED(status)) {
89 event.thing = LT_EV_UNKNOWN;
90 return &event;
91 }
92 if (WSTOPSIG(status) != SIGTRAP) {
93 event.thing = LT_EV_SIGNAL;
94 event.e_un.signum = WSTOPSIG(status);
95 return &event;
96 }
97 event.thing = LT_EV_BREAKPOINT;
Juan Cespedes35d70631998-03-15 14:05:40 +010098 if (!event.proc->instruction_pointer) {
99 event.proc->instruction_pointer = get_instruction_pointer(pid);
100 }
Juan Cespedes5e01f651998-03-08 22:31:44 +0100101 event.e_un.brk_addr = event.proc->instruction_pointer - DECR_PC_AFTER_BREAK;
102 return &event;
103}
104
Juan Cespedesd44c6b81998-09-25 14:48:42 +0200105static struct process * pid2proc(pid_t pid)
Juan Cespedes5e01f651998-03-08 22:31:44 +0100106{
107 struct process * tmp;
108
109 tmp = list_of_processes;
110 while(tmp) {
111 if (pid == tmp->pid) {
112 return tmp;
113 }
114 tmp = tmp->next;
115 }
116 return NULL;
117}
118