blob: 8b0fe1f28ffbece6c9afeb8f808605e4b59fb614 [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 }
40 event.proc->instruction_pointer = get_instruction_pointer(pid);
41 if (opt_d>1) {
42 output_line(0,"signal from pid %u", pid);
43 }
44 if (event.proc->breakpoints_enabled == -1) {
45 if (opt_d>0) {
46 output_line(0,"Enabling breakpoints for pid %u...", pid);
47 }
48 enable_all_breakpoints(event.proc);
49 event.thing = LT_EV_NONE;
50 continue_process(event.proc->pid);
51 return &event;
52 }
53 tmp = syscall_p(pid, status);
54 if (tmp>=0) {
55 event.thing = (event.proc->current_syscall >= 0) ? LT_EV_SYSRET : LT_EV_SYSCALL;
56 event.e_un.sysnum = tmp;
57 return &event;
58 }
59 if (WIFEXITED(status)) {
60 event.thing = LT_EV_EXIT;
61 event.e_un.ret_val = WEXITSTATUS(status);
62 return &event;
63 }
64 if (WIFSIGNALED(status)) {
65 event.thing = LT_EV_EXIT_SIGNAL;
66 event.e_un.signum = WTERMSIG(status);
67 return &event;
68 }
69 if (!WIFSTOPPED(status)) {
70 event.thing = LT_EV_UNKNOWN;
71 return &event;
72 }
73 if (WSTOPSIG(status) != SIGTRAP) {
74 event.thing = LT_EV_SIGNAL;
75 event.e_un.signum = WSTOPSIG(status);
76 return &event;
77 }
78 event.thing = LT_EV_BREAKPOINT;
79 event.e_un.brk_addr = event.proc->instruction_pointer - DECR_PC_AFTER_BREAK;
80 return &event;
81}
82
83static struct process * pid2proc(int pid)
84{
85 struct process * tmp;
86
87 tmp = list_of_processes;
88 while(tmp) {
89 if (pid == tmp->pid) {
90 return tmp;
91 }
92 tmp = tmp->next;
93 }
94 return NULL;
95}
96