1b725ae77Skettenis /* Low level Unix child interface to ttrace, for GDB when running under HP-UX.
2*11efff7fSkettenis
3*11efff7fSkettenis Copyright 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996,
4*11efff7fSkettenis 1998, 1999, 2000, 2001, 2003, 2004 Free Software Foundation, Inc.
5b725ae77Skettenis
6b725ae77Skettenis This file is part of GDB.
7b725ae77Skettenis
8b725ae77Skettenis This program is free software; you can redistribute it and/or modify
9b725ae77Skettenis it under the terms of the GNU General Public License as published by
10b725ae77Skettenis the Free Software Foundation; either version 2 of the License, or
11b725ae77Skettenis (at your option) any later version.
12b725ae77Skettenis
13b725ae77Skettenis This program is distributed in the hope that it will be useful,
14b725ae77Skettenis but WITHOUT ANY WARRANTY; without even the implied warranty of
15b725ae77Skettenis MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16b725ae77Skettenis GNU General Public License for more details.
17b725ae77Skettenis
18b725ae77Skettenis You should have received a copy of the GNU General Public License
19b725ae77Skettenis along with this program; if not, write to the Free Software
20b725ae77Skettenis Foundation, Inc., 59 Temple Place - Suite 330,
21b725ae77Skettenis Boston, MA 02111-1307, USA. */
22b725ae77Skettenis
23b725ae77Skettenis #include "defs.h"
24b725ae77Skettenis #include "frame.h"
25b725ae77Skettenis #include "inferior.h"
26b725ae77Skettenis #include "target.h"
27b725ae77Skettenis #include "gdb_string.h"
28b725ae77Skettenis #include "gdb_wait.h"
29b725ae77Skettenis #include "command.h"
30b725ae77Skettenis #include "gdbthread.h"
31*11efff7fSkettenis #include "infttrace.h"
32b725ae77Skettenis
33b725ae77Skettenis /* We need pstat functionality so that we can get the exec file
34b725ae77Skettenis for a process we attach to.
35b725ae77Skettenis
36b725ae77Skettenis According to HP, we should use the 64bit interfaces, so we
37b725ae77Skettenis define _PSTAT64 to achieve this. */
38b725ae77Skettenis #define _PSTAT64
39b725ae77Skettenis #include <sys/pstat.h>
40b725ae77Skettenis
41b725ae77Skettenis /* Some hackery to work around a use of the #define name NO_FLAGS
42b725ae77Skettenis * in both gdb and HPUX (bfd.h and /usr/include/machine/vmparam.h).
43b725ae77Skettenis */
44b725ae77Skettenis #ifdef NO_FLAGS
45b725ae77Skettenis #define INFTTRACE_TEMP_HACK NO_FLAGS
46b725ae77Skettenis #undef NO_FLAGS
47b725ae77Skettenis #endif
48b725ae77Skettenis
49b725ae77Skettenis #include <sys/param.h>
50b725ae77Skettenis #include <sys/dir.h>
51b725ae77Skettenis #include <signal.h>
52b725ae77Skettenis #include <sys/ioctl.h>
53b725ae77Skettenis
54b725ae77Skettenis #include <sys/ttrace.h>
55b725ae77Skettenis #include <sys/mman.h>
56b725ae77Skettenis
57b725ae77Skettenis #ifndef NO_PTRACE_H
58b725ae77Skettenis #ifdef PTRACE_IN_WRONG_PLACE
59b725ae77Skettenis #include <ptrace.h>
60b725ae77Skettenis #else
61b725ae77Skettenis #include <sys/ptrace.h>
62b725ae77Skettenis #endif
63b725ae77Skettenis #endif /* NO_PTRACE_H */
64b725ae77Skettenis
65b725ae77Skettenis /* Second half of the hackery above. Non-ANSI C, so
66b725ae77Skettenis * we can't use "#error", alas.
67b725ae77Skettenis */
68b725ae77Skettenis #ifdef NO_FLAGS
69b725ae77Skettenis #if (NO_FLAGS != INFTTRACE_TEMP_HACK )
70b725ae77Skettenis /* #error "Hackery to remove warning didn't work right" */
71b725ae77Skettenis #else
72b725ae77Skettenis /* Ok, new def'n of NO_FLAGS is same as old one; no action needed. */
73b725ae77Skettenis #endif
74b725ae77Skettenis #else
75b725ae77Skettenis /* #error "Didn't get expected re-definition of NO_FLAGS" */
76b725ae77Skettenis #define NO_FLAGS INFTTRACE_TEMP_HACK
77b725ae77Skettenis #endif
78b725ae77Skettenis
79b725ae77Skettenis #if !defined (PT_SETTRC)
80b725ae77Skettenis #define PT_SETTRC 0 /* Make process traceable by parent */
81b725ae77Skettenis #endif
82b725ae77Skettenis #if !defined (PT_READ_I)
83b725ae77Skettenis #define PT_READ_I 1 /* Read word from text space */
84b725ae77Skettenis #endif
85b725ae77Skettenis #if !defined (PT_READ_D)
86b725ae77Skettenis #define PT_READ_D 2 /* Read word from data space */
87b725ae77Skettenis #endif
88b725ae77Skettenis #if !defined (PT_READ_U)
89b725ae77Skettenis #define PT_READ_U 3 /* Read word from kernel user struct */
90b725ae77Skettenis #endif
91b725ae77Skettenis #if !defined (PT_WRITE_I)
92b725ae77Skettenis #define PT_WRITE_I 4 /* Write word to text space */
93b725ae77Skettenis #endif
94b725ae77Skettenis #if !defined (PT_WRITE_D)
95b725ae77Skettenis #define PT_WRITE_D 5 /* Write word to data space */
96b725ae77Skettenis #endif
97b725ae77Skettenis #if !defined (PT_WRITE_U)
98b725ae77Skettenis #define PT_WRITE_U 6 /* Write word to kernel user struct */
99b725ae77Skettenis #endif
100b725ae77Skettenis #if !defined (PT_CONTINUE)
101b725ae77Skettenis #define PT_CONTINUE 7 /* Continue after signal */
102b725ae77Skettenis #endif
103b725ae77Skettenis #if !defined (PT_STEP)
104b725ae77Skettenis #define PT_STEP 9 /* Set flag for single stepping */
105b725ae77Skettenis #endif
106b725ae77Skettenis #if !defined (PT_KILL)
107b725ae77Skettenis #define PT_KILL 8 /* Send child a SIGKILL signal */
108b725ae77Skettenis #endif
109b725ae77Skettenis
110b725ae77Skettenis #ifndef PT_ATTACH
111b725ae77Skettenis #define PT_ATTACH PTRACE_ATTACH
112b725ae77Skettenis #endif
113b725ae77Skettenis #ifndef PT_DETACH
114b725ae77Skettenis #define PT_DETACH PTRACE_DETACH
115b725ae77Skettenis #endif
116b725ae77Skettenis
117b725ae77Skettenis #include "gdbcore.h"
118*11efff7fSkettenis #ifdef HAVE_SYS_FILE_H
119b725ae77Skettenis #include <sys/file.h>
120b725ae77Skettenis #endif
121b725ae77Skettenis
122b725ae77Skettenis /* This semaphore is used to coordinate the child and parent processes
123b725ae77Skettenis after a fork(), and before an exec() by the child. See parent_attach_all
124b725ae77Skettenis for details.
125b725ae77Skettenis */
126b725ae77Skettenis typedef struct
127b725ae77Skettenis {
128b725ae77Skettenis int parent_channel[2]; /* Parent "talks" to [1], child "listens" to [0] */
129b725ae77Skettenis int child_channel[2]; /* Child "talks" to [1], parent "listens" to [0] */
130b725ae77Skettenis }
131b725ae77Skettenis startup_semaphore_t;
132b725ae77Skettenis
133b725ae77Skettenis #define SEM_TALK (1)
134b725ae77Skettenis #define SEM_LISTEN (0)
135b725ae77Skettenis
136b725ae77Skettenis static startup_semaphore_t startup_semaphore;
137b725ae77Skettenis
138b725ae77Skettenis /* See can_touch_threads_of_process for details. */
139b725ae77Skettenis static int vforking_child_pid = 0;
140b725ae77Skettenis static int vfork_in_flight = 0;
141b725ae77Skettenis
142b725ae77Skettenis /* 1 if ok as results of a ttrace or ttrace_wait call, 0 otherwise.
143b725ae77Skettenis */
144b725ae77Skettenis #define TT_OK( _status, _errno ) \
145b725ae77Skettenis (((_status) == 1) && ((_errno) == 0))
146b725ae77Skettenis
147b725ae77Skettenis #define TTRACE_ARG_TYPE uint64_t
148b725ae77Skettenis
149b725ae77Skettenis /* When supplied as the "addr" operand, ttrace interprets this
150b725ae77Skettenis to mean, "from the current address".
151b725ae77Skettenis */
152b725ae77Skettenis #define TT_USE_CURRENT_PC ((TTRACE_ARG_TYPE) TT_NOPC)
153b725ae77Skettenis
154b725ae77Skettenis /* When supplied as the "addr", "data" or "addr2" operand for most
155b725ae77Skettenis requests, ttrace interprets this to mean, "pay no heed to this
156b725ae77Skettenis argument".
157b725ae77Skettenis */
158b725ae77Skettenis #define TT_NIL ((TTRACE_ARG_TYPE) TT_NULLARG)
159b725ae77Skettenis
160b725ae77Skettenis /* This is capable of holding the value of a 32-bit register. The
161b725ae77Skettenis value is always left-aligned in the buffer; i.e., [0] contains
162b725ae77Skettenis the most-significant byte of the register's value, and [sizeof(reg)]
163b725ae77Skettenis contains the least-significant value.
164b725ae77Skettenis
165b725ae77Skettenis ??rehrauer: Yes, this assumes that an int is 32-bits on HP-UX, and
166b725ae77Skettenis that registers are 32-bits on HP-UX. The latter assumption changes
167b725ae77Skettenis with PA2.0.
168b725ae77Skettenis */
169b725ae77Skettenis typedef int register_value_t;
170b725ae77Skettenis
171b725ae77Skettenis /********************************************************************
172b725ae77Skettenis
173b725ae77Skettenis How this works:
174b725ae77Skettenis
175b725ae77Skettenis 1. Thread numbers
176b725ae77Skettenis
177b725ae77Skettenis The rest of GDB sees threads as being things with different
178b725ae77Skettenis "pid" (process id) values. See "thread.c" for details. The
179b725ae77Skettenis separate threads will be seen and reacted to if infttrace passes
180b725ae77Skettenis back different pid values (for _events_). See wait_for_inferior
181b725ae77Skettenis in inftarg.c.
182b725ae77Skettenis
183b725ae77Skettenis So infttrace is going to use thread ids externally, pretending
184b725ae77Skettenis they are process ids, and keep track internally so that it can
185b725ae77Skettenis use the real process id (and thread id) when calling ttrace.
186b725ae77Skettenis
187b725ae77Skettenis The data structure that supports this is a linked list of the
188b725ae77Skettenis current threads. Since at some date infttrace will have to
189b725ae77Skettenis deal with multiple processes, each list element records its
190b725ae77Skettenis corresponding pid, rather than having a single global.
191b725ae77Skettenis
192b725ae77Skettenis Note that the list is only approximately current; that's ok, as
193b725ae77Skettenis it's up to date when we need it (we hope!). Also, it can contain
194b725ae77Skettenis dead threads, as there's no harm if it does.
195b725ae77Skettenis
196b725ae77Skettenis The approach taken here is to bury the translation from external
197b725ae77Skettenis to internal inside "call_ttrace" and a few other places.
198b725ae77Skettenis
199b725ae77Skettenis There are some wrinkles:
200b725ae77Skettenis
201b725ae77Skettenis o When GDB forks itself to create the debug target process,
202b725ae77Skettenis there's only a pid of 0 around in the child, so the
203b725ae77Skettenis TT_PROC_SETTRC operation uses a more direct call to ttrace;
204b725ae77Skettenis Similiarly, the initial setting of the event mask happens
205b725ae77Skettenis early as well, and so is also special-cased, and an attach
206b725ae77Skettenis uses a real pid;
207b725ae77Skettenis
208b725ae77Skettenis o We define an unthreaded application as having a "pseudo"
209b725ae77Skettenis thread;
210b725ae77Skettenis
211b725ae77Skettenis o To keep from confusing the rest of GDB, we don't switch
212b725ae77Skettenis the PID for the pseudo thread to a TID. A table will help:
213b725ae77Skettenis
214b725ae77Skettenis Rest of GDB sees these PIDs: pid tid1 tid2 tid3 ...
215b725ae77Skettenis
216b725ae77Skettenis Our thread list stores: pid pid pid pid ...
217b725ae77Skettenis tid0 tid1 tid2 tid3
218b725ae77Skettenis
219b725ae77Skettenis Ttrace sees these TIDS: tid0 tid1 tid2 tid3 ...
220b725ae77Skettenis
221b725ae77Skettenis Both pid and tid0 will map to tid0, as there are infttrace.c-internal
222b725ae77Skettenis calls to ttrace using tid0.
223b725ae77Skettenis
224b725ae77Skettenis 2. Step and Continue
225b725ae77Skettenis
226b725ae77Skettenis Since we're implementing the "stop the world" model, sub-model
227b725ae77Skettenis "other threads run during step", we have some stuff to do:
228b725ae77Skettenis
229b725ae77Skettenis o User steps require continuing all threads other than the
230b725ae77Skettenis one the user is stepping;
231b725ae77Skettenis
232b725ae77Skettenis o Internal debugger steps (such as over a breakpoint or watchpoint,
233b725ae77Skettenis but not out of a library load thunk) require stepping only
234b725ae77Skettenis the selected thread; this means that we have to report the
235b725ae77Skettenis step finish on that thread, which can lead to complications;
236b725ae77Skettenis
237b725ae77Skettenis o When a thread is created, it is created running, rather
238b725ae77Skettenis than stopped--so we have to stop it.
239b725ae77Skettenis
240b725ae77Skettenis The OS doesn't guarantee the stopped thread list will be stable,
241b725ae77Skettenis no does it guarantee where on the stopped thread list a thread
242b725ae77Skettenis that is single-stepped will wind up: it's possible that it will
243b725ae77Skettenis be off the list for a while, it's possible the step will complete
244b725ae77Skettenis and it will be re-posted to the end...
245b725ae77Skettenis
246b725ae77Skettenis This means we have to scan the stopped thread list, build up
247b725ae77Skettenis a work-list, and then run down the work list; we can't do the
248b725ae77Skettenis step/continue during the scan.
249b725ae77Skettenis
250b725ae77Skettenis 3. Buffering events
251b725ae77Skettenis
252b725ae77Skettenis Then there's the issue of waiting for an event. We do this by
253b725ae77Skettenis noticing how many events are reported at the end of each wait.
254b725ae77Skettenis From then on, we "fake" all resumes and steps, returning instantly,
255b725ae77Skettenis and don't do another wait. Once all pending events are reported,
256b725ae77Skettenis we can really resume again.
257b725ae77Skettenis
258b725ae77Skettenis To keep this hidden, all the routines which know about tids and
259b725ae77Skettenis pids or real events and simulated ones are static (file-local).
260b725ae77Skettenis
261b725ae77Skettenis This code can make lots of calls to ttrace, in particular it
262b725ae77Skettenis can spin down the list of thread states more than once. If this
263b725ae77Skettenis becomes a performance hit, the spin could be done once and the
264b725ae77Skettenis various "tsp" blocks saved, keeping all later spins in this
265b725ae77Skettenis process.
266b725ae77Skettenis
267b725ae77Skettenis The O/S doesn't promise to keep the list straight, and so we must
268b725ae77Skettenis re-scan a lot. By observation, it looks like a single-step/wait
269b725ae77Skettenis puts the stepped thread at the end of the list but doesn't change
270b725ae77Skettenis it otherwise.
271b725ae77Skettenis
272b725ae77Skettenis ****************************************************************
273b725ae77Skettenis */
274b725ae77Skettenis
275b725ae77Skettenis /* Uncomment these to turn on various debugging output */
276b725ae77Skettenis /* #define THREAD_DEBUG */
277b725ae77Skettenis /* #define WAIT_BUFFER_DEBUG */
278b725ae77Skettenis /* #define PARANOIA */
279b725ae77Skettenis
280b725ae77Skettenis
281b725ae77Skettenis #define INFTTRACE_ALL_THREADS (-1)
282b725ae77Skettenis #define INFTTRACE_STEP (1)
283b725ae77Skettenis #define INFTTRACE_CONTINUE (0)
284b725ae77Skettenis
285b725ae77Skettenis /* FIX: this is used in inftarg.c/child_wait, in a hack.
286b725ae77Skettenis */
287b725ae77Skettenis extern int not_same_real_pid;
288b725ae77Skettenis
289b725ae77Skettenis /* This is used to count buffered events.
290b725ae77Skettenis */
291b725ae77Skettenis static unsigned int more_events_left = 0;
292b725ae77Skettenis
293b725ae77Skettenis /* Process state.
294b725ae77Skettenis */
295b725ae77Skettenis typedef enum process_state_enum
296b725ae77Skettenis {
297b725ae77Skettenis STOPPED,
298b725ae77Skettenis FAKE_STEPPING,
299b725ae77Skettenis FAKE_CONTINUE, /* For later use */
300b725ae77Skettenis RUNNING,
301b725ae77Skettenis FORKING,
302b725ae77Skettenis VFORKING
303b725ae77Skettenis }
304b725ae77Skettenis process_state_t;
305b725ae77Skettenis
306b725ae77Skettenis static process_state_t process_state = STOPPED;
307b725ae77Skettenis
308b725ae77Skettenis /* User-specified stepping modality.
309b725ae77Skettenis */
310b725ae77Skettenis typedef enum stepping_mode_enum
311b725ae77Skettenis {
312b725ae77Skettenis DO_DEFAULT, /* ...which is a continue! */
313b725ae77Skettenis DO_STEP,
314b725ae77Skettenis DO_CONTINUE
315b725ae77Skettenis }
316b725ae77Skettenis stepping_mode_t;
317b725ae77Skettenis
318b725ae77Skettenis /* Action to take on an attach, depends on
319b725ae77Skettenis * what kind (user command, fork, vfork).
320b725ae77Skettenis *
321b725ae77Skettenis * At the moment, this is either:
322b725ae77Skettenis *
323b725ae77Skettenis * o continue with a SIGTRAP signal, or
324b725ae77Skettenis *
325b725ae77Skettenis * o leave stopped.
326b725ae77Skettenis */
327b725ae77Skettenis typedef enum attach_continue_enum
328b725ae77Skettenis {
329b725ae77Skettenis DO_ATTACH_CONTINUE,
330b725ae77Skettenis DONT_ATTACH_CONTINUE
331b725ae77Skettenis }
332b725ae77Skettenis attach_continue_t;
333b725ae77Skettenis
334b725ae77Skettenis /* This flag is true if we are doing a step-over-bpt
335b725ae77Skettenis * with buffered events. We will have to be sure to
336b725ae77Skettenis * report the right thread, as otherwise the spaghetti
337b725ae77Skettenis * code in "infrun.c/wait_for_inferior" will get
338b725ae77Skettenis * confused.
339b725ae77Skettenis */
340b725ae77Skettenis static int doing_fake_step = 0;
341b725ae77Skettenis static lwpid_t fake_step_tid = 0;
342b725ae77Skettenis
343b725ae77Skettenis
344b725ae77Skettenis /****************************************************
345b725ae77Skettenis * Thread information structure routines and types. *
346b725ae77Skettenis ****************************************************
347b725ae77Skettenis */
348b725ae77Skettenis typedef
349b725ae77Skettenis struct thread_info_struct
350b725ae77Skettenis {
351b725ae77Skettenis int am_pseudo; /* This is a pseudo-thread for the process. */
352b725ae77Skettenis int pid; /* Process ID */
353b725ae77Skettenis lwpid_t tid; /* Thread ID */
354b725ae77Skettenis int handled; /* 1 if a buffered event was handled. */
355b725ae77Skettenis int seen; /* 1 if this thread was seen on a traverse. */
356b725ae77Skettenis int terminated; /* 1 if thread has terminated. */
357b725ae77Skettenis int have_signal; /* 1 if signal to be sent */
358b725ae77Skettenis enum target_signal signal_value; /* Signal to send */
359b725ae77Skettenis int have_start; /* 1 if alternate starting address */
360b725ae77Skettenis stepping_mode_t stepping_mode; /* Whether to step or continue */
361b725ae77Skettenis CORE_ADDR start; /* Where to start */
362b725ae77Skettenis int have_state; /* 1 if the event state has been set */
363b725ae77Skettenis ttstate_t last_stop_state; /* The most recently-waited event for this thread. */
364b725ae77Skettenis struct thread_info_struct
365b725ae77Skettenis *next; /* All threads are linked via this field. */
366b725ae77Skettenis struct thread_info_struct
367b725ae77Skettenis *next_pseudo; /* All pseudo-threads are linked via this field. */
368b725ae77Skettenis }
369b725ae77Skettenis thread_info;
370b725ae77Skettenis
371b725ae77Skettenis typedef
372b725ae77Skettenis struct thread_info_header_struct
373b725ae77Skettenis {
374b725ae77Skettenis int count;
375b725ae77Skettenis thread_info *head;
376b725ae77Skettenis thread_info *head_pseudo;
377b725ae77Skettenis
378b725ae77Skettenis }
379b725ae77Skettenis thread_info_header;
380b725ae77Skettenis
381b725ae77Skettenis static thread_info_header thread_head =
382b725ae77Skettenis {0, NULL, NULL};
383b725ae77Skettenis static thread_info_header deleted_threads =
384b725ae77Skettenis {0, NULL, NULL};
385b725ae77Skettenis
386b725ae77Skettenis static ptid_t saved_real_ptid;
387b725ae77Skettenis
388b725ae77Skettenis
389b725ae77Skettenis /*************************************************
390b725ae77Skettenis * Debugging support functions *
391b725ae77Skettenis *************************************************
392b725ae77Skettenis */
393b725ae77Skettenis CORE_ADDR
get_raw_pc(lwpid_t ttid)394b725ae77Skettenis get_raw_pc (lwpid_t ttid)
395b725ae77Skettenis {
396b725ae77Skettenis unsigned long pc_val;
397b725ae77Skettenis int offset;
398b725ae77Skettenis int res;
399b725ae77Skettenis
400b725ae77Skettenis offset = register_addr (PC_REGNUM, U_REGS_OFFSET);
401b725ae77Skettenis res = read_from_register_save_state (
402b725ae77Skettenis ttid,
403b725ae77Skettenis (TTRACE_ARG_TYPE) offset,
404b725ae77Skettenis (char *) &pc_val,
405b725ae77Skettenis sizeof (pc_val));
406b725ae77Skettenis if (res <= 0)
407b725ae77Skettenis {
408b725ae77Skettenis return (CORE_ADDR) pc_val;
409b725ae77Skettenis }
410b725ae77Skettenis else
411b725ae77Skettenis {
412b725ae77Skettenis return (CORE_ADDR) 0;
413b725ae77Skettenis }
414b725ae77Skettenis }
415b725ae77Skettenis
416b725ae77Skettenis static char *
get_printable_name_of_stepping_mode(stepping_mode_t mode)417b725ae77Skettenis get_printable_name_of_stepping_mode (stepping_mode_t mode)
418b725ae77Skettenis {
419b725ae77Skettenis switch (mode)
420b725ae77Skettenis {
421b725ae77Skettenis case DO_DEFAULT:
422b725ae77Skettenis return "DO_DEFAULT";
423b725ae77Skettenis case DO_STEP:
424b725ae77Skettenis return "DO_STEP";
425b725ae77Skettenis case DO_CONTINUE:
426b725ae77Skettenis return "DO_CONTINUE";
427b725ae77Skettenis default:
428b725ae77Skettenis return "?unknown mode?";
429b725ae77Skettenis }
430b725ae77Skettenis }
431b725ae77Skettenis
432b725ae77Skettenis /* This function returns a pointer to a string describing the
433b725ae77Skettenis * ttrace event being reported.
434b725ae77Skettenis */
435b725ae77Skettenis char *
get_printable_name_of_ttrace_event(ttevents_t event)436b725ae77Skettenis get_printable_name_of_ttrace_event (ttevents_t event)
437b725ae77Skettenis {
438b725ae77Skettenis /* This enumeration is "gappy", so don't use a table. */
439b725ae77Skettenis switch (event)
440b725ae77Skettenis {
441b725ae77Skettenis
442b725ae77Skettenis case TTEVT_NONE:
443b725ae77Skettenis return "TTEVT_NONE";
444b725ae77Skettenis case TTEVT_SIGNAL:
445b725ae77Skettenis return "TTEVT_SIGNAL";
446b725ae77Skettenis case TTEVT_FORK:
447b725ae77Skettenis return "TTEVT_FORK";
448b725ae77Skettenis case TTEVT_EXEC:
449b725ae77Skettenis return "TTEVT_EXEC";
450b725ae77Skettenis case TTEVT_EXIT:
451b725ae77Skettenis return "TTEVT_EXIT";
452b725ae77Skettenis case TTEVT_VFORK:
453b725ae77Skettenis return "TTEVT_VFORK";
454b725ae77Skettenis case TTEVT_SYSCALL_RETURN:
455b725ae77Skettenis return "TTEVT_SYSCALL_RETURN";
456b725ae77Skettenis case TTEVT_LWP_CREATE:
457b725ae77Skettenis return "TTEVT_LWP_CREATE";
458b725ae77Skettenis case TTEVT_LWP_TERMINATE:
459b725ae77Skettenis return "TTEVT_LWP_TERMINATE";
460b725ae77Skettenis case TTEVT_LWP_EXIT:
461b725ae77Skettenis return "TTEVT_LWP_EXIT";
462b725ae77Skettenis case TTEVT_LWP_ABORT_SYSCALL:
463b725ae77Skettenis return "TTEVT_LWP_ABORT_SYSCALL";
464b725ae77Skettenis case TTEVT_SYSCALL_ENTRY:
465b725ae77Skettenis return "TTEVT_SYSCALL_ENTRY";
466b725ae77Skettenis case TTEVT_SYSCALL_RESTART:
467b725ae77Skettenis return "TTEVT_SYSCALL_RESTART";
468b725ae77Skettenis default:
469b725ae77Skettenis return "?new event?";
470b725ae77Skettenis }
471b725ae77Skettenis }
472b725ae77Skettenis
473b725ae77Skettenis
474b725ae77Skettenis /* This function translates the ttrace request enumeration into
475b725ae77Skettenis * a character string that is its printable (aka "human readable")
476b725ae77Skettenis * name.
477b725ae77Skettenis */
478b725ae77Skettenis char *
get_printable_name_of_ttrace_request(ttreq_t request)479b725ae77Skettenis get_printable_name_of_ttrace_request (ttreq_t request)
480b725ae77Skettenis {
481b725ae77Skettenis if (!IS_TTRACE_REQ (request))
482b725ae77Skettenis return "?bad req?";
483b725ae77Skettenis
484b725ae77Skettenis /* This enumeration is "gappy", so don't use a table. */
485b725ae77Skettenis switch (request)
486b725ae77Skettenis {
487b725ae77Skettenis case TT_PROC_SETTRC:
488b725ae77Skettenis return "TT_PROC_SETTRC";
489b725ae77Skettenis case TT_PROC_ATTACH:
490b725ae77Skettenis return "TT_PROC_ATTACH";
491b725ae77Skettenis case TT_PROC_DETACH:
492b725ae77Skettenis return "TT_PROC_DETACH";
493b725ae77Skettenis case TT_PROC_RDTEXT:
494b725ae77Skettenis return "TT_PROC_RDTEXT";
495b725ae77Skettenis case TT_PROC_WRTEXT:
496b725ae77Skettenis return "TT_PROC_WRTEXT";
497b725ae77Skettenis case TT_PROC_RDDATA:
498b725ae77Skettenis return "TT_PROC_RDDATA";
499b725ae77Skettenis case TT_PROC_WRDATA:
500b725ae77Skettenis return "TT_PROC_WRDATA";
501b725ae77Skettenis case TT_PROC_STOP:
502b725ae77Skettenis return "TT_PROC_STOP";
503b725ae77Skettenis case TT_PROC_CONTINUE:
504b725ae77Skettenis return "TT_PROC_CONTINUE";
505b725ae77Skettenis case TT_PROC_GET_PATHNAME:
506b725ae77Skettenis return "TT_PROC_GET_PATHNAME";
507b725ae77Skettenis case TT_PROC_GET_EVENT_MASK:
508b725ae77Skettenis return "TT_PROC_GET_EVENT_MASK";
509b725ae77Skettenis case TT_PROC_SET_EVENT_MASK:
510b725ae77Skettenis return "TT_PROC_SET_EVENT_MASK";
511b725ae77Skettenis case TT_PROC_GET_FIRST_LWP_STATE:
512b725ae77Skettenis return "TT_PROC_GET_FIRST_LWP_STATE";
513b725ae77Skettenis case TT_PROC_GET_NEXT_LWP_STATE:
514b725ae77Skettenis return "TT_PROC_GET_NEXT_LWP_STATE";
515b725ae77Skettenis case TT_PROC_EXIT:
516b725ae77Skettenis return "TT_PROC_EXIT";
517b725ae77Skettenis case TT_PROC_GET_MPROTECT:
518b725ae77Skettenis return "TT_PROC_GET_MPROTECT";
519b725ae77Skettenis case TT_PROC_SET_MPROTECT:
520b725ae77Skettenis return "TT_PROC_SET_MPROTECT";
521b725ae77Skettenis case TT_PROC_SET_SCBM:
522b725ae77Skettenis return "TT_PROC_SET_SCBM";
523b725ae77Skettenis case TT_LWP_STOP:
524b725ae77Skettenis return "TT_LWP_STOP";
525b725ae77Skettenis case TT_LWP_CONTINUE:
526b725ae77Skettenis return "TT_LWP_CONTINUE";
527b725ae77Skettenis case TT_LWP_SINGLE:
528b725ae77Skettenis return "TT_LWP_SINGLE";
529b725ae77Skettenis case TT_LWP_RUREGS:
530b725ae77Skettenis return "TT_LWP_RUREGS";
531b725ae77Skettenis case TT_LWP_WUREGS:
532b725ae77Skettenis return "TT_LWP_WUREGS";
533b725ae77Skettenis case TT_LWP_GET_EVENT_MASK:
534b725ae77Skettenis return "TT_LWP_GET_EVENT_MASK";
535b725ae77Skettenis case TT_LWP_SET_EVENT_MASK:
536b725ae77Skettenis return "TT_LWP_SET_EVENT_MASK";
537b725ae77Skettenis case TT_LWP_GET_STATE:
538b725ae77Skettenis return "TT_LWP_GET_STATE";
539b725ae77Skettenis default:
540b725ae77Skettenis return "?new req?";
541b725ae77Skettenis }
542b725ae77Skettenis }
543b725ae77Skettenis
544b725ae77Skettenis
545b725ae77Skettenis /* This function translates the process state enumeration into
546b725ae77Skettenis * a character string that is its printable (aka "human readable")
547b725ae77Skettenis * name.
548b725ae77Skettenis */
549b725ae77Skettenis static char *
get_printable_name_of_process_state(process_state_t process_state)550b725ae77Skettenis get_printable_name_of_process_state (process_state_t process_state)
551b725ae77Skettenis {
552b725ae77Skettenis switch (process_state)
553b725ae77Skettenis {
554b725ae77Skettenis case STOPPED:
555b725ae77Skettenis return "STOPPED";
556b725ae77Skettenis case FAKE_STEPPING:
557b725ae77Skettenis return "FAKE_STEPPING";
558b725ae77Skettenis case RUNNING:
559b725ae77Skettenis return "RUNNING";
560b725ae77Skettenis case FORKING:
561b725ae77Skettenis return "FORKING";
562b725ae77Skettenis case VFORKING:
563b725ae77Skettenis return "VFORKING";
564b725ae77Skettenis default:
565b725ae77Skettenis return "?some unknown state?";
566b725ae77Skettenis }
567b725ae77Skettenis }
568b725ae77Skettenis
569b725ae77Skettenis /* Set a ttrace thread state to a safe, initial state.
570b725ae77Skettenis */
571b725ae77Skettenis static void
clear_ttstate_t(ttstate_t * tts)572b725ae77Skettenis clear_ttstate_t (ttstate_t *tts)
573b725ae77Skettenis {
574b725ae77Skettenis tts->tts_pid = 0;
575b725ae77Skettenis tts->tts_lwpid = 0;
576b725ae77Skettenis tts->tts_user_tid = 0;
577b725ae77Skettenis tts->tts_event = TTEVT_NONE;
578b725ae77Skettenis }
579b725ae77Skettenis
580b725ae77Skettenis /* Copy ttrace thread state TTS_FROM into TTS_TO.
581b725ae77Skettenis */
582b725ae77Skettenis static void
copy_ttstate_t(ttstate_t * tts_to,ttstate_t * tts_from)583b725ae77Skettenis copy_ttstate_t (ttstate_t *tts_to, ttstate_t *tts_from)
584b725ae77Skettenis {
585b725ae77Skettenis memcpy ((char *) tts_to, (char *) tts_from, sizeof (*tts_to));
586b725ae77Skettenis }
587b725ae77Skettenis
588b725ae77Skettenis /* Are there any live threads we know about?
589b725ae77Skettenis */
590b725ae77Skettenis static int
any_thread_records(void)591b725ae77Skettenis any_thread_records (void)
592b725ae77Skettenis {
593b725ae77Skettenis return (thread_head.count > 0);
594b725ae77Skettenis }
595b725ae77Skettenis
596b725ae77Skettenis /* Create, fill in and link in a thread descriptor.
597b725ae77Skettenis */
598b725ae77Skettenis static thread_info *
create_thread_info(int pid,lwpid_t tid)599b725ae77Skettenis create_thread_info (int pid, lwpid_t tid)
600b725ae77Skettenis {
601b725ae77Skettenis thread_info *new_p;
602b725ae77Skettenis thread_info *p;
603b725ae77Skettenis int thread_count_of_pid;
604b725ae77Skettenis
605b725ae77Skettenis new_p = xmalloc (sizeof (thread_info));
606b725ae77Skettenis new_p->pid = pid;
607b725ae77Skettenis new_p->tid = tid;
608b725ae77Skettenis new_p->have_signal = 0;
609b725ae77Skettenis new_p->have_start = 0;
610b725ae77Skettenis new_p->have_state = 0;
611b725ae77Skettenis clear_ttstate_t (&new_p->last_stop_state);
612b725ae77Skettenis new_p->am_pseudo = 0;
613b725ae77Skettenis new_p->handled = 0;
614b725ae77Skettenis new_p->seen = 0;
615b725ae77Skettenis new_p->terminated = 0;
616b725ae77Skettenis new_p->next = NULL;
617b725ae77Skettenis new_p->next_pseudo = NULL;
618b725ae77Skettenis new_p->stepping_mode = DO_DEFAULT;
619b725ae77Skettenis
620b725ae77Skettenis if (0 == thread_head.count)
621b725ae77Skettenis {
622b725ae77Skettenis #ifdef THREAD_DEBUG
623b725ae77Skettenis if (debug_on)
624b725ae77Skettenis printf ("First thread, pid %d tid %d!\n", pid, tid);
625b725ae77Skettenis #endif
626b725ae77Skettenis saved_real_ptid = inferior_ptid;
627b725ae77Skettenis }
628b725ae77Skettenis else
629b725ae77Skettenis {
630b725ae77Skettenis #ifdef THREAD_DEBUG
631b725ae77Skettenis if (debug_on)
632b725ae77Skettenis printf ("Subsequent thread, pid %d tid %d\n", pid, tid);
633b725ae77Skettenis #endif
634b725ae77Skettenis }
635b725ae77Skettenis
636b725ae77Skettenis /* Another day, another thread...
637b725ae77Skettenis */
638b725ae77Skettenis thread_head.count++;
639b725ae77Skettenis
640b725ae77Skettenis /* The new thread always goes at the head of the list.
641b725ae77Skettenis */
642b725ae77Skettenis new_p->next = thread_head.head;
643b725ae77Skettenis thread_head.head = new_p;
644b725ae77Skettenis
645b725ae77Skettenis /* Is this the "pseudo" thread of a process? It is if there's
646b725ae77Skettenis * no other thread for this process on the list. (Note that this
647b725ae77Skettenis * accomodates multiple processes, such as we see even for simple
648b725ae77Skettenis * cases like forking "non-threaded" programs.)
649b725ae77Skettenis */
650b725ae77Skettenis p = thread_head.head;
651b725ae77Skettenis thread_count_of_pid = 0;
652b725ae77Skettenis while (p)
653b725ae77Skettenis {
654b725ae77Skettenis if (p->pid == new_p->pid)
655b725ae77Skettenis thread_count_of_pid++;
656b725ae77Skettenis p = p->next;
657b725ae77Skettenis }
658b725ae77Skettenis
659b725ae77Skettenis /* Did we see any other threads for this pid? (Recall that we just
660b725ae77Skettenis * added this thread to the list...)
661b725ae77Skettenis */
662b725ae77Skettenis if (thread_count_of_pid == 1)
663b725ae77Skettenis {
664b725ae77Skettenis new_p->am_pseudo = 1;
665b725ae77Skettenis new_p->next_pseudo = thread_head.head_pseudo;
666b725ae77Skettenis thread_head.head_pseudo = new_p;
667b725ae77Skettenis }
668b725ae77Skettenis
669b725ae77Skettenis return new_p;
670b725ae77Skettenis }
671b725ae77Skettenis
672b725ae77Skettenis /* Get rid of our thread info.
673b725ae77Skettenis */
674b725ae77Skettenis static void
clear_thread_info(void)675b725ae77Skettenis clear_thread_info (void)
676b725ae77Skettenis {
677b725ae77Skettenis thread_info *p;
678b725ae77Skettenis thread_info *q;
679b725ae77Skettenis
680b725ae77Skettenis #ifdef THREAD_DEBUG
681b725ae77Skettenis if (debug_on)
682b725ae77Skettenis printf ("Clearing all thread info\n");
683b725ae77Skettenis #endif
684b725ae77Skettenis
685b725ae77Skettenis p = thread_head.head;
686b725ae77Skettenis while (p)
687b725ae77Skettenis {
688b725ae77Skettenis q = p;
689b725ae77Skettenis p = p->next;
690b725ae77Skettenis xfree (q);
691b725ae77Skettenis }
692b725ae77Skettenis
693b725ae77Skettenis thread_head.head = NULL;
694b725ae77Skettenis thread_head.head_pseudo = NULL;
695b725ae77Skettenis thread_head.count = 0;
696b725ae77Skettenis
697b725ae77Skettenis p = deleted_threads.head;
698b725ae77Skettenis while (p)
699b725ae77Skettenis {
700b725ae77Skettenis q = p;
701b725ae77Skettenis p = p->next;
702b725ae77Skettenis xfree (q);
703b725ae77Skettenis }
704b725ae77Skettenis
705b725ae77Skettenis deleted_threads.head = NULL;
706b725ae77Skettenis deleted_threads.head_pseudo = NULL;
707b725ae77Skettenis deleted_threads.count = 0;
708b725ae77Skettenis
709b725ae77Skettenis /* No threads, so can't have pending events.
710b725ae77Skettenis */
711b725ae77Skettenis more_events_left = 0;
712b725ae77Skettenis }
713b725ae77Skettenis
714b725ae77Skettenis /* Given a tid, find the thread block for it.
715b725ae77Skettenis */
716b725ae77Skettenis static thread_info *
find_thread_info(lwpid_t tid)717b725ae77Skettenis find_thread_info (lwpid_t tid)
718b725ae77Skettenis {
719b725ae77Skettenis thread_info *p;
720b725ae77Skettenis
721b725ae77Skettenis for (p = thread_head.head; p; p = p->next)
722b725ae77Skettenis {
723b725ae77Skettenis if (p->tid == tid)
724b725ae77Skettenis {
725b725ae77Skettenis return p;
726b725ae77Skettenis }
727b725ae77Skettenis }
728b725ae77Skettenis
729b725ae77Skettenis for (p = deleted_threads.head; p; p = p->next)
730b725ae77Skettenis {
731b725ae77Skettenis if (p->tid == tid)
732b725ae77Skettenis {
733b725ae77Skettenis return p;
734b725ae77Skettenis }
735b725ae77Skettenis }
736b725ae77Skettenis
737b725ae77Skettenis return NULL;
738b725ae77Skettenis }
739b725ae77Skettenis
740b725ae77Skettenis /* For any but the pseudo thread, this maps to the
741b725ae77Skettenis * thread ID. For the pseudo thread, if you pass either
742b725ae77Skettenis * the thread id or the PID, you get the pseudo thread ID.
743b725ae77Skettenis *
744b725ae77Skettenis * We have to be prepared for core gdb to ask about
745b725ae77Skettenis * deleted threads. We do the map, but we don't like it.
746b725ae77Skettenis */
747b725ae77Skettenis static lwpid_t
map_from_gdb_tid(lwpid_t gdb_tid)748b725ae77Skettenis map_from_gdb_tid (lwpid_t gdb_tid)
749b725ae77Skettenis {
750b725ae77Skettenis thread_info *p;
751b725ae77Skettenis
752b725ae77Skettenis /* First assume gdb_tid really is a tid, and try to find a
753b725ae77Skettenis * matching entry on the threads list.
754b725ae77Skettenis */
755b725ae77Skettenis for (p = thread_head.head; p; p = p->next)
756b725ae77Skettenis {
757b725ae77Skettenis if (p->tid == gdb_tid)
758b725ae77Skettenis return gdb_tid;
759b725ae77Skettenis }
760b725ae77Skettenis
761b725ae77Skettenis /* It doesn't appear to be a tid; perhaps it's really a pid?
762b725ae77Skettenis * Try to find a "pseudo" thread entry on the threads list.
763b725ae77Skettenis */
764b725ae77Skettenis for (p = thread_head.head_pseudo; p != NULL; p = p->next_pseudo)
765b725ae77Skettenis {
766b725ae77Skettenis if (p->pid == gdb_tid)
767b725ae77Skettenis return p->tid;
768b725ae77Skettenis }
769b725ae77Skettenis
770b725ae77Skettenis /* Perhaps it's the tid of a deleted thread we may still
771b725ae77Skettenis * have some knowledge of?
772b725ae77Skettenis */
773b725ae77Skettenis for (p = deleted_threads.head; p; p = p->next)
774b725ae77Skettenis {
775b725ae77Skettenis if (p->tid == gdb_tid)
776b725ae77Skettenis return gdb_tid;
777b725ae77Skettenis }
778b725ae77Skettenis
779b725ae77Skettenis /* Or perhaps it's the pid of a deleted process we may still
780b725ae77Skettenis * have knowledge of?
781b725ae77Skettenis */
782b725ae77Skettenis for (p = deleted_threads.head_pseudo; p != NULL; p = p->next_pseudo)
783b725ae77Skettenis {
784b725ae77Skettenis if (p->pid == gdb_tid)
785b725ae77Skettenis return p->tid;
786b725ae77Skettenis }
787b725ae77Skettenis
788b725ae77Skettenis return 0; /* Error? */
789b725ae77Skettenis }
790b725ae77Skettenis
791b725ae77Skettenis /* Map the other way: from a real tid to the
792b725ae77Skettenis * "pid" known by core gdb. This tid may be
793b725ae77Skettenis * for a thread that just got deleted, so we
794b725ae77Skettenis * also need to consider deleted threads.
795b725ae77Skettenis */
796b725ae77Skettenis static lwpid_t
map_to_gdb_tid(lwpid_t real_tid)797b725ae77Skettenis map_to_gdb_tid (lwpid_t real_tid)
798b725ae77Skettenis {
799b725ae77Skettenis thread_info *p;
800b725ae77Skettenis
801b725ae77Skettenis for (p = thread_head.head; p; p = p->next)
802b725ae77Skettenis {
803b725ae77Skettenis if (p->tid == real_tid)
804b725ae77Skettenis {
805b725ae77Skettenis if (p->am_pseudo)
806b725ae77Skettenis return p->pid;
807b725ae77Skettenis else
808b725ae77Skettenis return real_tid;
809b725ae77Skettenis }
810b725ae77Skettenis }
811b725ae77Skettenis
812b725ae77Skettenis for (p = deleted_threads.head; p; p = p->next)
813b725ae77Skettenis {
814b725ae77Skettenis if (p->tid == real_tid)
815b725ae77Skettenis if (p->am_pseudo)
816b725ae77Skettenis return p->pid; /* Error? */
817b725ae77Skettenis else
818b725ae77Skettenis return real_tid;
819b725ae77Skettenis }
820b725ae77Skettenis
821b725ae77Skettenis return 0; /* Error? Never heard of this thread! */
822b725ae77Skettenis }
823b725ae77Skettenis
824b725ae77Skettenis /* Do any threads have saved signals?
825b725ae77Skettenis */
826b725ae77Skettenis static int
saved_signals_exist(void)827b725ae77Skettenis saved_signals_exist (void)
828b725ae77Skettenis {
829b725ae77Skettenis thread_info *p;
830b725ae77Skettenis
831b725ae77Skettenis for (p = thread_head.head; p; p = p->next)
832b725ae77Skettenis {
833b725ae77Skettenis if (p->have_signal)
834b725ae77Skettenis {
835b725ae77Skettenis return 1;
836b725ae77Skettenis }
837b725ae77Skettenis }
838b725ae77Skettenis
839b725ae77Skettenis return 0;
840b725ae77Skettenis }
841b725ae77Skettenis
842b725ae77Skettenis /* Is this the tid for the zero-th thread?
843b725ae77Skettenis */
844b725ae77Skettenis static int
is_pseudo_thread(lwpid_t tid)845b725ae77Skettenis is_pseudo_thread (lwpid_t tid)
846b725ae77Skettenis {
847b725ae77Skettenis thread_info *p = find_thread_info (tid);
848b725ae77Skettenis if (NULL == p || p->terminated)
849b725ae77Skettenis return 0;
850b725ae77Skettenis else
851b725ae77Skettenis return p->am_pseudo;
852b725ae77Skettenis }
853b725ae77Skettenis
854b725ae77Skettenis /* Is this thread terminated?
855b725ae77Skettenis */
856b725ae77Skettenis static int
is_terminated(lwpid_t tid)857b725ae77Skettenis is_terminated (lwpid_t tid)
858b725ae77Skettenis {
859b725ae77Skettenis thread_info *p = find_thread_info (tid);
860b725ae77Skettenis
861b725ae77Skettenis if (NULL != p)
862b725ae77Skettenis return p->terminated;
863b725ae77Skettenis
864b725ae77Skettenis return 0;
865b725ae77Skettenis }
866b725ae77Skettenis
867b725ae77Skettenis /* Is this pid a real PID or a TID?
868b725ae77Skettenis */
869b725ae77Skettenis static int
is_process_id(int pid)870b725ae77Skettenis is_process_id (int pid)
871b725ae77Skettenis {
872b725ae77Skettenis lwpid_t tid;
873b725ae77Skettenis thread_info *tinfo;
874b725ae77Skettenis pid_t this_pid;
875b725ae77Skettenis int this_pid_count;
876b725ae77Skettenis
877b725ae77Skettenis /* What does PID really represent?
878b725ae77Skettenis */
879b725ae77Skettenis tid = map_from_gdb_tid (pid);
880b725ae77Skettenis if (tid <= 0)
881b725ae77Skettenis return 0; /* Actually, is probably an error... */
882b725ae77Skettenis
883b725ae77Skettenis tinfo = find_thread_info (tid);
884b725ae77Skettenis
885b725ae77Skettenis /* Does it appear to be a true thread?
886b725ae77Skettenis */
887b725ae77Skettenis if (!tinfo->am_pseudo)
888b725ae77Skettenis return 0;
889b725ae77Skettenis
890b725ae77Skettenis /* Else, it looks like it may be a process. See if there's any other
891b725ae77Skettenis * threads with the same process ID, though. If there are, then TID
892b725ae77Skettenis * just happens to be the first thread of several for this process.
893b725ae77Skettenis */
894b725ae77Skettenis this_pid = tinfo->pid;
895b725ae77Skettenis this_pid_count = 0;
896b725ae77Skettenis for (tinfo = thread_head.head; tinfo; tinfo = tinfo->next)
897b725ae77Skettenis {
898b725ae77Skettenis if (tinfo->pid == this_pid)
899b725ae77Skettenis this_pid_count++;
900b725ae77Skettenis }
901b725ae77Skettenis
902b725ae77Skettenis return (this_pid_count == 1);
903b725ae77Skettenis }
904b725ae77Skettenis
905b725ae77Skettenis
906b725ae77Skettenis /* Add a thread to our info. Prevent duplicate entries.
907b725ae77Skettenis */
908b725ae77Skettenis static thread_info *
add_tthread(int pid,lwpid_t tid)909b725ae77Skettenis add_tthread (int pid, lwpid_t tid)
910b725ae77Skettenis {
911b725ae77Skettenis thread_info *p;
912b725ae77Skettenis
913b725ae77Skettenis p = find_thread_info (tid);
914b725ae77Skettenis if (NULL == p)
915b725ae77Skettenis p = create_thread_info (pid, tid);
916b725ae77Skettenis
917b725ae77Skettenis return p;
918b725ae77Skettenis }
919b725ae77Skettenis
920b725ae77Skettenis /* Notice that a thread was deleted.
921b725ae77Skettenis */
922b725ae77Skettenis static void
del_tthread(lwpid_t tid)923b725ae77Skettenis del_tthread (lwpid_t tid)
924b725ae77Skettenis {
925b725ae77Skettenis thread_info *p;
926b725ae77Skettenis thread_info *chase;
927b725ae77Skettenis
928b725ae77Skettenis if (thread_head.count <= 0)
929b725ae77Skettenis {
930b725ae77Skettenis error ("Internal error in thread database.");
931b725ae77Skettenis return;
932b725ae77Skettenis }
933b725ae77Skettenis
934b725ae77Skettenis chase = NULL;
935b725ae77Skettenis for (p = thread_head.head; p; p = p->next)
936b725ae77Skettenis {
937b725ae77Skettenis if (p->tid == tid)
938b725ae77Skettenis {
939b725ae77Skettenis
940b725ae77Skettenis #ifdef THREAD_DEBUG
941b725ae77Skettenis if (debug_on)
942b725ae77Skettenis printf ("Delete here: %d \n", tid);
943b725ae77Skettenis #endif
944b725ae77Skettenis
945b725ae77Skettenis if (p->am_pseudo)
946b725ae77Skettenis {
947b725ae77Skettenis /*
948b725ae77Skettenis * Deleting a main thread is ok if we're doing
949b725ae77Skettenis * a parent-follow on a child; this is odd but
950b725ae77Skettenis * not wrong. It apparently _doesn't_ happen
951b725ae77Skettenis * on the child-follow, as we don't just delete
952b725ae77Skettenis * the pseudo while keeping the rest of the
953b725ae77Skettenis * threads around--instead, we clear out the whole
954b725ae77Skettenis * thread list at once.
955b725ae77Skettenis */
956b725ae77Skettenis thread_info *q;
957b725ae77Skettenis thread_info *q_chase;
958b725ae77Skettenis
959b725ae77Skettenis q_chase = NULL;
960b725ae77Skettenis for (q = thread_head.head_pseudo; q; q = q->next)
961b725ae77Skettenis {
962b725ae77Skettenis if (q == p)
963b725ae77Skettenis {
964b725ae77Skettenis /* Remove from pseudo list.
965b725ae77Skettenis */
966b725ae77Skettenis if (q_chase == NULL)
967b725ae77Skettenis thread_head.head_pseudo = p->next_pseudo;
968b725ae77Skettenis else
969b725ae77Skettenis q_chase->next = p->next_pseudo;
970b725ae77Skettenis }
971b725ae77Skettenis else
972b725ae77Skettenis q_chase = q;
973b725ae77Skettenis }
974b725ae77Skettenis }
975b725ae77Skettenis
976b725ae77Skettenis /* Remove from live list.
977b725ae77Skettenis */
978b725ae77Skettenis thread_head.count--;
979b725ae77Skettenis
980b725ae77Skettenis if (NULL == chase)
981b725ae77Skettenis thread_head.head = p->next;
982b725ae77Skettenis else
983b725ae77Skettenis chase->next = p->next;
984b725ae77Skettenis
985b725ae77Skettenis /* Add to deleted thread list.
986b725ae77Skettenis */
987b725ae77Skettenis p->next = deleted_threads.head;
988b725ae77Skettenis deleted_threads.head = p;
989b725ae77Skettenis deleted_threads.count++;
990b725ae77Skettenis if (p->am_pseudo)
991b725ae77Skettenis {
992b725ae77Skettenis p->next_pseudo = deleted_threads.head_pseudo;
993b725ae77Skettenis deleted_threads.head_pseudo = p;
994b725ae77Skettenis }
995b725ae77Skettenis p->terminated = 1;
996b725ae77Skettenis
997b725ae77Skettenis return;
998b725ae77Skettenis }
999b725ae77Skettenis
1000b725ae77Skettenis else
1001b725ae77Skettenis chase = p;
1002b725ae77Skettenis }
1003b725ae77Skettenis }
1004b725ae77Skettenis
1005b725ae77Skettenis /* Get the pid for this tid. (Has to be a real TID!).
1006b725ae77Skettenis */
1007b725ae77Skettenis static int
get_pid_for(lwpid_t tid)1008b725ae77Skettenis get_pid_for (lwpid_t tid)
1009b725ae77Skettenis {
1010b725ae77Skettenis thread_info *p;
1011b725ae77Skettenis
1012b725ae77Skettenis for (p = thread_head.head; p; p = p->next)
1013b725ae77Skettenis {
1014b725ae77Skettenis if (p->tid == tid)
1015b725ae77Skettenis {
1016b725ae77Skettenis return p->pid;
1017b725ae77Skettenis }
1018b725ae77Skettenis }
1019b725ae77Skettenis
1020b725ae77Skettenis for (p = deleted_threads.head; p; p = p->next)
1021b725ae77Skettenis {
1022b725ae77Skettenis if (p->tid == tid)
1023b725ae77Skettenis {
1024b725ae77Skettenis return p->pid;
1025b725ae77Skettenis }
1026b725ae77Skettenis }
1027b725ae77Skettenis
1028b725ae77Skettenis return 0;
1029b725ae77Skettenis }
1030b725ae77Skettenis
1031b725ae77Skettenis /* Note that this thread's current event has been handled.
1032b725ae77Skettenis */
1033b725ae77Skettenis static void
set_handled(int pid,lwpid_t tid)1034b725ae77Skettenis set_handled (int pid, lwpid_t tid)
1035b725ae77Skettenis {
1036b725ae77Skettenis thread_info *p;
1037b725ae77Skettenis
1038b725ae77Skettenis p = find_thread_info (tid);
1039b725ae77Skettenis if (NULL == p)
1040b725ae77Skettenis p = add_tthread (pid, tid);
1041b725ae77Skettenis
1042b725ae77Skettenis p->handled = 1;
1043b725ae77Skettenis }
1044b725ae77Skettenis
1045b725ae77Skettenis /* Was this thread's current event handled?
1046b725ae77Skettenis */
1047b725ae77Skettenis static int
was_handled(lwpid_t tid)1048b725ae77Skettenis was_handled (lwpid_t tid)
1049b725ae77Skettenis {
1050b725ae77Skettenis thread_info *p;
1051b725ae77Skettenis
1052b725ae77Skettenis p = find_thread_info (tid);
1053b725ae77Skettenis if (NULL != p)
1054b725ae77Skettenis return p->handled;
1055b725ae77Skettenis
1056b725ae77Skettenis return 0; /* New threads have not been handled */
1057b725ae77Skettenis }
1058b725ae77Skettenis
1059b725ae77Skettenis /* Set this thread to unhandled.
1060b725ae77Skettenis */
1061b725ae77Skettenis static void
clear_handled(lwpid_t tid)1062b725ae77Skettenis clear_handled (lwpid_t tid)
1063b725ae77Skettenis {
1064b725ae77Skettenis thread_info *p;
1065b725ae77Skettenis
1066b725ae77Skettenis #ifdef WAIT_BUFFER_DEBUG
1067b725ae77Skettenis if (debug_on)
1068b725ae77Skettenis printf ("clear_handled %d\n", (int) tid);
1069b725ae77Skettenis #endif
1070b725ae77Skettenis
1071b725ae77Skettenis p = find_thread_info (tid);
1072b725ae77Skettenis if (p == NULL)
1073b725ae77Skettenis error ("Internal error: No thread state to clear?");
1074b725ae77Skettenis
1075b725ae77Skettenis p->handled = 0;
1076b725ae77Skettenis }
1077b725ae77Skettenis
1078b725ae77Skettenis /* Set all threads to unhandled.
1079b725ae77Skettenis */
1080b725ae77Skettenis static void
clear_all_handled(void)1081b725ae77Skettenis clear_all_handled (void)
1082b725ae77Skettenis {
1083b725ae77Skettenis thread_info *p;
1084b725ae77Skettenis
1085b725ae77Skettenis #ifdef WAIT_BUFFER_DEBUG
1086b725ae77Skettenis if (debug_on)
1087b725ae77Skettenis printf ("clear_all_handled\n");
1088b725ae77Skettenis #endif
1089b725ae77Skettenis
1090b725ae77Skettenis for (p = thread_head.head; p; p = p->next)
1091b725ae77Skettenis {
1092b725ae77Skettenis p->handled = 0;
1093b725ae77Skettenis }
1094b725ae77Skettenis
1095b725ae77Skettenis for (p = deleted_threads.head; p; p = p->next)
1096b725ae77Skettenis {
1097b725ae77Skettenis p->handled = 0;
1098b725ae77Skettenis }
1099b725ae77Skettenis }
1100b725ae77Skettenis
1101b725ae77Skettenis /* Set this thread to default stepping mode.
1102b725ae77Skettenis */
1103b725ae77Skettenis static void
clear_stepping_mode(lwpid_t tid)1104b725ae77Skettenis clear_stepping_mode (lwpid_t tid)
1105b725ae77Skettenis {
1106b725ae77Skettenis thread_info *p;
1107b725ae77Skettenis
1108b725ae77Skettenis #ifdef WAIT_BUFFER_DEBUG
1109b725ae77Skettenis if (debug_on)
1110b725ae77Skettenis printf ("clear_stepping_mode %d\n", (int) tid);
1111b725ae77Skettenis #endif
1112b725ae77Skettenis
1113b725ae77Skettenis p = find_thread_info (tid);
1114b725ae77Skettenis if (p == NULL)
1115b725ae77Skettenis error ("Internal error: No thread state to clear?");
1116b725ae77Skettenis
1117b725ae77Skettenis p->stepping_mode = DO_DEFAULT;
1118b725ae77Skettenis }
1119b725ae77Skettenis
1120b725ae77Skettenis /* Set all threads to do default continue on resume.
1121b725ae77Skettenis */
1122b725ae77Skettenis static void
clear_all_stepping_mode(void)1123b725ae77Skettenis clear_all_stepping_mode (void)
1124b725ae77Skettenis {
1125b725ae77Skettenis thread_info *p;
1126b725ae77Skettenis
1127b725ae77Skettenis #ifdef WAIT_BUFFER_DEBUG
1128b725ae77Skettenis if (debug_on)
1129b725ae77Skettenis printf ("clear_all_stepping_mode\n");
1130b725ae77Skettenis #endif
1131b725ae77Skettenis
1132b725ae77Skettenis for (p = thread_head.head; p; p = p->next)
1133b725ae77Skettenis {
1134b725ae77Skettenis p->stepping_mode = DO_DEFAULT;
1135b725ae77Skettenis }
1136b725ae77Skettenis
1137b725ae77Skettenis for (p = deleted_threads.head; p; p = p->next)
1138b725ae77Skettenis {
1139b725ae77Skettenis p->stepping_mode = DO_DEFAULT;
1140b725ae77Skettenis }
1141b725ae77Skettenis }
1142b725ae77Skettenis
1143b725ae77Skettenis /* Set all threads to unseen on this pass.
1144b725ae77Skettenis */
1145b725ae77Skettenis static void
set_all_unseen(void)1146b725ae77Skettenis set_all_unseen (void)
1147b725ae77Skettenis {
1148b725ae77Skettenis thread_info *p;
1149b725ae77Skettenis
1150b725ae77Skettenis for (p = thread_head.head; p; p = p->next)
1151b725ae77Skettenis {
1152b725ae77Skettenis p->seen = 0;
1153b725ae77Skettenis }
1154b725ae77Skettenis }
1155b725ae77Skettenis
1156b725ae77Skettenis #if (defined( THREAD_DEBUG ) || defined( PARANOIA ))
1157b725ae77Skettenis /* debugging routine.
1158b725ae77Skettenis */
1159b725ae77Skettenis static void
print_tthread(thread_info * p)1160b725ae77Skettenis print_tthread (thread_info *p)
1161b725ae77Skettenis {
1162b725ae77Skettenis printf (" Thread pid %d, tid %d", p->pid, p->tid);
1163b725ae77Skettenis if (p->have_state)
1164b725ae77Skettenis printf (", event is %s",
1165b725ae77Skettenis get_printable_name_of_ttrace_event (p->last_stop_state.tts_event));
1166b725ae77Skettenis
1167b725ae77Skettenis if (p->am_pseudo)
1168b725ae77Skettenis printf (", pseudo thread");
1169b725ae77Skettenis
1170b725ae77Skettenis if (p->have_signal)
1171b725ae77Skettenis printf (", have signal 0x%x", p->signal_value);
1172b725ae77Skettenis
1173b725ae77Skettenis if (p->have_start)
1174b725ae77Skettenis printf (", have start at 0x%x", p->start);
1175b725ae77Skettenis
1176b725ae77Skettenis printf (", step is %s", get_printable_name_of_stepping_mode (p->stepping_mode));
1177b725ae77Skettenis
1178b725ae77Skettenis if (p->handled)
1179b725ae77Skettenis printf (", handled");
1180b725ae77Skettenis else
1181b725ae77Skettenis printf (", not handled");
1182b725ae77Skettenis
1183b725ae77Skettenis if (p->seen)
1184b725ae77Skettenis printf (", seen");
1185b725ae77Skettenis else
1186b725ae77Skettenis printf (", not seen");
1187b725ae77Skettenis
1188b725ae77Skettenis printf ("\n");
1189b725ae77Skettenis }
1190b725ae77Skettenis
1191b725ae77Skettenis static void
print_tthreads(void)1192b725ae77Skettenis print_tthreads (void)
1193b725ae77Skettenis {
1194b725ae77Skettenis thread_info *p;
1195b725ae77Skettenis
1196b725ae77Skettenis if (thread_head.count == 0)
1197b725ae77Skettenis printf ("Thread list is empty\n");
1198b725ae77Skettenis else
1199b725ae77Skettenis {
1200b725ae77Skettenis printf ("Thread list has ");
1201b725ae77Skettenis if (thread_head.count == 1)
1202b725ae77Skettenis printf ("1 entry:\n");
1203b725ae77Skettenis else
1204b725ae77Skettenis printf ("%d entries:\n", thread_head.count);
1205b725ae77Skettenis for (p = thread_head.head; p; p = p->next)
1206b725ae77Skettenis {
1207b725ae77Skettenis print_tthread (p);
1208b725ae77Skettenis }
1209b725ae77Skettenis }
1210b725ae77Skettenis
1211b725ae77Skettenis if (deleted_threads.count == 0)
1212b725ae77Skettenis printf ("Deleted thread list is empty\n");
1213b725ae77Skettenis else
1214b725ae77Skettenis {
1215b725ae77Skettenis printf ("Deleted thread list has ");
1216b725ae77Skettenis if (deleted_threads.count == 1)
1217b725ae77Skettenis printf ("1 entry:\n");
1218b725ae77Skettenis else
1219b725ae77Skettenis printf ("%d entries:\n", deleted_threads.count);
1220b725ae77Skettenis
1221b725ae77Skettenis for (p = deleted_threads.head; p; p = p->next)
1222b725ae77Skettenis {
1223b725ae77Skettenis print_tthread (p);
1224b725ae77Skettenis }
1225b725ae77Skettenis }
1226b725ae77Skettenis }
1227b725ae77Skettenis #endif
1228b725ae77Skettenis
1229b725ae77Skettenis /* Update the thread list based on the "seen" bits.
1230b725ae77Skettenis */
1231b725ae77Skettenis static void
update_thread_list(void)1232b725ae77Skettenis update_thread_list (void)
1233b725ae77Skettenis {
1234b725ae77Skettenis thread_info *p;
1235b725ae77Skettenis thread_info *chase;
1236b725ae77Skettenis
1237b725ae77Skettenis chase = NULL;
1238b725ae77Skettenis for (p = thread_head.head; p; p = p->next)
1239b725ae77Skettenis {
1240b725ae77Skettenis /* Is this an "unseen" thread which really happens to be a process?
1241b725ae77Skettenis If so, is it inferior_ptid and is a vfork in flight? If yes to
1242b725ae77Skettenis all, then DON'T REMOVE IT! We're in the midst of moving a vfork
1243b725ae77Skettenis operation, which is a multiple step thing, to the point where we
1244b725ae77Skettenis can touch the parent again. We've most likely stopped to examine
1245b725ae77Skettenis the child at a late stage in the vfork, and if we're not following
1246b725ae77Skettenis the child, we'd best not treat the parent as a dead "thread"...
1247b725ae77Skettenis */
1248b725ae77Skettenis if ((!p->seen) && p->am_pseudo && vfork_in_flight
1249b725ae77Skettenis && (p->pid != vforking_child_pid))
1250b725ae77Skettenis p->seen = 1;
1251b725ae77Skettenis
1252b725ae77Skettenis if (!p->seen)
1253b725ae77Skettenis {
1254b725ae77Skettenis /* Remove this one
1255b725ae77Skettenis */
1256b725ae77Skettenis
1257b725ae77Skettenis #ifdef THREAD_DEBUG
1258b725ae77Skettenis if (debug_on)
1259b725ae77Skettenis printf ("Delete unseen thread: %d \n", p->tid);
1260b725ae77Skettenis #endif
1261b725ae77Skettenis del_tthread (p->tid);
1262b725ae77Skettenis }
1263b725ae77Skettenis }
1264b725ae77Skettenis }
1265b725ae77Skettenis
1266b725ae77Skettenis
1267b725ae77Skettenis
1268b725ae77Skettenis /************************************************
1269b725ae77Skettenis * O/S call wrappers *
1270b725ae77Skettenis ************************************************
1271b725ae77Skettenis */
1272b725ae77Skettenis
1273b725ae77Skettenis /* This function simply calls ttrace with the given arguments.
1274b725ae77Skettenis * It exists so that all calls to ttrace are isolated. All
1275b725ae77Skettenis * parameters should be as specified by "man 2 ttrace".
1276b725ae77Skettenis *
1277b725ae77Skettenis * No other "raw" calls to ttrace should exist in this module.
1278b725ae77Skettenis */
1279b725ae77Skettenis static int
call_real_ttrace(ttreq_t request,pid_t pid,lwpid_t tid,TTRACE_ARG_TYPE addr,TTRACE_ARG_TYPE data,TTRACE_ARG_TYPE addr2)1280b725ae77Skettenis call_real_ttrace (ttreq_t request, pid_t pid, lwpid_t tid, TTRACE_ARG_TYPE addr,
1281b725ae77Skettenis TTRACE_ARG_TYPE data, TTRACE_ARG_TYPE addr2)
1282b725ae77Skettenis {
1283b725ae77Skettenis int tt_status;
1284b725ae77Skettenis
1285b725ae77Skettenis errno = 0;
1286b725ae77Skettenis tt_status = ttrace (request, pid, tid, addr, data, addr2);
1287b725ae77Skettenis
1288b725ae77Skettenis #ifdef THREAD_DEBUG
1289b725ae77Skettenis if (errno)
1290b725ae77Skettenis {
1291b725ae77Skettenis /* Don't bother for a known benign error: if you ask for the
1292b725ae77Skettenis * first thread state, but there is only one thread and it's
1293b725ae77Skettenis * not stopped, ttrace complains.
1294b725ae77Skettenis *
1295b725ae77Skettenis * We have this inside the #ifdef because our caller will do
1296b725ae77Skettenis * this check for real.
1297b725ae77Skettenis */
1298b725ae77Skettenis if (request != TT_PROC_GET_FIRST_LWP_STATE
1299b725ae77Skettenis || errno != EPROTO)
1300b725ae77Skettenis {
1301b725ae77Skettenis if (debug_on)
1302b725ae77Skettenis printf ("TT fail for %s, with pid %d, tid %d, status %d \n",
1303b725ae77Skettenis get_printable_name_of_ttrace_request (request),
1304b725ae77Skettenis pid, tid, tt_status);
1305b725ae77Skettenis }
1306b725ae77Skettenis }
1307b725ae77Skettenis #endif
1308b725ae77Skettenis
1309b725ae77Skettenis #if 0
1310b725ae77Skettenis /* ??rehrauer: It would probably be most robust to catch and report
1311b725ae77Skettenis * failed requests here. However, some clients of this interface
1312b725ae77Skettenis * seem to expect to catch & deal with them, so we'd best not.
1313b725ae77Skettenis */
1314b725ae77Skettenis if (errno)
1315b725ae77Skettenis {
1316b725ae77Skettenis strcpy (reason_for_failure, "ttrace (");
1317b725ae77Skettenis strcat (reason_for_failure, get_printable_name_of_ttrace_request (request));
1318b725ae77Skettenis strcat (reason_for_failure, ")");
1319b725ae77Skettenis printf ("ttrace error, errno = %d\n", errno);
1320b725ae77Skettenis perror_with_name (reason_for_failure);
1321b725ae77Skettenis }
1322b725ae77Skettenis #endif
1323b725ae77Skettenis
1324b725ae77Skettenis return tt_status;
1325b725ae77Skettenis }
1326b725ae77Skettenis
1327b725ae77Skettenis
1328b725ae77Skettenis /* This function simply calls ttrace_wait with the given arguments.
1329b725ae77Skettenis * It exists so that all calls to ttrace_wait are isolated.
1330b725ae77Skettenis *
1331b725ae77Skettenis * No "raw" calls to ttrace_wait should exist elsewhere.
1332b725ae77Skettenis */
1333b725ae77Skettenis static int
call_real_ttrace_wait(int pid,lwpid_t tid,ttwopt_t option,ttstate_t * tsp,size_t tsp_size)1334b725ae77Skettenis call_real_ttrace_wait (int pid, lwpid_t tid, ttwopt_t option, ttstate_t *tsp,
1335b725ae77Skettenis size_t tsp_size)
1336b725ae77Skettenis {
1337b725ae77Skettenis int ttw_status;
1338b725ae77Skettenis thread_info *tinfo = NULL;
1339b725ae77Skettenis
1340b725ae77Skettenis errno = 0;
1341b725ae77Skettenis ttw_status = ttrace_wait (pid, tid, option, tsp, tsp_size);
1342b725ae77Skettenis
1343b725ae77Skettenis if (errno)
1344b725ae77Skettenis {
1345b725ae77Skettenis #ifdef THREAD_DEBUG
1346b725ae77Skettenis if (debug_on)
1347b725ae77Skettenis printf ("TW fail with pid %d, tid %d \n", pid, tid);
1348b725ae77Skettenis #endif
1349b725ae77Skettenis
1350b725ae77Skettenis perror_with_name ("ttrace wait");
1351b725ae77Skettenis }
1352b725ae77Skettenis
1353b725ae77Skettenis return ttw_status;
1354b725ae77Skettenis }
1355b725ae77Skettenis
1356b725ae77Skettenis
1357b725ae77Skettenis /* A process may have one or more kernel threads, of which all or
1358b725ae77Skettenis none may be stopped. This function returns the ID of the first
1359b725ae77Skettenis kernel thread in a stopped state, or 0 if none are stopped.
1360b725ae77Skettenis
1361b725ae77Skettenis This function can be used with get_process_next_stopped_thread_id
1362b725ae77Skettenis to iterate over the IDs of all stopped threads of this process.
1363b725ae77Skettenis */
1364b725ae77Skettenis static lwpid_t
get_process_first_stopped_thread_id(int pid,ttstate_t * thread_state)1365b725ae77Skettenis get_process_first_stopped_thread_id (int pid, ttstate_t *thread_state)
1366b725ae77Skettenis {
1367b725ae77Skettenis int tt_status;
1368b725ae77Skettenis
1369b725ae77Skettenis tt_status = call_real_ttrace (TT_PROC_GET_FIRST_LWP_STATE,
1370b725ae77Skettenis (pid_t) pid,
1371b725ae77Skettenis (lwpid_t) TT_NIL,
1372b725ae77Skettenis (TTRACE_ARG_TYPE) thread_state,
1373b725ae77Skettenis (TTRACE_ARG_TYPE) sizeof (*thread_state),
1374b725ae77Skettenis TT_NIL);
1375b725ae77Skettenis
1376b725ae77Skettenis if (errno)
1377b725ae77Skettenis {
1378b725ae77Skettenis if (errno == EPROTO)
1379b725ae77Skettenis {
1380b725ae77Skettenis /* This is an error we can handle: there isn't any stopped
1381b725ae77Skettenis * thread. This happens when we're re-starting the application
1382b725ae77Skettenis * and it has only one thread. GET_NEXT handles the case of
1383b725ae77Skettenis * no more stopped threads well; GET_FIRST doesn't. (A ttrace
1384b725ae77Skettenis * "feature".)
1385b725ae77Skettenis */
1386b725ae77Skettenis tt_status = 1;
1387b725ae77Skettenis errno = 0;
1388b725ae77Skettenis return 0;
1389b725ae77Skettenis }
1390b725ae77Skettenis else
1391b725ae77Skettenis perror_with_name ("ttrace");
1392b725ae77Skettenis }
1393b725ae77Skettenis
1394b725ae77Skettenis if (tt_status < 0)
1395b725ae77Skettenis /* Failed somehow.
1396b725ae77Skettenis */
1397b725ae77Skettenis return 0;
1398b725ae77Skettenis
1399b725ae77Skettenis return thread_state->tts_lwpid;
1400b725ae77Skettenis }
1401b725ae77Skettenis
1402b725ae77Skettenis
1403b725ae77Skettenis /* This function returns the ID of the "next" kernel thread in a
1404b725ae77Skettenis stopped state, or 0 if there are none. "Next" refers to the
1405b725ae77Skettenis thread following that of the last successful call to this
1406b725ae77Skettenis function or to get_process_first_stopped_thread_id, using
1407b725ae77Skettenis the value of thread_state returned by that call.
1408b725ae77Skettenis
1409b725ae77Skettenis This function can be used with get_process_first_stopped_thread_id
1410b725ae77Skettenis to iterate over the IDs of all stopped threads of this process.
1411b725ae77Skettenis */
1412b725ae77Skettenis static lwpid_t
get_process_next_stopped_thread_id(int pid,ttstate_t * thread_state)1413b725ae77Skettenis get_process_next_stopped_thread_id (int pid, ttstate_t *thread_state)
1414b725ae77Skettenis {
1415b725ae77Skettenis int tt_status;
1416b725ae77Skettenis
1417b725ae77Skettenis tt_status = call_real_ttrace (
1418b725ae77Skettenis TT_PROC_GET_NEXT_LWP_STATE,
1419b725ae77Skettenis (pid_t) pid,
1420b725ae77Skettenis (lwpid_t) TT_NIL,
1421b725ae77Skettenis (TTRACE_ARG_TYPE) thread_state,
1422b725ae77Skettenis (TTRACE_ARG_TYPE) sizeof (*thread_state),
1423b725ae77Skettenis TT_NIL);
1424b725ae77Skettenis if (errno)
1425b725ae77Skettenis perror_with_name ("ttrace");
1426b725ae77Skettenis
1427b725ae77Skettenis if (tt_status < 0)
1428b725ae77Skettenis /* Failed
1429b725ae77Skettenis */
1430b725ae77Skettenis return 0;
1431b725ae77Skettenis
1432b725ae77Skettenis else if (tt_status == 0)
1433b725ae77Skettenis {
1434b725ae77Skettenis /* End of list, no next state. Don't return the
1435b725ae77Skettenis * tts_lwpid, as it's a meaningless "240".
1436b725ae77Skettenis *
1437b725ae77Skettenis * This is an HPUX "feature".
1438b725ae77Skettenis */
1439b725ae77Skettenis return 0;
1440b725ae77Skettenis }
1441b725ae77Skettenis
1442b725ae77Skettenis return thread_state->tts_lwpid;
1443b725ae77Skettenis }
1444b725ae77Skettenis
1445b725ae77Skettenis /* ??rehrauer: Eventually this function perhaps should be calling
1446b725ae77Skettenis pid_to_thread_id. However, that function currently does nothing
1447b725ae77Skettenis for HP-UX. Even then, I'm not clear whether that function
1448b725ae77Skettenis will return a "kernel" thread ID, or a "user" thread ID. If
1449b725ae77Skettenis the former, we can just call it here. If the latter, we must
1450b725ae77Skettenis map from the "user" tid to a "kernel" tid.
1451b725ae77Skettenis
1452b725ae77Skettenis NOTE: currently not called.
1453b725ae77Skettenis */
1454b725ae77Skettenis static lwpid_t
get_active_tid_of_pid(int pid)1455b725ae77Skettenis get_active_tid_of_pid (int pid)
1456b725ae77Skettenis {
1457b725ae77Skettenis ttstate_t thread_state;
1458b725ae77Skettenis
1459b725ae77Skettenis return get_process_first_stopped_thread_id (pid, &thread_state);
1460b725ae77Skettenis }
1461b725ae77Skettenis
1462b725ae77Skettenis /* This function returns 1 if tt_request is a ttrace request that
1463b725ae77Skettenis * operates upon all threads of a (i.e., the entire) process.
1464b725ae77Skettenis */
1465b725ae77Skettenis int
is_process_ttrace_request(ttreq_t tt_request)1466b725ae77Skettenis is_process_ttrace_request (ttreq_t tt_request)
1467b725ae77Skettenis {
1468b725ae77Skettenis return IS_TTRACE_PROCREQ (tt_request);
1469b725ae77Skettenis }
1470b725ae77Skettenis
1471b725ae77Skettenis
1472b725ae77Skettenis /* This function translates a thread ttrace request into
1473b725ae77Skettenis * the equivalent process request for a one-thread process.
1474b725ae77Skettenis */
1475b725ae77Skettenis static ttreq_t
make_process_version(ttreq_t request)1476b725ae77Skettenis make_process_version (ttreq_t request)
1477b725ae77Skettenis {
1478b725ae77Skettenis if (!IS_TTRACE_REQ (request))
1479b725ae77Skettenis {
1480b725ae77Skettenis error ("Internal error, bad ttrace request made\n");
1481b725ae77Skettenis return -1;
1482b725ae77Skettenis }
1483b725ae77Skettenis
1484b725ae77Skettenis switch (request)
1485b725ae77Skettenis {
1486b725ae77Skettenis case TT_LWP_STOP:
1487b725ae77Skettenis return TT_PROC_STOP;
1488b725ae77Skettenis
1489b725ae77Skettenis case TT_LWP_CONTINUE:
1490b725ae77Skettenis return TT_PROC_CONTINUE;
1491b725ae77Skettenis
1492b725ae77Skettenis case TT_LWP_GET_EVENT_MASK:
1493b725ae77Skettenis return TT_PROC_GET_EVENT_MASK;
1494b725ae77Skettenis
1495b725ae77Skettenis case TT_LWP_SET_EVENT_MASK:
1496b725ae77Skettenis return TT_PROC_SET_EVENT_MASK;
1497b725ae77Skettenis
1498b725ae77Skettenis case TT_LWP_SINGLE:
1499b725ae77Skettenis case TT_LWP_RUREGS:
1500b725ae77Skettenis case TT_LWP_WUREGS:
1501b725ae77Skettenis case TT_LWP_GET_STATE:
1502b725ae77Skettenis return -1; /* No equivalent */
1503b725ae77Skettenis
1504b725ae77Skettenis default:
1505b725ae77Skettenis return request;
1506b725ae77Skettenis }
1507b725ae77Skettenis }
1508b725ae77Skettenis
1509b725ae77Skettenis
1510b725ae77Skettenis /* This function translates the "pid" used by the rest of
1511b725ae77Skettenis * gdb to a real pid and a tid. It then calls "call_real_ttrace"
1512b725ae77Skettenis * with the given arguments.
1513b725ae77Skettenis *
1514b725ae77Skettenis * In general, other parts of this module should call this
1515b725ae77Skettenis * function when they are dealing with external users, who only
1516b725ae77Skettenis * have tids to pass (but they call it "pid" for historical
1517b725ae77Skettenis * reasons).
1518b725ae77Skettenis */
1519b725ae77Skettenis static int
call_ttrace(ttreq_t request,int gdb_tid,TTRACE_ARG_TYPE addr,TTRACE_ARG_TYPE data,TTRACE_ARG_TYPE addr2)1520b725ae77Skettenis call_ttrace (ttreq_t request, int gdb_tid, TTRACE_ARG_TYPE addr,
1521b725ae77Skettenis TTRACE_ARG_TYPE data, TTRACE_ARG_TYPE addr2)
1522b725ae77Skettenis {
1523b725ae77Skettenis lwpid_t real_tid;
1524b725ae77Skettenis int real_pid;
1525b725ae77Skettenis ttreq_t new_request;
1526b725ae77Skettenis int tt_status;
1527b725ae77Skettenis char reason_for_failure[100]; /* Arbitrary size, should be big enough. */
1528b725ae77Skettenis
1529b725ae77Skettenis #ifdef THREAD_DEBUG
1530b725ae77Skettenis int is_interesting = 0;
1531b725ae77Skettenis
1532b725ae77Skettenis if (TT_LWP_RUREGS == request)
1533b725ae77Skettenis {
1534b725ae77Skettenis is_interesting = 1; /* Adjust code here as desired */
1535b725ae77Skettenis }
1536b725ae77Skettenis
1537b725ae77Skettenis if (is_interesting && 0 && debug_on)
1538b725ae77Skettenis {
1539b725ae77Skettenis if (!is_process_ttrace_request (request))
1540b725ae77Skettenis {
1541b725ae77Skettenis printf ("TT: Thread request, tid is %d", gdb_tid);
1542b725ae77Skettenis printf ("== SINGLE at %x", addr);
1543b725ae77Skettenis }
1544b725ae77Skettenis else
1545b725ae77Skettenis {
1546b725ae77Skettenis printf ("TT: Process request, tid is %d\n", gdb_tid);
1547b725ae77Skettenis printf ("==! SINGLE at %x", addr);
1548b725ae77Skettenis }
1549b725ae77Skettenis }
1550b725ae77Skettenis #endif
1551b725ae77Skettenis
1552b725ae77Skettenis /* The initial SETTRC and SET_EVENT_MASK calls (and all others
1553b725ae77Skettenis * which happen before any threads get set up) should go
1554b725ae77Skettenis * directly to "call_real_ttrace", so they don't happen here.
1555b725ae77Skettenis *
1556b725ae77Skettenis * But hardware watchpoints do a SET_EVENT_MASK, so we can't
1557b725ae77Skettenis * rule them out....
1558b725ae77Skettenis */
1559b725ae77Skettenis #ifdef THREAD_DEBUG
1560b725ae77Skettenis if (request == TT_PROC_SETTRC && debug_on)
1561b725ae77Skettenis printf ("Unexpected call for TT_PROC_SETTRC\n");
1562b725ae77Skettenis #endif
1563b725ae77Skettenis
1564b725ae77Skettenis /* Sometimes we get called with a bogus tid (e.g., if a
1565b725ae77Skettenis * thread has terminated, we return 0; inftarg later asks
1566b725ae77Skettenis * whether the thread has exited/forked/vforked).
1567b725ae77Skettenis */
1568b725ae77Skettenis if (gdb_tid == 0)
1569b725ae77Skettenis {
1570b725ae77Skettenis errno = ESRCH; /* ttrace's response would probably be "No such process". */
1571b725ae77Skettenis return -1;
1572b725ae77Skettenis }
1573b725ae77Skettenis
1574b725ae77Skettenis /* All other cases should be able to expect that there are
1575b725ae77Skettenis * thread records.
1576b725ae77Skettenis */
1577b725ae77Skettenis if (!any_thread_records ())
1578b725ae77Skettenis {
1579b725ae77Skettenis #ifdef THREAD_DEBUG
1580b725ae77Skettenis if (debug_on)
1581b725ae77Skettenis warning ("No thread records for ttrace call");
1582b725ae77Skettenis #endif
1583b725ae77Skettenis errno = ESRCH; /* ttrace's response would be "No such process". */
1584b725ae77Skettenis return -1;
1585b725ae77Skettenis }
1586b725ae77Skettenis
1587b725ae77Skettenis /* OK, now the task is to translate the incoming tid into
1588b725ae77Skettenis * a pid/tid pair.
1589b725ae77Skettenis */
1590b725ae77Skettenis real_tid = map_from_gdb_tid (gdb_tid);
1591b725ae77Skettenis real_pid = get_pid_for (real_tid);
1592b725ae77Skettenis
1593b725ae77Skettenis /* Now check the result. "Real_pid" is NULL if our list
1594b725ae77Skettenis * didn't find it. We have some tricks we can play to fix
1595b725ae77Skettenis * this, however.
1596b725ae77Skettenis */
1597b725ae77Skettenis if (0 == real_pid)
1598b725ae77Skettenis {
1599b725ae77Skettenis ttstate_t thread_state;
1600b725ae77Skettenis
1601b725ae77Skettenis #ifdef THREAD_DEBUG
1602b725ae77Skettenis if (debug_on)
1603b725ae77Skettenis printf ("No saved pid for tid %d\n", gdb_tid);
1604b725ae77Skettenis #endif
1605b725ae77Skettenis
1606b725ae77Skettenis if (is_process_ttrace_request (request))
1607b725ae77Skettenis {
1608b725ae77Skettenis
1609b725ae77Skettenis /* Ok, we couldn't get a tid. Try to translate to
1610b725ae77Skettenis * the equivalent process operation. We expect this
1611b725ae77Skettenis * NOT to happen, so this is a desparation-type
1612b725ae77Skettenis * move. It can happen if there is an internal
1613b725ae77Skettenis * error and so no "wait()" call is ever done.
1614b725ae77Skettenis */
1615b725ae77Skettenis new_request = make_process_version (request);
1616b725ae77Skettenis if (new_request == -1)
1617b725ae77Skettenis {
1618b725ae77Skettenis
1619b725ae77Skettenis #ifdef THREAD_DEBUG
1620b725ae77Skettenis if (debug_on)
1621b725ae77Skettenis printf ("...and couldn't make process version of thread operation\n");
1622b725ae77Skettenis #endif
1623b725ae77Skettenis
1624b725ae77Skettenis /* Use hacky saved pid, which won't always be correct
1625b725ae77Skettenis * in the multi-process future. Use tid as thread,
1626b725ae77Skettenis * probably dooming this to failure. FIX!
1627b725ae77Skettenis */
1628b725ae77Skettenis if (! ptid_equal (saved_real_ptid, null_ptid))
1629b725ae77Skettenis {
1630b725ae77Skettenis #ifdef THREAD_DEBUG
1631b725ae77Skettenis if (debug_on)
1632b725ae77Skettenis printf ("...using saved pid %d\n",
1633b725ae77Skettenis PIDGET (saved_real_ptid));
1634b725ae77Skettenis #endif
1635b725ae77Skettenis
1636b725ae77Skettenis real_pid = PIDGET (saved_real_ptid);
1637b725ae77Skettenis real_tid = gdb_tid;
1638b725ae77Skettenis }
1639b725ae77Skettenis
1640b725ae77Skettenis else
1641b725ae77Skettenis error ("Unable to perform thread operation");
1642b725ae77Skettenis }
1643b725ae77Skettenis
1644b725ae77Skettenis else
1645b725ae77Skettenis {
1646b725ae77Skettenis /* Sucessfully translated this to a process request,
1647b725ae77Skettenis * which needs no thread value.
1648b725ae77Skettenis */
1649b725ae77Skettenis real_pid = gdb_tid;
1650b725ae77Skettenis real_tid = 0;
1651b725ae77Skettenis request = new_request;
1652b725ae77Skettenis
1653b725ae77Skettenis #ifdef THREAD_DEBUG
1654b725ae77Skettenis if (debug_on)
1655b725ae77Skettenis {
1656b725ae77Skettenis printf ("Translated thread request to process request\n");
1657b725ae77Skettenis if (ptid_equal (saved_real_ptid, null_ptid))
1658b725ae77Skettenis printf ("...but there's no saved pid\n");
1659b725ae77Skettenis
1660b725ae77Skettenis else
1661b725ae77Skettenis {
1662b725ae77Skettenis if (gdb_tid != PIDGET (saved_real_ptid))
1663b725ae77Skettenis printf ("...but have the wrong pid (%d rather than %d)\n",
1664b725ae77Skettenis gdb_tid, PIDGET (saved_real_ptid));
1665b725ae77Skettenis }
1666b725ae77Skettenis }
1667b725ae77Skettenis #endif
1668b725ae77Skettenis } /* Translated to a process request */
1669b725ae77Skettenis } /* Is a process request */
1670b725ae77Skettenis
1671b725ae77Skettenis else
1672b725ae77Skettenis {
1673b725ae77Skettenis /* We have to have a thread. Ooops.
1674b725ae77Skettenis */
1675b725ae77Skettenis error ("Thread request with no threads (%s)",
1676b725ae77Skettenis get_printable_name_of_ttrace_request (request));
1677b725ae77Skettenis }
1678b725ae77Skettenis }
1679b725ae77Skettenis
1680b725ae77Skettenis /* Ttrace doesn't like to see tid values on process requests,
1681b725ae77Skettenis * even if we have the right one.
1682b725ae77Skettenis */
1683b725ae77Skettenis if (is_process_ttrace_request (request))
1684b725ae77Skettenis {
1685b725ae77Skettenis real_tid = 0;
1686b725ae77Skettenis }
1687b725ae77Skettenis
1688b725ae77Skettenis #ifdef THREAD_DEBUG
1689b725ae77Skettenis if (is_interesting && 0 && debug_on)
1690b725ae77Skettenis {
1691b725ae77Skettenis printf (" now tid %d, pid %d\n", real_tid, real_pid);
1692b725ae77Skettenis printf (" request is %s\n", get_printable_name_of_ttrace_request (request));
1693b725ae77Skettenis }
1694b725ae77Skettenis #endif
1695b725ae77Skettenis
1696b725ae77Skettenis /* Finally, the (almost) real call.
1697b725ae77Skettenis */
1698b725ae77Skettenis tt_status = call_real_ttrace (request, real_pid, real_tid, addr, data, addr2);
1699b725ae77Skettenis
1700b725ae77Skettenis #ifdef THREAD_DEBUG
1701b725ae77Skettenis if (is_interesting && debug_on)
1702b725ae77Skettenis {
1703b725ae77Skettenis if (!TT_OK (tt_status, errno)
1704b725ae77Skettenis && !(tt_status == 0 & errno == 0))
1705b725ae77Skettenis printf (" got error (errno==%d, status==%d)\n", errno, tt_status);
1706b725ae77Skettenis }
1707b725ae77Skettenis #endif
1708b725ae77Skettenis
1709b725ae77Skettenis return tt_status;
1710b725ae77Skettenis }
1711b725ae77Skettenis
1712b725ae77Skettenis
1713b725ae77Skettenis /* Stop all the threads of a process.
1714b725ae77Skettenis
1715b725ae77Skettenis * NOTE: use of TT_PROC_STOP can cause a thread with a real event
1716b725ae77Skettenis * to get a TTEVT_NONE event, discarding the old event. Be
1717b725ae77Skettenis * very careful, and only call TT_PROC_STOP when you mean it!
1718b725ae77Skettenis */
1719b725ae77Skettenis static void
stop_all_threads_of_process(pid_t real_pid)1720b725ae77Skettenis stop_all_threads_of_process (pid_t real_pid)
1721b725ae77Skettenis {
1722b725ae77Skettenis int ttw_status;
1723b725ae77Skettenis
1724b725ae77Skettenis ttw_status = call_real_ttrace (TT_PROC_STOP,
1725b725ae77Skettenis (pid_t) real_pid,
1726b725ae77Skettenis (lwpid_t) TT_NIL,
1727b725ae77Skettenis (TTRACE_ARG_TYPE) TT_NIL,
1728b725ae77Skettenis (TTRACE_ARG_TYPE) TT_NIL,
1729b725ae77Skettenis TT_NIL);
1730b725ae77Skettenis if (errno)
1731b725ae77Skettenis perror_with_name ("ttrace stop of other threads");
1732b725ae77Skettenis }
1733b725ae77Skettenis
1734b725ae77Skettenis
1735b725ae77Skettenis /* Under some circumstances, it's unsafe to attempt to stop, or even
1736b725ae77Skettenis query the state of, a process' threads.
1737b725ae77Skettenis
1738b725ae77Skettenis In ttrace-based HP-UX, an example is a vforking child process. The
1739b725ae77Skettenis vforking parent and child are somewhat fragile, w/r/t what we can do
1740b725ae77Skettenis what we can do to them with ttrace, until after the child exits or
1741b725ae77Skettenis execs, or until the parent's vfork event is delivered. Until that
1742b725ae77Skettenis time, we must not try to stop the process' threads, or inquire how
1743b725ae77Skettenis many there are, or even alter its data segments, or it typically dies
1744b725ae77Skettenis with a SIGILL. Sigh.
1745b725ae77Skettenis
1746b725ae77Skettenis This function returns 1 if this stopped process, and the event that
1747b725ae77Skettenis we're told was responsible for its current stopped state, cannot safely
1748b725ae77Skettenis have its threads examined.
1749b725ae77Skettenis */
1750b725ae77Skettenis #define CHILD_VFORKED(evt,pid) \
1751b725ae77Skettenis (((evt) == TTEVT_VFORK) && ((pid) != PIDGET (inferior_ptid)))
1752b725ae77Skettenis #define CHILD_URPED(evt,pid) \
1753b725ae77Skettenis ((((evt) == TTEVT_EXEC) || ((evt) == TTEVT_EXIT)) && ((pid) != vforking_child_pid))
1754b725ae77Skettenis #define PARENT_VFORKED(evt,pid) \
1755b725ae77Skettenis (((evt) == TTEVT_VFORK) && ((pid) == PIDGET (inferior_ptid)))
1756b725ae77Skettenis
1757b725ae77Skettenis static int
can_touch_threads_of_process(int pid,ttevents_t stopping_event)1758b725ae77Skettenis can_touch_threads_of_process (int pid, ttevents_t stopping_event)
1759b725ae77Skettenis {
1760b725ae77Skettenis if (CHILD_VFORKED (stopping_event, pid))
1761b725ae77Skettenis {
1762b725ae77Skettenis vforking_child_pid = pid;
1763b725ae77Skettenis vfork_in_flight = 1;
1764b725ae77Skettenis }
1765b725ae77Skettenis
1766b725ae77Skettenis else if (vfork_in_flight &&
1767b725ae77Skettenis (PARENT_VFORKED (stopping_event, pid) ||
1768b725ae77Skettenis CHILD_URPED (stopping_event, pid)))
1769b725ae77Skettenis {
1770b725ae77Skettenis vfork_in_flight = 0;
1771b725ae77Skettenis vforking_child_pid = 0;
1772b725ae77Skettenis }
1773b725ae77Skettenis
1774b725ae77Skettenis return !vfork_in_flight;
1775b725ae77Skettenis }
1776b725ae77Skettenis
1777b725ae77Skettenis
1778b725ae77Skettenis /* If we can find an as-yet-unhandled thread state of a
1779b725ae77Skettenis * stopped thread of this process return 1 and set "tsp".
1780b725ae77Skettenis * Return 0 if we can't.
1781b725ae77Skettenis *
1782b725ae77Skettenis * If this function is used when the threads of PIS haven't
1783b725ae77Skettenis * been stopped, undefined behaviour is guaranteed!
1784b725ae77Skettenis */
1785b725ae77Skettenis static int
select_stopped_thread_of_process(int pid,ttstate_t * tsp)1786b725ae77Skettenis select_stopped_thread_of_process (int pid, ttstate_t *tsp)
1787b725ae77Skettenis {
1788b725ae77Skettenis lwpid_t candidate_tid, tid;
1789b725ae77Skettenis ttstate_t candidate_tstate, tstate;
1790b725ae77Skettenis
1791b725ae77Skettenis /* If we're not allowed to touch the process now, then just
1792b725ae77Skettenis * return the current value of *TSP.
1793b725ae77Skettenis *
1794b725ae77Skettenis * This supports "vfork". It's ok, really, to double the
1795b725ae77Skettenis * current event (the child EXEC, we hope!).
1796b725ae77Skettenis */
1797b725ae77Skettenis if (!can_touch_threads_of_process (pid, tsp->tts_event))
1798b725ae77Skettenis return 1;
1799b725ae77Skettenis
1800b725ae77Skettenis /* Decide which of (possibly more than one) events to
1801b725ae77Skettenis * return as the first one. We scan them all so that
1802b725ae77Skettenis * we always return the result of a fake-step first.
1803b725ae77Skettenis */
1804b725ae77Skettenis candidate_tid = 0;
1805b725ae77Skettenis for (tid = get_process_first_stopped_thread_id (pid, &tstate);
1806b725ae77Skettenis tid != 0;
1807b725ae77Skettenis tid = get_process_next_stopped_thread_id (pid, &tstate))
1808b725ae77Skettenis {
1809b725ae77Skettenis /* TTEVT_NONE events are uninteresting to our clients. They're
1810b725ae77Skettenis * an artifact of our "stop the world" model--the thread is
1811b725ae77Skettenis * stopped because we stopped it.
1812b725ae77Skettenis */
1813b725ae77Skettenis if (tstate.tts_event == TTEVT_NONE)
1814b725ae77Skettenis {
1815b725ae77Skettenis set_handled (pid, tstate.tts_lwpid);
1816b725ae77Skettenis }
1817b725ae77Skettenis
1818b725ae77Skettenis /* Did we just single-step a single thread, without letting any
1819b725ae77Skettenis * of the others run? Is this an event for that thread?
1820b725ae77Skettenis *
1821b725ae77Skettenis * If so, we believe our client would prefer to see this event
1822b725ae77Skettenis * over any others. (Typically the client wants to just push
1823b725ae77Skettenis * one thread a little farther forward, and then go around
1824b725ae77Skettenis * checking for what all threads are doing.)
1825b725ae77Skettenis */
1826b725ae77Skettenis else if (doing_fake_step && (tstate.tts_lwpid == fake_step_tid))
1827b725ae77Skettenis {
1828b725ae77Skettenis #ifdef WAIT_BUFFER_DEBUG
1829b725ae77Skettenis /* It's possible here to see either a SIGTRAP (due to
1830b725ae77Skettenis * successful completion of a step) or a SYSCALL_ENTRY
1831b725ae77Skettenis * (due to a step completion with active hardware
1832b725ae77Skettenis * watchpoints).
1833b725ae77Skettenis */
1834b725ae77Skettenis if (debug_on)
1835b725ae77Skettenis printf ("Ending fake step with tid %d, state %s\n",
1836b725ae77Skettenis tstate.tts_lwpid,
1837b725ae77Skettenis get_printable_name_of_ttrace_event (tstate.tts_event));
1838b725ae77Skettenis #endif
1839b725ae77Skettenis
1840b725ae77Skettenis /* Remember this one, and throw away any previous
1841b725ae77Skettenis * candidate.
1842b725ae77Skettenis */
1843b725ae77Skettenis candidate_tid = tstate.tts_lwpid;
1844b725ae77Skettenis candidate_tstate = tstate;
1845b725ae77Skettenis }
1846b725ae77Skettenis
1847b725ae77Skettenis #ifdef FORGET_DELETED_BPTS
1848b725ae77Skettenis
1849b725ae77Skettenis /* We can't just do this, as if we do, and then wind
1850b725ae77Skettenis * up the loop with no unhandled events, we need to
1851b725ae77Skettenis * handle that case--the appropriate reaction is to
1852b725ae77Skettenis * just continue, but there's no easy way to do that.
1853b725ae77Skettenis *
1854b725ae77Skettenis * Better to put this in the ttrace_wait call--if, when
1855b725ae77Skettenis * we fake a wait, we update our events based on the
1856b725ae77Skettenis * breakpoint_here_pc call and find there are no more events,
1857b725ae77Skettenis * then we better continue and so on.
1858b725ae77Skettenis *
1859b725ae77Skettenis * Or we could put it in the next/continue fake.
1860b725ae77Skettenis * But it has to go in the buffering code, not in the
1861b725ae77Skettenis * real go/wait code.
1862b725ae77Skettenis */
1863b725ae77Skettenis else if ((TTEVT_SIGNAL == tstate.tts_event)
1864b725ae77Skettenis && (5 == tstate.tts_u.tts_signal.tts_signo)
1865b725ae77Skettenis && (0 != get_raw_pc (tstate.tts_lwpid))
1866b725ae77Skettenis && !breakpoint_here_p (get_raw_pc (tstate.tts_lwpid)))
1867b725ae77Skettenis {
1868b725ae77Skettenis /*
1869b725ae77Skettenis * If the user deleted a breakpoint while this
1870b725ae77Skettenis * breakpoint-hit event was buffered, we can forget
1871b725ae77Skettenis * it now.
1872b725ae77Skettenis */
1873b725ae77Skettenis #ifdef WAIT_BUFFER_DEBUG
1874b725ae77Skettenis if (debug_on)
1875b725ae77Skettenis printf ("Forgetting deleted bp hit for thread %d\n",
1876b725ae77Skettenis tstate.tts_lwpid);
1877b725ae77Skettenis #endif
1878b725ae77Skettenis
1879b725ae77Skettenis set_handled (pid, tstate.tts_lwpid);
1880b725ae77Skettenis }
1881b725ae77Skettenis #endif
1882b725ae77Skettenis
1883b725ae77Skettenis /* Else, is this the first "unhandled" event? If so,
1884b725ae77Skettenis * we believe our client wants to see it (if we don't
1885b725ae77Skettenis * see a fake-step later on in the scan).
1886b725ae77Skettenis */
1887b725ae77Skettenis else if (!was_handled (tstate.tts_lwpid) && candidate_tid == 0)
1888b725ae77Skettenis {
1889b725ae77Skettenis candidate_tid = tstate.tts_lwpid;
1890b725ae77Skettenis candidate_tstate = tstate;
1891b725ae77Skettenis }
1892b725ae77Skettenis
1893b725ae77Skettenis /* This is either an event that has already been "handled",
1894b725ae77Skettenis * and thus we believe is uninteresting to our client, or we
1895b725ae77Skettenis * already have a candidate event. Ignore it...
1896b725ae77Skettenis */
1897b725ae77Skettenis }
1898b725ae77Skettenis
1899b725ae77Skettenis /* What do we report?
1900b725ae77Skettenis */
1901b725ae77Skettenis if (doing_fake_step)
1902b725ae77Skettenis {
1903b725ae77Skettenis if (candidate_tid == fake_step_tid)
1904b725ae77Skettenis {
1905b725ae77Skettenis /* Fake step.
1906b725ae77Skettenis */
1907b725ae77Skettenis tstate = candidate_tstate;
1908b725ae77Skettenis }
1909b725ae77Skettenis else
1910b725ae77Skettenis {
1911b725ae77Skettenis warning ("Internal error: fake-step failed to complete.");
1912b725ae77Skettenis return 0;
1913b725ae77Skettenis }
1914b725ae77Skettenis }
1915b725ae77Skettenis else if (candidate_tid != 0)
1916b725ae77Skettenis {
1917b725ae77Skettenis /* Found a candidate unhandled event.
1918b725ae77Skettenis */
1919b725ae77Skettenis tstate = candidate_tstate;
1920b725ae77Skettenis }
1921b725ae77Skettenis else if (tid != 0)
1922b725ae77Skettenis {
1923b725ae77Skettenis warning ("Internal error in call of ttrace_wait.");
1924b725ae77Skettenis return 0;
1925b725ae77Skettenis }
1926b725ae77Skettenis else
1927b725ae77Skettenis {
1928b725ae77Skettenis warning ("Internal error: no unhandled thread event to select");
1929b725ae77Skettenis return 0;
1930b725ae77Skettenis }
1931b725ae77Skettenis
1932b725ae77Skettenis copy_ttstate_t (tsp, &tstate);
1933b725ae77Skettenis return 1;
1934b725ae77Skettenis } /* End of select_stopped_thread_of_process */
1935b725ae77Skettenis
1936b725ae77Skettenis #ifdef PARANOIA
1937b725ae77Skettenis /* Check our internal thread data against the real thing.
1938b725ae77Skettenis */
1939b725ae77Skettenis static void
check_thread_consistency(pid_t real_pid)1940b725ae77Skettenis check_thread_consistency (pid_t real_pid)
1941b725ae77Skettenis {
1942b725ae77Skettenis int tid; /* really lwpid_t */
1943b725ae77Skettenis ttstate_t tstate;
1944b725ae77Skettenis thread_info *p;
1945b725ae77Skettenis
1946b725ae77Skettenis /* Spin down the O/S list of threads, checking that they
1947b725ae77Skettenis * match what we've got.
1948b725ae77Skettenis */
1949b725ae77Skettenis for (tid = get_process_first_stopped_thread_id (real_pid, &tstate);
1950b725ae77Skettenis tid != 0;
1951b725ae77Skettenis tid = get_process_next_stopped_thread_id (real_pid, &tstate))
1952b725ae77Skettenis {
1953b725ae77Skettenis
1954b725ae77Skettenis p = find_thread_info (tid);
1955b725ae77Skettenis
1956b725ae77Skettenis if (NULL == p)
1957b725ae77Skettenis {
1958b725ae77Skettenis warning ("No internal thread data for thread %d.", tid);
1959b725ae77Skettenis continue;
1960b725ae77Skettenis }
1961b725ae77Skettenis
1962b725ae77Skettenis if (!p->seen)
1963b725ae77Skettenis {
1964b725ae77Skettenis warning ("Inconsistent internal thread data for thread %d.", tid);
1965b725ae77Skettenis }
1966b725ae77Skettenis
1967b725ae77Skettenis if (p->terminated)
1968b725ae77Skettenis {
1969b725ae77Skettenis warning ("Thread %d is not terminated, internal error.", tid);
1970b725ae77Skettenis continue;
1971b725ae77Skettenis }
1972b725ae77Skettenis
1973b725ae77Skettenis
1974b725ae77Skettenis #define TT_COMPARE( fld ) \
1975b725ae77Skettenis tstate.fld != p->last_stop_state.fld
1976b725ae77Skettenis
1977b725ae77Skettenis if (p->have_state)
1978b725ae77Skettenis {
1979b725ae77Skettenis if (TT_COMPARE (tts_pid)
1980b725ae77Skettenis || TT_COMPARE (tts_lwpid)
1981b725ae77Skettenis || TT_COMPARE (tts_user_tid)
1982b725ae77Skettenis || TT_COMPARE (tts_event)
1983b725ae77Skettenis || TT_COMPARE (tts_flags)
1984b725ae77Skettenis || TT_COMPARE (tts_scno)
1985b725ae77Skettenis || TT_COMPARE (tts_scnargs))
1986b725ae77Skettenis {
1987b725ae77Skettenis warning ("Internal thread data for thread %d is wrong.", tid);
1988b725ae77Skettenis continue;
1989b725ae77Skettenis }
1990b725ae77Skettenis }
1991b725ae77Skettenis }
1992b725ae77Skettenis }
1993b725ae77Skettenis #endif /* PARANOIA */
1994b725ae77Skettenis
1995b725ae77Skettenis
1996b725ae77Skettenis /* This function wraps calls to "call_real_ttrace_wait" so
1997b725ae77Skettenis * that a actual wait is only done when all pending events
1998b725ae77Skettenis * have been reported.
1999b725ae77Skettenis *
2000b725ae77Skettenis * Note that typically it is called with a pid of "0", i.e.
2001b725ae77Skettenis * the "don't care" value.
2002b725ae77Skettenis *
2003b725ae77Skettenis * Return value is the status of the pseudo wait.
2004b725ae77Skettenis */
2005b725ae77Skettenis static int
call_ttrace_wait(int pid,ttwopt_t option,ttstate_t * tsp,size_t tsp_size)2006b725ae77Skettenis call_ttrace_wait (int pid, ttwopt_t option, ttstate_t *tsp, size_t tsp_size)
2007b725ae77Skettenis {
2008b725ae77Skettenis /* This holds the actual, for-real, true process ID.
2009b725ae77Skettenis */
2010b725ae77Skettenis static int real_pid;
2011b725ae77Skettenis
2012b725ae77Skettenis /* As an argument to ttrace_wait, zero pid
2013b725ae77Skettenis * means "Any process", and zero tid means
2014b725ae77Skettenis * "Any thread of the specified process".
2015b725ae77Skettenis */
2016b725ae77Skettenis int wait_pid = 0;
2017b725ae77Skettenis lwpid_t wait_tid = 0;
2018b725ae77Skettenis lwpid_t real_tid;
2019b725ae77Skettenis
2020b725ae77Skettenis int ttw_status = 0; /* To be returned */
2021b725ae77Skettenis
2022b725ae77Skettenis thread_info *tinfo = NULL;
2023b725ae77Skettenis
2024b725ae77Skettenis if (pid != 0)
2025b725ae77Skettenis {
2026b725ae77Skettenis /* Unexpected case.
2027b725ae77Skettenis */
2028b725ae77Skettenis #ifdef THREAD_DEBUG
2029b725ae77Skettenis if (debug_on)
2030b725ae77Skettenis printf ("TW: Pid to wait on is %d\n", pid);
2031b725ae77Skettenis #endif
2032b725ae77Skettenis
2033b725ae77Skettenis if (!any_thread_records ())
2034b725ae77Skettenis error ("No thread records for ttrace call w. specific pid");
2035b725ae77Skettenis
2036b725ae77Skettenis /* OK, now the task is to translate the incoming tid into
2037b725ae77Skettenis * a pid/tid pair.
2038b725ae77Skettenis */
2039b725ae77Skettenis real_tid = map_from_gdb_tid (pid);
2040b725ae77Skettenis real_pid = get_pid_for (real_tid);
2041b725ae77Skettenis #ifdef THREAD_DEBUG
2042b725ae77Skettenis if (debug_on)
2043b725ae77Skettenis printf ("==TW: real pid %d, real tid %d\n", real_pid, real_tid);
2044b725ae77Skettenis #endif
2045b725ae77Skettenis }
2046b725ae77Skettenis
2047b725ae77Skettenis
2048b725ae77Skettenis /* Sanity checks and set-up.
2049b725ae77Skettenis * Process State
2050b725ae77Skettenis *
2051b725ae77Skettenis * Stopped Running Fake-step (v)Fork
2052b725ae77Skettenis * \________________________________________
2053b725ae77Skettenis * |
2054b725ae77Skettenis * No buffered events | error wait wait wait
2055b725ae77Skettenis * |
2056b725ae77Skettenis * Buffered events | debuffer error wait debuffer (?)
2057b725ae77Skettenis *
2058b725ae77Skettenis */
2059b725ae77Skettenis if (more_events_left == 0)
2060b725ae77Skettenis {
2061b725ae77Skettenis
2062b725ae77Skettenis if (process_state == RUNNING)
2063b725ae77Skettenis {
2064b725ae77Skettenis /* OK--normal call of ttrace_wait with no buffered events.
2065b725ae77Skettenis */
2066b725ae77Skettenis ;
2067b725ae77Skettenis }
2068b725ae77Skettenis else if (process_state == FAKE_STEPPING)
2069b725ae77Skettenis {
2070b725ae77Skettenis /* Ok--call of ttrace_wait to support
2071b725ae77Skettenis * fake stepping with no buffered events.
2072b725ae77Skettenis *
2073b725ae77Skettenis * But we better be fake-stepping!
2074b725ae77Skettenis */
2075b725ae77Skettenis if (!doing_fake_step)
2076b725ae77Skettenis {
2077b725ae77Skettenis warning ("Inconsistent thread state.");
2078b725ae77Skettenis }
2079b725ae77Skettenis }
2080b725ae77Skettenis else if ((process_state == FORKING)
2081b725ae77Skettenis || (process_state == VFORKING))
2082b725ae77Skettenis {
2083b725ae77Skettenis /* Ok--there are two processes, so waiting
2084b725ae77Skettenis * for the second while the first is stopped
2085b725ae77Skettenis * is ok. Handled bits stay as they were.
2086b725ae77Skettenis */
2087b725ae77Skettenis ;
2088b725ae77Skettenis }
2089b725ae77Skettenis else if (process_state == STOPPED)
2090b725ae77Skettenis {
2091b725ae77Skettenis warning ("Process not running at wait call.");
2092b725ae77Skettenis }
2093b725ae77Skettenis else
2094b725ae77Skettenis /* No known state.
2095b725ae77Skettenis */
2096b725ae77Skettenis warning ("Inconsistent process state.");
2097b725ae77Skettenis }
2098b725ae77Skettenis
2099b725ae77Skettenis else
2100b725ae77Skettenis {
2101b725ae77Skettenis /* More events left
2102b725ae77Skettenis */
2103b725ae77Skettenis if (process_state == STOPPED)
2104b725ae77Skettenis {
2105b725ae77Skettenis /* OK--buffered events being unbuffered.
2106b725ae77Skettenis */
2107b725ae77Skettenis ;
2108b725ae77Skettenis }
2109b725ae77Skettenis else if (process_state == RUNNING)
2110b725ae77Skettenis {
2111b725ae77Skettenis /* An error--shouldn't have buffered events
2112b725ae77Skettenis * when running.
2113b725ae77Skettenis */
2114b725ae77Skettenis warning ("Trying to continue with buffered events:");
2115b725ae77Skettenis }
2116b725ae77Skettenis else if (process_state == FAKE_STEPPING)
2117b725ae77Skettenis {
2118b725ae77Skettenis /*
2119b725ae77Skettenis * Better be fake-stepping!
2120b725ae77Skettenis */
2121b725ae77Skettenis if (!doing_fake_step)
2122b725ae77Skettenis {
2123b725ae77Skettenis warning ("Losing buffered thread events!\n");
2124b725ae77Skettenis }
2125b725ae77Skettenis }
2126b725ae77Skettenis else if ((process_state == FORKING)
2127b725ae77Skettenis || (process_state == VFORKING))
2128b725ae77Skettenis {
2129b725ae77Skettenis /* Ok--there are two processes, so waiting
2130b725ae77Skettenis * for the second while the first is stopped
2131b725ae77Skettenis * is ok. Handled bits stay as they were.
2132b725ae77Skettenis */
2133b725ae77Skettenis ;
2134b725ae77Skettenis }
2135b725ae77Skettenis else
2136b725ae77Skettenis warning ("Process in unknown state with buffered events.");
2137b725ae77Skettenis }
2138b725ae77Skettenis
2139b725ae77Skettenis /* Sometimes we have to wait for a particular thread
2140b725ae77Skettenis * (if we're stepping over a bpt). In that case, we
2141b725ae77Skettenis * _know_ it's going to complete the single-step we
2142b725ae77Skettenis * asked for (because we're only doing the step under
2143b725ae77Skettenis * certain very well-understood circumstances), so it
2144b725ae77Skettenis * can't block.
2145b725ae77Skettenis */
2146b725ae77Skettenis if (doing_fake_step)
2147b725ae77Skettenis {
2148b725ae77Skettenis wait_tid = fake_step_tid;
2149b725ae77Skettenis wait_pid = get_pid_for (fake_step_tid);
2150b725ae77Skettenis
2151b725ae77Skettenis #ifdef WAIT_BUFFER_DEBUG
2152b725ae77Skettenis if (debug_on)
2153b725ae77Skettenis printf ("Doing a wait after a fake-step for %d, pid %d\n",
2154b725ae77Skettenis wait_tid, wait_pid);
2155b725ae77Skettenis #endif
2156b725ae77Skettenis }
2157b725ae77Skettenis
2158b725ae77Skettenis if (more_events_left == 0 /* No buffered events, need real ones. */
2159b725ae77Skettenis || process_state != STOPPED)
2160b725ae77Skettenis {
2161b725ae77Skettenis /* If there are no buffered events, and so we need
2162b725ae77Skettenis * real ones, or if we are FORKING, VFORKING,
2163b725ae77Skettenis * FAKE_STEPPING or RUNNING, and thus have to do
2164b725ae77Skettenis * a real wait, then do a real wait.
2165b725ae77Skettenis */
2166b725ae77Skettenis
2167b725ae77Skettenis #ifdef WAIT_BUFFER_DEBUG
2168b725ae77Skettenis /* Normal case... */
2169b725ae77Skettenis if (debug_on)
2170b725ae77Skettenis printf ("TW: do it for real; pid %d, tid %d\n", wait_pid, wait_tid);
2171b725ae77Skettenis #endif
2172b725ae77Skettenis
2173b725ae77Skettenis /* The actual wait call.
2174b725ae77Skettenis */
2175b725ae77Skettenis ttw_status = call_real_ttrace_wait (wait_pid, wait_tid, option, tsp, tsp_size);
2176b725ae77Skettenis
2177b725ae77Skettenis /* Note that the routines we'll call will be using "call_real_ttrace",
2178b725ae77Skettenis * not "call_ttrace", and thus need the real pid rather than the pseudo-tid
2179b725ae77Skettenis * the rest of the world uses (which is actually the tid).
2180b725ae77Skettenis */
2181b725ae77Skettenis real_pid = tsp->tts_pid;
2182b725ae77Skettenis
2183b725ae77Skettenis /* For most events: Stop the world!
2184b725ae77Skettenis
2185b725ae77Skettenis * It's sometimes not safe to stop all threads of a process.
2186b725ae77Skettenis * Sometimes it's not even safe to ask for the thread state
2187b725ae77Skettenis * of a process!
2188b725ae77Skettenis */
2189b725ae77Skettenis if (can_touch_threads_of_process (real_pid, tsp->tts_event))
2190b725ae77Skettenis {
2191b725ae77Skettenis /* If we're really only stepping a single thread, then don't
2192b725ae77Skettenis * try to stop all the others -- we only do this single-stepping
2193b725ae77Skettenis * business when all others were already stopped...and the stop
2194b725ae77Skettenis * would mess up other threads' events.
2195b725ae77Skettenis *
2196b725ae77Skettenis * Similiarly, if there are other threads with events,
2197b725ae77Skettenis * don't do the stop.
2198b725ae77Skettenis */
2199b725ae77Skettenis if (!doing_fake_step)
2200b725ae77Skettenis {
2201b725ae77Skettenis if (more_events_left > 0)
2202b725ae77Skettenis warning ("Internal error in stopping process");
2203b725ae77Skettenis
2204b725ae77Skettenis stop_all_threads_of_process (real_pid);
2205b725ae77Skettenis
2206b725ae77Skettenis /* At this point, we could scan and update_thread_list(),
2207b725ae77Skettenis * and only use the local list for the rest of the
2208b725ae77Skettenis * module! We'd get rid of the scans in the various
2209b725ae77Skettenis * continue routines (adding one in attach). It'd
2210b725ae77Skettenis * be great--UPGRADE ME!
2211b725ae77Skettenis */
2212b725ae77Skettenis }
2213b725ae77Skettenis }
2214b725ae77Skettenis
2215b725ae77Skettenis #ifdef PARANOIA
2216b725ae77Skettenis else if (debug_on)
2217b725ae77Skettenis {
2218b725ae77Skettenis if (more_events_left > 0)
2219b725ae77Skettenis printf ("== Can't stop process; more events!\n");
2220b725ae77Skettenis else
2221b725ae77Skettenis printf ("== Can't stop process!\n");
2222b725ae77Skettenis }
2223b725ae77Skettenis #endif
2224b725ae77Skettenis
2225b725ae77Skettenis process_state = STOPPED;
2226b725ae77Skettenis
2227b725ae77Skettenis #ifdef WAIT_BUFFER_DEBUG
2228b725ae77Skettenis if (debug_on)
2229b725ae77Skettenis printf ("Process set to STOPPED\n");
2230b725ae77Skettenis #endif
2231b725ae77Skettenis }
2232b725ae77Skettenis
2233b725ae77Skettenis else
2234b725ae77Skettenis {
2235b725ae77Skettenis /* Fake a call to ttrace_wait. The process must be
2236b725ae77Skettenis * STOPPED, as we aren't going to do any wait.
2237b725ae77Skettenis */
2238b725ae77Skettenis #ifdef WAIT_BUFFER_DEBUG
2239b725ae77Skettenis if (debug_on)
2240b725ae77Skettenis printf ("TW: fake it\n");
2241b725ae77Skettenis #endif
2242b725ae77Skettenis
2243b725ae77Skettenis if (process_state != STOPPED)
2244b725ae77Skettenis {
2245b725ae77Skettenis warning ("Process not stopped at wait call, in state '%s'.\n",
2246b725ae77Skettenis get_printable_name_of_process_state (process_state));
2247b725ae77Skettenis }
2248b725ae77Skettenis
2249b725ae77Skettenis if (doing_fake_step)
2250b725ae77Skettenis error ("Internal error in stepping over breakpoint");
2251b725ae77Skettenis
2252b725ae77Skettenis ttw_status = 0; /* Faking it is always successful! */
2253b725ae77Skettenis } /* End of fake or not? if */
2254b725ae77Skettenis
2255b725ae77Skettenis /* Pick an event to pass to our caller. Be paranoid.
2256b725ae77Skettenis */
2257b725ae77Skettenis if (!select_stopped_thread_of_process (real_pid, tsp))
2258b725ae77Skettenis warning ("Can't find event, using previous event.");
2259b725ae77Skettenis
2260b725ae77Skettenis else if (tsp->tts_event == TTEVT_NONE)
2261b725ae77Skettenis warning ("Internal error: no thread has a real event.");
2262b725ae77Skettenis
2263b725ae77Skettenis else if (doing_fake_step)
2264b725ae77Skettenis {
2265b725ae77Skettenis if (fake_step_tid != tsp->tts_lwpid)
2266b725ae77Skettenis warning ("Internal error in stepping over breakpoint.");
2267b725ae77Skettenis
2268b725ae77Skettenis /* This wait clears the (current) fake-step if there was one.
2269b725ae77Skettenis */
2270b725ae77Skettenis doing_fake_step = 0;
2271b725ae77Skettenis fake_step_tid = 0;
2272b725ae77Skettenis }
2273b725ae77Skettenis
2274b725ae77Skettenis /* We now have a correct tsp and ttw_status for the thread
2275b725ae77Skettenis * which we want to report. So it's "handled"! This call
2276b725ae77Skettenis * will add it to our list if it's not there already.
2277b725ae77Skettenis */
2278b725ae77Skettenis set_handled (real_pid, tsp->tts_lwpid);
2279b725ae77Skettenis
2280b725ae77Skettenis /* Save a copy of the ttrace state of this thread, in our local
2281b725ae77Skettenis thread descriptor.
2282b725ae77Skettenis
2283b725ae77Skettenis This caches the state. The implementation of queries like
2284b725ae77Skettenis hpux_has_execd can then use this cached state, rather than
2285b725ae77Skettenis be forced to make an explicit ttrace call to get it.
2286b725ae77Skettenis
2287b725ae77Skettenis (Guard against the condition that this is the first time we've
2288b725ae77Skettenis waited on, i.e., seen this thread, and so haven't yet entered
2289b725ae77Skettenis it into our list of threads.)
2290b725ae77Skettenis */
2291b725ae77Skettenis tinfo = find_thread_info (tsp->tts_lwpid);
2292b725ae77Skettenis if (tinfo != NULL)
2293b725ae77Skettenis {
2294b725ae77Skettenis copy_ttstate_t (&tinfo->last_stop_state, tsp);
2295b725ae77Skettenis tinfo->have_state = 1;
2296b725ae77Skettenis }
2297b725ae77Skettenis
2298b725ae77Skettenis return ttw_status;
2299b725ae77Skettenis } /* call_ttrace_wait */
2300b725ae77Skettenis
2301b725ae77Skettenis #if defined(CHILD_REPORTED_EXEC_EVENTS_PER_EXEC_CALL)
2302b725ae77Skettenis int
child_reported_exec_events_per_exec_call(void)2303b725ae77Skettenis child_reported_exec_events_per_exec_call (void)
2304b725ae77Skettenis {
2305b725ae77Skettenis return 1; /* ttrace reports the event once per call. */
2306b725ae77Skettenis }
2307b725ae77Skettenis #endif
2308b725ae77Skettenis
2309b725ae77Skettenis
2310b725ae77Skettenis
2311b725ae77Skettenis /* Our implementation of hardware watchpoints involves making memory
2312b725ae77Skettenis pages write-protected. We must remember a page's original permissions,
2313b725ae77Skettenis and we must also know when it is appropriate to restore a page's
2314b725ae77Skettenis permissions to its original state.
2315b725ae77Skettenis
2316b725ae77Skettenis We use a "dictionary" of hardware-watched pages to do this. Each
2317b725ae77Skettenis hardware-watched page is recorded in the dictionary. Each page's
2318b725ae77Skettenis dictionary entry contains the original permissions and a reference
2319b725ae77Skettenis count. Pages are hashed into the dictionary by their start address.
2320b725ae77Skettenis
2321b725ae77Skettenis When hardware watchpoint is set on page X for the first time, page X
2322b725ae77Skettenis is added to the dictionary with a reference count of 1. If other
2323b725ae77Skettenis hardware watchpoints are subsequently set on page X, its reference
2324b725ae77Skettenis count is incremented. When hardware watchpoints are removed from
2325b725ae77Skettenis page X, its reference count is decremented. If a page's reference
2326b725ae77Skettenis count drops to 0, it's permissions are restored and the page's entry
2327b725ae77Skettenis is thrown out of the dictionary.
2328b725ae77Skettenis */
2329b725ae77Skettenis typedef struct memory_page
2330b725ae77Skettenis {
2331b725ae77Skettenis CORE_ADDR page_start;
2332b725ae77Skettenis int reference_count;
2333b725ae77Skettenis int original_permissions;
2334b725ae77Skettenis struct memory_page *next;
2335b725ae77Skettenis struct memory_page *previous;
2336b725ae77Skettenis }
2337b725ae77Skettenis memory_page_t;
2338b725ae77Skettenis
2339b725ae77Skettenis #define MEMORY_PAGE_DICTIONARY_BUCKET_COUNT 128
2340b725ae77Skettenis
2341b725ae77Skettenis static struct
2342b725ae77Skettenis {
2343b725ae77Skettenis LONGEST page_count;
2344b725ae77Skettenis int page_size;
2345b725ae77Skettenis int page_protections_allowed;
2346b725ae77Skettenis /* These are just the heads of chains of actual page descriptors. */
2347b725ae77Skettenis memory_page_t buckets[MEMORY_PAGE_DICTIONARY_BUCKET_COUNT];
2348b725ae77Skettenis }
2349b725ae77Skettenis memory_page_dictionary;
2350b725ae77Skettenis
2351b725ae77Skettenis
2352b725ae77Skettenis static void
require_memory_page_dictionary(void)2353b725ae77Skettenis require_memory_page_dictionary (void)
2354b725ae77Skettenis {
2355b725ae77Skettenis int i;
2356b725ae77Skettenis
2357b725ae77Skettenis /* Is the memory page dictionary ready for use? If so, we're done. */
2358b725ae77Skettenis if (memory_page_dictionary.page_count >= (LONGEST) 0)
2359b725ae77Skettenis return;
2360b725ae77Skettenis
2361b725ae77Skettenis /* Else, initialize it. */
2362b725ae77Skettenis memory_page_dictionary.page_count = (LONGEST) 0;
2363b725ae77Skettenis
2364b725ae77Skettenis for (i = 0; i < MEMORY_PAGE_DICTIONARY_BUCKET_COUNT; i++)
2365b725ae77Skettenis {
2366b725ae77Skettenis memory_page_dictionary.buckets[i].page_start = (CORE_ADDR) 0;
2367b725ae77Skettenis memory_page_dictionary.buckets[i].reference_count = 0;
2368b725ae77Skettenis memory_page_dictionary.buckets[i].next = NULL;
2369b725ae77Skettenis memory_page_dictionary.buckets[i].previous = NULL;
2370b725ae77Skettenis }
2371b725ae77Skettenis }
2372b725ae77Skettenis
2373b725ae77Skettenis
2374b725ae77Skettenis static void
retire_memory_page_dictionary(void)2375b725ae77Skettenis retire_memory_page_dictionary (void)
2376b725ae77Skettenis {
2377b725ae77Skettenis memory_page_dictionary.page_count = (LONGEST) - 1;
2378b725ae77Skettenis }
2379b725ae77Skettenis
2380b725ae77Skettenis
2381b725ae77Skettenis /* Write-protect the memory page that starts at this address.
2382b725ae77Skettenis
2383b725ae77Skettenis Returns the original permissions of the page.
2384b725ae77Skettenis */
2385b725ae77Skettenis static int
write_protect_page(int pid,CORE_ADDR page_start)2386b725ae77Skettenis write_protect_page (int pid, CORE_ADDR page_start)
2387b725ae77Skettenis {
2388b725ae77Skettenis int tt_status;
2389b725ae77Skettenis int original_permissions;
2390b725ae77Skettenis int new_permissions;
2391b725ae77Skettenis
2392b725ae77Skettenis tt_status = call_ttrace (TT_PROC_GET_MPROTECT,
2393b725ae77Skettenis pid,
2394b725ae77Skettenis (TTRACE_ARG_TYPE) page_start,
2395b725ae77Skettenis TT_NIL,
2396b725ae77Skettenis (TTRACE_ARG_TYPE) & original_permissions);
2397b725ae77Skettenis if (errno || (tt_status < 0))
2398b725ae77Skettenis {
2399b725ae77Skettenis return 0; /* What else can we do? */
2400b725ae77Skettenis }
2401b725ae77Skettenis
2402b725ae77Skettenis /* We'll also write-protect the page now, if that's allowed. */
2403b725ae77Skettenis if (memory_page_dictionary.page_protections_allowed)
2404b725ae77Skettenis {
2405b725ae77Skettenis new_permissions = original_permissions & ~PROT_WRITE;
2406b725ae77Skettenis tt_status = call_ttrace (TT_PROC_SET_MPROTECT,
2407b725ae77Skettenis pid,
2408b725ae77Skettenis (TTRACE_ARG_TYPE) page_start,
2409b725ae77Skettenis (TTRACE_ARG_TYPE) memory_page_dictionary.page_size,
2410b725ae77Skettenis (TTRACE_ARG_TYPE) new_permissions);
2411b725ae77Skettenis if (errno || (tt_status < 0))
2412b725ae77Skettenis {
2413b725ae77Skettenis return 0; /* What else can we do? */
2414b725ae77Skettenis }
2415b725ae77Skettenis }
2416b725ae77Skettenis
2417b725ae77Skettenis return original_permissions;
2418b725ae77Skettenis }
2419b725ae77Skettenis
2420b725ae77Skettenis
2421b725ae77Skettenis /* Unwrite-protect the memory page that starts at this address, restoring
2422b725ae77Skettenis (what we must assume are) its original permissions.
2423b725ae77Skettenis */
2424b725ae77Skettenis static void
unwrite_protect_page(int pid,CORE_ADDR page_start,int original_permissions)2425b725ae77Skettenis unwrite_protect_page (int pid, CORE_ADDR page_start, int original_permissions)
2426b725ae77Skettenis {
2427b725ae77Skettenis int tt_status;
2428b725ae77Skettenis
2429b725ae77Skettenis tt_status = call_ttrace (TT_PROC_SET_MPROTECT,
2430b725ae77Skettenis pid,
2431b725ae77Skettenis (TTRACE_ARG_TYPE) page_start,
2432b725ae77Skettenis (TTRACE_ARG_TYPE) memory_page_dictionary.page_size,
2433b725ae77Skettenis (TTRACE_ARG_TYPE) original_permissions);
2434b725ae77Skettenis if (errno || (tt_status < 0))
2435b725ae77Skettenis {
2436b725ae77Skettenis return; /* What else can we do? */
2437b725ae77Skettenis }
2438b725ae77Skettenis }
2439b725ae77Skettenis
2440b725ae77Skettenis
2441b725ae77Skettenis /* Memory page-protections are used to implement "hardware" watchpoints
2442b725ae77Skettenis on HP-UX.
2443b725ae77Skettenis
2444b725ae77Skettenis For every memory page that is currently being watched (i.e., that
2445b725ae77Skettenis presently should be write-protected), write-protect it.
2446b725ae77Skettenis */
2447b725ae77Skettenis void
hppa_enable_page_protection_events(int pid)2448b725ae77Skettenis hppa_enable_page_protection_events (int pid)
2449b725ae77Skettenis {
2450b725ae77Skettenis int bucket;
2451b725ae77Skettenis
2452b725ae77Skettenis memory_page_dictionary.page_protections_allowed = 1;
2453b725ae77Skettenis
2454b725ae77Skettenis for (bucket = 0; bucket < MEMORY_PAGE_DICTIONARY_BUCKET_COUNT; bucket++)
2455b725ae77Skettenis {
2456b725ae77Skettenis memory_page_t *page;
2457b725ae77Skettenis
2458b725ae77Skettenis page = memory_page_dictionary.buckets[bucket].next;
2459b725ae77Skettenis while (page != NULL)
2460b725ae77Skettenis {
2461b725ae77Skettenis page->original_permissions = write_protect_page (pid, page->page_start);
2462b725ae77Skettenis page = page->next;
2463b725ae77Skettenis }
2464b725ae77Skettenis }
2465b725ae77Skettenis }
2466b725ae77Skettenis
2467b725ae77Skettenis
2468b725ae77Skettenis /* Memory page-protections are used to implement "hardware" watchpoints
2469b725ae77Skettenis on HP-UX.
2470b725ae77Skettenis
2471b725ae77Skettenis For every memory page that is currently being watched (i.e., that
2472b725ae77Skettenis presently is or should be write-protected), un-write-protect it.
2473b725ae77Skettenis */
2474b725ae77Skettenis void
hppa_disable_page_protection_events(int pid)2475b725ae77Skettenis hppa_disable_page_protection_events (int pid)
2476b725ae77Skettenis {
2477b725ae77Skettenis int bucket;
2478b725ae77Skettenis
2479b725ae77Skettenis for (bucket = 0; bucket < MEMORY_PAGE_DICTIONARY_BUCKET_COUNT; bucket++)
2480b725ae77Skettenis {
2481b725ae77Skettenis memory_page_t *page;
2482b725ae77Skettenis
2483b725ae77Skettenis page = memory_page_dictionary.buckets[bucket].next;
2484b725ae77Skettenis while (page != NULL)
2485b725ae77Skettenis {
2486b725ae77Skettenis unwrite_protect_page (pid, page->page_start, page->original_permissions);
2487b725ae77Skettenis page = page->next;
2488b725ae77Skettenis }
2489b725ae77Skettenis }
2490b725ae77Skettenis
2491b725ae77Skettenis memory_page_dictionary.page_protections_allowed = 0;
2492b725ae77Skettenis }
2493b725ae77Skettenis
2494b725ae77Skettenis /* Count the number of outstanding events. At this
2495b725ae77Skettenis * point, we have selected one thread and its event
2496b725ae77Skettenis * as the one to be "reported" upwards to core gdb.
2497b725ae77Skettenis * That thread is already marked as "handled".
2498b725ae77Skettenis *
2499b725ae77Skettenis * Note: we could just scan our own thread list. FIXME!
2500b725ae77Skettenis */
2501b725ae77Skettenis static int
count_unhandled_events(int real_pid,lwpid_t real_tid)2502b725ae77Skettenis count_unhandled_events (int real_pid, lwpid_t real_tid)
2503b725ae77Skettenis {
2504b725ae77Skettenis ttstate_t tstate;
2505b725ae77Skettenis lwpid_t ttid;
2506b725ae77Skettenis int events_left;
2507b725ae77Skettenis
2508b725ae77Skettenis /* Ok, find out how many threads have real events to report.
2509b725ae77Skettenis */
2510b725ae77Skettenis events_left = 0;
2511b725ae77Skettenis ttid = get_process_first_stopped_thread_id (real_pid, &tstate);
2512b725ae77Skettenis
2513b725ae77Skettenis #ifdef THREAD_DEBUG
2514b725ae77Skettenis if (debug_on)
2515b725ae77Skettenis {
2516b725ae77Skettenis if (ttid == 0)
2517b725ae77Skettenis printf ("Process %d has no threads\n", real_pid);
2518b725ae77Skettenis else
2519b725ae77Skettenis printf ("Process %d has these threads:\n", real_pid);
2520b725ae77Skettenis }
2521b725ae77Skettenis #endif
2522b725ae77Skettenis
2523b725ae77Skettenis while (ttid > 0)
2524b725ae77Skettenis {
2525b725ae77Skettenis if (tstate.tts_event != TTEVT_NONE
2526b725ae77Skettenis && !was_handled (ttid))
2527b725ae77Skettenis {
2528b725ae77Skettenis /* TTEVT_NONE implies we just stopped it ourselves
2529b725ae77Skettenis * because we're the stop-the-world guys, so it's
2530b725ae77Skettenis * not an event from our point of view.
2531b725ae77Skettenis *
2532b725ae77Skettenis * If "was_handled" is true, this is an event we
2533b725ae77Skettenis * already handled, so don't count it.
2534b725ae77Skettenis *
2535b725ae77Skettenis * Note that we don't count the thread with the
2536b725ae77Skettenis * currently-reported event, as it's already marked
2537b725ae77Skettenis * as handled.
2538b725ae77Skettenis */
2539b725ae77Skettenis events_left++;
2540b725ae77Skettenis }
2541b725ae77Skettenis
2542b725ae77Skettenis #if defined( THREAD_DEBUG ) || defined( WAIT_BUFFER_DEBUG )
2543b725ae77Skettenis if (debug_on)
2544b725ae77Skettenis {
2545b725ae77Skettenis if (ttid == real_tid)
2546b725ae77Skettenis printf ("*"); /* Thread we're reporting */
2547b725ae77Skettenis else
2548b725ae77Skettenis printf (" ");
2549b725ae77Skettenis
2550b725ae77Skettenis if (tstate.tts_event != TTEVT_NONE)
2551b725ae77Skettenis printf ("+"); /* Thread with a real event */
2552b725ae77Skettenis else
2553b725ae77Skettenis printf (" ");
2554b725ae77Skettenis
2555b725ae77Skettenis if (was_handled (ttid))
2556b725ae77Skettenis printf ("h"); /* Thread has been handled */
2557b725ae77Skettenis else
2558b725ae77Skettenis printf (" ");
2559b725ae77Skettenis
2560b725ae77Skettenis printf (" %d, with event %s", ttid,
2561b725ae77Skettenis get_printable_name_of_ttrace_event (tstate.tts_event));
2562b725ae77Skettenis
2563b725ae77Skettenis if (tstate.tts_event == TTEVT_SIGNAL
2564b725ae77Skettenis && 5 == tstate.tts_u.tts_signal.tts_signo)
2565b725ae77Skettenis {
2566b725ae77Skettenis CORE_ADDR pc_val;
2567b725ae77Skettenis
2568b725ae77Skettenis pc_val = get_raw_pc (ttid);
2569b725ae77Skettenis
2570b725ae77Skettenis if (pc_val > 0)
2571b725ae77Skettenis printf (" breakpoint at 0x%x\n", pc_val);
2572b725ae77Skettenis else
2573b725ae77Skettenis printf (" bpt, can't fetch pc.\n");
2574b725ae77Skettenis }
2575b725ae77Skettenis else
2576b725ae77Skettenis printf ("\n");
2577b725ae77Skettenis }
2578b725ae77Skettenis #endif
2579b725ae77Skettenis
2580b725ae77Skettenis ttid = get_process_next_stopped_thread_id (real_pid, &tstate);
2581b725ae77Skettenis }
2582b725ae77Skettenis
2583b725ae77Skettenis #if defined( THREAD_DEBUG ) || defined( WAIT_BUFFER_DEBUG )
2584b725ae77Skettenis if (debug_on)
2585b725ae77Skettenis if (events_left > 0)
2586b725ae77Skettenis printf ("There are thus %d pending events\n", events_left);
2587b725ae77Skettenis #endif
2588b725ae77Skettenis
2589b725ae77Skettenis return events_left;
2590b725ae77Skettenis }
2591b725ae77Skettenis
2592b725ae77Skettenis /* This function is provided as a sop to clients that are calling
2593b725ae77Skettenis * ptrace_wait to wait for a process to stop. (see the
2594b725ae77Skettenis * implementation of child_wait.) Return value is the pid for
2595b725ae77Skettenis * the event that ended the wait.
2596b725ae77Skettenis *
2597b725ae77Skettenis * Note: used by core gdb and so uses the pseudo-pid (really tid).
2598b725ae77Skettenis */
2599b725ae77Skettenis int
ptrace_wait(ptid_t ptid,int * status)2600b725ae77Skettenis ptrace_wait (ptid_t ptid, int *status)
2601b725ae77Skettenis {
2602b725ae77Skettenis ttstate_t tsp;
2603b725ae77Skettenis int ttwait_return;
2604b725ae77Skettenis int real_pid;
2605b725ae77Skettenis ttstate_t state;
2606b725ae77Skettenis lwpid_t real_tid;
2607b725ae77Skettenis int return_pid;
2608b725ae77Skettenis
2609b725ae77Skettenis /* The ptrace implementation of this also ignores pid.
2610b725ae77Skettenis */
2611b725ae77Skettenis *status = 0;
2612b725ae77Skettenis
2613b725ae77Skettenis ttwait_return = call_ttrace_wait (0, TTRACE_WAITOK, &tsp, sizeof (tsp));
2614b725ae77Skettenis if (ttwait_return < 0)
2615b725ae77Skettenis {
2616b725ae77Skettenis /* ??rehrauer: It appears that if our inferior exits and we
2617b725ae77Skettenis haven't asked for exit events, that we're not getting any
2618b725ae77Skettenis indication save a negative return from ttrace_wait and an
2619b725ae77Skettenis errno set to ESRCH?
2620b725ae77Skettenis */
2621b725ae77Skettenis if (errno == ESRCH)
2622b725ae77Skettenis {
2623b725ae77Skettenis *status = 0; /* WIFEXITED */
2624b725ae77Skettenis return PIDGET (inferior_ptid);
2625b725ae77Skettenis }
2626b725ae77Skettenis
2627b725ae77Skettenis warning ("Call of ttrace_wait returned with errno %d.",
2628b725ae77Skettenis errno);
2629b725ae77Skettenis *status = ttwait_return;
2630b725ae77Skettenis return PIDGET (inferior_ptid);
2631b725ae77Skettenis }
2632b725ae77Skettenis
2633b725ae77Skettenis real_pid = tsp.tts_pid;
2634b725ae77Skettenis real_tid = tsp.tts_lwpid;
2635b725ae77Skettenis
2636b725ae77Skettenis /* One complication is that the "tts_event" structure has
2637b725ae77Skettenis * a set of flags, and more than one can be set. So we
2638b725ae77Skettenis * either have to force an order (as we do here), or handle
2639b725ae77Skettenis * more than one flag at a time.
2640b725ae77Skettenis */
2641b725ae77Skettenis if (tsp.tts_event & TTEVT_LWP_CREATE)
2642b725ae77Skettenis {
2643b725ae77Skettenis
2644b725ae77Skettenis /* Unlike what you might expect, this event is reported in
2645b725ae77Skettenis * the _creating_ thread, and the _created_ thread (whose tid
2646b725ae77Skettenis * we have) is still running. So we have to stop it. This
2647b725ae77Skettenis * has already been done in "call_ttrace_wait", but should we
2648b725ae77Skettenis * ever abandon the "stop-the-world" model, here's the command
2649b725ae77Skettenis * to use:
2650b725ae77Skettenis *
2651b725ae77Skettenis * call_ttrace( TT_LWP_STOP, real_tid, TT_NIL, TT_NIL, TT_NIL );
2652b725ae77Skettenis *
2653b725ae77Skettenis * Note that this would depend on being called _after_ "add_tthread"
2654b725ae77Skettenis * below for the tid-to-pid translation to be done in "call_ttrace".
2655b725ae77Skettenis */
2656b725ae77Skettenis
2657b725ae77Skettenis #ifdef THREAD_DEBUG
2658b725ae77Skettenis if (debug_on)
2659b725ae77Skettenis printf ("New thread: pid %d, tid %d, creator tid %d\n",
2660b725ae77Skettenis real_pid, tsp.tts_u.tts_thread.tts_target_lwpid,
2661b725ae77Skettenis real_tid);
2662b725ae77Skettenis #endif
2663b725ae77Skettenis
2664b725ae77Skettenis /* Now we have to return the tid of the created thread, not
2665b725ae77Skettenis * the creating thread, or "wait_for_inferior" won't know we
2666b725ae77Skettenis * have a new "process" (thread). Plus we should record it
2667b725ae77Skettenis * right, too.
2668b725ae77Skettenis */
2669b725ae77Skettenis real_tid = tsp.tts_u.tts_thread.tts_target_lwpid;
2670b725ae77Skettenis
2671b725ae77Skettenis add_tthread (real_pid, real_tid);
2672b725ae77Skettenis }
2673b725ae77Skettenis
2674b725ae77Skettenis else if ((tsp.tts_event & TTEVT_LWP_TERMINATE)
2675b725ae77Skettenis || (tsp.tts_event & TTEVT_LWP_EXIT))
2676b725ae77Skettenis {
2677b725ae77Skettenis
2678b725ae77Skettenis #ifdef THREAD_DEBUG
2679b725ae77Skettenis if (debug_on)
2680b725ae77Skettenis printf ("Thread dies: %d\n", real_tid);
2681b725ae77Skettenis #endif
2682b725ae77Skettenis
2683b725ae77Skettenis del_tthread (real_tid);
2684b725ae77Skettenis }
2685b725ae77Skettenis
2686b725ae77Skettenis else if (tsp.tts_event & TTEVT_EXEC)
2687b725ae77Skettenis {
2688b725ae77Skettenis
2689b725ae77Skettenis #ifdef THREAD_DEBUG
2690b725ae77Skettenis if (debug_on)
2691b725ae77Skettenis printf ("Pid %d has zero'th thread %d; inferior pid is %d\n",
2692b725ae77Skettenis real_pid, real_tid, PIDGET (inferior_ptid));
2693b725ae77Skettenis #endif
2694b725ae77Skettenis
2695b725ae77Skettenis add_tthread (real_pid, real_tid);
2696b725ae77Skettenis }
2697b725ae77Skettenis
2698b725ae77Skettenis #ifdef THREAD_DEBUG
2699b725ae77Skettenis else if (debug_on)
2700b725ae77Skettenis {
2701b725ae77Skettenis printf ("Process-level event %s, using tid %d\n",
2702b725ae77Skettenis get_printable_name_of_ttrace_event (tsp.tts_event),
2703b725ae77Skettenis real_tid);
2704b725ae77Skettenis
2705b725ae77Skettenis /* OK to do this, as "add_tthread" won't add
2706b725ae77Skettenis * duplicate entries. Also OK not to do it,
2707b725ae77Skettenis * as this event isn't one which can change the
2708b725ae77Skettenis * thread state.
2709b725ae77Skettenis */
2710b725ae77Skettenis add_tthread (real_pid, real_tid);
2711b725ae77Skettenis }
2712b725ae77Skettenis #endif
2713b725ae77Skettenis
2714b725ae77Skettenis
2715b725ae77Skettenis /* How many events are left to report later?
2716b725ae77Skettenis * In a non-stop-the-world model, this isn't needed.
2717b725ae77Skettenis *
2718b725ae77Skettenis * Note that it's not always safe to query the thread state of a process,
2719b725ae77Skettenis * which is what count_unhandled_events does. (If unsafe, we're left with
2720b725ae77Skettenis * no other resort than to assume that no more events remain...)
2721b725ae77Skettenis */
2722b725ae77Skettenis if (can_touch_threads_of_process (real_pid, tsp.tts_event))
2723b725ae77Skettenis more_events_left = count_unhandled_events (real_pid, real_tid);
2724b725ae77Skettenis
2725b725ae77Skettenis else
2726b725ae77Skettenis {
2727b725ae77Skettenis if (more_events_left > 0)
2728b725ae77Skettenis warning ("Vfork or fork causing loss of %d buffered events.",
2729b725ae77Skettenis more_events_left);
2730b725ae77Skettenis
2731b725ae77Skettenis more_events_left = 0;
2732b725ae77Skettenis }
2733b725ae77Skettenis
2734b725ae77Skettenis /* Attempt to translate the ttrace_wait-returned status into the
2735b725ae77Skettenis ptrace equivalent.
2736b725ae77Skettenis
2737b725ae77Skettenis ??rehrauer: This is somewhat fragile. We really ought to rewrite
2738b725ae77Skettenis clients that expect to pick apart a ptrace wait status, to use
2739b725ae77Skettenis something a little more abstract.
2740b725ae77Skettenis */
2741b725ae77Skettenis if ((tsp.tts_event & TTEVT_EXEC)
2742b725ae77Skettenis || (tsp.tts_event & TTEVT_FORK)
2743b725ae77Skettenis || (tsp.tts_event & TTEVT_VFORK))
2744b725ae77Skettenis {
2745b725ae77Skettenis /* Forks come in pairs (parent and child), so core gdb
2746b725ae77Skettenis * will do two waits. Be ready to notice this.
2747b725ae77Skettenis */
2748b725ae77Skettenis if (tsp.tts_event & TTEVT_FORK)
2749b725ae77Skettenis {
2750b725ae77Skettenis process_state = FORKING;
2751b725ae77Skettenis
2752b725ae77Skettenis #ifdef WAIT_BUFFER_DEBUG
2753b725ae77Skettenis if (debug_on)
2754b725ae77Skettenis printf ("Process set to FORKING\n");
2755b725ae77Skettenis #endif
2756b725ae77Skettenis }
2757b725ae77Skettenis else if (tsp.tts_event & TTEVT_VFORK)
2758b725ae77Skettenis {
2759b725ae77Skettenis process_state = VFORKING;
2760b725ae77Skettenis
2761b725ae77Skettenis #ifdef WAIT_BUFFER_DEBUG
2762b725ae77Skettenis if (debug_on)
2763b725ae77Skettenis printf ("Process set to VFORKING\n");
2764b725ae77Skettenis #endif
2765b725ae77Skettenis }
2766b725ae77Skettenis
2767b725ae77Skettenis /* Make an exec or fork look like a breakpoint. Definitely a hack,
2768b725ae77Skettenis but I don't think non HP-UX-specific clients really carefully
2769b725ae77Skettenis inspect the first events they get after inferior startup, so
2770b725ae77Skettenis it probably almost doesn't matter what we claim this is.
2771b725ae77Skettenis */
2772b725ae77Skettenis
2773b725ae77Skettenis #ifdef THREAD_DEBUG
2774b725ae77Skettenis if (debug_on)
2775b725ae77Skettenis printf ("..a process 'event'\n");
2776b725ae77Skettenis #endif
2777b725ae77Skettenis
2778b725ae77Skettenis /* Also make fork and exec events look like bpts, so they can be caught.
2779b725ae77Skettenis */
2780b725ae77Skettenis *status = 0177 | (_SIGTRAP << 8);
2781b725ae77Skettenis }
2782b725ae77Skettenis
2783b725ae77Skettenis /* Special-cases: We ask for syscall entry and exit events to implement
2784b725ae77Skettenis "fast" (aka "hardware") watchpoints.
2785b725ae77Skettenis
2786b725ae77Skettenis When we get a syscall entry, we want to disable page-protections,
2787b725ae77Skettenis and resume the inferior; this isn't an event we wish for
2788b725ae77Skettenis wait_for_inferior to see. Note that we must resume ONLY the
2789b725ae77Skettenis thread that reported the syscall entry; we don't want to allow
2790b725ae77Skettenis other threads to run with the page protections off, as they might
2791b725ae77Skettenis then be able to write to watch memory without it being caught.
2792b725ae77Skettenis
2793b725ae77Skettenis When we get a syscall exit, we want to reenable page-protections,
2794b725ae77Skettenis but we don't want to resume the inferior; this is an event we wish
2795b725ae77Skettenis wait_for_inferior to see. Make it look like the signal we normally
2796b725ae77Skettenis get for a single-step completion. This should cause wait_for_inferior
2797b725ae77Skettenis to evaluate whether any watchpoint triggered.
2798b725ae77Skettenis
2799b725ae77Skettenis Or rather, that's what we'd LIKE to do for syscall exit; we can't,
2800b725ae77Skettenis due to some HP-UX "features". Some syscalls have problems with
2801b725ae77Skettenis write-protections on some pages, and some syscalls seem to have
2802b725ae77Skettenis pending writes to those pages at the time we're getting the return
2803b725ae77Skettenis event. So, we'll single-step the inferior to get out of the syscall,
2804b725ae77Skettenis and then reenable protections.
2805b725ae77Skettenis
2806b725ae77Skettenis Note that we're intentionally allowing the syscall exit case to
2807b725ae77Skettenis fall through into the succeeding cases, as sometimes we single-
2808b725ae77Skettenis step out of one syscall only to immediately enter another...
2809b725ae77Skettenis */
2810b725ae77Skettenis else if ((tsp.tts_event & TTEVT_SYSCALL_ENTRY)
2811b725ae77Skettenis || (tsp.tts_event & TTEVT_SYSCALL_RETURN))
2812b725ae77Skettenis {
2813b725ae77Skettenis /* Make a syscall event look like a breakpoint. Same comments
2814b725ae77Skettenis as for exec & fork events.
2815b725ae77Skettenis */
2816b725ae77Skettenis #ifdef THREAD_DEBUG
2817b725ae77Skettenis if (debug_on)
2818b725ae77Skettenis printf ("..a syscall 'event'\n");
2819b725ae77Skettenis #endif
2820b725ae77Skettenis
2821b725ae77Skettenis /* Also make syscall events look like bpts, so they can be caught.
2822b725ae77Skettenis */
2823b725ae77Skettenis *status = 0177 | (_SIGTRAP << 8);
2824b725ae77Skettenis }
2825b725ae77Skettenis
2826b725ae77Skettenis else if ((tsp.tts_event & TTEVT_LWP_CREATE)
2827b725ae77Skettenis || (tsp.tts_event & TTEVT_LWP_TERMINATE)
2828b725ae77Skettenis || (tsp.tts_event & TTEVT_LWP_EXIT))
2829b725ae77Skettenis {
2830b725ae77Skettenis /* Make a thread event look like a breakpoint. Same comments
2831b725ae77Skettenis * as for exec & fork events.
2832b725ae77Skettenis */
2833b725ae77Skettenis #ifdef THREAD_DEBUG
2834b725ae77Skettenis if (debug_on)
2835b725ae77Skettenis printf ("..a thread 'event'\n");
2836b725ae77Skettenis #endif
2837b725ae77Skettenis
2838b725ae77Skettenis /* Also make thread events look like bpts, so they can be caught.
2839b725ae77Skettenis */
2840b725ae77Skettenis *status = 0177 | (_SIGTRAP << 8);
2841b725ae77Skettenis }
2842b725ae77Skettenis
2843b725ae77Skettenis else if ((tsp.tts_event & TTEVT_EXIT))
2844b725ae77Skettenis { /* WIFEXITED */
2845b725ae77Skettenis
2846b725ae77Skettenis #ifdef THREAD_DEBUG
2847b725ae77Skettenis if (debug_on)
2848b725ae77Skettenis printf ("..an exit\n");
2849b725ae77Skettenis #endif
2850b725ae77Skettenis
2851b725ae77Skettenis /* Prevent rest of gdb from thinking this is
2852b725ae77Skettenis * a new thread if for some reason it's never
2853b725ae77Skettenis * seen the main thread before.
2854b725ae77Skettenis */
2855b725ae77Skettenis inferior_ptid = pid_to_ptid (map_to_gdb_tid (real_tid)); /* HACK, FIX */
2856b725ae77Skettenis
2857b725ae77Skettenis *status = 0 | (tsp.tts_u.tts_exit.tts_exitcode);
2858b725ae77Skettenis }
2859b725ae77Skettenis
2860b725ae77Skettenis else if (tsp.tts_event & TTEVT_SIGNAL)
2861b725ae77Skettenis { /* WIFSTOPPED */
2862b725ae77Skettenis #ifdef THREAD_DEBUG
2863b725ae77Skettenis if (debug_on)
2864b725ae77Skettenis printf ("..a signal, %d\n", tsp.tts_u.tts_signal.tts_signo);
2865b725ae77Skettenis #endif
2866b725ae77Skettenis
2867b725ae77Skettenis *status = 0177 | (tsp.tts_u.tts_signal.tts_signo << 8);
2868b725ae77Skettenis }
2869b725ae77Skettenis
2870b725ae77Skettenis else
2871b725ae77Skettenis { /* !WIFSTOPPED */
2872b725ae77Skettenis
2873b725ae77Skettenis /* This means the process or thread terminated. But we should've
2874b725ae77Skettenis caught an explicit exit/termination above. So warn (this is
2875b725ae77Skettenis really an internal error) and claim the process or thread
2876b725ae77Skettenis terminated with a SIGTRAP.
2877b725ae77Skettenis */
2878b725ae77Skettenis
2879b725ae77Skettenis warning ("process_wait: unknown process state");
2880b725ae77Skettenis
2881b725ae77Skettenis #ifdef THREAD_DEBUG
2882b725ae77Skettenis if (debug_on)
2883b725ae77Skettenis printf ("Process-level event %s, using tid %d\n",
2884b725ae77Skettenis get_printable_name_of_ttrace_event (tsp.tts_event),
2885b725ae77Skettenis real_tid);
2886b725ae77Skettenis #endif
2887b725ae77Skettenis
2888b725ae77Skettenis *status = _SIGTRAP;
2889b725ae77Skettenis }
2890b725ae77Skettenis
2891b725ae77Skettenis #ifdef THREAD_DEBUG
2892b725ae77Skettenis if (debug_on)
2893b725ae77Skettenis printf ("Done waiting, pid is %d, tid %d\n", real_pid, real_tid);
2894b725ae77Skettenis #endif
2895b725ae77Skettenis
2896b725ae77Skettenis /* All code external to this module uses the tid, but calls
2897b725ae77Skettenis * it "pid". There's some tweaking so that the outside sees
2898b725ae77Skettenis * the first thread as having the same number as the starting
2899b725ae77Skettenis * pid.
2900b725ae77Skettenis */
2901b725ae77Skettenis return_pid = map_to_gdb_tid (real_tid);
2902b725ae77Skettenis
2903b725ae77Skettenis if (real_tid == 0 || return_pid == 0)
2904b725ae77Skettenis {
2905b725ae77Skettenis warning ("Internal error: process-wait failed.");
2906b725ae77Skettenis }
2907b725ae77Skettenis
2908b725ae77Skettenis return return_pid;
2909b725ae77Skettenis }
2910b725ae77Skettenis
2911b725ae77Skettenis
2912b725ae77Skettenis /* This function causes the caller's process to be traced by its
2913b725ae77Skettenis parent. This is intended to be called after GDB forks itself,
2914b725ae77Skettenis and before the child execs the target. Despite the name, it
2915b725ae77Skettenis is called by the child.
2916b725ae77Skettenis
2917b725ae77Skettenis Note that HP-UX ttrace is rather funky in how this is done.
2918b725ae77Skettenis If the parent wants to get the initial exec event of a child,
2919b725ae77Skettenis it must set the ttrace event mask of the child to include execs.
2920b725ae77Skettenis (The child cannot do this itself.) This must be done after the
2921b725ae77Skettenis child is forked, but before it execs.
2922b725ae77Skettenis
2923b725ae77Skettenis To coordinate the parent and child, we implement a semaphore using
2924b725ae77Skettenis pipes. After SETTRC'ing itself, the child tells the parent that
2925b725ae77Skettenis it is now traceable by the parent, and waits for the parent's
2926b725ae77Skettenis acknowledgement. The parent can then set the child's event mask,
2927b725ae77Skettenis and notify the child that it can now exec.
2928b725ae77Skettenis
2929b725ae77Skettenis (The acknowledgement by parent happens as a result of a call to
2930b725ae77Skettenis child_acknowledge_created_inferior.)
2931b725ae77Skettenis */
2932b725ae77Skettenis int
parent_attach_all(int p1,PTRACE_ARG3_TYPE p2,int p3)2933b725ae77Skettenis parent_attach_all (int p1, PTRACE_ARG3_TYPE p2, int p3)
2934b725ae77Skettenis {
2935b725ae77Skettenis int tt_status;
2936b725ae77Skettenis
2937b725ae77Skettenis /* We need a memory home for a constant, to pass it to ttrace.
2938b725ae77Skettenis The value of the constant is arbitrary, so long as both
2939b725ae77Skettenis parent and child use the same value. Might as well use the
2940b725ae77Skettenis "magic" constant provided by ttrace...
2941b725ae77Skettenis */
2942b725ae77Skettenis uint64_t tc_magic_child = TT_VERSION;
2943b725ae77Skettenis uint64_t tc_magic_parent = 0;
2944b725ae77Skettenis
2945b725ae77Skettenis tt_status = call_real_ttrace (
2946b725ae77Skettenis TT_PROC_SETTRC,
2947b725ae77Skettenis (int) TT_NIL,
2948b725ae77Skettenis (lwpid_t) TT_NIL,
2949b725ae77Skettenis TT_NIL,
2950b725ae77Skettenis (TTRACE_ARG_TYPE) TT_VERSION,
2951b725ae77Skettenis TT_NIL);
2952b725ae77Skettenis
2953b725ae77Skettenis if (tt_status < 0)
2954b725ae77Skettenis return tt_status;
2955b725ae77Skettenis
2956b725ae77Skettenis /* Notify the parent that we're potentially ready to exec(). */
2957b725ae77Skettenis write (startup_semaphore.child_channel[SEM_TALK],
2958b725ae77Skettenis &tc_magic_child,
2959b725ae77Skettenis sizeof (tc_magic_child));
2960b725ae77Skettenis
2961b725ae77Skettenis /* Wait for acknowledgement from the parent. */
2962b725ae77Skettenis read (startup_semaphore.parent_channel[SEM_LISTEN],
2963b725ae77Skettenis &tc_magic_parent,
2964b725ae77Skettenis sizeof (tc_magic_parent));
2965b725ae77Skettenis
2966b725ae77Skettenis if (tc_magic_child != tc_magic_parent)
2967b725ae77Skettenis warning ("mismatched semaphore magic");
2968b725ae77Skettenis
2969b725ae77Skettenis /* Discard our copy of the semaphore. */
2970b725ae77Skettenis (void) close (startup_semaphore.parent_channel[SEM_LISTEN]);
2971b725ae77Skettenis (void) close (startup_semaphore.parent_channel[SEM_TALK]);
2972b725ae77Skettenis (void) close (startup_semaphore.child_channel[SEM_LISTEN]);
2973b725ae77Skettenis (void) close (startup_semaphore.child_channel[SEM_TALK]);
2974b725ae77Skettenis
2975b725ae77Skettenis return tt_status;
2976b725ae77Skettenis }
2977b725ae77Skettenis
2978b725ae77Skettenis /* Despite being file-local, this routine is dealing with
2979b725ae77Skettenis * actual process IDs, not thread ids. That's because it's
2980b725ae77Skettenis * called before the first "wait" call, and there's no map
2981b725ae77Skettenis * yet from tids to pids.
2982b725ae77Skettenis *
2983b725ae77Skettenis * When it is called, a forked child is running, but waiting on
2984b725ae77Skettenis * the semaphore. If you stop the child and re-start it,
2985b725ae77Skettenis * things get confused, so don't do that! An attached child is
2986b725ae77Skettenis * stopped.
2987b725ae77Skettenis *
2988b725ae77Skettenis * Since this is called after either attach or run, we
2989b725ae77Skettenis * have to be the common part of both.
2990b725ae77Skettenis */
2991b725ae77Skettenis static void
require_notification_of_events(int real_pid)2992b725ae77Skettenis require_notification_of_events (int real_pid)
2993b725ae77Skettenis {
2994b725ae77Skettenis int tt_status;
2995b725ae77Skettenis ttevent_t notifiable_events;
2996b725ae77Skettenis
2997b725ae77Skettenis lwpid_t tid;
2998b725ae77Skettenis ttstate_t thread_state;
2999b725ae77Skettenis
3000b725ae77Skettenis #ifdef THREAD_DEBUG
3001b725ae77Skettenis if (debug_on)
3002b725ae77Skettenis printf ("Require notif, pid is %d\n", real_pid);
3003b725ae77Skettenis #endif
3004b725ae77Skettenis
3005b725ae77Skettenis /* Temporary HACK: tell inftarg.c/child_wait to not
3006b725ae77Skettenis * loop until pids are the same.
3007b725ae77Skettenis */
3008b725ae77Skettenis not_same_real_pid = 0;
3009b725ae77Skettenis
3010b725ae77Skettenis sigemptyset (¬ifiable_events.tte_signals);
3011b725ae77Skettenis notifiable_events.tte_opts = TTEO_NONE;
3012b725ae77Skettenis
3013b725ae77Skettenis /* This ensures that forked children inherit their parent's
3014b725ae77Skettenis * event mask, which we're setting here.
3015b725ae77Skettenis *
3016b725ae77Skettenis * NOTE: if you debug gdb with itself, then the ultimate
3017b725ae77Skettenis * debuggee gets flags set by the outermost gdb, as
3018b725ae77Skettenis * a child of a child will still inherit.
3019b725ae77Skettenis */
3020b725ae77Skettenis notifiable_events.tte_opts |= TTEO_PROC_INHERIT;
3021b725ae77Skettenis
3022b725ae77Skettenis notifiable_events.tte_events = TTEVT_DEFAULT;
3023b725ae77Skettenis notifiable_events.tte_events |= TTEVT_SIGNAL;
3024b725ae77Skettenis notifiable_events.tte_events |= TTEVT_EXEC;
3025b725ae77Skettenis notifiable_events.tte_events |= TTEVT_EXIT;
3026b725ae77Skettenis notifiable_events.tte_events |= TTEVT_FORK;
3027b725ae77Skettenis notifiable_events.tte_events |= TTEVT_VFORK;
3028b725ae77Skettenis notifiable_events.tte_events |= TTEVT_LWP_CREATE;
3029b725ae77Skettenis notifiable_events.tte_events |= TTEVT_LWP_EXIT;
3030b725ae77Skettenis notifiable_events.tte_events |= TTEVT_LWP_TERMINATE;
3031b725ae77Skettenis
3032b725ae77Skettenis tt_status = call_real_ttrace (
3033b725ae77Skettenis TT_PROC_SET_EVENT_MASK,
3034b725ae77Skettenis real_pid,
3035b725ae77Skettenis (lwpid_t) TT_NIL,
3036b725ae77Skettenis (TTRACE_ARG_TYPE) & notifiable_events,
3037b725ae77Skettenis (TTRACE_ARG_TYPE) sizeof (notifiable_events),
3038b725ae77Skettenis TT_NIL);
3039b725ae77Skettenis }
3040b725ae77Skettenis
3041b725ae77Skettenis static void
require_notification_of_exec_events(int real_pid)3042b725ae77Skettenis require_notification_of_exec_events (int real_pid)
3043b725ae77Skettenis {
3044b725ae77Skettenis int tt_status;
3045b725ae77Skettenis ttevent_t notifiable_events;
3046b725ae77Skettenis
3047b725ae77Skettenis lwpid_t tid;
3048b725ae77Skettenis ttstate_t thread_state;
3049b725ae77Skettenis
3050b725ae77Skettenis #ifdef THREAD_DEBUG
3051b725ae77Skettenis if (debug_on)
3052b725ae77Skettenis printf ("Require notif, pid is %d\n", real_pid);
3053b725ae77Skettenis #endif
3054b725ae77Skettenis
3055b725ae77Skettenis /* Temporary HACK: tell inftarg.c/child_wait to not
3056b725ae77Skettenis * loop until pids are the same.
3057b725ae77Skettenis */
3058b725ae77Skettenis not_same_real_pid = 0;
3059b725ae77Skettenis
3060b725ae77Skettenis sigemptyset (¬ifiable_events.tte_signals);
3061b725ae77Skettenis notifiable_events.tte_opts = TTEO_NOSTRCCHLD;
3062b725ae77Skettenis
3063b725ae77Skettenis /* This ensures that forked children don't inherit their parent's
3064b725ae77Skettenis * event mask, which we're setting here.
3065b725ae77Skettenis */
3066b725ae77Skettenis notifiable_events.tte_opts &= ~TTEO_PROC_INHERIT;
3067b725ae77Skettenis
3068b725ae77Skettenis notifiable_events.tte_events = TTEVT_DEFAULT;
3069b725ae77Skettenis notifiable_events.tte_events |= TTEVT_EXEC;
3070b725ae77Skettenis notifiable_events.tte_events |= TTEVT_EXIT;
3071b725ae77Skettenis
3072b725ae77Skettenis tt_status = call_real_ttrace (
3073b725ae77Skettenis TT_PROC_SET_EVENT_MASK,
3074b725ae77Skettenis real_pid,
3075b725ae77Skettenis (lwpid_t) TT_NIL,
3076b725ae77Skettenis (TTRACE_ARG_TYPE) & notifiable_events,
3077b725ae77Skettenis (TTRACE_ARG_TYPE) sizeof (notifiable_events),
3078b725ae77Skettenis TT_NIL);
3079b725ae77Skettenis }
3080b725ae77Skettenis
3081b725ae77Skettenis
3082b725ae77Skettenis /* This function is called by the parent process, with pid being the
3083b725ae77Skettenis * ID of the child process, after the debugger has forked.
3084b725ae77Skettenis */
3085b725ae77Skettenis void
child_acknowledge_created_inferior(int pid)3086b725ae77Skettenis child_acknowledge_created_inferior (int pid)
3087b725ae77Skettenis {
3088b725ae77Skettenis /* We need a memory home for a constant, to pass it to ttrace.
3089b725ae77Skettenis The value of the constant is arbitrary, so long as both
3090b725ae77Skettenis parent and child use the same value. Might as well use the
3091b725ae77Skettenis "magic" constant provided by ttrace...
3092b725ae77Skettenis */
3093b725ae77Skettenis uint64_t tc_magic_parent = TT_VERSION;
3094b725ae77Skettenis uint64_t tc_magic_child = 0;
3095b725ae77Skettenis
3096b725ae77Skettenis /* Wait for the child to tell us that it has forked. */
3097b725ae77Skettenis read (startup_semaphore.child_channel[SEM_LISTEN],
3098b725ae77Skettenis &tc_magic_child,
3099b725ae77Skettenis sizeof (tc_magic_child));
3100b725ae77Skettenis
3101b725ae77Skettenis /* Clear thread info now. We'd like to do this in
3102b725ae77Skettenis * "require...", but that messes up attach.
3103b725ae77Skettenis */
3104b725ae77Skettenis clear_thread_info ();
3105b725ae77Skettenis
3106b725ae77Skettenis /* Tell the "rest of gdb" that the initial thread exists.
3107b725ae77Skettenis * This isn't really a hack. Other thread-based versions
3108b725ae77Skettenis * of gdb (e.g. gnu-nat.c) seem to do the same thing.
3109b725ae77Skettenis *
3110b725ae77Skettenis * Q: Why don't we also add this thread to the local
3111b725ae77Skettenis * list via "add_tthread"?
3112b725ae77Skettenis *
3113b725ae77Skettenis * A: Because we don't know the tid, and can't stop the
3114b725ae77Skettenis * the process safely to ask what it is. Anyway, we'll
3115b725ae77Skettenis * add it when it gets the EXEC event.
3116b725ae77Skettenis */
3117b725ae77Skettenis add_thread (pid_to_ptid (pid)); /* in thread.c */
3118b725ae77Skettenis
3119b725ae77Skettenis /* We can now set the child's ttrace event mask.
3120b725ae77Skettenis */
3121b725ae77Skettenis require_notification_of_exec_events (pid);
3122b725ae77Skettenis
3123b725ae77Skettenis /* Tell ourselves that the process is running.
3124b725ae77Skettenis */
3125b725ae77Skettenis process_state = RUNNING;
3126b725ae77Skettenis
3127b725ae77Skettenis /* Notify the child that it can exec. */
3128b725ae77Skettenis write (startup_semaphore.parent_channel[SEM_TALK],
3129b725ae77Skettenis &tc_magic_parent,
3130b725ae77Skettenis sizeof (tc_magic_parent));
3131b725ae77Skettenis
3132b725ae77Skettenis /* Discard our copy of the semaphore. */
3133b725ae77Skettenis (void) close (startup_semaphore.parent_channel[SEM_LISTEN]);
3134b725ae77Skettenis (void) close (startup_semaphore.parent_channel[SEM_TALK]);
3135b725ae77Skettenis (void) close (startup_semaphore.child_channel[SEM_LISTEN]);
3136b725ae77Skettenis (void) close (startup_semaphore.child_channel[SEM_TALK]);
3137b725ae77Skettenis }
3138b725ae77Skettenis
3139b725ae77Skettenis
3140b725ae77Skettenis /*
3141b725ae77Skettenis * arrange for notification of all events by
3142b725ae77Skettenis * calling require_notification_of_events.
3143b725ae77Skettenis */
3144b725ae77Skettenis void
child_post_startup_inferior(ptid_t ptid)3145b725ae77Skettenis child_post_startup_inferior (ptid_t ptid)
3146b725ae77Skettenis {
3147b725ae77Skettenis require_notification_of_events (PIDGET (ptid));
3148b725ae77Skettenis }
3149b725ae77Skettenis
3150b725ae77Skettenis /* From here on, we should expect tids rather than pids.
3151b725ae77Skettenis */
3152b725ae77Skettenis static void
hppa_enable_catch_fork(int tid)3153b725ae77Skettenis hppa_enable_catch_fork (int tid)
3154b725ae77Skettenis {
3155b725ae77Skettenis int tt_status;
3156b725ae77Skettenis ttevent_t ttrace_events;
3157b725ae77Skettenis
3158b725ae77Skettenis /* Get the set of events that are currently enabled.
3159b725ae77Skettenis */
3160b725ae77Skettenis tt_status = call_ttrace (TT_PROC_GET_EVENT_MASK,
3161b725ae77Skettenis tid,
3162b725ae77Skettenis (TTRACE_ARG_TYPE) & ttrace_events,
3163b725ae77Skettenis (TTRACE_ARG_TYPE) sizeof (ttrace_events),
3164b725ae77Skettenis TT_NIL);
3165b725ae77Skettenis if (errno)
3166b725ae77Skettenis perror_with_name ("ttrace");
3167b725ae77Skettenis
3168b725ae77Skettenis /* Add forks to that set. */
3169b725ae77Skettenis ttrace_events.tte_events |= TTEVT_FORK;
3170b725ae77Skettenis
3171b725ae77Skettenis #ifdef THREAD_DEBUG
3172b725ae77Skettenis if (debug_on)
3173b725ae77Skettenis printf ("enable fork, tid is %d\n", tid);
3174b725ae77Skettenis #endif
3175b725ae77Skettenis
3176b725ae77Skettenis tt_status = call_ttrace (TT_PROC_SET_EVENT_MASK,
3177b725ae77Skettenis tid,
3178b725ae77Skettenis (TTRACE_ARG_TYPE) & ttrace_events,
3179b725ae77Skettenis (TTRACE_ARG_TYPE) sizeof (ttrace_events),
3180b725ae77Skettenis TT_NIL);
3181b725ae77Skettenis if (errno)
3182b725ae77Skettenis perror_with_name ("ttrace");
3183b725ae77Skettenis }
3184b725ae77Skettenis
3185b725ae77Skettenis
3186b725ae77Skettenis static void
hppa_disable_catch_fork(int tid)3187b725ae77Skettenis hppa_disable_catch_fork (int tid)
3188b725ae77Skettenis {
3189b725ae77Skettenis int tt_status;
3190b725ae77Skettenis ttevent_t ttrace_events;
3191b725ae77Skettenis
3192b725ae77Skettenis /* Get the set of events that are currently enabled.
3193b725ae77Skettenis */
3194b725ae77Skettenis tt_status = call_ttrace (TT_PROC_GET_EVENT_MASK,
3195b725ae77Skettenis tid,
3196b725ae77Skettenis (TTRACE_ARG_TYPE) & ttrace_events,
3197b725ae77Skettenis (TTRACE_ARG_TYPE) sizeof (ttrace_events),
3198b725ae77Skettenis TT_NIL);
3199b725ae77Skettenis
3200b725ae77Skettenis if (errno)
3201b725ae77Skettenis perror_with_name ("ttrace");
3202b725ae77Skettenis
3203b725ae77Skettenis /* Remove forks from that set. */
3204b725ae77Skettenis ttrace_events.tte_events &= ~TTEVT_FORK;
3205b725ae77Skettenis
3206b725ae77Skettenis #ifdef THREAD_DEBUG
3207b725ae77Skettenis if (debug_on)
3208b725ae77Skettenis printf ("disable fork, tid is %d\n", tid);
3209b725ae77Skettenis #endif
3210b725ae77Skettenis
3211b725ae77Skettenis tt_status = call_ttrace (TT_PROC_SET_EVENT_MASK,
3212b725ae77Skettenis tid,
3213b725ae77Skettenis (TTRACE_ARG_TYPE) & ttrace_events,
3214b725ae77Skettenis (TTRACE_ARG_TYPE) sizeof (ttrace_events),
3215b725ae77Skettenis TT_NIL);
3216b725ae77Skettenis
3217b725ae77Skettenis if (errno)
3218b725ae77Skettenis perror_with_name ("ttrace");
3219b725ae77Skettenis }
3220b725ae77Skettenis
3221b725ae77Skettenis
3222b725ae77Skettenis #if defined(CHILD_INSERT_FORK_CATCHPOINT)
3223b725ae77Skettenis int
child_insert_fork_catchpoint(int tid)3224b725ae77Skettenis child_insert_fork_catchpoint (int tid)
3225b725ae77Skettenis {
3226b725ae77Skettenis /* Enable reporting of fork events from the kernel. */
3227b725ae77Skettenis /* ??rehrauer: For the moment, we're always enabling these events,
3228b725ae77Skettenis and just ignoring them if there's no catchpoint to catch them.
3229b725ae77Skettenis */
3230b725ae77Skettenis return 0;
3231b725ae77Skettenis }
3232b725ae77Skettenis #endif
3233b725ae77Skettenis
3234b725ae77Skettenis
3235b725ae77Skettenis #if defined(CHILD_REMOVE_FORK_CATCHPOINT)
3236b725ae77Skettenis int
child_remove_fork_catchpoint(int tid)3237b725ae77Skettenis child_remove_fork_catchpoint (int tid)
3238b725ae77Skettenis {
3239b725ae77Skettenis /* Disable reporting of fork events from the kernel. */
3240b725ae77Skettenis /* ??rehrauer: For the moment, we're always enabling these events,
3241b725ae77Skettenis and just ignoring them if there's no catchpoint to catch them.
3242b725ae77Skettenis */
3243b725ae77Skettenis return 0;
3244b725ae77Skettenis }
3245b725ae77Skettenis #endif
3246b725ae77Skettenis
3247b725ae77Skettenis
3248b725ae77Skettenis static void
hppa_enable_catch_vfork(int tid)3249b725ae77Skettenis hppa_enable_catch_vfork (int tid)
3250b725ae77Skettenis {
3251b725ae77Skettenis int tt_status;
3252b725ae77Skettenis ttevent_t ttrace_events;
3253b725ae77Skettenis
3254b725ae77Skettenis /* Get the set of events that are currently enabled.
3255b725ae77Skettenis */
3256b725ae77Skettenis tt_status = call_ttrace (TT_PROC_GET_EVENT_MASK,
3257b725ae77Skettenis tid,
3258b725ae77Skettenis (TTRACE_ARG_TYPE) & ttrace_events,
3259b725ae77Skettenis (TTRACE_ARG_TYPE) sizeof (ttrace_events),
3260b725ae77Skettenis TT_NIL);
3261b725ae77Skettenis
3262b725ae77Skettenis if (errno)
3263b725ae77Skettenis perror_with_name ("ttrace");
3264b725ae77Skettenis
3265b725ae77Skettenis /* Add vforks to that set. */
3266b725ae77Skettenis ttrace_events.tte_events |= TTEVT_VFORK;
3267b725ae77Skettenis
3268b725ae77Skettenis #ifdef THREAD_DEBUG
3269b725ae77Skettenis if (debug_on)
3270b725ae77Skettenis printf ("enable vfork, tid is %d\n", tid);
3271b725ae77Skettenis #endif
3272b725ae77Skettenis
3273b725ae77Skettenis tt_status = call_ttrace (TT_PROC_SET_EVENT_MASK,
3274b725ae77Skettenis tid,
3275b725ae77Skettenis (TTRACE_ARG_TYPE) & ttrace_events,
3276b725ae77Skettenis (TTRACE_ARG_TYPE) sizeof (ttrace_events),
3277b725ae77Skettenis TT_NIL);
3278b725ae77Skettenis
3279b725ae77Skettenis if (errno)
3280b725ae77Skettenis perror_with_name ("ttrace");
3281b725ae77Skettenis }
3282b725ae77Skettenis
3283b725ae77Skettenis
3284b725ae77Skettenis static void
hppa_disable_catch_vfork(int tid)3285b725ae77Skettenis hppa_disable_catch_vfork (int tid)
3286b725ae77Skettenis {
3287b725ae77Skettenis int tt_status;
3288b725ae77Skettenis ttevent_t ttrace_events;
3289b725ae77Skettenis
3290b725ae77Skettenis /* Get the set of events that are currently enabled. */
3291b725ae77Skettenis tt_status = call_ttrace (TT_PROC_GET_EVENT_MASK,
3292b725ae77Skettenis tid,
3293b725ae77Skettenis (TTRACE_ARG_TYPE) & ttrace_events,
3294b725ae77Skettenis (TTRACE_ARG_TYPE) sizeof (ttrace_events),
3295b725ae77Skettenis TT_NIL);
3296b725ae77Skettenis
3297b725ae77Skettenis if (errno)
3298b725ae77Skettenis perror_with_name ("ttrace");
3299b725ae77Skettenis
3300b725ae77Skettenis /* Remove vforks from that set. */
3301b725ae77Skettenis ttrace_events.tte_events &= ~TTEVT_VFORK;
3302b725ae77Skettenis
3303b725ae77Skettenis #ifdef THREAD_DEBUG
3304b725ae77Skettenis if (debug_on)
3305b725ae77Skettenis printf ("disable vfork, tid is %d\n", tid);
3306b725ae77Skettenis #endif
3307b725ae77Skettenis tt_status = call_ttrace (TT_PROC_SET_EVENT_MASK,
3308b725ae77Skettenis tid,
3309b725ae77Skettenis (TTRACE_ARG_TYPE) & ttrace_events,
3310b725ae77Skettenis (TTRACE_ARG_TYPE) sizeof (ttrace_events),
3311b725ae77Skettenis TT_NIL);
3312b725ae77Skettenis
3313b725ae77Skettenis if (errno)
3314b725ae77Skettenis perror_with_name ("ttrace");
3315b725ae77Skettenis }
3316b725ae77Skettenis
3317b725ae77Skettenis
3318b725ae77Skettenis #if defined(CHILD_INSERT_VFORK_CATCHPOINT)
3319b725ae77Skettenis int
child_insert_vfork_catchpoint(int tid)3320b725ae77Skettenis child_insert_vfork_catchpoint (int tid)
3321b725ae77Skettenis {
3322b725ae77Skettenis /* Enable reporting of vfork events from the kernel. */
3323b725ae77Skettenis /* ??rehrauer: For the moment, we're always enabling these events,
3324b725ae77Skettenis and just ignoring them if there's no catchpoint to catch them.
3325b725ae77Skettenis */
3326b725ae77Skettenis return 0;
3327b725ae77Skettenis }
3328b725ae77Skettenis #endif
3329b725ae77Skettenis
3330b725ae77Skettenis
3331b725ae77Skettenis #if defined(CHILD_REMOVE_VFORK_CATCHPOINT)
3332b725ae77Skettenis int
child_remove_vfork_catchpoint(int tid)3333b725ae77Skettenis child_remove_vfork_catchpoint (int tid)
3334b725ae77Skettenis {
3335b725ae77Skettenis /* Disable reporting of vfork events from the kernel. */
3336b725ae77Skettenis /* ??rehrauer: For the moment, we're always enabling these events,
3337b725ae77Skettenis and just ignoring them if there's no catchpoint to catch them.
3338b725ae77Skettenis */
3339b725ae77Skettenis return 0;
3340b725ae77Skettenis }
3341b725ae77Skettenis #endif
3342b725ae77Skettenis
3343b725ae77Skettenis /* Q: Do we need to map the returned process ID to a thread ID?
3344b725ae77Skettenis
3345b725ae77Skettenis * A: I don't think so--here we want a _real_ pid. Any later
3346b725ae77Skettenis * operations will call "require_notification_of_events" and
3347b725ae77Skettenis * start the mapping.
3348b725ae77Skettenis */
3349b725ae77Skettenis int
hpux_has_forked(int tid,int * childpid)3350b725ae77Skettenis hpux_has_forked (int tid, int *childpid)
3351b725ae77Skettenis {
3352b725ae77Skettenis int tt_status;
3353b725ae77Skettenis ttstate_t ttrace_state;
3354b725ae77Skettenis thread_info *tinfo;
3355b725ae77Skettenis
3356b725ae77Skettenis /* Do we have cached thread state that we can consult? If so, use it. */
3357b725ae77Skettenis tinfo = find_thread_info (map_from_gdb_tid (tid));
3358b725ae77Skettenis if (tinfo != NULL)
3359b725ae77Skettenis {
3360b725ae77Skettenis copy_ttstate_t (&ttrace_state, &tinfo->last_stop_state);
3361b725ae77Skettenis }
3362b725ae77Skettenis
3363b725ae77Skettenis /* Nope, must read the thread's current state */
3364b725ae77Skettenis else
3365b725ae77Skettenis {
3366b725ae77Skettenis tt_status = call_ttrace (TT_LWP_GET_STATE,
3367b725ae77Skettenis tid,
3368b725ae77Skettenis (TTRACE_ARG_TYPE) & ttrace_state,
3369b725ae77Skettenis (TTRACE_ARG_TYPE) sizeof (ttrace_state),
3370b725ae77Skettenis TT_NIL);
3371b725ae77Skettenis
3372b725ae77Skettenis if (errno)
3373b725ae77Skettenis perror_with_name ("ttrace");
3374b725ae77Skettenis
3375b725ae77Skettenis if (tt_status < 0)
3376b725ae77Skettenis return 0;
3377b725ae77Skettenis }
3378b725ae77Skettenis
3379b725ae77Skettenis if (ttrace_state.tts_event & TTEVT_FORK)
3380b725ae77Skettenis {
3381b725ae77Skettenis *childpid = ttrace_state.tts_u.tts_fork.tts_fpid;
3382b725ae77Skettenis return 1;
3383b725ae77Skettenis }
3384b725ae77Skettenis
3385b725ae77Skettenis return 0;
3386b725ae77Skettenis }
3387b725ae77Skettenis
3388b725ae77Skettenis /* See hpux_has_forked for pid discussion.
3389b725ae77Skettenis */
3390b725ae77Skettenis int
hpux_has_vforked(int tid,int * childpid)3391b725ae77Skettenis hpux_has_vforked (int tid, int *childpid)
3392b725ae77Skettenis {
3393b725ae77Skettenis int tt_status;
3394b725ae77Skettenis ttstate_t ttrace_state;
3395b725ae77Skettenis thread_info *tinfo;
3396b725ae77Skettenis
3397b725ae77Skettenis /* Do we have cached thread state that we can consult? If so, use it. */
3398b725ae77Skettenis tinfo = find_thread_info (map_from_gdb_tid (tid));
3399b725ae77Skettenis if (tinfo != NULL)
3400b725ae77Skettenis copy_ttstate_t (&ttrace_state, &tinfo->last_stop_state);
3401b725ae77Skettenis
3402b725ae77Skettenis /* Nope, must read the thread's current state */
3403b725ae77Skettenis else
3404b725ae77Skettenis {
3405b725ae77Skettenis tt_status = call_ttrace (TT_LWP_GET_STATE,
3406b725ae77Skettenis tid,
3407b725ae77Skettenis (TTRACE_ARG_TYPE) & ttrace_state,
3408b725ae77Skettenis (TTRACE_ARG_TYPE) sizeof (ttrace_state),
3409b725ae77Skettenis TT_NIL);
3410b725ae77Skettenis
3411b725ae77Skettenis if (errno)
3412b725ae77Skettenis perror_with_name ("ttrace");
3413b725ae77Skettenis
3414b725ae77Skettenis if (tt_status < 0)
3415b725ae77Skettenis return 0;
3416b725ae77Skettenis }
3417b725ae77Skettenis
3418b725ae77Skettenis if (ttrace_state.tts_event & TTEVT_VFORK)
3419b725ae77Skettenis {
3420b725ae77Skettenis *childpid = ttrace_state.tts_u.tts_fork.tts_fpid;
3421b725ae77Skettenis return 1;
3422b725ae77Skettenis }
3423b725ae77Skettenis
3424b725ae77Skettenis return 0;
3425b725ae77Skettenis }
3426b725ae77Skettenis
3427b725ae77Skettenis
3428b725ae77Skettenis #if defined(CHILD_INSERT_EXEC_CATCHPOINT)
3429b725ae77Skettenis int
child_insert_exec_catchpoint(int tid)3430b725ae77Skettenis child_insert_exec_catchpoint (int tid)
3431b725ae77Skettenis {
3432b725ae77Skettenis /* Enable reporting of exec events from the kernel. */
3433b725ae77Skettenis /* ??rehrauer: For the moment, we're always enabling these events,
3434b725ae77Skettenis and just ignoring them if there's no catchpoint to catch them.
3435b725ae77Skettenis */
3436b725ae77Skettenis return 0;
3437b725ae77Skettenis }
3438b725ae77Skettenis #endif
3439b725ae77Skettenis
3440b725ae77Skettenis
3441b725ae77Skettenis #if defined(CHILD_REMOVE_EXEC_CATCHPOINT)
3442b725ae77Skettenis int
child_remove_exec_catchpoint(int tid)3443b725ae77Skettenis child_remove_exec_catchpoint (int tid)
3444b725ae77Skettenis {
3445b725ae77Skettenis /* Disable reporting of execevents from the kernel. */
3446b725ae77Skettenis /* ??rehrauer: For the moment, we're always enabling these events,
3447b725ae77Skettenis and just ignoring them if there's no catchpoint to catch them.
3448b725ae77Skettenis */
3449b725ae77Skettenis return 0;
3450b725ae77Skettenis }
3451b725ae77Skettenis #endif
3452b725ae77Skettenis
3453b725ae77Skettenis
3454b725ae77Skettenis int
hpux_has_execd(int tid,char ** execd_pathname)3455b725ae77Skettenis hpux_has_execd (int tid, char **execd_pathname)
3456b725ae77Skettenis {
3457b725ae77Skettenis int tt_status;
3458b725ae77Skettenis ttstate_t ttrace_state;
3459b725ae77Skettenis thread_info *tinfo;
3460b725ae77Skettenis
3461b725ae77Skettenis /* Do we have cached thread state that we can consult? If so, use it. */
3462b725ae77Skettenis tinfo = find_thread_info (map_from_gdb_tid (tid));
3463b725ae77Skettenis if (tinfo != NULL)
3464b725ae77Skettenis copy_ttstate_t (&ttrace_state, &tinfo->last_stop_state);
3465b725ae77Skettenis
3466b725ae77Skettenis /* Nope, must read the thread's current state */
3467b725ae77Skettenis else
3468b725ae77Skettenis {
3469b725ae77Skettenis tt_status = call_ttrace (TT_LWP_GET_STATE,
3470b725ae77Skettenis tid,
3471b725ae77Skettenis (TTRACE_ARG_TYPE) & ttrace_state,
3472b725ae77Skettenis (TTRACE_ARG_TYPE) sizeof (ttrace_state),
3473b725ae77Skettenis TT_NIL);
3474b725ae77Skettenis
3475b725ae77Skettenis if (errno)
3476b725ae77Skettenis perror_with_name ("ttrace");
3477b725ae77Skettenis
3478b725ae77Skettenis if (tt_status < 0)
3479b725ae77Skettenis return 0;
3480b725ae77Skettenis }
3481b725ae77Skettenis
3482b725ae77Skettenis if (ttrace_state.tts_event & TTEVT_EXEC)
3483b725ae77Skettenis {
3484b725ae77Skettenis /* See child_pid_to_exec_file in this file: this is a macro.
3485b725ae77Skettenis */
3486b725ae77Skettenis char *exec_file = target_pid_to_exec_file (tid);
3487b725ae77Skettenis
3488b725ae77Skettenis *execd_pathname = savestring (exec_file, strlen (exec_file));
3489b725ae77Skettenis return 1;
3490b725ae77Skettenis }
3491b725ae77Skettenis
3492b725ae77Skettenis return 0;
3493b725ae77Skettenis }
3494b725ae77Skettenis
3495b725ae77Skettenis
3496b725ae77Skettenis int
hpux_has_syscall_event(int pid,enum target_waitkind * kind,int * syscall_id)3497b725ae77Skettenis hpux_has_syscall_event (int pid, enum target_waitkind *kind, int *syscall_id)
3498b725ae77Skettenis {
3499b725ae77Skettenis int tt_status;
3500b725ae77Skettenis ttstate_t ttrace_state;
3501b725ae77Skettenis thread_info *tinfo;
3502b725ae77Skettenis
3503b725ae77Skettenis /* Do we have cached thread state that we can consult? If so, use it. */
3504b725ae77Skettenis tinfo = find_thread_info (map_from_gdb_tid (pid));
3505b725ae77Skettenis if (tinfo != NULL)
3506b725ae77Skettenis copy_ttstate_t (&ttrace_state, &tinfo->last_stop_state);
3507b725ae77Skettenis
3508b725ae77Skettenis /* Nope, must read the thread's current state */
3509b725ae77Skettenis else
3510b725ae77Skettenis {
3511b725ae77Skettenis tt_status = call_ttrace (TT_LWP_GET_STATE,
3512b725ae77Skettenis pid,
3513b725ae77Skettenis (TTRACE_ARG_TYPE) & ttrace_state,
3514b725ae77Skettenis (TTRACE_ARG_TYPE) sizeof (ttrace_state),
3515b725ae77Skettenis TT_NIL);
3516b725ae77Skettenis
3517b725ae77Skettenis if (errno)
3518b725ae77Skettenis perror_with_name ("ttrace");
3519b725ae77Skettenis
3520b725ae77Skettenis if (tt_status < 0)
3521b725ae77Skettenis return 0;
3522b725ae77Skettenis }
3523b725ae77Skettenis
3524b725ae77Skettenis *kind = TARGET_WAITKIND_SPURIOUS; /* Until proven otherwise... */
3525b725ae77Skettenis *syscall_id = -1;
3526b725ae77Skettenis
3527b725ae77Skettenis if (ttrace_state.tts_event & TTEVT_SYSCALL_ENTRY)
3528b725ae77Skettenis *kind = TARGET_WAITKIND_SYSCALL_ENTRY;
3529b725ae77Skettenis else if (ttrace_state.tts_event & TTEVT_SYSCALL_RETURN)
3530b725ae77Skettenis *kind = TARGET_WAITKIND_SYSCALL_RETURN;
3531b725ae77Skettenis else
3532b725ae77Skettenis return 0;
3533b725ae77Skettenis
3534b725ae77Skettenis *syscall_id = ttrace_state.tts_scno;
3535b725ae77Skettenis return 1;
3536b725ae77Skettenis }
3537b725ae77Skettenis
3538b725ae77Skettenis
3539b725ae77Skettenis
3540b725ae77Skettenis #if defined(CHILD_THREAD_ALIVE)
3541b725ae77Skettenis
3542b725ae77Skettenis /* Check to see if the given thread is alive.
3543b725ae77Skettenis
3544b725ae77Skettenis * We'll trust the thread list, as the more correct
3545b725ae77Skettenis * approach of stopping the process and spinning down
3546b725ae77Skettenis * the OS's thread list is _very_ expensive.
3547b725ae77Skettenis *
3548b725ae77Skettenis * May need a FIXME for that reason.
3549b725ae77Skettenis */
3550b725ae77Skettenis int
child_thread_alive(ptid_t ptid)3551b725ae77Skettenis child_thread_alive (ptid_t ptid)
3552b725ae77Skettenis {
3553b725ae77Skettenis lwpid_t gdb_tid = PIDGET (ptid);
3554b725ae77Skettenis lwpid_t tid;
3555b725ae77Skettenis
3556b725ae77Skettenis /* This spins down the lists twice.
3557b725ae77Skettenis * Possible peformance improvement here!
3558b725ae77Skettenis */
3559b725ae77Skettenis tid = map_from_gdb_tid (gdb_tid);
3560b725ae77Skettenis return !is_terminated (tid);
3561b725ae77Skettenis }
3562b725ae77Skettenis
3563b725ae77Skettenis #endif
3564b725ae77Skettenis
3565b725ae77Skettenis
3566b725ae77Skettenis
3567b725ae77Skettenis /* This function attempts to read the specified number of bytes from the
3568b725ae77Skettenis save_state_t that is our view into the hardware registers, starting at
3569b725ae77Skettenis ss_offset, and ending at ss_offset + sizeof_buf - 1
3570b725ae77Skettenis
3571b725ae77Skettenis If this function succeeds, it deposits the fetched bytes into buf,
3572b725ae77Skettenis and returns 0.
3573b725ae77Skettenis
3574b725ae77Skettenis If it fails, it returns a negative result. The contents of buf are
3575b725ae77Skettenis undefined it this function fails.
3576b725ae77Skettenis */
3577b725ae77Skettenis int
read_from_register_save_state(int tid,TTRACE_ARG_TYPE ss_offset,char * buf,int sizeof_buf)3578b725ae77Skettenis read_from_register_save_state (int tid, TTRACE_ARG_TYPE ss_offset, char *buf,
3579b725ae77Skettenis int sizeof_buf)
3580b725ae77Skettenis {
3581b725ae77Skettenis int tt_status;
3582b725ae77Skettenis register_value_t register_value = 0;
3583b725ae77Skettenis
3584b725ae77Skettenis tt_status = call_ttrace (TT_LWP_RUREGS,
3585b725ae77Skettenis tid,
3586b725ae77Skettenis ss_offset,
3587b725ae77Skettenis (TTRACE_ARG_TYPE) sizeof_buf,
3588b725ae77Skettenis (TTRACE_ARG_TYPE) buf);
3589b725ae77Skettenis
3590b725ae77Skettenis if (tt_status == 1)
3591b725ae77Skettenis /* Map ttrace's version of success to our version.
3592b725ae77Skettenis * Sometime ttrace returns 0, but that's ok here.
3593b725ae77Skettenis */
3594b725ae77Skettenis return 0;
3595b725ae77Skettenis
3596b725ae77Skettenis return tt_status;
3597b725ae77Skettenis }
3598b725ae77Skettenis
3599b725ae77Skettenis
3600b725ae77Skettenis /* This function attempts to write the specified number of bytes to the
3601b725ae77Skettenis save_state_t that is our view into the hardware registers, starting at
3602b725ae77Skettenis ss_offset, and ending at ss_offset + sizeof_buf - 1
3603b725ae77Skettenis
3604b725ae77Skettenis If this function succeeds, it deposits the bytes in buf, and returns 0.
3605b725ae77Skettenis
3606b725ae77Skettenis If it fails, it returns a negative result. The contents of the save_state_t
3607b725ae77Skettenis are undefined it this function fails.
3608b725ae77Skettenis */
3609b725ae77Skettenis int
write_to_register_save_state(int tid,TTRACE_ARG_TYPE ss_offset,char * buf,int sizeof_buf)3610b725ae77Skettenis write_to_register_save_state (int tid, TTRACE_ARG_TYPE ss_offset, char *buf,
3611b725ae77Skettenis int sizeof_buf)
3612b725ae77Skettenis {
3613b725ae77Skettenis int tt_status;
3614b725ae77Skettenis register_value_t register_value = 0;
3615b725ae77Skettenis
3616b725ae77Skettenis tt_status = call_ttrace (TT_LWP_WUREGS,
3617b725ae77Skettenis tid,
3618b725ae77Skettenis ss_offset,
3619b725ae77Skettenis (TTRACE_ARG_TYPE) sizeof_buf,
3620b725ae77Skettenis (TTRACE_ARG_TYPE) buf);
3621b725ae77Skettenis return tt_status;
3622b725ae77Skettenis }
3623b725ae77Skettenis
3624b725ae77Skettenis
3625b725ae77Skettenis /* This function is a sop to the largeish number of direct calls
3626b725ae77Skettenis to call_ptrace that exist in other files. Rather than create
3627b725ae77Skettenis functions whose name abstracts away from ptrace, and change all
3628b725ae77Skettenis the present callers of call_ptrace, we'll do the expedient (and
3629b725ae77Skettenis perhaps only practical) thing.
3630b725ae77Skettenis
3631b725ae77Skettenis Note HP-UX explicitly disallows a mix of ptrace & ttrace on a traced
3632b725ae77Skettenis process. Thus, we must translate all ptrace requests into their
3633b725ae77Skettenis process-specific, ttrace equivalents.
3634b725ae77Skettenis */
3635b725ae77Skettenis int
call_ptrace(int pt_request,int gdb_tid,PTRACE_ARG3_TYPE addr,int data)3636b725ae77Skettenis call_ptrace (int pt_request, int gdb_tid, PTRACE_ARG3_TYPE addr, int data)
3637b725ae77Skettenis {
3638b725ae77Skettenis ttreq_t tt_request;
3639b725ae77Skettenis TTRACE_ARG_TYPE tt_addr = (TTRACE_ARG_TYPE) addr;
3640b725ae77Skettenis TTRACE_ARG_TYPE tt_data = (TTRACE_ARG_TYPE) data;
3641b725ae77Skettenis TTRACE_ARG_TYPE tt_addr2 = TT_NIL;
3642b725ae77Skettenis int tt_status;
3643b725ae77Skettenis register_value_t register_value;
3644b725ae77Skettenis int read_buf;
3645b725ae77Skettenis
3646b725ae77Skettenis /* Perform the necessary argument translation. Note that some
3647b725ae77Skettenis cases are funky enough in the ttrace realm that we handle them
3648b725ae77Skettenis very specially.
3649b725ae77Skettenis */
3650b725ae77Skettenis switch (pt_request)
3651b725ae77Skettenis {
3652b725ae77Skettenis /* The following cases cannot conveniently be handled conveniently
3653b725ae77Skettenis by merely adjusting the ptrace arguments and feeding into the
3654b725ae77Skettenis generic call to ttrace at the bottom of this function.
3655b725ae77Skettenis
3656b725ae77Skettenis Note that because all branches of this switch end in "return",
3657b725ae77Skettenis there's no need for any "break" statements.
3658b725ae77Skettenis */
3659b725ae77Skettenis case PT_SETTRC:
3660b725ae77Skettenis return parent_attach_all (0, 0, 0);
3661b725ae77Skettenis
3662b725ae77Skettenis case PT_RUREGS:
3663b725ae77Skettenis tt_status = read_from_register_save_state (gdb_tid,
3664b725ae77Skettenis tt_addr,
3665b725ae77Skettenis ®ister_value,
3666b725ae77Skettenis sizeof (register_value));
3667b725ae77Skettenis if (tt_status < 0)
3668b725ae77Skettenis return tt_status;
3669b725ae77Skettenis return register_value;
3670b725ae77Skettenis
3671b725ae77Skettenis case PT_WUREGS:
3672b725ae77Skettenis register_value = (int) tt_data;
3673b725ae77Skettenis tt_status = write_to_register_save_state (gdb_tid,
3674b725ae77Skettenis tt_addr,
3675b725ae77Skettenis ®ister_value,
3676b725ae77Skettenis sizeof (register_value));
3677b725ae77Skettenis return tt_status;
3678b725ae77Skettenis break;
3679b725ae77Skettenis
3680b725ae77Skettenis case PT_READ_I:
3681b725ae77Skettenis tt_status = call_ttrace (TT_PROC_RDTEXT, /* Implicit 4-byte xfer becomes block-xfer. */
3682b725ae77Skettenis gdb_tid,
3683b725ae77Skettenis tt_addr,
3684b725ae77Skettenis (TTRACE_ARG_TYPE) 4,
3685b725ae77Skettenis (TTRACE_ARG_TYPE) & read_buf);
3686b725ae77Skettenis if (tt_status < 0)
3687b725ae77Skettenis return tt_status;
3688b725ae77Skettenis return read_buf;
3689b725ae77Skettenis
3690b725ae77Skettenis case PT_READ_D:
3691b725ae77Skettenis tt_status = call_ttrace (TT_PROC_RDDATA, /* Implicit 4-byte xfer becomes block-xfer. */
3692b725ae77Skettenis gdb_tid,
3693b725ae77Skettenis tt_addr,
3694b725ae77Skettenis (TTRACE_ARG_TYPE) 4,
3695b725ae77Skettenis (TTRACE_ARG_TYPE) & read_buf);
3696b725ae77Skettenis if (tt_status < 0)
3697b725ae77Skettenis return tt_status;
3698b725ae77Skettenis return read_buf;
3699b725ae77Skettenis
3700b725ae77Skettenis case PT_ATTACH:
3701b725ae77Skettenis tt_status = call_real_ttrace (TT_PROC_ATTACH,
3702b725ae77Skettenis map_from_gdb_tid (gdb_tid),
3703b725ae77Skettenis (lwpid_t) TT_NIL,
3704b725ae77Skettenis tt_addr,
3705b725ae77Skettenis (TTRACE_ARG_TYPE) TT_VERSION,
3706b725ae77Skettenis tt_addr2);
3707b725ae77Skettenis if (tt_status < 0)
3708b725ae77Skettenis return tt_status;
3709b725ae77Skettenis return tt_status;
3710b725ae77Skettenis
3711b725ae77Skettenis /* The following cases are handled by merely adjusting the ptrace
3712b725ae77Skettenis arguments and feeding into the generic call to ttrace.
3713b725ae77Skettenis */
3714b725ae77Skettenis case PT_DETACH:
3715b725ae77Skettenis tt_request = TT_PROC_DETACH;
3716b725ae77Skettenis break;
3717b725ae77Skettenis
3718b725ae77Skettenis case PT_WRITE_I:
3719b725ae77Skettenis tt_request = TT_PROC_WRTEXT; /* Translates 4-byte xfer to block-xfer. */
3720b725ae77Skettenis tt_data = 4; /* This many bytes. */
3721b725ae77Skettenis tt_addr2 = (TTRACE_ARG_TYPE) & data; /* Address of xfer source. */
3722b725ae77Skettenis break;
3723b725ae77Skettenis
3724b725ae77Skettenis case PT_WRITE_D:
3725b725ae77Skettenis tt_request = TT_PROC_WRDATA; /* Translates 4-byte xfer to block-xfer. */
3726b725ae77Skettenis tt_data = 4; /* This many bytes. */
3727b725ae77Skettenis tt_addr2 = (TTRACE_ARG_TYPE) & data; /* Address of xfer source. */
3728b725ae77Skettenis break;
3729b725ae77Skettenis
3730b725ae77Skettenis case PT_RDTEXT:
3731b725ae77Skettenis tt_request = TT_PROC_RDTEXT;
3732b725ae77Skettenis break;
3733b725ae77Skettenis
3734b725ae77Skettenis case PT_RDDATA:
3735b725ae77Skettenis tt_request = TT_PROC_RDDATA;
3736b725ae77Skettenis break;
3737b725ae77Skettenis
3738b725ae77Skettenis case PT_WRTEXT:
3739b725ae77Skettenis tt_request = TT_PROC_WRTEXT;
3740b725ae77Skettenis break;
3741b725ae77Skettenis
3742b725ae77Skettenis case PT_WRDATA:
3743b725ae77Skettenis tt_request = TT_PROC_WRDATA;
3744b725ae77Skettenis break;
3745b725ae77Skettenis
3746b725ae77Skettenis case PT_CONTINUE:
3747b725ae77Skettenis tt_request = TT_PROC_CONTINUE;
3748b725ae77Skettenis break;
3749b725ae77Skettenis
3750b725ae77Skettenis case PT_STEP:
3751b725ae77Skettenis tt_request = TT_LWP_SINGLE; /* Should not be making this request? */
3752b725ae77Skettenis break;
3753b725ae77Skettenis
3754b725ae77Skettenis case PT_KILL:
3755b725ae77Skettenis tt_request = TT_PROC_EXIT;
3756b725ae77Skettenis break;
3757b725ae77Skettenis
3758b725ae77Skettenis case PT_GET_PROCESS_PATHNAME:
3759b725ae77Skettenis tt_request = TT_PROC_GET_PATHNAME;
3760b725ae77Skettenis break;
3761b725ae77Skettenis
3762b725ae77Skettenis default:
3763b725ae77Skettenis tt_request = pt_request; /* Let ttrace be the one to complain. */
3764b725ae77Skettenis break;
3765b725ae77Skettenis }
3766b725ae77Skettenis
3767b725ae77Skettenis return call_ttrace (tt_request,
3768b725ae77Skettenis gdb_tid,
3769b725ae77Skettenis tt_addr,
3770b725ae77Skettenis tt_data,
3771b725ae77Skettenis tt_addr2);
3772b725ae77Skettenis }
3773b725ae77Skettenis
3774b725ae77Skettenis /* Kill that pesky process!
3775b725ae77Skettenis */
3776b725ae77Skettenis void
kill_inferior(void)3777b725ae77Skettenis kill_inferior (void)
3778b725ae77Skettenis {
3779b725ae77Skettenis int tid;
3780b725ae77Skettenis int wait_status;
3781b725ae77Skettenis thread_info *t;
3782b725ae77Skettenis thread_info **paranoia;
3783b725ae77Skettenis int para_count, i;
3784b725ae77Skettenis
3785b725ae77Skettenis if (PIDGET (inferior_ptid) == 0)
3786b725ae77Skettenis return;
3787b725ae77Skettenis
3788b725ae77Skettenis /* Walk the list of "threads", some of which are "pseudo threads",
3789b725ae77Skettenis aka "processes". For each that is NOT inferior_ptid, stop it,
3790b725ae77Skettenis and detach it.
3791b725ae77Skettenis
3792b725ae77Skettenis You see, we may not have just a single process to kill. If we're
3793b725ae77Skettenis restarting or quitting or detaching just after the inferior has
3794b725ae77Skettenis forked, then we've actually two processes to clean up.
3795b725ae77Skettenis
3796b725ae77Skettenis But we can't just call target_mourn_inferior() for each, since that
3797b725ae77Skettenis zaps the target vector.
3798b725ae77Skettenis */
3799b725ae77Skettenis
3800b725ae77Skettenis paranoia = (thread_info **) xmalloc (thread_head.count *
3801b725ae77Skettenis sizeof (thread_info *));
3802b725ae77Skettenis para_count = 0;
3803b725ae77Skettenis
3804b725ae77Skettenis t = thread_head.head;
3805b725ae77Skettenis while (t)
3806b725ae77Skettenis {
3807b725ae77Skettenis
3808b725ae77Skettenis paranoia[para_count] = t;
3809b725ae77Skettenis for (i = 0; i < para_count; i++)
3810b725ae77Skettenis {
3811b725ae77Skettenis if (t->next == paranoia[i])
3812b725ae77Skettenis {
3813b725ae77Skettenis warning ("Bad data in gdb's thread data; repairing.");
3814b725ae77Skettenis t->next = 0;
3815b725ae77Skettenis }
3816b725ae77Skettenis }
3817b725ae77Skettenis para_count++;
3818b725ae77Skettenis
3819b725ae77Skettenis if (t->am_pseudo && (t->pid != PIDGET (inferior_ptid)))
3820b725ae77Skettenis {
3821b725ae77Skettenis call_ttrace (TT_PROC_EXIT,
3822b725ae77Skettenis t->pid,
3823b725ae77Skettenis TT_NIL,
3824b725ae77Skettenis TT_NIL,
3825b725ae77Skettenis TT_NIL);
3826b725ae77Skettenis }
3827b725ae77Skettenis t = t->next;
3828b725ae77Skettenis }
3829b725ae77Skettenis
3830b725ae77Skettenis xfree (paranoia);
3831b725ae77Skettenis
3832b725ae77Skettenis call_ttrace (TT_PROC_EXIT,
3833b725ae77Skettenis PIDGET (inferior_ptid),
3834b725ae77Skettenis TT_NIL,
3835b725ae77Skettenis TT_NIL,
3836b725ae77Skettenis TT_NIL);
3837b725ae77Skettenis target_mourn_inferior ();
3838b725ae77Skettenis clear_thread_info ();
3839b725ae77Skettenis }
3840b725ae77Skettenis
3841b725ae77Skettenis
3842*11efff7fSkettenis #ifndef DEPRECATED_CHILD_RESUME
3843b725ae77Skettenis
3844b725ae77Skettenis /* Sanity check a thread about to be continued.
3845b725ae77Skettenis */
3846b725ae77Skettenis static void
thread_dropping_event_check(thread_info * p)3847b725ae77Skettenis thread_dropping_event_check (thread_info *p)
3848b725ae77Skettenis {
3849b725ae77Skettenis if (!p->handled)
3850b725ae77Skettenis {
3851b725ae77Skettenis /*
3852b725ae77Skettenis * This seems to happen when we "next" over a
3853b725ae77Skettenis * "fork()" while following the parent. If it's
3854b725ae77Skettenis * the FORK event, that's ok. If it's a SIGNAL
3855b725ae77Skettenis * in the unfollowed child, that's ok to--but
3856b725ae77Skettenis * how can we know that's what's going on?
3857b725ae77Skettenis *
3858b725ae77Skettenis * FIXME!
3859b725ae77Skettenis */
3860b725ae77Skettenis if (p->have_state)
3861b725ae77Skettenis {
3862b725ae77Skettenis if (p->last_stop_state.tts_event == TTEVT_FORK)
3863b725ae77Skettenis {
3864b725ae77Skettenis /* Ok */
3865b725ae77Skettenis ;
3866b725ae77Skettenis }
3867b725ae77Skettenis else if (p->last_stop_state.tts_event == TTEVT_SIGNAL)
3868b725ae77Skettenis {
3869b725ae77Skettenis /* Ok, close eyes and let it happen.
3870b725ae77Skettenis */
3871b725ae77Skettenis ;
3872b725ae77Skettenis }
3873b725ae77Skettenis else
3874b725ae77Skettenis {
3875b725ae77Skettenis /* This shouldn't happen--we're dropping a
3876b725ae77Skettenis * real event.
3877b725ae77Skettenis */
3878b725ae77Skettenis warning ("About to continue process %d, thread %d with unhandled event %s.",
3879b725ae77Skettenis p->pid, p->tid,
3880b725ae77Skettenis get_printable_name_of_ttrace_event (
3881b725ae77Skettenis p->last_stop_state.tts_event));
3882b725ae77Skettenis
3883b725ae77Skettenis #ifdef PARANOIA
3884b725ae77Skettenis if (debug_on)
3885b725ae77Skettenis print_tthread (p);
3886b725ae77Skettenis #endif
3887b725ae77Skettenis }
3888b725ae77Skettenis }
3889b725ae77Skettenis else
3890b725ae77Skettenis {
3891b725ae77Skettenis /* No saved state, have to assume it failed.
3892b725ae77Skettenis */
3893b725ae77Skettenis warning ("About to continue process %d, thread %d with unhandled event.",
3894b725ae77Skettenis p->pid, p->tid);
3895b725ae77Skettenis #ifdef PARANOIA
3896b725ae77Skettenis if (debug_on)
3897b725ae77Skettenis print_tthread (p);
3898b725ae77Skettenis #endif
3899b725ae77Skettenis }
3900b725ae77Skettenis }
3901b725ae77Skettenis
3902b725ae77Skettenis } /* thread_dropping_event_check */
3903b725ae77Skettenis
3904b725ae77Skettenis /* Use a loop over the threads to continue all the threads but
3905b725ae77Skettenis * the one specified, which is to be stepped.
3906b725ae77Skettenis */
3907b725ae77Skettenis static void
threads_continue_all_but_one(lwpid_t gdb_tid,int signal)3908b725ae77Skettenis threads_continue_all_but_one (lwpid_t gdb_tid, int signal)
3909b725ae77Skettenis {
3910b725ae77Skettenis thread_info *p;
3911b725ae77Skettenis int thread_signal;
3912b725ae77Skettenis lwpid_t real_tid;
3913b725ae77Skettenis lwpid_t scan_tid;
3914b725ae77Skettenis ttstate_t state;
3915b725ae77Skettenis int real_pid;
3916b725ae77Skettenis
3917b725ae77Skettenis #ifdef THREAD_DEBUG
3918b725ae77Skettenis if (debug_on)
3919b725ae77Skettenis printf ("Using loop over threads to step/resume with signals\n");
3920b725ae77Skettenis #endif
3921b725ae77Skettenis
3922b725ae77Skettenis /* First update the thread list.
3923b725ae77Skettenis */
3924b725ae77Skettenis set_all_unseen ();
3925b725ae77Skettenis real_tid = map_from_gdb_tid (gdb_tid);
3926b725ae77Skettenis real_pid = get_pid_for (real_tid);
3927b725ae77Skettenis
3928b725ae77Skettenis scan_tid = get_process_first_stopped_thread_id (real_pid, &state);
3929b725ae77Skettenis while (0 != scan_tid)
3930b725ae77Skettenis {
3931b725ae77Skettenis
3932b725ae77Skettenis #ifdef THREAD_DEBUG
3933b725ae77Skettenis /* FIX: later should check state is stopped;
3934b725ae77Skettenis * state.tts_flags & TTS_STATEMASK == TTS_WASSUSPENDED
3935b725ae77Skettenis */
3936b725ae77Skettenis if (debug_on)
3937b725ae77Skettenis if ((state.tts_flags & TTS_STATEMASK) != TTS_WASSUSPENDED)
3938b725ae77Skettenis printf ("About to continue non-stopped thread %d\n", scan_tid);
3939b725ae77Skettenis #endif
3940b725ae77Skettenis
3941b725ae77Skettenis p = find_thread_info (scan_tid);
3942b725ae77Skettenis if (NULL == p)
3943b725ae77Skettenis {
3944b725ae77Skettenis add_tthread (real_pid, scan_tid);
3945b725ae77Skettenis p = find_thread_info (scan_tid);
3946b725ae77Skettenis
3947b725ae77Skettenis /* This is either a newly-created thread or the
3948b725ae77Skettenis * result of a fork; in either case there's no
3949b725ae77Skettenis * actual event to worry about.
3950b725ae77Skettenis */
3951b725ae77Skettenis p->handled = 1;
3952b725ae77Skettenis
3953b725ae77Skettenis if (state.tts_event != TTEVT_NONE)
3954b725ae77Skettenis {
3955b725ae77Skettenis /* Oops, do need to worry!
3956b725ae77Skettenis */
3957b725ae77Skettenis warning ("Unexpected thread with \"%s\" event.",
3958b725ae77Skettenis get_printable_name_of_ttrace_event (state.tts_event));
3959b725ae77Skettenis }
3960b725ae77Skettenis }
3961b725ae77Skettenis else if (scan_tid != p->tid)
3962b725ae77Skettenis error ("Bad data in thread database.");
3963b725ae77Skettenis
3964b725ae77Skettenis #ifdef THREAD_DEBUG
3965b725ae77Skettenis if (debug_on)
3966b725ae77Skettenis if (p->terminated)
3967b725ae77Skettenis printf ("Why are we continuing a dead thread?\n");
3968b725ae77Skettenis #endif
3969b725ae77Skettenis
3970b725ae77Skettenis p->seen = 1;
3971b725ae77Skettenis
3972b725ae77Skettenis scan_tid = get_process_next_stopped_thread_id (real_pid, &state);
3973b725ae77Skettenis }
3974b725ae77Skettenis
3975b725ae77Skettenis /* Remove unseen threads.
3976b725ae77Skettenis */
3977b725ae77Skettenis update_thread_list ();
3978b725ae77Skettenis
3979b725ae77Skettenis /* Now run down the thread list and continue or step.
3980b725ae77Skettenis */
3981b725ae77Skettenis for (p = thread_head.head; p; p = p->next)
3982b725ae77Skettenis {
3983b725ae77Skettenis
3984b725ae77Skettenis /* Sanity check.
3985b725ae77Skettenis */
3986b725ae77Skettenis thread_dropping_event_check (p);
3987b725ae77Skettenis
3988b725ae77Skettenis /* Pass the correct signals along.
3989b725ae77Skettenis */
3990b725ae77Skettenis if (p->have_signal)
3991b725ae77Skettenis {
3992b725ae77Skettenis thread_signal = p->signal_value;
3993b725ae77Skettenis p->have_signal = 0;
3994b725ae77Skettenis }
3995b725ae77Skettenis else
3996b725ae77Skettenis thread_signal = 0;
3997b725ae77Skettenis
3998b725ae77Skettenis if (p->tid != real_tid)
3999b725ae77Skettenis {
4000b725ae77Skettenis /*
4001b725ae77Skettenis * Not the thread of interest, so continue it
4002b725ae77Skettenis * as the user expects.
4003b725ae77Skettenis */
4004b725ae77Skettenis if (p->stepping_mode == DO_STEP)
4005b725ae77Skettenis {
4006b725ae77Skettenis /* Just step this thread.
4007b725ae77Skettenis */
4008b725ae77Skettenis call_ttrace (
4009b725ae77Skettenis TT_LWP_SINGLE,
4010b725ae77Skettenis p->tid,
4011b725ae77Skettenis TT_USE_CURRENT_PC,
4012b725ae77Skettenis (TTRACE_ARG_TYPE) target_signal_to_host (signal),
4013b725ae77Skettenis TT_NIL);
4014b725ae77Skettenis }
4015b725ae77Skettenis else
4016b725ae77Skettenis {
4017b725ae77Skettenis /* Regular continue (default case).
4018b725ae77Skettenis */
4019b725ae77Skettenis call_ttrace (
4020b725ae77Skettenis TT_LWP_CONTINUE,
4021b725ae77Skettenis p->tid,
4022b725ae77Skettenis TT_USE_CURRENT_PC,
4023b725ae77Skettenis (TTRACE_ARG_TYPE) target_signal_to_host (thread_signal),
4024b725ae77Skettenis TT_NIL);
4025b725ae77Skettenis }
4026b725ae77Skettenis }
4027b725ae77Skettenis else
4028b725ae77Skettenis {
4029b725ae77Skettenis /* Step the thread of interest.
4030b725ae77Skettenis */
4031b725ae77Skettenis call_ttrace (
4032b725ae77Skettenis TT_LWP_SINGLE,
4033b725ae77Skettenis real_tid,
4034b725ae77Skettenis TT_USE_CURRENT_PC,
4035b725ae77Skettenis (TTRACE_ARG_TYPE) target_signal_to_host (signal),
4036b725ae77Skettenis TT_NIL);
4037b725ae77Skettenis }
4038b725ae77Skettenis } /* Loop over threads */
4039b725ae77Skettenis } /* End threads_continue_all_but_one */
4040b725ae77Skettenis
4041b725ae77Skettenis /* Use a loop over the threads to continue all the threads.
4042b725ae77Skettenis * This is done when a signal must be sent to any of the threads.
4043b725ae77Skettenis */
4044b725ae77Skettenis static void
threads_continue_all_with_signals(lwpid_t gdb_tid,int signal)4045b725ae77Skettenis threads_continue_all_with_signals (lwpid_t gdb_tid, int signal)
4046b725ae77Skettenis {
4047b725ae77Skettenis thread_info *p;
4048b725ae77Skettenis int thread_signal;
4049b725ae77Skettenis lwpid_t real_tid;
4050b725ae77Skettenis lwpid_t scan_tid;
4051b725ae77Skettenis ttstate_t state;
4052b725ae77Skettenis int real_pid;
4053b725ae77Skettenis
4054b725ae77Skettenis #ifdef THREAD_DEBUG
4055b725ae77Skettenis if (debug_on)
4056b725ae77Skettenis printf ("Using loop over threads to resume with signals\n");
4057b725ae77Skettenis #endif
4058b725ae77Skettenis
4059b725ae77Skettenis /* Scan and update thread list.
4060b725ae77Skettenis */
4061b725ae77Skettenis set_all_unseen ();
4062b725ae77Skettenis real_tid = map_from_gdb_tid (gdb_tid);
4063b725ae77Skettenis real_pid = get_pid_for (real_tid);
4064b725ae77Skettenis
4065b725ae77Skettenis scan_tid = get_process_first_stopped_thread_id (real_pid, &state);
4066b725ae77Skettenis while (0 != scan_tid)
4067b725ae77Skettenis {
4068b725ae77Skettenis
4069b725ae77Skettenis #ifdef THREAD_DEBUG
4070b725ae77Skettenis if (debug_on)
4071b725ae77Skettenis if ((state.tts_flags & TTS_STATEMASK) != TTS_WASSUSPENDED)
4072b725ae77Skettenis warning ("About to continue non-stopped thread %d\n", scan_tid);
4073b725ae77Skettenis #endif
4074b725ae77Skettenis
4075b725ae77Skettenis p = find_thread_info (scan_tid);
4076b725ae77Skettenis if (NULL == p)
4077b725ae77Skettenis {
4078b725ae77Skettenis add_tthread (real_pid, scan_tid);
4079b725ae77Skettenis p = find_thread_info (scan_tid);
4080b725ae77Skettenis
4081b725ae77Skettenis /* This is either a newly-created thread or the
4082b725ae77Skettenis * result of a fork; in either case there's no
4083b725ae77Skettenis * actual event to worry about.
4084b725ae77Skettenis */
4085b725ae77Skettenis p->handled = 1;
4086b725ae77Skettenis
4087b725ae77Skettenis if (state.tts_event != TTEVT_NONE)
4088b725ae77Skettenis {
4089b725ae77Skettenis /* Oops, do need to worry!
4090b725ae77Skettenis */
4091b725ae77Skettenis warning ("Unexpected thread with \"%s\" event.",
4092b725ae77Skettenis get_printable_name_of_ttrace_event (state.tts_event));
4093b725ae77Skettenis }
4094b725ae77Skettenis }
4095b725ae77Skettenis
4096b725ae77Skettenis #ifdef THREAD_DEBUG
4097b725ae77Skettenis if (debug_on)
4098b725ae77Skettenis if (p->terminated)
4099b725ae77Skettenis printf ("Why are we continuing a dead thread? (1)\n");
4100b725ae77Skettenis #endif
4101b725ae77Skettenis
4102b725ae77Skettenis p->seen = 1;
4103b725ae77Skettenis
4104b725ae77Skettenis scan_tid = get_process_next_stopped_thread_id (real_pid, &state);
4105b725ae77Skettenis }
4106b725ae77Skettenis
4107b725ae77Skettenis /* Remove unseen threads from our list.
4108b725ae77Skettenis */
4109b725ae77Skettenis update_thread_list ();
4110b725ae77Skettenis
4111b725ae77Skettenis /* Continue the threads.
4112b725ae77Skettenis */
4113b725ae77Skettenis for (p = thread_head.head; p; p = p->next)
4114b725ae77Skettenis {
4115b725ae77Skettenis
4116b725ae77Skettenis /* Sanity check.
4117b725ae77Skettenis */
4118b725ae77Skettenis thread_dropping_event_check (p);
4119b725ae77Skettenis
4120b725ae77Skettenis /* Pass the correct signals along.
4121b725ae77Skettenis */
4122b725ae77Skettenis if (p->tid == real_tid)
4123b725ae77Skettenis {
4124b725ae77Skettenis thread_signal = signal;
4125b725ae77Skettenis p->have_signal = 0;
4126b725ae77Skettenis }
4127b725ae77Skettenis else if (p->have_signal)
4128b725ae77Skettenis {
4129b725ae77Skettenis thread_signal = p->signal_value;
4130b725ae77Skettenis p->have_signal = 0;
4131b725ae77Skettenis }
4132b725ae77Skettenis else
4133b725ae77Skettenis thread_signal = 0;
4134b725ae77Skettenis
4135b725ae77Skettenis if (p->stepping_mode == DO_STEP)
4136b725ae77Skettenis {
4137b725ae77Skettenis call_ttrace (
4138b725ae77Skettenis TT_LWP_SINGLE,
4139b725ae77Skettenis p->tid,
4140b725ae77Skettenis TT_USE_CURRENT_PC,
4141b725ae77Skettenis (TTRACE_ARG_TYPE) target_signal_to_host (signal),
4142b725ae77Skettenis TT_NIL);
4143b725ae77Skettenis }
4144b725ae77Skettenis else
4145b725ae77Skettenis {
4146b725ae77Skettenis /* Continue this thread (default case).
4147b725ae77Skettenis */
4148b725ae77Skettenis call_ttrace (
4149b725ae77Skettenis TT_LWP_CONTINUE,
4150b725ae77Skettenis p->tid,
4151b725ae77Skettenis TT_USE_CURRENT_PC,
4152b725ae77Skettenis (TTRACE_ARG_TYPE) target_signal_to_host (thread_signal),
4153b725ae77Skettenis TT_NIL);
4154b725ae77Skettenis }
4155b725ae77Skettenis }
4156b725ae77Skettenis } /* End threads_continue_all_with_signals */
4157b725ae77Skettenis
4158b725ae77Skettenis /* Step one thread only.
4159b725ae77Skettenis */
4160b725ae77Skettenis static void
thread_fake_step(lwpid_t tid,enum target_signal signal)4161b725ae77Skettenis thread_fake_step (lwpid_t tid, enum target_signal signal)
4162b725ae77Skettenis {
4163b725ae77Skettenis thread_info *p;
4164b725ae77Skettenis
4165b725ae77Skettenis #ifdef THREAD_DEBUG
4166b725ae77Skettenis if (debug_on)
4167b725ae77Skettenis {
4168b725ae77Skettenis printf ("Doing a fake-step over a bpt, etc. for %d\n", tid);
4169b725ae77Skettenis
4170b725ae77Skettenis if (is_terminated (tid))
4171b725ae77Skettenis printf ("Why are we continuing a dead thread? (4)\n");
4172b725ae77Skettenis }
4173b725ae77Skettenis #endif
4174b725ae77Skettenis
4175b725ae77Skettenis if (doing_fake_step)
4176b725ae77Skettenis warning ("Step while step already in progress.");
4177b725ae77Skettenis
4178b725ae77Skettenis /* See if there's a saved signal value for this
4179b725ae77Skettenis * thread to be passed on, but no current signal.
4180b725ae77Skettenis */
4181b725ae77Skettenis p = find_thread_info (tid);
4182b725ae77Skettenis if (p != NULL)
4183b725ae77Skettenis {
4184b725ae77Skettenis if (p->have_signal && signal == TARGET_SIGNAL_0)
4185b725ae77Skettenis {
4186b725ae77Skettenis /* Pass on a saved signal.
4187b725ae77Skettenis */
4188b725ae77Skettenis signal = p->signal_value;
4189b725ae77Skettenis }
4190b725ae77Skettenis
4191b725ae77Skettenis p->have_signal = 0;
4192b725ae77Skettenis }
4193b725ae77Skettenis
4194b725ae77Skettenis if (!p->handled)
4195b725ae77Skettenis warning ("Internal error: continuing unhandled thread.");
4196b725ae77Skettenis
4197b725ae77Skettenis call_ttrace (TT_LWP_SINGLE,
4198b725ae77Skettenis tid,
4199b725ae77Skettenis TT_USE_CURRENT_PC,
4200b725ae77Skettenis (TTRACE_ARG_TYPE) target_signal_to_host (signal),
4201b725ae77Skettenis TT_NIL);
4202b725ae77Skettenis
4203b725ae77Skettenis /* Do bookkeeping so "call_ttrace_wait" knows it has to wait
4204b725ae77Skettenis * for this thread only, and clear any saved signal info.
4205b725ae77Skettenis */
4206b725ae77Skettenis doing_fake_step = 1;
4207b725ae77Skettenis fake_step_tid = tid;
4208b725ae77Skettenis
4209b725ae77Skettenis } /* End thread_fake_step */
4210b725ae77Skettenis
4211b725ae77Skettenis /* Continue one thread when a signal must be sent to it.
4212b725ae77Skettenis */
4213b725ae77Skettenis static void
threads_continue_one_with_signal(lwpid_t gdb_tid,int signal)4214b725ae77Skettenis threads_continue_one_with_signal (lwpid_t gdb_tid, int signal)
4215b725ae77Skettenis {
4216b725ae77Skettenis thread_info *p;
4217b725ae77Skettenis lwpid_t real_tid;
4218b725ae77Skettenis int real_pid;
4219b725ae77Skettenis
4220b725ae77Skettenis #ifdef THREAD_DEBUG
4221b725ae77Skettenis if (debug_on)
4222b725ae77Skettenis printf ("Continuing one thread with a signal\n");
4223b725ae77Skettenis #endif
4224b725ae77Skettenis
4225b725ae77Skettenis real_tid = map_from_gdb_tid (gdb_tid);
4226b725ae77Skettenis real_pid = get_pid_for (real_tid);
4227b725ae77Skettenis
4228b725ae77Skettenis p = find_thread_info (real_tid);
4229b725ae77Skettenis if (NULL == p)
4230b725ae77Skettenis {
4231b725ae77Skettenis add_tthread (real_pid, real_tid);
4232b725ae77Skettenis }
4233b725ae77Skettenis
4234b725ae77Skettenis #ifdef THREAD_DEBUG
4235b725ae77Skettenis if (debug_on)
4236b725ae77Skettenis if (p->terminated)
4237b725ae77Skettenis printf ("Why are we continuing a dead thread? (2)\n");
4238b725ae77Skettenis #endif
4239b725ae77Skettenis
4240b725ae77Skettenis if (!p->handled)
4241b725ae77Skettenis warning ("Internal error: continuing unhandled thread.");
4242b725ae77Skettenis
4243b725ae77Skettenis p->have_signal = 0;
4244b725ae77Skettenis
4245b725ae77Skettenis call_ttrace (TT_LWP_CONTINUE,
4246b725ae77Skettenis gdb_tid,
4247b725ae77Skettenis TT_USE_CURRENT_PC,
4248b725ae77Skettenis (TTRACE_ARG_TYPE) target_signal_to_host (signal),
4249b725ae77Skettenis TT_NIL);
4250b725ae77Skettenis }
4251b725ae77Skettenis #endif
4252b725ae77Skettenis
4253*11efff7fSkettenis #ifndef DEPRECATED_CHILD_RESUME
4254b725ae77Skettenis
4255b725ae77Skettenis /* Resume execution of the inferior process.
4256b725ae77Skettenis
4257b725ae77Skettenis * This routine is in charge of setting the "handled" bits.
4258b725ae77Skettenis *
4259b725ae77Skettenis * If STEP is zero, continue it.
4260b725ae77Skettenis * If STEP is nonzero, single-step it.
4261b725ae77Skettenis *
4262b725ae77Skettenis * If SIGNAL is nonzero, give it that signal.
4263b725ae77Skettenis *
4264b725ae77Skettenis * If TID is -1, apply to all threads.
4265b725ae77Skettenis * If TID is not -1, apply to specified thread.
4266b725ae77Skettenis *
4267b725ae77Skettenis * STEP
4268b725ae77Skettenis * \ !0 0
4269b725ae77Skettenis * TID \________________________________________________
4270b725ae77Skettenis * |
4271b725ae77Skettenis * -1 | Step current Continue all threads
4272b725ae77Skettenis * | thread and (but which gets any
4273b725ae77Skettenis * | continue others signal?--We look at
4274b725ae77Skettenis * | "inferior_ptid")
4275b725ae77Skettenis * |
4276b725ae77Skettenis * N | Step _this_ thread Continue _this_ thread
4277b725ae77Skettenis * | and leave others and leave others
4278b725ae77Skettenis * | stopped; internally stopped; used only for
4279b725ae77Skettenis * | used by gdb, never hardware watchpoints
4280b725ae77Skettenis * | a user command. and attach, never a
4281b725ae77Skettenis * | user command.
4282b725ae77Skettenis */
4283b725ae77Skettenis void
child_resume(ptid_t ptid,int step,enum target_signal signal)4284b725ae77Skettenis child_resume (ptid_t ptid, int step, enum target_signal signal)
4285b725ae77Skettenis {
4286b725ae77Skettenis int resume_all_threads;
4287b725ae77Skettenis lwpid_t tid;
4288b725ae77Skettenis process_state_t new_process_state;
4289b725ae77Skettenis lwpid_t gdb_tid = PIDGET (ptid);
4290b725ae77Skettenis
4291b725ae77Skettenis resume_all_threads =
4292b725ae77Skettenis (gdb_tid == INFTTRACE_ALL_THREADS) ||
4293b725ae77Skettenis (vfork_in_flight);
4294b725ae77Skettenis
4295b725ae77Skettenis if (resume_all_threads)
4296b725ae77Skettenis {
4297b725ae77Skettenis /* Resume all threads, but first pick a tid value
4298b725ae77Skettenis * so we can get the pid when in call_ttrace doing
4299b725ae77Skettenis * the map.
4300b725ae77Skettenis */
4301b725ae77Skettenis if (vfork_in_flight)
4302b725ae77Skettenis tid = vforking_child_pid;
4303b725ae77Skettenis else
4304b725ae77Skettenis tid = map_from_gdb_tid (PIDGET (inferior_ptid));
4305b725ae77Skettenis }
4306b725ae77Skettenis else
4307b725ae77Skettenis tid = map_from_gdb_tid (gdb_tid);
4308b725ae77Skettenis
4309b725ae77Skettenis #ifdef THREAD_DEBUG
4310b725ae77Skettenis if (debug_on)
4311b725ae77Skettenis {
4312b725ae77Skettenis if (more_events_left)
4313b725ae77Skettenis printf ("More events; ");
4314b725ae77Skettenis
4315b725ae77Skettenis if (signal != 0)
4316b725ae77Skettenis printf ("Sending signal %d; ", signal);
4317b725ae77Skettenis
4318b725ae77Skettenis if (resume_all_threads)
4319b725ae77Skettenis {
4320b725ae77Skettenis if (step == 0)
4321b725ae77Skettenis printf ("Continue process %d\n", tid);
4322b725ae77Skettenis else
4323b725ae77Skettenis printf ("Step/continue thread %d\n", tid);
4324b725ae77Skettenis }
4325b725ae77Skettenis else
4326b725ae77Skettenis {
4327b725ae77Skettenis if (step == 0)
4328b725ae77Skettenis printf ("Continue thread %d\n", tid);
4329b725ae77Skettenis else
4330b725ae77Skettenis printf ("Step just thread %d\n", tid);
4331b725ae77Skettenis }
4332b725ae77Skettenis
4333b725ae77Skettenis if (vfork_in_flight)
4334b725ae77Skettenis printf ("Vfork in flight\n");
4335b725ae77Skettenis }
4336b725ae77Skettenis #endif
4337b725ae77Skettenis
4338b725ae77Skettenis if (process_state == RUNNING)
4339b725ae77Skettenis warning ("Internal error in resume logic; doing resume or step anyway.");
4340b725ae77Skettenis
4341b725ae77Skettenis if (!step /* Asked to continue... */
4342b725ae77Skettenis && resume_all_threads /* whole process.. */
4343b725ae77Skettenis && signal != 0 /* with a signal... */
4344b725ae77Skettenis && more_events_left > 0)
4345b725ae77Skettenis { /* but we can't yet--save it! */
4346b725ae77Skettenis
4347b725ae77Skettenis /* Continue with signal means we have to set the pending
4348b725ae77Skettenis * signal value for this thread.
4349b725ae77Skettenis */
4350b725ae77Skettenis thread_info *k;
4351b725ae77Skettenis
4352b725ae77Skettenis #ifdef THREAD_DEBUG
4353b725ae77Skettenis if (debug_on)
4354b725ae77Skettenis printf ("Saving signal %d for thread %d\n", signal, tid);
4355b725ae77Skettenis #endif
4356b725ae77Skettenis
4357b725ae77Skettenis k = find_thread_info (tid);
4358b725ae77Skettenis if (k != NULL)
4359b725ae77Skettenis {
4360b725ae77Skettenis k->have_signal = 1;
4361b725ae77Skettenis k->signal_value = signal;
4362b725ae77Skettenis
4363b725ae77Skettenis #ifdef THREAD_DEBUG
4364b725ae77Skettenis if (debug_on)
4365b725ae77Skettenis if (k->terminated)
4366b725ae77Skettenis printf ("Why are we continuing a dead thread? (3)\n");
4367b725ae77Skettenis #endif
4368b725ae77Skettenis
4369b725ae77Skettenis }
4370b725ae77Skettenis
4371b725ae77Skettenis #ifdef THREAD_DEBUG
4372b725ae77Skettenis else if (debug_on)
4373b725ae77Skettenis {
4374b725ae77Skettenis printf ("No thread info for tid %d\n", tid);
4375b725ae77Skettenis }
4376b725ae77Skettenis #endif
4377b725ae77Skettenis }
4378b725ae77Skettenis
4379b725ae77Skettenis /* Are we faking this "continue" or "step"?
4380b725ae77Skettenis
4381b725ae77Skettenis * We used to do steps by continuing all the threads for
4382b725ae77Skettenis * which the events had been handled already. While
4383b725ae77Skettenis * conceptually nicer (hides it all in a lower level), this
4384b725ae77Skettenis * can lead to starvation and a hang (e.g. all but one thread
4385b725ae77Skettenis * are unhandled at a breakpoint just before a "join" operation,
4386b725ae77Skettenis * and one thread is in the join, and the user wants to step that
4387b725ae77Skettenis * thread).
4388b725ae77Skettenis */
4389b725ae77Skettenis if (resume_all_threads /* Whole process, therefore user command */
4390b725ae77Skettenis && more_events_left > 0)
4391b725ae77Skettenis { /* But we can't do this yet--fake it! */
4392b725ae77Skettenis thread_info *p;
4393b725ae77Skettenis
4394b725ae77Skettenis if (!step)
4395b725ae77Skettenis {
4396b725ae77Skettenis /* No need to do any notes on a per-thread
4397b725ae77Skettenis * basis--we're done!
4398b725ae77Skettenis */
4399b725ae77Skettenis #ifdef WAIT_BUFFER_DEBUG
4400b725ae77Skettenis if (debug_on)
4401b725ae77Skettenis printf ("Faking a process resume.\n");
4402b725ae77Skettenis #endif
4403b725ae77Skettenis
4404b725ae77Skettenis return;
4405b725ae77Skettenis }
4406b725ae77Skettenis else
4407b725ae77Skettenis {
4408b725ae77Skettenis
4409b725ae77Skettenis #ifdef WAIT_BUFFER_DEBUG
4410b725ae77Skettenis if (debug_on)
4411b725ae77Skettenis printf ("Faking a process step.\n");
4412b725ae77Skettenis #endif
4413b725ae77Skettenis
4414b725ae77Skettenis }
4415b725ae77Skettenis
4416b725ae77Skettenis p = find_thread_info (tid);
4417b725ae77Skettenis if (p == NULL)
4418b725ae77Skettenis {
4419b725ae77Skettenis warning ("No thread information for tid %d, 'next' command ignored.\n", tid);
4420b725ae77Skettenis return;
4421b725ae77Skettenis }
4422b725ae77Skettenis else
4423b725ae77Skettenis {
4424b725ae77Skettenis
4425b725ae77Skettenis #ifdef THREAD_DEBUG
4426b725ae77Skettenis if (debug_on)
4427b725ae77Skettenis if (p->terminated)
4428b725ae77Skettenis printf ("Why are we continuing a dead thread? (3.5)\n");
4429b725ae77Skettenis #endif
4430b725ae77Skettenis
4431b725ae77Skettenis if (p->stepping_mode != DO_DEFAULT)
4432b725ae77Skettenis {
4433b725ae77Skettenis warning ("Step or continue command applied to thread which is already stepping or continuing; command ignored.");
4434b725ae77Skettenis
4435b725ae77Skettenis return;
4436b725ae77Skettenis }
4437b725ae77Skettenis
4438b725ae77Skettenis if (step)
4439b725ae77Skettenis p->stepping_mode = DO_STEP;
4440b725ae77Skettenis else
4441b725ae77Skettenis p->stepping_mode = DO_CONTINUE;
4442b725ae77Skettenis
4443b725ae77Skettenis return;
4444b725ae77Skettenis } /* Have thread info */
4445b725ae77Skettenis } /* Must fake step or go */
4446b725ae77Skettenis
4447b725ae77Skettenis /* Execept for fake-steps, from here on we know we are
4448b725ae77Skettenis * going to wind up with a running process which will
4449b725ae77Skettenis * need a real wait.
4450b725ae77Skettenis */
4451b725ae77Skettenis new_process_state = RUNNING;
4452b725ae77Skettenis
4453b725ae77Skettenis /* An address of TT_USE_CURRENT_PC tells ttrace to continue from where
4454b725ae77Skettenis * it was. (If GDB wanted it to start some other way, we have already
4455b725ae77Skettenis * written a new PC value to the child.)
4456b725ae77Skettenis *
4457b725ae77Skettenis * If this system does not support PT_STEP, a higher level function will
4458b725ae77Skettenis * have called single_step() to transmute the step request into a
4459b725ae77Skettenis * continue request (by setting breakpoints on all possible successor
4460b725ae77Skettenis * instructions), so we don't have to worry about that here.
4461b725ae77Skettenis */
4462b725ae77Skettenis if (step)
4463b725ae77Skettenis {
4464b725ae77Skettenis if (resume_all_threads)
4465b725ae77Skettenis {
4466b725ae77Skettenis /*
4467b725ae77Skettenis * Regular user step: other threads get a "continue".
4468b725ae77Skettenis */
4469b725ae77Skettenis threads_continue_all_but_one (tid, signal);
4470b725ae77Skettenis clear_all_handled ();
4471b725ae77Skettenis clear_all_stepping_mode ();
4472b725ae77Skettenis }
4473b725ae77Skettenis
4474b725ae77Skettenis else
4475b725ae77Skettenis {
4476b725ae77Skettenis /* "Fake step": gdb is stepping one thread over a
4477b725ae77Skettenis * breakpoint, watchpoint, or out of a library load
4478b725ae77Skettenis * event, etc. The rest just stay where they are.
4479b725ae77Skettenis *
4480b725ae77Skettenis * Also used when there are pending events: we really
4481b725ae77Skettenis * step the current thread, but leave the rest stopped.
4482b725ae77Skettenis * Users can't request this, but "wait_for_inferior"
4483b725ae77Skettenis * does--a lot!
4484b725ae77Skettenis */
4485b725ae77Skettenis thread_fake_step (tid, signal);
4486b725ae77Skettenis
4487b725ae77Skettenis /* Clear the "handled" state of this thread, because
4488b725ae77Skettenis * we'll soon get a new event for it. Other events
4489b725ae77Skettenis * stay as they were.
4490b725ae77Skettenis */
4491b725ae77Skettenis clear_handled (tid);
4492b725ae77Skettenis clear_stepping_mode (tid);
4493b725ae77Skettenis new_process_state = FAKE_STEPPING;
4494b725ae77Skettenis }
4495b725ae77Skettenis }
4496b725ae77Skettenis
4497b725ae77Skettenis else
4498b725ae77Skettenis {
4499b725ae77Skettenis /* TT_LWP_CONTINUE can pass signals to threads, TT_PROC_CONTINUE can't.
4500b725ae77Skettenis Therefore, we really can't use TT_PROC_CONTINUE here.
4501b725ae77Skettenis
4502b725ae77Skettenis Consider a process which stopped due to signal which gdb decides
4503b725ae77Skettenis to handle and not pass on to the inferior. In that case we must
4504b725ae77Skettenis clear the pending signal by restarting the inferior using
4505b725ae77Skettenis TT_LWP_CONTINUE and pass zero as the signal number. Else the
4506b725ae77Skettenis pending signal will be passed to the inferior. interrupt.exp
4507b725ae77Skettenis in the testsuite does this precise thing and fails due to the
4508b725ae77Skettenis unwanted signal delivery to the inferior. */
4509b725ae77Skettenis /* drow/2002-12-05: However, note that we must use TT_PROC_CONTINUE
4510b725ae77Skettenis if we are tracing a vfork. */
4511b725ae77Skettenis if (vfork_in_flight)
4512b725ae77Skettenis {
4513b725ae77Skettenis call_ttrace (TT_PROC_CONTINUE, tid, TT_NIL, TT_NIL, TT_NIL);
4514b725ae77Skettenis clear_all_handled ();
4515b725ae77Skettenis clear_all_stepping_mode ();
4516b725ae77Skettenis }
4517b725ae77Skettenis else if (resume_all_threads)
4518b725ae77Skettenis {
4519b725ae77Skettenis #ifdef THREAD_DEBUG
4520b725ae77Skettenis if (debug_on)
4521b725ae77Skettenis printf ("Doing a continue by loop of all threads\n");
4522b725ae77Skettenis #endif
4523b725ae77Skettenis
4524b725ae77Skettenis threads_continue_all_with_signals (tid, signal);
4525b725ae77Skettenis
4526b725ae77Skettenis clear_all_handled ();
4527b725ae77Skettenis clear_all_stepping_mode ();
4528b725ae77Skettenis }
4529b725ae77Skettenis else
4530b725ae77Skettenis {
4531b725ae77Skettenis #ifdef THREAD_DEBUG
4532b725ae77Skettenis printf ("Doing a continue w/signal of just thread %d\n", tid);
4533b725ae77Skettenis #endif
4534b725ae77Skettenis
4535b725ae77Skettenis threads_continue_one_with_signal (tid, signal);
4536b725ae77Skettenis
4537b725ae77Skettenis /* Clear the "handled" state of this thread, because we
4538b725ae77Skettenis will soon get a new event for it. Other events can
4539b725ae77Skettenis stay as they were. */
4540b725ae77Skettenis clear_handled (tid);
4541b725ae77Skettenis clear_stepping_mode (tid);
4542b725ae77Skettenis }
4543b725ae77Skettenis }
4544b725ae77Skettenis
4545b725ae77Skettenis process_state = new_process_state;
4546b725ae77Skettenis
4547b725ae77Skettenis #ifdef WAIT_BUFFER_DEBUG
4548b725ae77Skettenis if (debug_on)
4549b725ae77Skettenis printf ("Process set to %s\n",
4550b725ae77Skettenis get_printable_name_of_process_state (process_state));
4551b725ae77Skettenis #endif
4552b725ae77Skettenis
4553b725ae77Skettenis }
4554*11efff7fSkettenis #endif /* DEPRECATED_CHILD_RESUME */
4555b725ae77Skettenis
4556b725ae77Skettenis /*
4557b725ae77Skettenis * Like it says.
4558b725ae77Skettenis *
4559b725ae77Skettenis * One worry is that we may not be attaching to "inferior_ptid"
4560b725ae77Skettenis * and thus may not want to clear out our data. FIXME?
4561b725ae77Skettenis *
4562b725ae77Skettenis */
4563b725ae77Skettenis static void
update_thread_state_after_attach(int pid,attach_continue_t kind_of_go)4564b725ae77Skettenis update_thread_state_after_attach (int pid, attach_continue_t kind_of_go)
4565b725ae77Skettenis {
4566b725ae77Skettenis int tt_status;
4567b725ae77Skettenis ttstate_t thread_state;
4568b725ae77Skettenis lwpid_t a_thread;
4569b725ae77Skettenis lwpid_t tid;
4570b725ae77Skettenis
4571b725ae77Skettenis /* The process better be stopped.
4572b725ae77Skettenis */
4573b725ae77Skettenis if (process_state != STOPPED
4574b725ae77Skettenis && process_state != VFORKING)
4575b725ae77Skettenis warning ("Internal error attaching.");
4576b725ae77Skettenis
4577b725ae77Skettenis /* Clear out old tthread info and start over. This has the
4578b725ae77Skettenis * side effect of ensuring that the TRAP is reported as being
4579b725ae77Skettenis * in the right thread (re-mapped from tid to pid).
4580b725ae77Skettenis *
4581b725ae77Skettenis * It's because we need to add the tthread _now_ that we
4582b725ae77Skettenis * need to call "clear_thread_info" _now_, and that's why
4583b725ae77Skettenis * "require_notification_of_events" doesn't clear the thread
4584b725ae77Skettenis * info (it's called later than this routine).
4585b725ae77Skettenis */
4586b725ae77Skettenis clear_thread_info ();
4587b725ae77Skettenis a_thread = 0;
4588b725ae77Skettenis
4589b725ae77Skettenis for (tid = get_process_first_stopped_thread_id (pid, &thread_state);
4590b725ae77Skettenis tid != 0;
4591b725ae77Skettenis tid = get_process_next_stopped_thread_id (pid, &thread_state))
4592b725ae77Skettenis {
4593b725ae77Skettenis thread_info *p;
4594b725ae77Skettenis
4595b725ae77Skettenis if (a_thread == 0)
4596b725ae77Skettenis {
4597b725ae77Skettenis a_thread = tid;
4598b725ae77Skettenis #ifdef THREAD_DEBUG
4599b725ae77Skettenis if (debug_on)
4600b725ae77Skettenis printf ("Attaching to process %d, thread %d\n",
4601b725ae77Skettenis pid, a_thread);
4602b725ae77Skettenis #endif
4603b725ae77Skettenis }
4604b725ae77Skettenis
4605b725ae77Skettenis /* Tell ourselves and the "rest of gdb" that this thread
4606b725ae77Skettenis * exists.
4607b725ae77Skettenis *
4608b725ae77Skettenis * This isn't really a hack. Other thread-based versions
4609b725ae77Skettenis * of gdb (e.g. gnu-nat.c) seem to do the same thing.
4610b725ae77Skettenis *
4611b725ae77Skettenis * We don't need to do mapping here, as we know this
4612b725ae77Skettenis * is the first thread and thus gets the real pid
4613b725ae77Skettenis * (and is "inferior_ptid").
4614b725ae77Skettenis *
4615b725ae77Skettenis * NOTE: it probably isn't the originating thread,
4616b725ae77Skettenis * but that doesn't matter (we hope!).
4617b725ae77Skettenis */
4618b725ae77Skettenis add_tthread (pid, tid);
4619b725ae77Skettenis p = find_thread_info (tid);
4620b725ae77Skettenis if (NULL == p) /* ?We just added it! */
4621b725ae77Skettenis error ("Internal error adding a thread on attach.");
4622b725ae77Skettenis
4623b725ae77Skettenis copy_ttstate_t (&p->last_stop_state, &thread_state);
4624b725ae77Skettenis p->have_state = 1;
4625b725ae77Skettenis
4626b725ae77Skettenis if (DO_ATTACH_CONTINUE == kind_of_go)
4627b725ae77Skettenis {
4628b725ae77Skettenis /*
4629b725ae77Skettenis * If we are going to CONTINUE afterwards,
4630b725ae77Skettenis * raising a SIGTRAP, don't bother trying to
4631b725ae77Skettenis * handle this event. But check first!
4632b725ae77Skettenis */
4633b725ae77Skettenis switch (p->last_stop_state.tts_event)
4634b725ae77Skettenis {
4635b725ae77Skettenis
4636b725ae77Skettenis case TTEVT_NONE:
4637b725ae77Skettenis /* Ok to set this handled.
4638b725ae77Skettenis */
4639b725ae77Skettenis break;
4640b725ae77Skettenis
4641b725ae77Skettenis default:
4642b725ae77Skettenis warning ("Internal error; skipping event %s on process %d, thread %d.",
4643b725ae77Skettenis get_printable_name_of_ttrace_event (
4644b725ae77Skettenis p->last_stop_state.tts_event),
4645b725ae77Skettenis p->pid, p->tid);
4646b725ae77Skettenis }
4647b725ae77Skettenis
4648b725ae77Skettenis set_handled (pid, tid);
4649b725ae77Skettenis
4650b725ae77Skettenis }
4651b725ae77Skettenis else
4652b725ae77Skettenis {
4653b725ae77Skettenis /* There will be no "continue" opertion, so the
4654b725ae77Skettenis * process remains stopped. Don't set any events
4655b725ae77Skettenis * handled except the "gimmies".
4656b725ae77Skettenis */
4657b725ae77Skettenis switch (p->last_stop_state.tts_event)
4658b725ae77Skettenis {
4659b725ae77Skettenis
4660b725ae77Skettenis case TTEVT_NONE:
4661b725ae77Skettenis /* Ok to ignore this.
4662b725ae77Skettenis */
4663b725ae77Skettenis set_handled (pid, tid);
4664b725ae77Skettenis break;
4665b725ae77Skettenis
4666b725ae77Skettenis case TTEVT_EXEC:
4667b725ae77Skettenis case TTEVT_FORK:
4668b725ae77Skettenis /* Expected "other" FORK or EXEC event from a
4669b725ae77Skettenis * fork or vfork.
4670b725ae77Skettenis */
4671b725ae77Skettenis break;
4672b725ae77Skettenis
4673b725ae77Skettenis default:
4674b725ae77Skettenis printf ("Internal error: failed to handle event %s on process %d, thread %d.",
4675b725ae77Skettenis get_printable_name_of_ttrace_event (
4676b725ae77Skettenis p->last_stop_state.tts_event),
4677b725ae77Skettenis p->pid, p->tid);
4678b725ae77Skettenis }
4679b725ae77Skettenis }
4680b725ae77Skettenis
4681b725ae77Skettenis add_thread (pid_to_ptid (pid)); /* in thread.c */
4682b725ae77Skettenis }
4683b725ae77Skettenis
4684b725ae77Skettenis #ifdef PARANOIA
4685b725ae77Skettenis if (debug_on)
4686b725ae77Skettenis print_tthreads ();
4687b725ae77Skettenis #endif
4688b725ae77Skettenis
4689b725ae77Skettenis /* One mustn't call ttrace_wait() after attaching via ttrace,
4690b725ae77Skettenis 'cause the process is stopped already.
4691b725ae77Skettenis
4692b725ae77Skettenis However, the upper layers of gdb's execution control will
4693b725ae77Skettenis want to wait after attaching (but not after forks, in
4694b725ae77Skettenis which case they will be doing a "target_resume", anticipating
4695b725ae77Skettenis a later TTEVT_EXEC or TTEVT_FORK event).
4696b725ae77Skettenis
4697b725ae77Skettenis To make this attach() implementation more compatible with
4698b725ae77Skettenis others, we'll make the attached-to process raise a SIGTRAP.
4699b725ae77Skettenis
4700b725ae77Skettenis Issue: this continues only one thread. That could be
4701b725ae77Skettenis dangerous if the thread is blocked--the process won't run
4702b725ae77Skettenis and no trap will be raised. FIX! (check state.tts_flags?
4703b725ae77Skettenis need one that's either TTS_WASRUNNING--but we've stopped
4704b725ae77Skettenis it and made it TTS_WASSUSPENDED. Hum...FIXME!)
4705b725ae77Skettenis */
4706b725ae77Skettenis if (DO_ATTACH_CONTINUE == kind_of_go)
4707b725ae77Skettenis {
4708b725ae77Skettenis tt_status = call_real_ttrace (
4709b725ae77Skettenis TT_LWP_CONTINUE,
4710b725ae77Skettenis pid,
4711b725ae77Skettenis a_thread,
4712b725ae77Skettenis TT_USE_CURRENT_PC,
4713b725ae77Skettenis (TTRACE_ARG_TYPE) target_signal_to_host (TARGET_SIGNAL_TRAP),
4714b725ae77Skettenis TT_NIL);
4715b725ae77Skettenis if (errno)
4716b725ae77Skettenis perror_with_name ("ttrace");
4717b725ae77Skettenis
4718b725ae77Skettenis clear_handled (a_thread); /* So TRAP will be reported. */
4719b725ae77Skettenis
4720b725ae77Skettenis /* Now running.
4721b725ae77Skettenis */
4722b725ae77Skettenis process_state = RUNNING;
4723b725ae77Skettenis }
4724b725ae77Skettenis
4725b725ae77Skettenis attach_flag = 1;
4726b725ae77Skettenis }
4727b725ae77Skettenis
4728b725ae77Skettenis
4729b725ae77Skettenis /* Start debugging the process whose number is PID.
4730b725ae77Skettenis * (A _real_ pid).
4731b725ae77Skettenis */
4732b725ae77Skettenis int
attach(int pid)4733b725ae77Skettenis attach (int pid)
4734b725ae77Skettenis {
4735b725ae77Skettenis int tt_status;
4736b725ae77Skettenis
4737b725ae77Skettenis tt_status = call_real_ttrace (
4738b725ae77Skettenis TT_PROC_ATTACH,
4739b725ae77Skettenis pid,
4740b725ae77Skettenis (lwpid_t) TT_NIL,
4741b725ae77Skettenis TT_NIL,
4742b725ae77Skettenis (TTRACE_ARG_TYPE) TT_VERSION,
4743b725ae77Skettenis TT_NIL);
4744b725ae77Skettenis if (errno)
4745b725ae77Skettenis perror_with_name ("ttrace attach");
4746b725ae77Skettenis
4747b725ae77Skettenis /* If successful, the process is now stopped.
4748b725ae77Skettenis */
4749b725ae77Skettenis process_state = STOPPED;
4750b725ae77Skettenis
4751b725ae77Skettenis /* Our caller ("attach_command" in "infcmd.c")
4752b725ae77Skettenis * expects to do a "wait_for_inferior" after
4753b725ae77Skettenis * the attach, so make sure the inferior is
4754b725ae77Skettenis * running when we're done.
4755b725ae77Skettenis */
4756b725ae77Skettenis update_thread_state_after_attach (pid, DO_ATTACH_CONTINUE);
4757b725ae77Skettenis
4758b725ae77Skettenis return pid;
4759b725ae77Skettenis }
4760b725ae77Skettenis
4761b725ae77Skettenis
4762b725ae77Skettenis #if defined(CHILD_POST_ATTACH)
4763b725ae77Skettenis void
child_post_attach(int pid)4764b725ae77Skettenis child_post_attach (int pid)
4765b725ae77Skettenis {
4766b725ae77Skettenis #ifdef THREAD_DEBUG
4767b725ae77Skettenis if (debug_on)
4768b725ae77Skettenis printf ("child-post-attach call\n");
4769b725ae77Skettenis #endif
4770b725ae77Skettenis
4771b725ae77Skettenis require_notification_of_events (pid);
4772b725ae77Skettenis }
4773b725ae77Skettenis #endif
4774b725ae77Skettenis
4775b725ae77Skettenis
4776b725ae77Skettenis /* Stop debugging the process whose number is PID
4777b725ae77Skettenis and continue it with signal number SIGNAL.
4778b725ae77Skettenis SIGNAL = 0 means just continue it.
4779b725ae77Skettenis */
4780b725ae77Skettenis void
detach(int signal)4781b725ae77Skettenis detach (int signal)
4782b725ae77Skettenis {
4783b725ae77Skettenis errno = 0;
4784b725ae77Skettenis call_ttrace (TT_PROC_DETACH,
4785b725ae77Skettenis PIDGET (inferior_ptid),
4786b725ae77Skettenis TT_NIL,
4787b725ae77Skettenis (TTRACE_ARG_TYPE) signal,
4788b725ae77Skettenis TT_NIL);
4789b725ae77Skettenis attach_flag = 0;
4790b725ae77Skettenis
4791b725ae77Skettenis clear_thread_info ();
4792b725ae77Skettenis
4793b725ae77Skettenis /* Process-state? */
4794b725ae77Skettenis }
4795b725ae77Skettenis
4796b725ae77Skettenis
4797b725ae77Skettenis /* Default the type of the ttrace transfer to int. */
4798b725ae77Skettenis #ifndef TTRACE_XFER_TYPE
4799b725ae77Skettenis #define TTRACE_XFER_TYPE int
4800b725ae77Skettenis #endif
4801b725ae77Skettenis
4802b725ae77Skettenis void
_initialize_kernel_u_addr(void)4803b725ae77Skettenis _initialize_kernel_u_addr (void)
4804b725ae77Skettenis {
4805b725ae77Skettenis }
4806b725ae77Skettenis
4807b725ae77Skettenis #if !defined (CHILD_XFER_MEMORY)
4808b725ae77Skettenis /* NOTE! I tried using TTRACE_READDATA, etc., to read and write memory
4809b725ae77Skettenis in the NEW_SUN_TTRACE case.
4810b725ae77Skettenis It ought to be straightforward. But it appears that writing did
4811b725ae77Skettenis not write the data that I specified. I cannot understand where
4812b725ae77Skettenis it got the data that it actually did write. */
4813b725ae77Skettenis
4814b725ae77Skettenis /* Copy LEN bytes to or from inferior's memory starting at MEMADDR
4815b725ae77Skettenis to debugger memory starting at MYADDR. Copy to inferior if
4816b725ae77Skettenis WRITE is nonzero. TARGET is ignored.
4817b725ae77Skettenis
4818*11efff7fSkettenis Returns the length copied, which is either the LEN argument or
4819*11efff7fSkettenis zero. This xfer function does not do partial moves, since
4820*11efff7fSkettenis deprecated_child_ops doesn't allow memory operations to cross below
4821*11efff7fSkettenis us in the target stack anyway. */
4822b725ae77Skettenis
4823b725ae77Skettenis int
child_xfer_memory(CORE_ADDR memaddr,char * myaddr,int len,int write,struct mem_attrib * attrib,struct target_ops * target)4824b725ae77Skettenis child_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
4825b725ae77Skettenis struct mem_attrib *attrib,
4826b725ae77Skettenis struct target_ops *target)
4827b725ae77Skettenis {
4828b725ae77Skettenis int i;
4829b725ae77Skettenis /* Round starting address down to longword boundary. */
4830b725ae77Skettenis CORE_ADDR addr = memaddr & -(CORE_ADDR) sizeof (TTRACE_XFER_TYPE);
4831b725ae77Skettenis /* Round ending address up; get number of longwords that makes. */
4832b725ae77Skettenis int count
4833b725ae77Skettenis = (((memaddr + len) - addr) + sizeof (TTRACE_XFER_TYPE) - 1)
4834b725ae77Skettenis / sizeof (TTRACE_XFER_TYPE);
4835b725ae77Skettenis /* Allocate buffer of that many longwords. */
4836b725ae77Skettenis /* FIXME (alloca): This code, cloned from infptrace.c, is unsafe
4837b725ae77Skettenis because it uses alloca to allocate a buffer of arbitrary size.
4838b725ae77Skettenis For very large xfers, this could crash GDB's stack. */
4839b725ae77Skettenis TTRACE_XFER_TYPE *buffer
4840b725ae77Skettenis = (TTRACE_XFER_TYPE *) alloca (count * sizeof (TTRACE_XFER_TYPE));
4841b725ae77Skettenis
4842b725ae77Skettenis if (write)
4843b725ae77Skettenis {
4844b725ae77Skettenis /* Fill start and end extra bytes of buffer with existing memory data. */
4845b725ae77Skettenis
4846b725ae77Skettenis if (addr != memaddr || len < (int) sizeof (TTRACE_XFER_TYPE))
4847b725ae77Skettenis {
4848b725ae77Skettenis /* Need part of initial word -- fetch it. */
4849b725ae77Skettenis buffer[0] = call_ttrace (TT_LWP_RDTEXT,
4850b725ae77Skettenis PIDGET (inferior_ptid),
4851b725ae77Skettenis (TTRACE_ARG_TYPE) addr,
4852b725ae77Skettenis TT_NIL,
4853b725ae77Skettenis TT_NIL);
4854b725ae77Skettenis }
4855b725ae77Skettenis
4856b725ae77Skettenis if (count > 1) /* FIXME, avoid if even boundary */
4857b725ae77Skettenis {
4858b725ae77Skettenis buffer[count - 1] = call_ttrace (TT_LWP_RDTEXT,
4859b725ae77Skettenis PIDGET (inferior_ptid),
4860b725ae77Skettenis ((TTRACE_ARG_TYPE)
4861b725ae77Skettenis (addr + (count - 1) * sizeof (TTRACE_XFER_TYPE))),
4862b725ae77Skettenis TT_NIL,
4863b725ae77Skettenis TT_NIL);
4864b725ae77Skettenis }
4865b725ae77Skettenis
4866b725ae77Skettenis /* Copy data to be written over corresponding part of buffer */
4867b725ae77Skettenis
4868b725ae77Skettenis memcpy ((char *) buffer + (memaddr & (sizeof (TTRACE_XFER_TYPE) - 1)),
4869b725ae77Skettenis myaddr,
4870b725ae77Skettenis len);
4871b725ae77Skettenis
4872b725ae77Skettenis /* Write the entire buffer. */
4873b725ae77Skettenis
4874b725ae77Skettenis for (i = 0; i < count; i++, addr += sizeof (TTRACE_XFER_TYPE))
4875b725ae77Skettenis {
4876b725ae77Skettenis errno = 0;
4877b725ae77Skettenis call_ttrace (TT_LWP_WRDATA,
4878b725ae77Skettenis PIDGET (inferior_ptid),
4879b725ae77Skettenis (TTRACE_ARG_TYPE) addr,
4880b725ae77Skettenis (TTRACE_ARG_TYPE) buffer[i],
4881b725ae77Skettenis TT_NIL);
4882b725ae77Skettenis if (errno)
4883b725ae77Skettenis {
4884b725ae77Skettenis /* Using the appropriate one (I or D) is necessary for
4885b725ae77Skettenis Gould NP1, at least. */
4886b725ae77Skettenis errno = 0;
4887b725ae77Skettenis call_ttrace (TT_LWP_WRTEXT,
4888b725ae77Skettenis PIDGET (inferior_ptid),
4889b725ae77Skettenis (TTRACE_ARG_TYPE) addr,
4890b725ae77Skettenis (TTRACE_ARG_TYPE) buffer[i],
4891b725ae77Skettenis TT_NIL);
4892b725ae77Skettenis }
4893b725ae77Skettenis if (errno)
4894b725ae77Skettenis return 0;
4895b725ae77Skettenis }
4896b725ae77Skettenis }
4897b725ae77Skettenis else
4898b725ae77Skettenis {
4899b725ae77Skettenis /* Read all the longwords */
4900b725ae77Skettenis for (i = 0; i < count; i++, addr += sizeof (TTRACE_XFER_TYPE))
4901b725ae77Skettenis {
4902b725ae77Skettenis errno = 0;
4903b725ae77Skettenis buffer[i] = call_ttrace (TT_LWP_RDTEXT,
4904b725ae77Skettenis PIDGET (inferior_ptid),
4905b725ae77Skettenis (TTRACE_ARG_TYPE) addr,
4906b725ae77Skettenis TT_NIL,
4907b725ae77Skettenis TT_NIL);
4908b725ae77Skettenis if (errno)
4909b725ae77Skettenis return 0;
4910b725ae77Skettenis QUIT;
4911b725ae77Skettenis }
4912b725ae77Skettenis
4913b725ae77Skettenis /* Copy appropriate bytes out of the buffer. */
4914b725ae77Skettenis memcpy (myaddr,
4915b725ae77Skettenis (char *) buffer + (memaddr & (sizeof (TTRACE_XFER_TYPE) - 1)),
4916b725ae77Skettenis len);
4917b725ae77Skettenis }
4918b725ae77Skettenis return len;
4919b725ae77Skettenis }
4920b725ae77Skettenis
4921b725ae77Skettenis
4922b725ae77Skettenis static void
udot_info(void)4923b725ae77Skettenis udot_info (void)
4924b725ae77Skettenis {
4925b725ae77Skettenis int udot_off; /* Offset into user struct */
4926b725ae77Skettenis int udot_val; /* Value from user struct at udot_off */
4927b725ae77Skettenis char mess[128]; /* For messages */
4928b725ae77Skettenis
4929b725ae77Skettenis if (!target_has_execution)
4930b725ae77Skettenis {
4931b725ae77Skettenis error ("The program is not being run.");
4932b725ae77Skettenis }
4933b725ae77Skettenis
4934b725ae77Skettenis #if !defined (KERNEL_U_SIZE)
4935b725ae77Skettenis
4936b725ae77Skettenis /* Adding support for this command is easy. Typically you just add a
4937b725ae77Skettenis routine, called "kernel_u_size" that returns the size of the user
4938b725ae77Skettenis struct, to the appropriate *-nat.c file and then add to the native
4939b725ae77Skettenis config file "#define KERNEL_U_SIZE kernel_u_size()" */
4940b725ae77Skettenis error ("Don't know how large ``struct user'' is in this version of gdb.");
4941b725ae77Skettenis
4942b725ae77Skettenis #else
4943b725ae77Skettenis
4944b725ae77Skettenis for (udot_off = 0; udot_off < KERNEL_U_SIZE; udot_off += sizeof (udot_val))
4945b725ae77Skettenis {
4946b725ae77Skettenis if ((udot_off % 24) == 0)
4947b725ae77Skettenis {
4948b725ae77Skettenis if (udot_off > 0)
4949b725ae77Skettenis {
4950b725ae77Skettenis printf_filtered ("\n");
4951b725ae77Skettenis }
4952b725ae77Skettenis printf_filtered ("%04x:", udot_off);
4953b725ae77Skettenis }
4954b725ae77Skettenis udot_val = call_ttrace (TT_LWP_RUREGS,
4955b725ae77Skettenis PIDGET (inferior_ptid),
4956b725ae77Skettenis (TTRACE_ARG_TYPE) udot_off,
4957b725ae77Skettenis TT_NIL,
4958b725ae77Skettenis TT_NIL);
4959b725ae77Skettenis if (errno != 0)
4960b725ae77Skettenis {
4961b725ae77Skettenis sprintf (mess, "\nreading user struct at offset 0x%x", udot_off);
4962b725ae77Skettenis perror_with_name (mess);
4963b725ae77Skettenis }
4964b725ae77Skettenis /* Avoid using nonportable (?) "*" in print specs */
4965b725ae77Skettenis printf_filtered (sizeof (int) == 4 ? " 0x%08x" : " 0x%16x", udot_val);
4966b725ae77Skettenis }
4967b725ae77Skettenis printf_filtered ("\n");
4968b725ae77Skettenis
4969b725ae77Skettenis #endif
4970b725ae77Skettenis }
4971b725ae77Skettenis #endif /* !defined (CHILD_XFER_MEMORY). */
4972b725ae77Skettenis
4973b725ae77Skettenis
4974b725ae77Skettenis /* TTrace version of "target_pid_to_exec_file"
4975b725ae77Skettenis */
4976b725ae77Skettenis char *
child_pid_to_exec_file(int tid)4977b725ae77Skettenis child_pid_to_exec_file (int tid)
4978b725ae77Skettenis {
4979b725ae77Skettenis int tt_status;
4980b725ae77Skettenis static char exec_file_buffer[1024];
4981b725ae77Skettenis pid_t pid;
4982b725ae77Skettenis static struct pst_status buf;
4983b725ae77Skettenis
4984b725ae77Skettenis /* On various versions of hpux11, this may fail due to a supposed
4985b725ae77Skettenis kernel bug. We have alternate methods to get this information
4986b725ae77Skettenis (ie pstat). */
4987b725ae77Skettenis tt_status = call_ttrace (TT_PROC_GET_PATHNAME,
4988b725ae77Skettenis tid,
4989b725ae77Skettenis (uint64_t) exec_file_buffer,
4990b725ae77Skettenis sizeof (exec_file_buffer) - 1,
4991b725ae77Skettenis 0);
4992b725ae77Skettenis if (tt_status >= 0)
4993b725ae77Skettenis return exec_file_buffer;
4994b725ae77Skettenis
4995b725ae77Skettenis /* Try to get process information via pstat and extract the filename
4996b725ae77Skettenis from the pst_cmd field within the pst_status structure. */
4997b725ae77Skettenis if (pstat_getproc (&buf, sizeof (struct pst_status), 0, tid) != -1)
4998b725ae77Skettenis {
4999b725ae77Skettenis char *p = buf.pst_cmd;
5000b725ae77Skettenis
5001b725ae77Skettenis while (*p && *p != ' ')
5002b725ae77Skettenis p++;
5003b725ae77Skettenis *p = 0;
5004b725ae77Skettenis
5005b725ae77Skettenis return (buf.pst_cmd);
5006b725ae77Skettenis }
5007b725ae77Skettenis
5008b725ae77Skettenis return (NULL);
5009b725ae77Skettenis }
5010b725ae77Skettenis
5011b725ae77Skettenis void
pre_fork_inferior(void)5012b725ae77Skettenis pre_fork_inferior (void)
5013b725ae77Skettenis {
5014b725ae77Skettenis int status;
5015b725ae77Skettenis
5016b725ae77Skettenis status = pipe (startup_semaphore.parent_channel);
5017b725ae77Skettenis if (status < 0)
5018b725ae77Skettenis {
5019b725ae77Skettenis warning ("error getting parent pipe for startup semaphore");
5020b725ae77Skettenis return;
5021b725ae77Skettenis }
5022b725ae77Skettenis
5023b725ae77Skettenis status = pipe (startup_semaphore.child_channel);
5024b725ae77Skettenis if (status < 0)
5025b725ae77Skettenis {
5026b725ae77Skettenis warning ("error getting child pipe for startup semaphore");
5027b725ae77Skettenis return;
5028b725ae77Skettenis }
5029b725ae77Skettenis }
5030b725ae77Skettenis
5031b725ae77Skettenis /* Called from child_follow_fork in hppah-nat.c.
5032b725ae77Skettenis *
5033b725ae77Skettenis * This seems to be intended to attach after a fork or
5034b725ae77Skettenis * vfork, while "attach" is used to attach to a pid
5035b725ae77Skettenis * given by the user. The check for an existing attach
5036b725ae77Skettenis * seems odd--it always fails in our test system.
5037b725ae77Skettenis */
5038b725ae77Skettenis int
hppa_require_attach(int pid)5039b725ae77Skettenis hppa_require_attach (int pid)
5040b725ae77Skettenis {
5041b725ae77Skettenis int tt_status;
5042b725ae77Skettenis CORE_ADDR pc;
5043b725ae77Skettenis CORE_ADDR pc_addr;
5044b725ae77Skettenis unsigned int regs_offset;
5045b725ae77Skettenis process_state_t old_process_state = process_state;
5046b725ae77Skettenis
5047b725ae77Skettenis /* Are we already attached? There appears to be no explicit
5048b725ae77Skettenis * way to answer this via ttrace, so we try something which
5049b725ae77Skettenis * should be innocuous if we are attached. If that fails,
5050b725ae77Skettenis * then we assume we're not attached, and so attempt to make
5051b725ae77Skettenis * it so.
5052b725ae77Skettenis */
5053b725ae77Skettenis errno = 0;
5054b725ae77Skettenis tt_status = call_real_ttrace (TT_PROC_STOP,
5055b725ae77Skettenis pid,
5056b725ae77Skettenis (lwpid_t) TT_NIL,
5057b725ae77Skettenis (TTRACE_ARG_TYPE) TT_NIL,
5058b725ae77Skettenis (TTRACE_ARG_TYPE) TT_NIL,
5059b725ae77Skettenis TT_NIL);
5060b725ae77Skettenis
5061b725ae77Skettenis if (errno)
5062b725ae77Skettenis {
5063b725ae77Skettenis /* No change to process-state!
5064b725ae77Skettenis */
5065b725ae77Skettenis errno = 0;
5066b725ae77Skettenis pid = attach (pid);
5067b725ae77Skettenis }
5068b725ae77Skettenis else
5069b725ae77Skettenis {
5070b725ae77Skettenis /* If successful, the process is now stopped. But if
5071b725ae77Skettenis * we're VFORKING, the parent is still running, so don't
5072b725ae77Skettenis * change the process state.
5073b725ae77Skettenis */
5074b725ae77Skettenis if (process_state != VFORKING)
5075b725ae77Skettenis process_state = STOPPED;
5076b725ae77Skettenis
5077b725ae77Skettenis /* If we were already attached, you'd think that we
5078b725ae77Skettenis * would need to start going again--but you'd be wrong,
5079b725ae77Skettenis * as the fork-following code is actually in the middle
5080b725ae77Skettenis * of the "resume" routine in in "infrun.c" and so
5081b725ae77Skettenis * will (almost) immediately do a resume.
5082b725ae77Skettenis *
5083b725ae77Skettenis * On the other hand, if we are VFORKING, which means
5084b725ae77Skettenis * that the child and the parent share a process for a
5085b725ae77Skettenis * while, we know that "resume" won't be resuming
5086b725ae77Skettenis * until the child EXEC event is seen. But we still
5087b725ae77Skettenis * don't want to continue, as the event is already
5088b725ae77Skettenis * there waiting.
5089b725ae77Skettenis */
5090b725ae77Skettenis update_thread_state_after_attach (pid, DONT_ATTACH_CONTINUE);
5091b725ae77Skettenis } /* STOP succeeded */
5092b725ae77Skettenis
5093b725ae77Skettenis return pid;
5094b725ae77Skettenis }
5095b725ae77Skettenis
5096b725ae77Skettenis int
hppa_require_detach(int pid,int signal)5097b725ae77Skettenis hppa_require_detach (int pid, int signal)
5098b725ae77Skettenis {
5099b725ae77Skettenis int tt_status;
5100b725ae77Skettenis
5101b725ae77Skettenis /* If signal is non-zero, we must pass the signal on to the active
5102b725ae77Skettenis thread prior to detaching. We do this by continuing the threads
5103b725ae77Skettenis with the signal.
5104b725ae77Skettenis */
5105b725ae77Skettenis if (signal != 0)
5106b725ae77Skettenis {
5107b725ae77Skettenis errno = 0;
5108b725ae77Skettenis threads_continue_all_with_signals (pid, signal);
5109b725ae77Skettenis }
5110b725ae77Skettenis
5111b725ae77Skettenis errno = 0;
5112b725ae77Skettenis tt_status = call_ttrace (TT_PROC_DETACH,
5113b725ae77Skettenis pid,
5114b725ae77Skettenis TT_NIL,
5115b725ae77Skettenis TT_NIL,
5116b725ae77Skettenis TT_NIL);
5117b725ae77Skettenis
5118b725ae77Skettenis errno = 0; /* Ignore any errors. */
5119b725ae77Skettenis
5120b725ae77Skettenis /* process_state? */
5121b725ae77Skettenis
5122b725ae77Skettenis return pid;
5123b725ae77Skettenis }
5124b725ae77Skettenis
5125b725ae77Skettenis /* Given the starting address of a memory page, hash it to a bucket in
5126b725ae77Skettenis the memory page dictionary.
5127b725ae77Skettenis */
5128b725ae77Skettenis static int
get_dictionary_bucket_of_page(CORE_ADDR page_start)5129b725ae77Skettenis get_dictionary_bucket_of_page (CORE_ADDR page_start)
5130b725ae77Skettenis {
5131b725ae77Skettenis int hash;
5132b725ae77Skettenis
5133b725ae77Skettenis hash = (page_start / memory_page_dictionary.page_size);
5134b725ae77Skettenis hash = hash % MEMORY_PAGE_DICTIONARY_BUCKET_COUNT;
5135b725ae77Skettenis
5136b725ae77Skettenis return hash;
5137b725ae77Skettenis }
5138b725ae77Skettenis
5139b725ae77Skettenis
5140b725ae77Skettenis /* Given a memory page's starting address, get (i.e., find an existing
5141b725ae77Skettenis or create a new) dictionary entry for the page. The page will be
5142b725ae77Skettenis write-protected when this function returns, but may have a reference
5143b725ae77Skettenis count of 0 (if the page was newly-added to the dictionary).
5144b725ae77Skettenis */
5145b725ae77Skettenis static memory_page_t *
get_dictionary_entry_of_page(int pid,CORE_ADDR page_start)5146b725ae77Skettenis get_dictionary_entry_of_page (int pid, CORE_ADDR page_start)
5147b725ae77Skettenis {
5148b725ae77Skettenis int bucket;
5149b725ae77Skettenis memory_page_t *page = NULL;
5150b725ae77Skettenis memory_page_t *previous_page = NULL;
5151b725ae77Skettenis
5152b725ae77Skettenis /* We're going to be using the dictionary now, than-kew. */
5153b725ae77Skettenis require_memory_page_dictionary ();
5154b725ae77Skettenis
5155b725ae77Skettenis /* Try to find an existing dictionary entry for this page. Hash
5156b725ae77Skettenis on the page's starting address.
5157b725ae77Skettenis */
5158b725ae77Skettenis bucket = get_dictionary_bucket_of_page (page_start);
5159b725ae77Skettenis page = &memory_page_dictionary.buckets[bucket];
5160b725ae77Skettenis while (page != NULL)
5161b725ae77Skettenis {
5162b725ae77Skettenis if (page->page_start == page_start)
5163b725ae77Skettenis break;
5164b725ae77Skettenis previous_page = page;
5165b725ae77Skettenis page = page->next;
5166b725ae77Skettenis }
5167b725ae77Skettenis
5168b725ae77Skettenis /* Did we find a dictionary entry for this page? If not, then
5169b725ae77Skettenis add it to the dictionary now.
5170b725ae77Skettenis */
5171b725ae77Skettenis if (page == NULL)
5172b725ae77Skettenis {
5173b725ae77Skettenis /* Create a new entry. */
5174b725ae77Skettenis page = (memory_page_t *) xmalloc (sizeof (memory_page_t));
5175b725ae77Skettenis page->page_start = page_start;
5176b725ae77Skettenis page->reference_count = 0;
5177b725ae77Skettenis page->next = NULL;
5178b725ae77Skettenis page->previous = NULL;
5179b725ae77Skettenis
5180b725ae77Skettenis /* We'll write-protect the page now, if that's allowed. */
5181b725ae77Skettenis page->original_permissions = write_protect_page (pid, page_start);
5182b725ae77Skettenis
5183b725ae77Skettenis /* Add the new entry to the dictionary. */
5184b725ae77Skettenis page->previous = previous_page;
5185b725ae77Skettenis previous_page->next = page;
5186b725ae77Skettenis
5187b725ae77Skettenis memory_page_dictionary.page_count++;
5188b725ae77Skettenis }
5189b725ae77Skettenis
5190b725ae77Skettenis return page;
5191b725ae77Skettenis }
5192b725ae77Skettenis
5193b725ae77Skettenis
5194b725ae77Skettenis static void
remove_dictionary_entry_of_page(int pid,memory_page_t * page)5195b725ae77Skettenis remove_dictionary_entry_of_page (int pid, memory_page_t *page)
5196b725ae77Skettenis {
5197b725ae77Skettenis /* Restore the page's original permissions. */
5198b725ae77Skettenis unwrite_protect_page (pid, page->page_start, page->original_permissions);
5199b725ae77Skettenis
5200b725ae77Skettenis /* Kick the page out of the dictionary. */
5201b725ae77Skettenis if (page->previous != NULL)
5202b725ae77Skettenis page->previous->next = page->next;
5203b725ae77Skettenis if (page->next != NULL)
5204b725ae77Skettenis page->next->previous = page->previous;
5205b725ae77Skettenis
5206b725ae77Skettenis /* Just in case someone retains a handle to this after it's freed. */
5207b725ae77Skettenis page->page_start = (CORE_ADDR) 0;
5208b725ae77Skettenis
5209b725ae77Skettenis memory_page_dictionary.page_count--;
5210b725ae77Skettenis
5211b725ae77Skettenis xfree (page);
5212b725ae77Skettenis }
5213b725ae77Skettenis
5214b725ae77Skettenis
5215b725ae77Skettenis static void
hppa_enable_syscall_events(int pid)5216b725ae77Skettenis hppa_enable_syscall_events (int pid)
5217b725ae77Skettenis {
5218b725ae77Skettenis int tt_status;
5219b725ae77Skettenis ttevent_t ttrace_events;
5220b725ae77Skettenis
5221b725ae77Skettenis /* Get the set of events that are currently enabled. */
5222b725ae77Skettenis tt_status = call_ttrace (TT_PROC_GET_EVENT_MASK,
5223b725ae77Skettenis pid,
5224b725ae77Skettenis (TTRACE_ARG_TYPE) & ttrace_events,
5225b725ae77Skettenis (TTRACE_ARG_TYPE) sizeof (ttrace_events),
5226b725ae77Skettenis TT_NIL);
5227b725ae77Skettenis if (errno)
5228b725ae77Skettenis perror_with_name ("ttrace");
5229b725ae77Skettenis
5230b725ae77Skettenis /* Add syscall events to that set. */
5231b725ae77Skettenis ttrace_events.tte_events |= TTEVT_SYSCALL_ENTRY;
5232b725ae77Skettenis ttrace_events.tte_events |= TTEVT_SYSCALL_RETURN;
5233b725ae77Skettenis
5234b725ae77Skettenis tt_status = call_ttrace (TT_PROC_SET_EVENT_MASK,
5235b725ae77Skettenis pid,
5236b725ae77Skettenis (TTRACE_ARG_TYPE) & ttrace_events,
5237b725ae77Skettenis (TTRACE_ARG_TYPE) sizeof (ttrace_events),
5238b725ae77Skettenis TT_NIL);
5239b725ae77Skettenis if (errno)
5240b725ae77Skettenis perror_with_name ("ttrace");
5241b725ae77Skettenis }
5242b725ae77Skettenis
5243b725ae77Skettenis
5244b725ae77Skettenis static void
hppa_disable_syscall_events(int pid)5245b725ae77Skettenis hppa_disable_syscall_events (int pid)
5246b725ae77Skettenis {
5247b725ae77Skettenis int tt_status;
5248b725ae77Skettenis ttevent_t ttrace_events;
5249b725ae77Skettenis
5250b725ae77Skettenis /* Get the set of events that are currently enabled. */
5251b725ae77Skettenis tt_status = call_ttrace (TT_PROC_GET_EVENT_MASK,
5252b725ae77Skettenis pid,
5253b725ae77Skettenis (TTRACE_ARG_TYPE) & ttrace_events,
5254b725ae77Skettenis (TTRACE_ARG_TYPE) sizeof (ttrace_events),
5255b725ae77Skettenis TT_NIL);
5256b725ae77Skettenis if (errno)
5257b725ae77Skettenis perror_with_name ("ttrace");
5258b725ae77Skettenis
5259b725ae77Skettenis /* Remove syscall events from that set. */
5260b725ae77Skettenis ttrace_events.tte_events &= ~TTEVT_SYSCALL_ENTRY;
5261b725ae77Skettenis ttrace_events.tte_events &= ~TTEVT_SYSCALL_RETURN;
5262b725ae77Skettenis
5263b725ae77Skettenis tt_status = call_ttrace (TT_PROC_SET_EVENT_MASK,
5264b725ae77Skettenis pid,
5265b725ae77Skettenis (TTRACE_ARG_TYPE) & ttrace_events,
5266b725ae77Skettenis (TTRACE_ARG_TYPE) sizeof (ttrace_events),
5267b725ae77Skettenis TT_NIL);
5268b725ae77Skettenis if (errno)
5269b725ae77Skettenis perror_with_name ("ttrace");
5270b725ae77Skettenis }
5271b725ae77Skettenis
5272b725ae77Skettenis
5273b725ae77Skettenis /* The address range beginning with START and ending with START+LEN-1
5274b725ae77Skettenis (inclusive) is to be watched via page-protection by a new watchpoint.
5275b725ae77Skettenis Set protection for all pages that overlap that range.
5276b725ae77Skettenis
5277b725ae77Skettenis Note that our caller sets TYPE to:
5278b725ae77Skettenis 0 for a bp_hardware_watchpoint,
5279b725ae77Skettenis 1 for a bp_read_watchpoint,
5280b725ae77Skettenis 2 for a bp_access_watchpoint
5281b725ae77Skettenis
5282b725ae77Skettenis (Yes, this is intentionally (though lord only knows why) different
5283b725ae77Skettenis from the TYPE that is passed to hppa_remove_hw_watchpoint.)
5284b725ae77Skettenis */
5285b725ae77Skettenis int
hppa_insert_hw_watchpoint(int pid,CORE_ADDR start,LONGEST len,int type)5286b725ae77Skettenis hppa_insert_hw_watchpoint (int pid, CORE_ADDR start, LONGEST len, int type)
5287b725ae77Skettenis {
5288b725ae77Skettenis CORE_ADDR page_start;
5289b725ae77Skettenis int dictionary_was_empty;
5290b725ae77Skettenis int page_size;
5291b725ae77Skettenis int page_id;
5292b725ae77Skettenis LONGEST range_size_in_pages;
5293b725ae77Skettenis
5294b725ae77Skettenis if (type != 0)
5295b725ae77Skettenis error ("read or access hardware watchpoints not supported on HP-UX");
5296b725ae77Skettenis
5297b725ae77Skettenis /* Examine all pages in the address range. */
5298b725ae77Skettenis require_memory_page_dictionary ();
5299b725ae77Skettenis
5300b725ae77Skettenis dictionary_was_empty = (memory_page_dictionary.page_count == (LONGEST) 0);
5301b725ae77Skettenis
5302b725ae77Skettenis page_size = memory_page_dictionary.page_size;
5303b725ae77Skettenis page_start = (start / page_size) * page_size;
5304b725ae77Skettenis range_size_in_pages = ((LONGEST) len + (LONGEST) page_size - 1) / (LONGEST) page_size;
5305b725ae77Skettenis
5306b725ae77Skettenis for (page_id = 0; page_id < range_size_in_pages; page_id++, page_start += page_size)
5307b725ae77Skettenis {
5308b725ae77Skettenis memory_page_t *page;
5309b725ae77Skettenis
5310b725ae77Skettenis /* This gets the page entered into the dictionary if it was
5311b725ae77Skettenis not already entered.
5312b725ae77Skettenis */
5313b725ae77Skettenis page = get_dictionary_entry_of_page (pid, page_start);
5314b725ae77Skettenis page->reference_count++;
5315b725ae77Skettenis }
5316b725ae77Skettenis
5317b725ae77Skettenis /* Our implementation depends on seeing calls to kernel code, for the
5318b725ae77Skettenis following reason. Here we ask to be notified of syscalls.
5319b725ae77Skettenis
5320b725ae77Skettenis When a protected page is accessed by user code, HP-UX raises a SIGBUS.
5321b725ae77Skettenis Fine.
5322b725ae77Skettenis
5323b725ae77Skettenis But when kernel code accesses the page, it doesn't give a SIGBUS.
5324b725ae77Skettenis Rather, the system call that touched the page fails, with errno=EFAULT.
5325b725ae77Skettenis Not good for us.
5326b725ae77Skettenis
5327b725ae77Skettenis We could accomodate this "feature" by asking to be notified of syscall
5328b725ae77Skettenis entries & exits; upon getting an entry event, disabling page-protections;
5329b725ae77Skettenis upon getting an exit event, reenabling page-protections and then checking
5330b725ae77Skettenis if any watchpoints triggered.
5331b725ae77Skettenis
5332b725ae77Skettenis However, this turns out to be a real performance loser. syscalls are
5333b725ae77Skettenis usually a frequent occurrence. Having to unprotect-reprotect all watched
5334b725ae77Skettenis pages, and also to then read all watched memory locations and compare for
5335b725ae77Skettenis triggers, can be quite expensive.
5336b725ae77Skettenis
5337b725ae77Skettenis Instead, we'll only ask to be notified of syscall exits. When we get
5338b725ae77Skettenis one, we'll check whether errno is set. If not, or if it's not EFAULT,
5339b725ae77Skettenis we can just continue the inferior.
5340b725ae77Skettenis
5341b725ae77Skettenis If errno is set upon syscall exit to EFAULT, we must perform some fairly
5342b725ae77Skettenis hackish stuff to determine whether the failure really was due to a
5343b725ae77Skettenis page-protect trap on a watched location.
5344b725ae77Skettenis */
5345b725ae77Skettenis if (dictionary_was_empty)
5346b725ae77Skettenis hppa_enable_syscall_events (pid);
5347b725ae77Skettenis
5348b725ae77Skettenis return 1;
5349b725ae77Skettenis }
5350b725ae77Skettenis
5351b725ae77Skettenis
5352b725ae77Skettenis /* The address range beginning with START and ending with START+LEN-1
5353b725ae77Skettenis (inclusive) was being watched via page-protection by a watchpoint
5354b725ae77Skettenis which has been removed. Remove protection for all pages that
5355b725ae77Skettenis overlap that range, which are not also being watched by other
5356b725ae77Skettenis watchpoints.
5357b725ae77Skettenis */
5358b725ae77Skettenis int
hppa_remove_hw_watchpoint(int pid,CORE_ADDR start,LONGEST len,int type)5359b725ae77Skettenis hppa_remove_hw_watchpoint (int pid, CORE_ADDR start, LONGEST len, int type)
5360b725ae77Skettenis {
5361b725ae77Skettenis CORE_ADDR page_start;
5362b725ae77Skettenis int dictionary_is_empty;
5363b725ae77Skettenis int page_size;
5364b725ae77Skettenis int page_id;
5365b725ae77Skettenis LONGEST range_size_in_pages;
5366b725ae77Skettenis
5367b725ae77Skettenis if (type != 0)
5368b725ae77Skettenis error ("read or access hardware watchpoints not supported on HP-UX");
5369b725ae77Skettenis
5370b725ae77Skettenis /* Examine all pages in the address range. */
5371b725ae77Skettenis require_memory_page_dictionary ();
5372b725ae77Skettenis
5373b725ae77Skettenis page_size = memory_page_dictionary.page_size;
5374b725ae77Skettenis page_start = (start / page_size) * page_size;
5375b725ae77Skettenis range_size_in_pages = ((LONGEST) len + (LONGEST) page_size - 1) / (LONGEST) page_size;
5376b725ae77Skettenis
5377b725ae77Skettenis for (page_id = 0; page_id < range_size_in_pages; page_id++, page_start += page_size)
5378b725ae77Skettenis {
5379b725ae77Skettenis memory_page_t *page;
5380b725ae77Skettenis
5381b725ae77Skettenis page = get_dictionary_entry_of_page (pid, page_start);
5382b725ae77Skettenis page->reference_count--;
5383b725ae77Skettenis
5384b725ae77Skettenis /* Was this the last reference of this page? If so, then we
5385b725ae77Skettenis must scrub the entry from the dictionary, and also restore
5386b725ae77Skettenis the page's original permissions.
5387b725ae77Skettenis */
5388b725ae77Skettenis if (page->reference_count == 0)
5389b725ae77Skettenis remove_dictionary_entry_of_page (pid, page);
5390b725ae77Skettenis }
5391b725ae77Skettenis
5392b725ae77Skettenis dictionary_is_empty = (memory_page_dictionary.page_count == (LONGEST) 0);
5393b725ae77Skettenis
5394b725ae77Skettenis /* If write protections are currently disallowed, then that implies that
5395b725ae77Skettenis wait_for_inferior believes that the inferior is within a system call.
5396b725ae77Skettenis Since we want to see both syscall entry and return, it's clearly not
5397b725ae77Skettenis good to disable syscall events in this state!
5398b725ae77Skettenis
5399b725ae77Skettenis ??rehrauer: Yeah, it'd be better if we had a specific flag that said,
5400b725ae77Skettenis "inferior is between syscall events now". Oh well.
5401b725ae77Skettenis */
5402b725ae77Skettenis if (dictionary_is_empty && memory_page_dictionary.page_protections_allowed)
5403b725ae77Skettenis hppa_disable_syscall_events (pid);
5404b725ae77Skettenis
5405b725ae77Skettenis return 1;
5406b725ae77Skettenis }
5407b725ae77Skettenis
5408b725ae77Skettenis
5409b725ae77Skettenis /* Could we implement a watchpoint of this type via our available
5410b725ae77Skettenis hardware support?
5411b725ae77Skettenis
5412b725ae77Skettenis This query does not consider whether a particular address range
5413b725ae77Skettenis could be so watched, but just whether support is generally available
5414b725ae77Skettenis for such things. See hppa_range_profitable_for_hw_watchpoint for a
5415b725ae77Skettenis query that answers whether a particular range should be watched via
5416b725ae77Skettenis hardware support.
5417b725ae77Skettenis */
5418b725ae77Skettenis int
hppa_can_use_hw_watchpoint(int type,int cnt,int ot)5419b725ae77Skettenis hppa_can_use_hw_watchpoint (int type, int cnt, int ot)
5420b725ae77Skettenis {
5421b725ae77Skettenis return (type == bp_hardware_watchpoint);
5422b725ae77Skettenis }
5423b725ae77Skettenis
5424b725ae77Skettenis
5425b725ae77Skettenis /* Assuming we could set a hardware watchpoint on this address, do
5426b725ae77Skettenis we think it would be profitable ("a good idea") to do so? If not,
5427b725ae77Skettenis we can always set a regular (aka single-step & test) watchpoint
5428b725ae77Skettenis on the address...
5429b725ae77Skettenis */
5430b725ae77Skettenis int
hppa_range_profitable_for_hw_watchpoint(int pid,CORE_ADDR start,LONGEST len)5431b725ae77Skettenis hppa_range_profitable_for_hw_watchpoint (int pid, CORE_ADDR start, LONGEST len)
5432b725ae77Skettenis {
5433b725ae77Skettenis int range_is_stack_based;
5434b725ae77Skettenis int range_is_accessible;
5435b725ae77Skettenis CORE_ADDR page_start;
5436b725ae77Skettenis int page_size;
5437b725ae77Skettenis int page;
5438b725ae77Skettenis LONGEST range_size_in_pages;
5439b725ae77Skettenis
5440b725ae77Skettenis /* ??rehrauer: For now, say that all addresses are potentially
5441b725ae77Skettenis profitable. Possibly later we'll want to test the address
5442b725ae77Skettenis for "stackness"?
5443b725ae77Skettenis */
5444b725ae77Skettenis range_is_stack_based = 0;
5445b725ae77Skettenis
5446b725ae77Skettenis /* If any page in the range is inaccessible, then we cannot
5447b725ae77Skettenis really use hardware watchpointing, even though our client
5448b725ae77Skettenis thinks we can. In that case, it's actually an error to
5449b725ae77Skettenis attempt to use hw watchpoints, so we'll tell our client
5450b725ae77Skettenis that the range is "unprofitable", and hope that they listen...
5451b725ae77Skettenis */
5452b725ae77Skettenis range_is_accessible = 1; /* Until proven otherwise. */
5453b725ae77Skettenis
5454b725ae77Skettenis /* Examine all pages in the address range. */
5455b725ae77Skettenis errno = 0;
5456b725ae77Skettenis page_size = sysconf (_SC_PAGE_SIZE);
5457b725ae77Skettenis
5458b725ae77Skettenis /* If we can't determine page size, we're hosed. Tell our
5459b725ae77Skettenis client it's unprofitable to use hw watchpoints for this
5460b725ae77Skettenis range.
5461b725ae77Skettenis */
5462b725ae77Skettenis if (errno || (page_size <= 0))
5463b725ae77Skettenis {
5464b725ae77Skettenis errno = 0;
5465b725ae77Skettenis return 0;
5466b725ae77Skettenis }
5467b725ae77Skettenis
5468b725ae77Skettenis page_start = (start / page_size) * page_size;
5469b725ae77Skettenis range_size_in_pages = len / (LONGEST) page_size;
5470b725ae77Skettenis
5471b725ae77Skettenis for (page = 0; page < range_size_in_pages; page++, page_start += page_size)
5472b725ae77Skettenis {
5473b725ae77Skettenis int tt_status;
5474b725ae77Skettenis int page_permissions;
5475b725ae77Skettenis
5476b725ae77Skettenis /* Is this page accessible? */
5477b725ae77Skettenis errno = 0;
5478b725ae77Skettenis tt_status = call_ttrace (TT_PROC_GET_MPROTECT,
5479b725ae77Skettenis pid,
5480b725ae77Skettenis (TTRACE_ARG_TYPE) page_start,
5481b725ae77Skettenis TT_NIL,
5482b725ae77Skettenis (TTRACE_ARG_TYPE) & page_permissions);
5483b725ae77Skettenis if (errno || (tt_status < 0))
5484b725ae77Skettenis {
5485b725ae77Skettenis errno = 0;
5486b725ae77Skettenis range_is_accessible = 0;
5487b725ae77Skettenis break;
5488b725ae77Skettenis }
5489b725ae77Skettenis
5490b725ae77Skettenis /* Yes, go for another... */
5491b725ae77Skettenis }
5492b725ae77Skettenis
5493b725ae77Skettenis return (!range_is_stack_based && range_is_accessible);
5494b725ae77Skettenis }
5495b725ae77Skettenis
5496b725ae77Skettenis
5497b725ae77Skettenis char *
hppa_pid_or_tid_to_str(ptid_t ptid)5498b725ae77Skettenis hppa_pid_or_tid_to_str (ptid_t ptid)
5499b725ae77Skettenis {
5500b725ae77Skettenis static char buf[100]; /* Static because address returned. */
5501b725ae77Skettenis pid_t id = PIDGET (ptid);
5502b725ae77Skettenis
5503b725ae77Skettenis /* Does this appear to be a process? If so, print it that way. */
5504b725ae77Skettenis if (is_process_id (id))
5505b725ae77Skettenis return child_pid_to_str (ptid);
5506b725ae77Skettenis
5507b725ae77Skettenis /* Else, print both the GDB thread number and the system thread id. */
5508b725ae77Skettenis sprintf (buf, "thread %d (", pid_to_thread_id (ptid));
5509b725ae77Skettenis strcat (buf, hppa_tid_to_str (ptid));
5510b725ae77Skettenis strcat (buf, ")\0");
5511b725ae77Skettenis
5512b725ae77Skettenis return buf;
5513b725ae77Skettenis }
5514b725ae77Skettenis
5515b725ae77Skettenis
5516b725ae77Skettenis void
hppa_ensure_vforking_parent_remains_stopped(int pid)5517b725ae77Skettenis hppa_ensure_vforking_parent_remains_stopped (int pid)
5518b725ae77Skettenis {
5519b725ae77Skettenis /* Nothing to do when using ttrace. Only the ptrace-based implementation
5520b725ae77Skettenis must do real work.
5521b725ae77Skettenis */
5522b725ae77Skettenis }
5523b725ae77Skettenis
5524b725ae77Skettenis
5525b725ae77Skettenis int
hppa_resume_execd_vforking_child_to_get_parent_vfork(void)5526b725ae77Skettenis hppa_resume_execd_vforking_child_to_get_parent_vfork (void)
5527b725ae77Skettenis {
5528b725ae77Skettenis return 0; /* No, the parent vfork is available now. */
5529b725ae77Skettenis }
5530b725ae77Skettenis
5531b725ae77Skettenis
5532b725ae77Skettenis /* Write a register as a 64bit value. This may be necessary if the
5533b725ae77Skettenis native OS is too braindamaged to allow some (or all) registers to
5534b725ae77Skettenis be written in 32bit hunks such as hpux11 and the PC queue registers.
5535b725ae77Skettenis
5536b725ae77Skettenis This is horribly gross and disgusting. */
5537b725ae77Skettenis
5538b725ae77Skettenis int
ttrace_write_reg_64(int gdb_tid,CORE_ADDR dest_addr,CORE_ADDR src_addr)5539b725ae77Skettenis ttrace_write_reg_64 (int gdb_tid, CORE_ADDR dest_addr, CORE_ADDR src_addr)
5540b725ae77Skettenis {
5541b725ae77Skettenis pid_t pid;
5542b725ae77Skettenis lwpid_t tid;
5543b725ae77Skettenis int tt_status;
5544b725ae77Skettenis
5545b725ae77Skettenis tid = map_from_gdb_tid (gdb_tid);
5546b725ae77Skettenis pid = get_pid_for (tid);
5547b725ae77Skettenis
5548b725ae77Skettenis errno = 0;
5549b725ae77Skettenis tt_status = ttrace (TT_LWP_WUREGS,
5550b725ae77Skettenis pid,
5551b725ae77Skettenis tid,
5552b725ae77Skettenis (TTRACE_ARG_TYPE) dest_addr,
5553b725ae77Skettenis 8,
5554b725ae77Skettenis (TTRACE_ARG_TYPE) src_addr );
5555b725ae77Skettenis
5556b725ae77Skettenis #ifdef THREAD_DEBUG
5557b725ae77Skettenis if (errno)
5558b725ae77Skettenis {
5559b725ae77Skettenis /* Don't bother for a known benign error: if you ask for the
5560b725ae77Skettenis first thread state, but there is only one thread and it's
5561b725ae77Skettenis not stopped, ttrace complains.
5562b725ae77Skettenis
5563b725ae77Skettenis We have this inside the #ifdef because our caller will do
5564b725ae77Skettenis this check for real. */
5565b725ae77Skettenis if( request != TT_PROC_GET_FIRST_LWP_STATE
5566b725ae77Skettenis || errno != EPROTO )
5567b725ae77Skettenis {
5568b725ae77Skettenis if( debug_on )
5569b725ae77Skettenis printf( "TT fail for %s, with pid %d, tid %d, status %d \n",
5570b725ae77Skettenis get_printable_name_of_ttrace_request (TT_LWP_WUREGS),
5571b725ae77Skettenis pid, tid, tt_status );
5572b725ae77Skettenis }
5573b725ae77Skettenis }
5574b725ae77Skettenis #endif
5575b725ae77Skettenis
5576b725ae77Skettenis return tt_status;
5577b725ae77Skettenis }
5578b725ae77Skettenis
5579b725ae77Skettenis void
_initialize_infttrace(void)5580b725ae77Skettenis _initialize_infttrace (void)
5581b725ae77Skettenis {
5582b725ae77Skettenis /* Initialize the ttrace-based hardware watchpoint implementation. */
5583b725ae77Skettenis memory_page_dictionary.page_count = (LONGEST) - 1;
5584b725ae77Skettenis memory_page_dictionary.page_protections_allowed = 1;
5585b725ae77Skettenis
5586b725ae77Skettenis errno = 0;
5587b725ae77Skettenis memory_page_dictionary.page_size = sysconf (_SC_PAGE_SIZE);
5588b725ae77Skettenis
5589b725ae77Skettenis /* We do a lot of casts from pointers to TTRACE_ARG_TYPE; make sure
5590b725ae77Skettenis this is okay. */
5591b725ae77Skettenis if (sizeof (TTRACE_ARG_TYPE) < sizeof (void *))
5592b725ae77Skettenis internal_error (__FILE__, __LINE__, "failed internal consistency check");
5593b725ae77Skettenis
5594b725ae77Skettenis if (errno || (memory_page_dictionary.page_size <= 0))
5595b725ae77Skettenis perror_with_name ("sysconf");
5596b725ae77Skettenis }
5597