]> git.pld-linux.org Git - packages/gdb.git/blame - gdb-threads.patch
- more %%{__make} macros.
[packages/gdb.git] / gdb-threads.patch
CommitLineData
0f840cc8 11999-08-13 Jim Kingdon <http://developer.redhat.com/>
2
3 Threads code from gdb 4.18-codefusion-990706:
4 * infrun.c (signal_stop_update, signal_print_update,
5 signal_pass_update): new functions.
6 * inferior.h: new prototypes for above functions.
7 * target.h (enum strata): add thread stratum.
8 * linuxthreads.c: new file. Support for debugging linux threads.
9 * config/i386/nm-linux.h: several new prototypes for above.
10 * config/i386/linux.mh: add linuxthreads.o to NATDEPFILES.
11
12 More threads code from the same place:
13 * config/i386/tm-linux.h (REALTIME_LO, REALTIME_HI): Add
14 definitions.
15 * target.h (enum target_signal): Add TARGET_SIGNAL_REALTIME_32.
16 * target.c (signals, target_signal_from_host,
17 target_signal_to_host): Add clauses for
18 TARGET_SIGNAL_REALTIME_32.
19
20 * various files: various minor changes to make the above work
21 with GDB 4.18.
22
23diff -Ncr /home/kingdon/work/gdb/gdb/config/i386/linux.mh ./gdb/config/i386/linux.mh
24*** /home/kingdon/work/gdb/gdb/config/i386/linux.mh Thu Apr 15 21:34:19 1999
25--- ./gdb/config/i386/linux.mh Fri Aug 13 00:51:14 1999
26***************
27*** 4,7 ****
28 XDEPFILES= ser-tcp.o
29
30 NAT_FILE= nm-linux.h
31! NATDEPFILES= infptrace.o solib.o inftarg.o fork-child.o corelow.o core-aout.o core-regset.o i386v-nat.o i386v4-nat.o
32--- 4,7 ----
33 XDEPFILES= ser-tcp.o
34
35 NAT_FILE= nm-linux.h
36! NATDEPFILES= infptrace.o solib.o inftarg.o fork-child.o corelow.o core-aout.o core-regset.o i386v-nat.o i386v4-nat.o linuxthreads.o
37diff -Ncr /home/kingdon/work/gdb/gdb/config/i386/nm-linux.h ./gdb/config/i386/nm-linux.h
38*** /home/kingdon/work/gdb/gdb/config/i386/nm-linux.h Thu Jul 8 16:09:02 1999
39--- ./gdb/config/i386/nm-linux.h Fri Aug 13 00:49:54 1999
40***************
41*** 71,74 ****
42--- 71,92 ----
43 extern int
44 i386_remove_watchpoint PARAMS ((int pid, CORE_ADDR addr, int len));
45
46+ /* Support for the glibc linuxthreads package. */
47+
48+ #ifdef __STDC__
49+ struct objfile;
50+ #endif
51+
52+ extern void
53+ linuxthreads_new_objfile PARAMS ((struct objfile *objfile));
54+ #define target_new_objfile(OBJFILE) linuxthreads_new_objfile (OBJFILE)
55+
56+ extern char *
57+ linuxthreads_pid_to_str PARAMS ((int pid));
58+ #define target_pid_to_str(PID) linuxthreads_pid_to_str (PID)
59+
60+ extern int
61+ linuxthreads_prepare_to_proceed PARAMS ((int step));
62+ #define PREPARE_TO_PROCEED() linuxthreads_prepare_to_proceed (1)
63+
64 #endif /* #ifndef NM_LINUX_H */
65diff -Ncr /home/kingdon/work/gdb/gdb/config/i386/tm-linux.h ./gdb/config/i386/tm-linux.h
66*** /home/kingdon/work/gdb/gdb/config/i386/tm-linux.h Tue Aug 3 16:40:28 1999
67--- ./gdb/config/i386/tm-linux.h Sat Aug 14 19:15:35 1999
68***************
69*** 104,107 ****
70--- 104,121 ----
71
72 extern CORE_ADDR i386_linux_sigtramp_saved_sp PARAMS ((struct frame_info *));
73
74+
75+ /* Some versions of Linux have real-time signal support in the C library, and
76+ some don't. We have to include this file to find out. */
77+ #include <signal.h>
78+
79+ #ifdef __SIGRTMIN
80+ #define REALTIME_LO __SIGRTMIN
81+ #define REALTIME_HI (__SIGRTMAX + 1)
82+ #else
83+ #define REALTIME_LO 32
84+ #define REALTIME_HI 64
85+ #endif
86+
87+
88 #endif /* #ifndef TM_LINUX_H */
89diff -Ncr /home/kingdon/work/gdb/gdb/inferior.h ./gdb/inferior.h
90*** /home/kingdon/work/gdb/gdb/inferior.h Thu Jul 8 16:02:22 1999
91--- ./gdb/inferior.h Fri Aug 13 00:43:51 1999
92***************
93*** 260,265 ****
94--- 260,271 ----
95
96 extern int signal_pass_state PARAMS ((int));
97
98+ extern int signal_stop_update PARAMS ((int, int));
99+
100+ extern int signal_print_update PARAMS ((int, int));
101+
102+ extern int signal_pass_update PARAMS ((int, int));
103+
104 /* From infcmd.c */
105
106 extern void tty_command PARAMS ((char *, int));
107diff -Ncr /home/kingdon/work/gdb/gdb/infrun.c ./gdb/infrun.c
108*** /home/kingdon/work/gdb/gdb/infrun.c Thu Aug 12 11:13:29 1999
109--- ./gdb/infrun.c Fri Aug 13 00:33:34 1999
110***************
111*** 3291,3296 ****
112--- 3291,3323 ----
113 return signal_program[signo];
114 }
115
116+ int signal_stop_update (signo, state)
117+ int signo;
118+ int state;
119+ {
120+ int ret = signal_stop[signo];
121+ signal_stop[signo] = state;
122+ return ret;
123+ }
124+
125+ int signal_print_update (signo, state)
126+ int signo;
127+ int state;
128+ {
129+ int ret = signal_print[signo];
130+ signal_print[signo] = state;
131+ return ret;
132+ }
133+
134+ int signal_pass_update (signo, state)
135+ int signo;
136+ int state;
137+ {
138+ int ret = signal_program[signo];
139+ signal_program[signo] = state;
140+ return ret;
141+ }
142+
143 static void
144 sig_print_header (void)
145 {
146diff -Ncr /home/kingdon/work/gdb/gdb/linuxthreads.c ./gdb/linuxthreads.c
147*** /home/kingdon/work/gdb/gdb/linuxthreads.c Wed Dec 31 19:00:00 1969
148--- ./gdb/linuxthreads.c Fri Aug 13 00:46:01 1999
149***************
150*** 0 ****
151--- 1,1631 ----
152+ /* Low level interface for debugging GNU/Linux threads for GDB,
153+ the GNU debugger.
154+ Copyright 1998, 1999 Free Software Foundation, Inc.
155+
156+ This file is part of GDB.
157+
158+ This program is free software; you can redistribute it and/or modify
159+ it under the terms of the GNU General Public License as published by
160+ the Free Software Foundation; either version 2 of the License, or
161+ (at your option) any later version.
162+
163+ This program is distributed in the hope that it will be useful,
164+ but WITHOUT ANY WARRANTY; without even the implied warranty of
165+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
166+ GNU General Public License for more details.
167+
168+ You should have received a copy of the GNU General Public License
169+ along with this program; if not, write to the Free Software
170+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
171+
172+ /* This module implements the debugging interface of the linuxthreads package
173+ of the glibc. This package implements a simple clone()-based implementation
174+ of Posix threads for Linux. To use this module, be sure that you have at
175+ least the version of the linuxthreads package that holds the support of
176+ GDB (currently 0.8 included in the glibc-2.0.7).
177+
178+ Right now, the linuxthreads package does not care of priority scheduling,
179+ so, neither this module does; In particular, the threads are resumed
180+ in any order, which could lead to different scheduling than the one
181+ happening when GDB does not control the execution.
182+
183+ The latest point is that ptrace(PT_ATTACH, ...) is intrusive in Linux:
184+ When a process is attached, then the attaching process becomes the current
185+ parent of the attached process, and the old parent has lost this child.
186+ If the old parent does a wait[...](), then this child is no longer
187+ considered by the kernel as a child of the old parent, thus leading to
188+ results of the call different when the child is attached and when it's not.
189+
190+ A fix has been submitted to the Linux community to solve this problem,
191+ which consequences are not visible to the application itself, but on the
192+ process which may wait() for the completion of the application (mostly,
193+ it may consider that the application no longer exists (errno == ECHILD),
194+ although it does, and thus being unable to get the exit status and resource
195+ usage of the child. If by chance, it is able to wait() for the application
196+ after it has died (by receiving first a SIGCHILD, and then doing a wait(),
197+ then the exit status and resource usage may be wrong, because the
198+ linuxthreads package heavily relies on wait() synchronization to keep
199+ them correct. */
200+
201+ #include <sys/types.h> /* for pid_t */
202+ #include <sys/ptrace.h> /* for PT_* flags */
203+ #include <sys/wait.h> /* for WUNTRACED and __WCLONE flags */
204+ #include <signal.h> /* for struct sigaction and NSIG */
205+ #include <sys/utsname.h>
206+
207+ #include "defs.h"
208+ #include "target.h"
209+ #include "inferior.h"
210+ #include "gdbcore.h"
211+ #include "gdbthread.h"
212+ #include "wait.h"
213+ #include "gdbcmd.h"
214+ #include "breakpoint.h"
215+
216+ #ifndef PT_ATTACH
217+ #define PT_ATTACH PTRACE_ATTACH
218+ #endif
219+ #ifndef PT_KILL
220+ #define PT_KILL PTRACE_KILL
221+ #endif
222+ #ifndef PT_READ_U
223+ #define PT_READ_U PTRACE_PEEKUSR
224+ #endif
225+
226+ #ifdef NSIG
227+ #define LINUXTHREAD_NSIG NSIG
228+ #else
229+ #ifdef _NSIG
230+ #define LINUXTHREAD_NSIG _NSIG
231+ #endif
232+ #endif
233+
234+ extern int child_suppress_run; /* make inftarg.c non-runnable */
235+ struct target_ops linuxthreads_ops; /* Forward declaration */
236+ extern struct target_ops child_ops; /* target vector for inftarg.c */
237+
238+ static CORE_ADDR linuxthreads_handles; /* array of linuxthreads handles */
239+ static CORE_ADDR linuxthreads_manager; /* pid of linuxthreads manager thread */
240+ static CORE_ADDR linuxthreads_initial; /* pid of linuxthreads initial thread */
241+ static CORE_ADDR linuxthreads_debug; /* linuxthreads internal debug flag */
242+ static CORE_ADDR linuxthreads_num; /* number of valid handle entries */
243+
244+ static int linuxthreads_max; /* Maximum number of linuxthreads.
245+ Zero if this executable doesn't use
246+ threads, or wasn't linked with a
247+ debugger-friendly version of the
248+ linuxthreads library. */
249+
250+ static int linuxthreads_sizeof_handle; /* size of a linuxthreads handle */
251+ static int linuxthreads_offset_descr; /* h_descr offset of the linuxthreads
252+ handle */
253+ static int linuxthreads_offset_pid; /* p_pid offset of the linuxthreads
254+ descr */
255+
256+ static int linuxthreads_manager_pid; /* manager pid */
257+ static int linuxthreads_initial_pid; /* initial pid */
258+
259+ /* These variables form a bag of threads with interesting status. If
260+ wait_thread (PID) finds that PID stopped for some interesting
261+ reason (i.e. anything other than stopped with SIGSTOP), then it
262+ records its status in this queue. linuxthreads_wait and
263+ linuxthreads_find_trap extract processes from here. */
264+ static int *linuxthreads_wait_pid; /* wait array of pid */
265+ static int *linuxthreads_wait_status; /* wait array of status */
266+ static int linuxthreads_wait_last; /* index of last valid elt in
267+ linuxthreads_wait_{pid,status} */
268+
269+ static sigset_t linuxthreads_wait_mask; /* sigset with SIGCHLD */
270+
271+ static int linuxthreads_step_pid; /* current stepped pid */
272+ static int linuxthreads_step_signo; /* current stepped target signal */
273+ static int linuxthreads_exit_status; /* exit status of initial thread */
274+
275+ static int linuxthreads_inferior_pid; /* temporary internal inferior pid */
276+ static int linuxthreads_breakpoint_pid; /* last pid that hit a breakpoint */
277+ static int linuxthreads_attach_pending; /* attach command without wait */
278+
279+ static int linuxthreads_breakpoints_inserted; /* any breakpoints inserted */
280+
281+ /* LinuxThreads uses certain signals for communication between
282+ processes; we need to tell GDB to pass them through silently to the
283+ inferior. The LinuxThreads library has global variables we can
284+ read containing the relevant signal numbers, but since the signal
285+ numbers are chosen at run-time, those variables aren't initialized
286+ until the shared library's constructors have had a chance to run. */
287+
288+ struct linuxthreads_signal {
289+
290+ /* The name of the LinuxThreads library variable that contains
291+ the signal number. */
292+ char *var;
293+
294+ /* True if this variable must exist for us to debug properly. */
295+ int required;
296+
297+ /* The variable's address in the inferior, or zero if the
298+ LinuxThreads library hasn't been loaded into this inferior yet. */
299+ CORE_ADDR addr;
300+
301+ /* The signal number, or zero if we don't know yet (either because
302+ we haven't found the variable, or it hasn't been initialized).
303+ This is an actual target signal number that you could pass to
304+ `kill', not a GDB signal number. */
305+ int signal;
306+
307+ /* GDB's original settings for `stop' and `print' for this signal.
308+ We restore them when the user selects a different executable.
309+ Invariant: if sig->signal != 0, then sig->{stop,print} contain
310+ the original settings. */
311+ int stop, print;
312+ };
313+
314+ struct linuxthreads_signal linuxthreads_sig_restart = {
315+ "__pthread_sig_restart", 1, 0, 0, 0
316+ };
317+ struct linuxthreads_signal linuxthreads_sig_cancel = {
318+ "__pthread_sig_cancel", 1, 0, 0, 0
319+ };
320+ struct linuxthreads_signal linuxthreads_sig_debug = {
321+ "__pthread_sig_debug", 0, 0, 0, 0
322+ };
323+
324+ /* A table of breakpoint locations, one per PID. */
325+ static struct linuxthreads_breakpoint {
326+ CORE_ADDR pc; /* PC of breakpoint */
327+ int pid; /* pid of breakpoint */
328+ int step; /* whether the pc has been reached after sstep */
329+ } *linuxthreads_breakpoint_zombie; /* Zombie breakpoints array */
330+ static int linuxthreads_breakpoint_last; /* Last zombie breakpoint */
331+
332+ /* linuxthreads_{insert,remove}_breakpoint pass the breakpoint address
333+ to {insert,remove}_breakpoint via this variable, since
334+ iterate_active_threads doesn't provide any way to pass values
335+ through to the worker function. */
336+ static CORE_ADDR linuxthreads_breakpoint_addr;
337+
338+ #define REMOVE_BREAKPOINT_ZOMBIE(_i) \
339+ { \
340+ if ((_i) < linuxthreads_breakpoint_last) \
341+ linuxthreads_breakpoint_zombie[(_i)] = \
342+ linuxthreads_breakpoint_zombie[linuxthreads_breakpoint_last]; \
343+ linuxthreads_breakpoint_last--; \
344+ }
345+
346+
347+ \f
348+ #ifndef PTRACE_XFER_TYPE
349+ #define PTRACE_XFER_TYPE int
350+ #endif
351+ /* Check to see if the given thread is alive. */
352+ static int
353+ linuxthreads_thread_alive (pid)
354+ int pid;
355+ {
356+ errno = 0;
357+ return ptrace (PT_READ_U, pid, (PTRACE_ARG3_TYPE)0, 0) >= 0 || errno == 0;
358+ }
359+
360+ /* On detach(), find a SIGTRAP status. If stop is non-zero, find a
361+ SIGSTOP one, too.
362+
363+ Make sure PID is ready to run, and free of interference from our
364+ efforts to debug it (e.g., pending SIGSTOP or SIGTRAP signals). If
365+ STOP is zero, just look for a SIGTRAP. If STOP is non-zero, look
366+ for a SIGSTOP, too. Return non-zero if PID is alive and ready to
367+ run; return zero if PID is dead.
368+
369+ PID may or may not be stopped at the moment, and we may or may not
370+ have waited for it already. We check the linuxthreads_wait bag in
371+ case we've already got a status for it. We may possibly wait for
372+ it ourselves.
373+
374+ PID may have signals waiting to be delivered. If they're caused by
375+ our efforts to debug it, accept them with wait, but don't pass them
376+ through to PID. Do pass all other signals through. */
377+ static int
378+ linuxthreads_find_trap (pid, stop)
379+ int pid;
380+ int stop;
381+ {
382+ int i;
383+ int rpid;
384+ int status;
385+ int found_stop = 0;
386+ int found_trap = 0;
387+
388+ /* PID may have any number of signals pending. The kernel will
389+ report each of them to us via wait, and then it's up to us to
390+ pass them along to the process via ptrace, if we so choose.
391+
392+ We need to paw through the whole set until we've found a SIGTRAP
393+ (or a SIGSTOP, if `stop' is set). We don't pass the SIGTRAP (or
394+ SIGSTOP) through, but we do re-send all the others, so PID will
395+ receive them when we resume it. */
396+ int *wstatus = alloca (LINUXTHREAD_NSIG * sizeof (int));
397+ int last = 0;
398+
399+ /* Look at the pending status */
400+ for (i = linuxthreads_wait_last; i >= 0; i--)
401+ if (linuxthreads_wait_pid[i] == pid)
402+ {
403+ status = linuxthreads_wait_status[i];
404+
405+ /* Delete the i'th member of the table. Since the table is
406+ unordered, we can do this simply by copying the table's
407+ last element to the i'th position, and shrinking the table
408+ by one element. */
409+ if (i < linuxthreads_wait_last)
410+ {
411+ linuxthreads_wait_status[i] =
412+ linuxthreads_wait_status[linuxthreads_wait_last];
413+ linuxthreads_wait_pid[i] =
414+ linuxthreads_wait_pid[linuxthreads_wait_last];
415+ }
416+ linuxthreads_wait_last--;
417+
418+ if (!WIFSTOPPED(status)) /* Thread has died */
419+ return 0;
420+
421+ if (WSTOPSIG(status) == SIGTRAP)
422+ {
423+ if (stop)
424+ found_trap = 1;
425+ else
426+ return 1;
427+ }
428+ else if (WSTOPSIG(status) == SIGSTOP)
429+ {
430+ if (stop)
431+ found_stop = 1;
432+ }
433+ else
434+ {
435+ wstatus[0] = status;
436+ last = 1;
437+ }
438+
439+ break;
440+ }
441+
442+ if (stop)
443+ {
444+ /* Make sure that we'll find what we're looking for. */
445+ if (!found_trap)
446+ kill (pid, SIGTRAP);
447+ if (!found_stop)
448+ kill (pid, SIGSTOP);
449+ }
450+
451+ /* Catch all status until SIGTRAP and optionally SIGSTOP show up. */
452+ for (;;)
453+ {
454+ child_resume (pid, 1, TARGET_SIGNAL_0);
455+
456+ for (;;)
457+ {
458+ rpid = waitpid (pid, &status, __WCLONE);
459+ if (rpid > 0)
460+ break;
461+ if (errno == EINTR)
462+ continue;
463+
464+ /* There are a few reasons the wait call above may have
465+ failed. If the thread manager dies, its children get
466+ reparented, and this interferes with GDB waiting for
467+ them, in some cases. Another possibility is that the
468+ initial thread was not cloned, so calling wait with
469+ __WCLONE won't find it. I think neither of these should
470+ occur in modern Linux kernels --- they don't seem to in
471+ 2.0.36. */
472+ rpid = waitpid (pid, &status, 0);
473+ if (rpid > 0)
474+ break;
475+ if (errno != EINTR)
476+ perror_with_name ("waitpid");
477+ }
478+
479+ if (!WIFSTOPPED(status)) /* Thread has died */
480+ return 0;
481+
482+ if (WSTOPSIG(status) == SIGTRAP)
483+ if (!stop || found_stop)
484+ break;
485+ else
486+ found_trap = 1;
487+ else if (WSTOPSIG(status) != SIGSTOP)
488+ wstatus[last++] = status;
489+ else if (stop)
490+ if (found_trap)
491+ break;
492+ else
493+ found_stop = 1;
494+ }
495+
496+ /* Resend any other signals we noticed to the thread, to be received
497+ when we continue it. */
498+ while (--last >= 0)
499+ kill (pid, WSTOPSIG(wstatus[last]));
500+
501+ return 1;
502+ }
503+
504+ /* Cleanup stub for save_inferior_pid. */
505+ static void
506+ restore_inferior_pid (arg)
507+ void *arg;
508+ {
509+ int pid = (int) arg;
510+ inferior_pid = pid;
511+ }
512+
513+ /* Register a cleanup to restore the value of inferior_pid. */
514+ static struct cleanup *
515+ save_inferior_pid ()
516+ {
517+ return make_cleanup (restore_inferior_pid, (void *) inferior_pid);
518+ }
519+
520+ static void
521+ sigchld_handler(signo)
522+ int signo;
523+ {
524+ /* This handler is used to get an EINTR while doing waitpid()
525+ when an event is received */
526+ }
527+
528+ /* Have we already collected a wait status for PID in the
529+ linuxthreads_wait bag? */
530+ static int
531+ linuxthreads_pending_status (pid)
532+ int pid;
533+ {
534+ int i;
535+ for (i = linuxthreads_wait_last; i >= 0; i--)
536+ if (linuxthreads_wait_pid[i] == pid)
537+ return 1;
538+ return 0;
539+ }
540+
541+ \f
542+ /* Internal linuxthreads signal management */
543+
544+ /* Check in OBJFILE for the variable that holds the number for signal SIG.
545+ We assume that we've already found other LinuxThreads-ish variables
546+ in OBJFILE, so we complain if it's required, but not there.
547+ Return true iff things are okay. */
548+ static int
549+ find_signal_var (struct linuxthreads_signal *sig,
550+ struct objfile *objfile)
551+ {
552+ struct minimal_symbol *ms = lookup_minimal_symbol (sig->var, NULL, objfile);
553+
554+ if (! ms)
555+ {
556+ if (sig->required)
557+ {
558+ fprintf_unfiltered (gdb_stderr,
559+ "Unable to find linuxthreads symbol \"%s\"\n",
560+ sig->var);
561+ return 0;
562+ }
563+ else
564+ {
565+ sig->addr = 0;
566+ return 1;
567+ }
568+ }
569+
570+ sig->addr = SYMBOL_VALUE_ADDRESS (ms);
571+
572+ return 1;
573+ }
574+
575+ static int
576+ find_all_signal_vars (struct objfile *objfile)
577+ {
578+ return ( find_signal_var (&linuxthreads_sig_restart, objfile)
579+ && find_signal_var (&linuxthreads_sig_cancel, objfile)
580+ && find_signal_var (&linuxthreads_sig_debug, objfile));
581+ }
582+
583+ /* A struct complaint isn't appropriate here. */
584+ static int complained_cannot_determine_thread_signal_number = 0;
585+
586+ /* Check to see if the variable holding the signal number for SIG has
587+ been initialized yet. If it has, tell GDB to pass that signal
588+ through to the inferior silently. */
589+ static void
590+ check_signal_number (struct linuxthreads_signal *sig)
591+ {
592+ int num;
593+
594+ if (sig->signal)
595+ /* We already know this signal number. */
596+ return;
597+
598+ if (! sig->addr)
599+ /* We don't know the variable's address yet. */
600+ return;
601+
602+ if (target_read_memory (sig->addr, (char *)&num, sizeof (num))
603+ != 0)
604+ {
605+ /* If this happens once, it'll probably happen for all the
606+ signals, so only complain once. */
607+ if (! complained_cannot_determine_thread_signal_number)
608+ warning ("Cannot determine thread signal number; "
609+ "GDB may report spurious signals.");
610+ complained_cannot_determine_thread_signal_number = 1;
611+ return;
612+ }
613+
614+ if (num == 0)
615+ /* It hasn't been initialized yet. */
616+ return;
617+
618+ /* We know sig->signal was zero, and is becoming non-zero, so it's
619+ okay to sample GDB's original settings. */
620+ sig->signal = num;
621+ sig->stop = signal_stop_update (target_signal_from_host (num), 0);
622+ sig->print = signal_print_update (target_signal_from_host (num), 0);
623+ }
624+
625+
626+ static void
627+ check_all_signal_numbers (void)
628+ {
629+ /* If this isn't a LinuxThreads program, quit early. */
630+ if (! linuxthreads_max)
631+ return;
632+
633+ check_signal_number (&linuxthreads_sig_restart);
634+ check_signal_number (&linuxthreads_sig_cancel);
635+ check_signal_number (&linuxthreads_sig_debug);
636+
637+ /* handle linuxthread exit */
638+ if (linuxthreads_sig_debug.signal
639+ || linuxthreads_sig_restart.signal)
640+ {
641+ struct sigaction sact;
642+
643+ sact.sa_handler = sigchld_handler;
644+ sigemptyset(&sact.sa_mask);
645+ sact.sa_flags = 0;
646+ if (linuxthreads_sig_debug.signal > 0)
647+ sigaction(linuxthreads_sig_cancel.signal, &sact, NULL);
648+ else
649+ sigaction(linuxthreads_sig_restart.signal, &sact, NULL);
650+ }
651+ }
652+
653+
654+ /* Restore GDB's original settings for SIG.
655+ This should only be called when we're no longer sure if we're
656+ talking to an executable that uses LinuxThreads, so we clear the
657+ signal number and variable address too. */
658+ static void
659+ restore_signal (struct linuxthreads_signal *sig)
660+ {
661+ if (! sig->signal)
662+ return;
663+
664+ /* We know sig->signal was non-zero, and is becoming zero, so it's
665+ okay to restore GDB's original settings. */
666+ signal_stop_update (target_signal_from_host (sig->signal), sig->stop);
667+ signal_print_update (target_signal_from_host (sig->signal), sig->print);
668+
669+ sig->signal = 0;
670+ sig->addr = 0;
671+ }
672+
673+
674+ /* Restore GDB's original settings for all LinuxThreads signals.
675+ This should only be called when we're no longer sure if we're
676+ talking to an executable that uses LinuxThreads, so we clear the
677+ signal number and variable address too. */
678+ static void
679+ restore_all_signals (void)
680+ {
681+ restore_signal (&linuxthreads_sig_restart);
682+ restore_signal (&linuxthreads_sig_cancel);
683+ restore_signal (&linuxthreads_sig_debug);
684+
685+ /* If it happens again, we should complain again. */
686+ complained_cannot_determine_thread_signal_number = 0;
687+ }
688+
689+
690+ \f
691+
692+ /* Apply FUNC to the pid of each active thread. This consults the
693+ inferior's handle table to find active threads.
694+
695+ If ALL is non-zero, process all threads.
696+ If ALL is zero, skip threads with pending status. */
697+ static void
698+ iterate_active_threads (func, all)
699+ void (*func)(int);
700+ int all;
701+ {
702+ CORE_ADDR descr;
703+ int pid;
704+ int i;
705+ int num;
706+
707+ read_memory (linuxthreads_num, (char *)&num, sizeof (int));
708+
709+ for (i = 0; i < linuxthreads_max && num > 0; i++)
710+ {
711+ read_memory (linuxthreads_handles +
712+ linuxthreads_sizeof_handle * i + linuxthreads_offset_descr,
713+ (char *)&descr, sizeof (void *));
714+ if (descr)
715+ {
716+ num--;
717+ read_memory (descr + linuxthreads_offset_pid,
718+ (char *)&pid, sizeof (pid_t));
719+ if (pid > 0 && pid != linuxthreads_manager_pid
720+ && (all || (!linuxthreads_pending_status (pid))))
721+ (*func)(pid);
722+ }
723+ }
724+
725+ }
726+
727+ /* Insert a thread breakpoint at linuxthreads_breakpoint_addr.
728+ This is the worker function for linuxthreads_insert_breakpoint,
729+ which passes it to iterate_active_threads. */
730+ static void
731+ insert_breakpoint (pid)
732+ int pid;
733+ {
734+ int j;
735+
736+ /* Remove (if any) the positive zombie breakpoint. */
737+ for (j = linuxthreads_breakpoint_last; j >= 0; j--)
738+ if (linuxthreads_breakpoint_zombie[j].pid == pid)
739+ {
740+ if ((linuxthreads_breakpoint_zombie[j].pc - DECR_PC_AFTER_BREAK
741+ == linuxthreads_breakpoint_addr)
742+ && !linuxthreads_breakpoint_zombie[j].step)
743+ REMOVE_BREAKPOINT_ZOMBIE(j);
744+ break;
745+ }
746+ }
747+
748+ /* Note that we're about to remove a thread breakpoint at
749+ linuxthreads_breakpoint_addr.
750+
751+ This is the worker function for linuxthreads_remove_breakpoint,
752+ which passes it to iterate_active_threads. The actual work of
753+ overwriting the breakpoint instruction is done by
754+ child_ops.to_remove_breakpoint; here, we simply create a zombie
755+ breakpoint if the thread's PC is pointing at the breakpoint being
756+ removed. */
757+ static void
758+ remove_breakpoint (pid)
759+ int pid;
760+ {
761+ int j;
762+
763+ /* Insert a positive zombie breakpoint (if needed). */
764+ for (j = 0; j <= linuxthreads_breakpoint_last; j++)
765+ if (linuxthreads_breakpoint_zombie[j].pid == pid)
766+ break;
767+
768+ if (in_thread_list (pid) && linuxthreads_thread_alive (pid))
769+ {
770+ CORE_ADDR pc = read_pc_pid (pid);
771+ if (linuxthreads_breakpoint_addr == pc - DECR_PC_AFTER_BREAK
772+ && j > linuxthreads_breakpoint_last)
773+ {
774+ linuxthreads_breakpoint_zombie[j].pid = pid;
775+ linuxthreads_breakpoint_zombie[j].pc = pc;
776+ linuxthreads_breakpoint_zombie[j].step = 0;
777+ linuxthreads_breakpoint_last++;
778+ }
779+ }
780+ }
781+
782+ /* Kill a thread */
783+ static void
784+ kill_thread (pid)
785+ int pid;
786+ {
787+ if (in_thread_list (pid))
788+ ptrace (PT_KILL, pid, (PTRACE_ARG3_TYPE) 0, 0);
789+ else
790+ kill (pid, SIGKILL);
791+ }
792+
793+ /* Resume a thread */
794+ static void
795+ resume_thread (pid)
796+ int pid;
797+ {
798+ if (pid != inferior_pid
799+ && in_thread_list (pid)
800+ && linuxthreads_thread_alive (pid))
801+ if (pid == linuxthreads_step_pid)
802+ child_resume (pid, 1, linuxthreads_step_signo);
803+ else
804+ child_resume (pid, 0, TARGET_SIGNAL_0);
805+ }
806+
807+ /* Detach a thread */
808+ static void
809+ detach_thread (pid)
810+ int pid;
811+ {
812+ if (in_thread_list (pid) && linuxthreads_thread_alive (pid))
813+ {
814+ /* Remove pending SIGTRAP and SIGSTOP */
815+ linuxthreads_find_trap (pid, 1);
816+
817+ inferior_pid = pid;
818+ detach (TARGET_SIGNAL_0);
819+ inferior_pid = linuxthreads_manager_pid;
820+ }
821+ }
822+
823+ /* Stop a thread */
824+ static void
825+ stop_thread (pid)
826+ int pid;
827+ {
828+ if (pid != inferior_pid)
829+ if (in_thread_list (pid))
830+ kill (pid, SIGSTOP);
831+ else if (ptrace (PT_ATTACH, pid, (PTRACE_ARG3_TYPE) 0, 0) == 0)
832+ {
833+ if (!linuxthreads_attach_pending)
834+ printf_unfiltered ("[New %s]\n", target_pid_to_str (pid));
835+ add_thread (pid);
836+ if (linuxthreads_sig_debug.signal)
837+ /* After a new thread in glibc 2.1 signals gdb its existence,
838+ it suspends itself and wait for linuxthreads_sig_restart,
839+ now we can wake up it. */
840+ kill (pid, linuxthreads_sig_restart.signal);
841+ }
842+ else
843+ perror_with_name ("ptrace in stop_thread");
844+ }
845+
846+ /* Wait for a thread */
847+ static void
848+ wait_thread (pid)
849+ int pid;
850+ {
851+ int status;
852+ int rpid;
853+
854+ if (pid != inferior_pid && in_thread_list (pid))
855+ {
856+ for (;;)
857+ {
858+ /* Get first pid status. */
859+ rpid = waitpid(pid, &status, __WCLONE);
860+ if (rpid > 0)
861+ break;
862+ if (errno == EINTR)
863+ continue;
864+
865+ /* There are two reasons this might have failed:
866+
867+ 1) PID is the initial thread, which wasn't cloned, so
868+ passing the __WCLONE flag to waitpid prevented us from
869+ finding it.
870+
871+ 2) The manager thread is the parent of all but the
872+ initial thread; if it dies, the children will all be
873+ reparented to init, which will wait for them. This means
874+ our call to waitpid won't find them.
875+
876+ Actually, based on a casual look at the 2.0.36 kernel
877+ code, I don't think either of these cases happen. But I
878+ don't have things set up for remotely debugging the
879+ kernel, so I'm not sure. And perhaps older kernels
880+ didn't work. */
881+ rpid = waitpid(pid, &status, 0);
882+ if (rpid > 0)
883+ break;
884+ if (errno != EINTR && linuxthreads_thread_alive (pid))
885+ perror_with_name ("waitpid");
886+
887+ /* the thread is dead. */
888+ return;
889+ }
890+ if (!WIFSTOPPED(status) || WSTOPSIG(status) != SIGSTOP)
891+ {
892+ linuxthreads_wait_pid[++linuxthreads_wait_last] = pid;
893+ linuxthreads_wait_status[linuxthreads_wait_last] = status;
894+ }
895+ }
896+ }
897+
898+ /* Walk through the linuxthreads handles in order to detect all
899+ threads and stop them */
900+ static void
901+ update_stop_threads (test_pid)
902+ int test_pid;
903+ {
904+ struct cleanup *old_chain = NULL;
905+
906+ check_all_signal_numbers ();
907+
908+ if (linuxthreads_manager_pid == 0)
909+ {
910+ if (linuxthreads_manager)
911+ {
912+ if (test_pid > 0 && test_pid != inferior_pid)
913+ {
914+ old_chain = save_inferior_pid ();
915+ inferior_pid = test_pid;
916+ }
917+ read_memory (linuxthreads_manager,
918+ (char *)&linuxthreads_manager_pid, sizeof (pid_t));
919+ }
920+ if (linuxthreads_initial)
921+ {
922+ if (test_pid > 0 && test_pid != inferior_pid)
923+ {
924+ old_chain = save_inferior_pid ();
925+ inferior_pid = test_pid;
926+ }
927+ read_memory(linuxthreads_initial,
928+ (char *)&linuxthreads_initial_pid, sizeof (pid_t));
929+ }
930+ }
931+
932+ if (linuxthreads_manager_pid != 0)
933+ {
934+ if (old_chain == NULL && test_pid > 0 &&
935+ test_pid != inferior_pid && linuxthreads_thread_alive (test_pid))
936+ {
937+ old_chain = save_inferior_pid ();
938+ inferior_pid = test_pid;
939+ }
940+
941+ if (linuxthreads_thread_alive (inferior_pid))
942+ {
943+ if (test_pid > 0)
944+ {
945+ if (test_pid != linuxthreads_manager_pid
946+ && !linuxthreads_pending_status (linuxthreads_manager_pid))
947+ {
948+ stop_thread (linuxthreads_manager_pid);
949+ wait_thread (linuxthreads_manager_pid);
950+ }
951+ if (!in_thread_list (test_pid))
952+ {
953+ if (!linuxthreads_attach_pending)
954+ printf_unfiltered ("[New %s]\n",
955+ target_pid_to_str (test_pid));
956+ add_thread (test_pid);
957+ if (linuxthreads_sig_debug.signal
958+ && inferior_pid == test_pid)
959+ /* After a new thread in glibc 2.1 signals gdb its
960+ existence, it suspends itself and wait for
961+ linuxthreads_sig_restart, now we can wake up
962+ it. */
963+ kill (test_pid, linuxthreads_sig_restart.signal);
964+ }
965+ }
966+ iterate_active_threads (stop_thread, 0);
967+ iterate_active_threads (wait_thread, 0);
968+ }
969+ }
970+
971+ if (old_chain != NULL)
972+ do_cleanups (old_chain);
973+ }
974+
975+ /* This routine is called whenever a new symbol table is read in, or when all
976+ symbol tables are removed. libpthread can only be initialized when it
977+ finds the right variables in libpthread.so. Since it's a shared library,
978+ those variables don't show up until the library gets mapped and the symbol
979+ table is read in. */
980+
981+ void
982+ linuxthreads_new_objfile (objfile)
983+ struct objfile *objfile;
984+ {
985+ struct minimal_symbol *ms;
986+
987+ if (!objfile)
988+ {
989+ /* We're starting an entirely new executable, so we can no
990+ longer be sure that it uses LinuxThreads. Restore the signal
991+ flags to their original states. */
992+ restore_all_signals ();
993+
994+ /* Indicate that we don't know anything's address any more. */
995+ linuxthreads_max = 0;
996+
997+ return;
998+ }
999+
1000+ /* If we've already found our variables in another objfile, don't
1001+ bother looking for them again. */
1002+ if (linuxthreads_max)
1003+ return;
1004+
1005+ if (! lookup_minimal_symbol ("__pthread_initial_thread", NULL, objfile))
1006+ /* This object file isn't the pthreads library. */
1007+ return;
1008+
1009+ if ((ms = lookup_minimal_symbol ("__pthread_threads_debug",
1010+ NULL, objfile)) == NULL)
1011+ {
1012+ /* The debugging-aware libpthreads is not present in this objfile */
1013+ warning ("\
1014+ This program seems to use POSIX threads, but the thread library used\n\
1015+ does not support debugging. This may make using GDB difficult. Don't\n\
1016+ set breakpoints or single-step through code that might be executed by\n\
1017+ any thread other than the main thread.");
1018+ return;
1019+ }
1020+ linuxthreads_debug = SYMBOL_VALUE_ADDRESS (ms);
1021+
1022+ /* Read internal structures configuration */
1023+ if ((ms = lookup_minimal_symbol ("__pthread_sizeof_handle",
1024+ NULL, objfile)) == NULL
1025+ || target_read_memory (SYMBOL_VALUE_ADDRESS (ms),
1026+ (char *)&linuxthreads_sizeof_handle,
1027+ sizeof (linuxthreads_sizeof_handle)) != 0)
1028+ {
1029+ fprintf_unfiltered (gdb_stderr,
1030+ "Unable to find linuxthreads symbol \"%s\"\n",
1031+ "__pthread_sizeof_handle");
1032+ return;
1033+ }
1034+
1035+ if ((ms = lookup_minimal_symbol ("__pthread_offsetof_descr",
1036+ NULL, objfile)) == NULL
1037+ || target_read_memory (SYMBOL_VALUE_ADDRESS (ms),
1038+ (char *)&linuxthreads_offset_descr,
1039+ sizeof (linuxthreads_offset_descr)) != 0)
1040+ {
1041+ fprintf_unfiltered (gdb_stderr,
1042+ "Unable to find linuxthreads symbol \"%s\"\n",
1043+ "__pthread_offsetof_descr");
1044+ return;
1045+ }
1046+
1047+ if ((ms = lookup_minimal_symbol ("__pthread_offsetof_pid",
1048+ NULL, objfile)) == NULL
1049+ || target_read_memory (SYMBOL_VALUE_ADDRESS (ms),
1050+ (char *)&linuxthreads_offset_pid,
1051+ sizeof (linuxthreads_offset_pid)) != 0)
1052+ {
1053+ fprintf_unfiltered (gdb_stderr,
1054+ "Unable to find linuxthreads symbol \"%s\"\n",
1055+ "__pthread_offsetof_pid");
1056+ return;
1057+ }
1058+
1059+ if (! find_all_signal_vars (objfile))
1060+ return;
1061+
1062+ /* Read adresses of internal structures to access */
1063+ if ((ms = lookup_minimal_symbol ("__pthread_handles",
1064+ NULL, objfile)) == NULL)
1065+ {
1066+ fprintf_unfiltered (gdb_stderr,
1067+ "Unable to find linuxthreads symbol \"%s\"\n",
1068+ "__pthread_handles");
1069+ return;
1070+ }
1071+ linuxthreads_handles = SYMBOL_VALUE_ADDRESS (ms);
1072+
1073+ if ((ms = lookup_minimal_symbol ("__pthread_handles_num",
1074+ NULL, objfile)) == NULL)
1075+ {
1076+ fprintf_unfiltered (gdb_stderr,
1077+ "Unable to find linuxthreads symbol \"%s\"\n",
1078+ "__pthread_handles_num");
1079+ return;
1080+ }
1081+ linuxthreads_num = SYMBOL_VALUE_ADDRESS (ms);
1082+
1083+ if ((ms = lookup_minimal_symbol ("__pthread_manager_thread",
1084+ NULL, objfile)) == NULL)
1085+ {
1086+ fprintf_unfiltered (gdb_stderr,
1087+ "Unable to find linuxthreads symbol \"%s\"\n",
1088+ "__pthread_manager_thread");
1089+ return;
1090+ }
1091+ linuxthreads_manager = SYMBOL_VALUE_ADDRESS (ms) + linuxthreads_offset_pid;
1092+
1093+ if ((ms = lookup_minimal_symbol ("__pthread_initial_thread",
1094+ NULL, objfile)) == NULL)
1095+ {
1096+ fprintf_unfiltered (gdb_stderr,
1097+ "Unable to find linuxthreads symbol \"%s\"\n",
1098+ "__pthread_initial_thread");
1099+ return;
1100+ }
1101+ linuxthreads_initial = SYMBOL_VALUE_ADDRESS (ms) + linuxthreads_offset_pid;
1102+
1103+ /* Search for this last, so it won't be set to a non-zero value unless
1104+ we successfully found all the symbols above. */
1105+ if ((ms = lookup_minimal_symbol ("__pthread_threads_max",
1106+ NULL, objfile)) == NULL
1107+ || target_read_memory (SYMBOL_VALUE_ADDRESS (ms),
1108+ (char *)&linuxthreads_max,
1109+ sizeof (linuxthreads_max)) != 0)
1110+ {
1111+ fprintf_unfiltered (gdb_stderr,
1112+ "Unable to find linuxthreads symbol \"%s\"\n",
1113+ "__pthread_threads_max");
1114+ return;
1115+ }
1116+
1117+ /* Allocate gdb internal structures */
1118+ linuxthreads_wait_pid =
1119+ (int *)xmalloc (sizeof (int) * (linuxthreads_max + 1));
1120+ linuxthreads_wait_status =
1121+ (int *)xmalloc (sizeof (int) * (linuxthreads_max + 1));
1122+ linuxthreads_breakpoint_zombie = (struct linuxthreads_breakpoint *)
1123+ xmalloc (sizeof (struct linuxthreads_breakpoint) * (linuxthreads_max + 1));
1124+
1125+ if (inferior_pid && !linuxthreads_attach_pending)
1126+ {
1127+ int on = 1;
1128+ target_write_memory (linuxthreads_debug, (char *)&on, sizeof (on));
1129+ linuxthreads_attach_pending = 1;
1130+ update_stop_threads (inferior_pid);
1131+ linuxthreads_attach_pending = 0;
1132+ }
1133+ }
1134+
1135+ /* If we have switched threads from a one that stopped at breakpoint,
1136+ return 1 otherwise 0. */
1137+
1138+ int
1139+ linuxthreads_prepare_to_proceed (step)
1140+ int step;
1141+ {
1142+ if (!linuxthreads_max
1143+ || !linuxthreads_manager_pid
1144+ || !linuxthreads_breakpoint_pid
1145+ || !breakpoint_here_p (read_pc_pid (linuxthreads_breakpoint_pid)))
1146+ return 0;
1147+
1148+ if (step)
1149+ {
1150+ /* Mark the current inferior as single stepping process. */
1151+ linuxthreads_step_pid = inferior_pid;
1152+ }
1153+
1154+ linuxthreads_inferior_pid = linuxthreads_breakpoint_pid;
1155+ return linuxthreads_breakpoint_pid;
1156+ }
1157+
1158+ /* Convert a pid to printable form. */
1159+
1160+ char *
1161+ linuxthreads_pid_to_str (pid)
1162+ int pid;
1163+ {
1164+ static char buf[100];
1165+
1166+ sprintf (buf, "%s %d%s", linuxthreads_max ? "Thread" : "Pid", pid,
1167+ (pid == linuxthreads_manager_pid) ? " (manager thread)"
1168+ : (pid == linuxthreads_initial_pid) ? " (initial thread)"
1169+ : "");
1170+
1171+ return buf;
1172+ }
1173+
1174+ /* Attach to process PID, then initialize for debugging it
1175+ and wait for the trace-trap that results from attaching. */
1176+
1177+ static void
1178+ linuxthreads_attach (args, from_tty)
1179+ char *args;
1180+ int from_tty;
1181+ {
1182+ if (!args)
1183+ error_no_arg ("process-id to attach");
1184+
1185+ push_target (&linuxthreads_ops);
1186+ linuxthreads_breakpoints_inserted = 1;
1187+ linuxthreads_breakpoint_last = -1;
1188+ linuxthreads_wait_last = -1;
1189+ linuxthreads_exit_status = __W_STOPCODE(0);
1190+
1191+ child_ops.to_attach (args, from_tty);
1192+
1193+ if (linuxthreads_max)
1194+ linuxthreads_attach_pending = 1;
1195+ }
1196+
1197+ /* Take a program previously attached to and detaches it.
1198+ The program resumes execution and will no longer stop
1199+ on signals, etc. We'd better not have left any breakpoints
1200+ in the program or it'll die when it hits one. For this
1201+ to work, it may be necessary for the process to have been
1202+ previously attached. It *might* work if the program was
1203+ started via the normal ptrace (PTRACE_TRACEME). */
1204+
1205+ static void
1206+ linuxthreads_detach (args, from_tty)
1207+ char *args;
1208+ int from_tty;
1209+ {
1210+ if (linuxthreads_max)
1211+ {
1212+ int i;
1213+ int pid;
1214+ int off = 0;
1215+ target_write_memory (linuxthreads_debug, (char *)&off, sizeof (off));
1216+
1217+ /* Walk through linuxthreads array in order to detach known threads. */
1218+ if (linuxthreads_manager_pid != 0)
1219+ {
1220+ /* Get rid of all positive zombie breakpoints. */
1221+ for (i = 0; i <= linuxthreads_breakpoint_last; i++)
1222+ {
1223+ if (linuxthreads_breakpoint_zombie[i].step)
1224+ continue;
1225+
1226+ pid = linuxthreads_breakpoint_zombie[i].pid;
1227+ if (!linuxthreads_thread_alive (pid))
1228+ continue;
1229+
1230+ if (linuxthreads_breakpoint_zombie[i].pc != read_pc_pid (pid))
1231+ continue;
1232+
1233+ /* Continue in STEP mode until the thread pc has moved or
1234+ until SIGTRAP is found on the same PC. */
1235+ if (linuxthreads_find_trap (pid, 0)
1236+ && linuxthreads_breakpoint_zombie[i].pc == read_pc_pid (pid))
1237+ write_pc_pid (linuxthreads_breakpoint_zombie[i].pc
1238+ - DECR_PC_AFTER_BREAK, pid);
1239+ }
1240+
1241+ /* Detach thread after thread. */
1242+ inferior_pid = linuxthreads_manager_pid;
1243+ iterate_active_threads (detach_thread, 1);
1244+
1245+ /* Remove pending SIGTRAP and SIGSTOP */
1246+ linuxthreads_find_trap (inferior_pid, 1);
1247+
1248+ linuxthreads_wait_last = -1;
1249+ linuxthreads_exit_status = __W_STOPCODE(0);
1250+ }
1251+
1252+ linuxthreads_inferior_pid = 0;
1253+ linuxthreads_breakpoint_pid = 0;
1254+ linuxthreads_step_pid = 0;
1255+ linuxthreads_step_signo = TARGET_SIGNAL_0;
1256+ linuxthreads_manager_pid = 0;
1257+ linuxthreads_initial_pid = 0;
1258+ linuxthreads_attach_pending = 0;
1259+ init_thread_list (); /* Destroy thread info */
1260+ }
1261+
1262+ child_ops.to_detach (args, from_tty);
1263+
1264+ unpush_target (&linuxthreads_ops);
1265+ }
1266+
1267+ /* Resume execution of process PID. If STEP is nozero, then
1268+ just single step it. If SIGNAL is nonzero, restart it with that
1269+ signal activated. */
1270+
1271+ static void
1272+ linuxthreads_resume (pid, step, signo)
1273+ int pid;
1274+ int step;
1275+ enum target_signal signo;
1276+ {
1277+ if (!linuxthreads_max || stop_soon_quietly || linuxthreads_manager_pid == 0)
1278+ child_ops.to_resume (pid, step, signo);
1279+ else
1280+ {
1281+ int rpid;
1282+ if (linuxthreads_inferior_pid)
1283+ {
1284+ /* Prepare resume of the last thread that hit a breakpoint */
1285+ linuxthreads_breakpoints_inserted = 0;
1286+ rpid = linuxthreads_inferior_pid;
1287+ linuxthreads_step_signo = signo;
1288+ }
1289+ else
1290+ {
1291+ struct cleanup *old_chain = NULL;
1292+ int i;
1293+
1294+ if (pid < 0)
1295+ {
1296+ linuxthreads_step_pid = step ? inferior_pid : 0;
1297+ linuxthreads_step_signo = signo;
1298+ rpid = inferior_pid;
1299+ }
1300+ else
1301+ rpid = pid;
1302+
1303+ if (pid < 0 || !step)
1304+ {
1305+ linuxthreads_breakpoints_inserted = 1;
1306+
1307+ /* Walk through linuxthreads array in order to resume threads */
1308+ if (pid >= 0 && inferior_pid != pid)
1309+ {
1310+ old_chain = save_inferior_pid ();
1311+ inferior_pid = pid;
1312+ }
1313+
1314+ iterate_active_threads (resume_thread, 0);
1315+ if (linuxthreads_manager_pid != inferior_pid
1316+ && !linuxthreads_pending_status (linuxthreads_manager_pid))
1317+ resume_thread (linuxthreads_manager_pid);
1318+ }
1319+ else
1320+ linuxthreads_breakpoints_inserted = 0;
1321+
1322+ /* Deal with zombie breakpoint */
1323+ for (i = 0; i <= linuxthreads_breakpoint_last; i++)
1324+ if (linuxthreads_breakpoint_zombie[i].pid == rpid)
1325+ {
1326+ if (linuxthreads_breakpoint_zombie[i].pc != read_pc_pid (rpid))
1327+ {
1328+ /* The current pc is out of zombie breakpoint. */
1329+ REMOVE_BREAKPOINT_ZOMBIE(i);
1330+ }
1331+ break;
1332+ }
1333+
1334+ if (old_chain != NULL)
1335+ do_cleanups (old_chain);
1336+ }
1337+
1338+ /* Resume initial thread. */
1339+ if (!linuxthreads_pending_status (rpid))
1340+ child_ops.to_resume (rpid, step, signo);
1341+ }
1342+ }
1343+
1344+ /* Wait for any threads to stop. We may have to convert PID from a thread id
1345+ to a LWP id, and vice versa on the way out. */
1346+
1347+ static int
1348+ linuxthreads_wait (int pid, struct target_waitstatus *ourstatus)
1349+ {
1350+ int status;
1351+ int rpid;
1352+ int i;
1353+ int last;
1354+ int *wstatus;
1355+
1356+ if (linuxthreads_max && !linuxthreads_breakpoints_inserted)
1357+ wstatus = alloca (LINUXTHREAD_NSIG * sizeof (int));
1358+
1359+ /* See if the inferior has chosen values for its signals yet. By
1360+ checking for them here, we can be sure we've updated GDB's signal
1361+ handling table before the inferior ever gets one of them. (Well,
1362+ before we notice, anyway.) */
1363+ check_all_signal_numbers ();
1364+
1365+ for (;;)
1366+ {
1367+ if (!linuxthreads_max)
1368+ rpid = 0;
1369+ else if (!linuxthreads_breakpoints_inserted)
1370+ {
1371+ if (linuxthreads_inferior_pid)
1372+ pid = linuxthreads_inferior_pid;
1373+ else if (pid < 0)
1374+ pid = inferior_pid;
1375+ last = rpid = 0;
1376+ }
1377+ else if (pid < 0 && linuxthreads_wait_last >= 0)
1378+ {
1379+ status = linuxthreads_wait_status[linuxthreads_wait_last];
1380+ rpid = linuxthreads_wait_pid[linuxthreads_wait_last--];
1381+ }
1382+ else if (pid > 0 && linuxthreads_pending_status (pid))
1383+ {
1384+ for (i = linuxthreads_wait_last; i >= 0; i--)
1385+ if (linuxthreads_wait_pid[i] == pid)
1386+ break;
1387+ if (i < 0)
1388+ rpid = 0;
1389+ else
1390+ {
1391+ status = linuxthreads_wait_status[i];
1392+ rpid = pid;
1393+ if (i < linuxthreads_wait_last)
1394+ {
1395+ linuxthreads_wait_status[i] =
1396+ linuxthreads_wait_status[linuxthreads_wait_last];
1397+ linuxthreads_wait_pid[i] =
1398+ linuxthreads_wait_pid[linuxthreads_wait_last];
1399+ }
1400+ linuxthreads_wait_last--;
1401+ }
1402+ }
1403+ else
1404+ rpid = 0;
1405+
1406+ if (rpid == 0)
1407+ {
1408+ int save_errno;
1409+ sigset_t omask;
1410+
1411+ set_sigint_trap(); /* Causes SIGINT to be passed on to the
1412+ attached process. */
1413+ set_sigio_trap ();
1414+
1415+ sigprocmask(SIG_BLOCK, &linuxthreads_wait_mask, &omask);
1416+ for (;;)
1417+ {
1418+ rpid = waitpid (pid, &status, __WCLONE | WNOHANG);
1419+ if (rpid > 0)
1420+ break;
1421+ if (rpid == 0)
1422+ save_errno = 0;
1423+ else if (errno != EINTR)
1424+ save_errno = errno;
1425+ else
1426+ continue;
1427+
1428+ rpid = waitpid (pid, &status, WNOHANG);
1429+ if (rpid > 0)
1430+ break;
1431+ if (rpid < 0)
1432+ if (errno == EINTR)
1433+ continue;
1434+ else if (save_errno != 0)
1435+ break;
1436+
1437+ sigsuspend(&omask);
1438+ }
1439+ sigprocmask(SIG_SETMASK, &omask, NULL);
1440+
1441+ save_errno = errno;
1442+ clear_sigio_trap ();
1443+
1444+ clear_sigint_trap();
1445+
1446+ if (rpid == -1)
1447+ {
1448+ if (WIFEXITED(linuxthreads_exit_status))
1449+ {
1450+ store_waitstatus (ourstatus, linuxthreads_exit_status);
1451+ return inferior_pid;
1452+ }
1453+ else
1454+ {
1455+ fprintf_unfiltered
1456+ (gdb_stderr, "Child process unexpectedly missing: %s.\n",
1457+ safe_strerror (save_errno));
1458+ /* Claim it exited with unknown signal. */
1459+ ourstatus->kind = TARGET_WAITKIND_SIGNALLED;
1460+ ourstatus->value.sig = TARGET_SIGNAL_UNKNOWN;
1461+ return -1;
1462+ }
1463+ }
1464+
1465+ /* Signals arrive in any order. So get all signals until SIGTRAP
1466+ and resend previous ones to be held after. */
1467+ if (linuxthreads_max
1468+ && !linuxthreads_breakpoints_inserted
1469+ && WIFSTOPPED(status))
1470+ if (WSTOPSIG(status) == SIGTRAP)
1471+ {
1472+ while (--last >= 0)
1473+ kill (rpid, WSTOPSIG(wstatus[last]));
1474+
1475+ /* insert negative zombie breakpoint */
1476+ for (i = 0; i <= linuxthreads_breakpoint_last; i++)
1477+ if (linuxthreads_breakpoint_zombie[i].pid == rpid)
1478+ break;
1479+ if (i > linuxthreads_breakpoint_last)
1480+ {
1481+ linuxthreads_breakpoint_zombie[i].pid = rpid;
1482+ linuxthreads_breakpoint_last++;
1483+ }
1484+ linuxthreads_breakpoint_zombie[i].pc = read_pc_pid (rpid);
1485+ linuxthreads_breakpoint_zombie[i].step = 1;
1486+ }
1487+ else
1488+ {
1489+ if (WSTOPSIG(status) != SIGSTOP)
1490+ {
1491+ for (i = 0; i < last; i++)
1492+ if (wstatus[i] == status)
1493+ break;
1494+ if (i >= last)
1495+ wstatus[last++] = status;
1496+ }
1497+ child_resume (rpid, 1, TARGET_SIGNAL_0);
1498+ continue;
1499+ }
1500+ if (linuxthreads_inferior_pid)
1501+ linuxthreads_inferior_pid = 0;
1502+ }
1503+
1504+ if (linuxthreads_max && !stop_soon_quietly)
1505+ {
1506+ if (linuxthreads_max
1507+ && WIFSTOPPED(status)
1508+ && WSTOPSIG(status) == SIGSTOP)
1509+ {
1510+ /* Skip SIGSTOP signals. */
1511+ if (!linuxthreads_pending_status (rpid))
1512+ if (linuxthreads_step_pid == rpid)
1513+ child_resume (rpid, 1, linuxthreads_step_signo);
1514+ else
1515+ child_resume (rpid, 0, TARGET_SIGNAL_0);
1516+ continue;
1517+ }
1518+
1519+ /* Do no report exit status of cloned threads. */
1520+ if (WIFEXITED(status))
1521+ {
1522+ if (rpid == linuxthreads_initial_pid)
1523+ linuxthreads_exit_status = status;
1524+
1525+ /* Remove any zombie breakpoint. */
1526+ for (i = 0; i <= linuxthreads_breakpoint_last; i++)
1527+ if (linuxthreads_breakpoint_zombie[i].pid == rpid)
1528+ {
1529+ REMOVE_BREAKPOINT_ZOMBIE(i);
1530+ break;
1531+ }
1532+ if (pid > 0)
1533+ pid = -1;
1534+ continue;
1535+ }
1536+
1537+ /* Deal with zombie breakpoint */
1538+ for (i = 0; i <= linuxthreads_breakpoint_last; i++)
1539+ if (linuxthreads_breakpoint_zombie[i].pid == rpid)
1540+ break;
1541+
1542+ if (i <= linuxthreads_breakpoint_last)
1543+ {
1544+ /* There is a potential zombie breakpoint */
1545+ if (WIFEXITED(status)
1546+ || linuxthreads_breakpoint_zombie[i].pc != read_pc_pid (rpid))
1547+ {
1548+ /* The current pc is out of zombie breakpoint. */
1549+ REMOVE_BREAKPOINT_ZOMBIE(i);
1550+ }
1551+ else if (!linuxthreads_breakpoint_zombie[i].step
1552+ && WIFSTOPPED(status) && WSTOPSIG(status) == SIGTRAP)
1553+ {
1554+ /* This is a real one ==> decrement PC and restart. */
1555+ write_pc_pid (linuxthreads_breakpoint_zombie[i].pc
1556+ - DECR_PC_AFTER_BREAK, rpid);
1557+ if (linuxthreads_step_pid == rpid)
1558+ child_resume (rpid, 1, linuxthreads_step_signo);
1559+ else
1560+ child_resume (rpid, 0, TARGET_SIGNAL_0);
1561+ continue;
1562+ }
1563+ }
1564+
1565+ /* Walk through linuxthreads array in order to stop them */
1566+ if (linuxthreads_breakpoints_inserted)
1567+ update_stop_threads (rpid);
1568+
1569+ }
1570+ else if (rpid != inferior_pid)
1571+ continue;
1572+
1573+ store_waitstatus (ourstatus, status);
1574+
1575+ if (linuxthreads_attach_pending && !stop_soon_quietly)
1576+ {
1577+ int on = 1;
1578+ target_write_memory (linuxthreads_debug, (char *)&on, sizeof (on));
1579+ update_stop_threads (rpid);
1580+ linuxthreads_attach_pending = 0;
1581+ }
1582+
1583+ if (linuxthreads_breakpoints_inserted
1584+ && WIFSTOPPED(status)
1585+ && WSTOPSIG(status) == SIGTRAP)
1586+ linuxthreads_breakpoint_pid = rpid;
1587+ else if (linuxthreads_breakpoint_pid)
1588+ linuxthreads_breakpoint_pid = 0;
1589+
1590+ return rpid;
1591+ }
1592+ }
1593+
1594+ /* Fork an inferior process, and start debugging it with ptrace. */
1595+
1596+ static void
1597+ linuxthreads_create_inferior (exec_file, allargs, env)
1598+ char *exec_file;
1599+ char *allargs;
1600+ char **env;
1601+ {
1602+ if (!exec_file && !exec_bfd)
1603+ {
1604+ error ("No executable file specified.\n\
1605+ Use the \"file\" or \"exec-file\" command.");
1606+ return;
1607+ }
1608+
1609+ push_target (&linuxthreads_ops);
1610+ linuxthreads_breakpoints_inserted = 1;
1611+ linuxthreads_breakpoint_last = -1;
1612+ linuxthreads_wait_last = -1;
1613+ linuxthreads_exit_status = __W_STOPCODE(0);
1614+
1615+ if (linuxthreads_max)
1616+ linuxthreads_attach_pending = 1;
1617+
1618+ child_ops.to_create_inferior (exec_file, allargs, env);
1619+ }
1620+
1621+ /* Clean up after the inferior dies. */
1622+
1623+ static void
1624+ linuxthreads_mourn_inferior ()
1625+ {
1626+ if (linuxthreads_max)
1627+ {
1628+ int off = 0;
1629+ target_write_memory (linuxthreads_debug, (char *)&off, sizeof (off));
1630+
1631+ linuxthreads_inferior_pid = 0;
1632+ linuxthreads_breakpoint_pid = 0;
1633+ linuxthreads_step_pid = 0;
1634+ linuxthreads_step_signo = TARGET_SIGNAL_0;
1635+ linuxthreads_manager_pid = 0;
1636+ linuxthreads_initial_pid = 0;
1637+ linuxthreads_attach_pending = 0;
1638+ init_thread_list(); /* Destroy thread info */
1639+ }
1640+
1641+ child_ops.to_mourn_inferior ();
1642+
1643+ unpush_target (&linuxthreads_ops);
1644+ }
1645+
1646+ /* Kill the inferior process */
1647+
1648+ static void
1649+ linuxthreads_kill ()
1650+ {
1651+ int rpid;
1652+ int status;
1653+
1654+ if (inferior_pid == 0)
1655+ return;
1656+
1657+ if (linuxthreads_max && linuxthreads_manager_pid != 0)
1658+ {
1659+ /* Remove all threads status. */
1660+ inferior_pid = linuxthreads_manager_pid;
1661+ iterate_active_threads (kill_thread, 1);
1662+ }
1663+
1664+ kill_thread (inferior_pid);
1665+
1666+ #if 0
1667+ /* doing_quit_force solves a real problem, but I think a properly
1668+ placed call to catch_errors would do the trick much more cleanly. */
1669+ if (doing_quit_force >= 0)
1670+ {
1671+ if (linuxthreads_max && linuxthreads_manager_pid != 0)
1672+ {
1673+ /* Wait for thread to complete */
1674+ while ((rpid = waitpid (-1, &status, __WCLONE)) > 0)
1675+ if (!WIFEXITED(status))
1676+ kill_thread (rpid);
1677+
1678+ while ((rpid = waitpid (-1, &status, 0)) > 0)
1679+ if (!WIFEXITED(status))
1680+ kill_thread (rpid);
1681+ }
1682+ else
1683+ while ((rpid = waitpid (inferior_pid, &status, 0)) > 0)
1684+ if (!WIFEXITED(status))
1685+ ptrace (PT_KILL, inferior_pid, (PTRACE_ARG3_TYPE) 0, 0);
1686+ }
1687+ #endif
1688+
1689+ /* Wait for all threads. */
1690+ do
1691+ rpid = waitpid (-1, &status, __WCLONE | WNOHANG);
1692+ while (rpid > 0 || errno == EINTR);
1693+
1694+ do
1695+ rpid = waitpid (-1, &status, WNOHANG);
1696+ while (rpid > 0 || errno == EINTR);
1697+
1698+ linuxthreads_mourn_inferior ();
1699+ }
1700+
1701+ /* Insert a breakpoint */
1702+
1703+ static int
1704+ linuxthreads_insert_breakpoint (addr, contents_cache)
1705+ CORE_ADDR addr;
1706+ char *contents_cache;
1707+ {
1708+ if (linuxthreads_max && linuxthreads_manager_pid != 0)
1709+ {
1710+ linuxthreads_breakpoint_addr = addr;
1711+ iterate_active_threads (insert_breakpoint, 1);
1712+ insert_breakpoint (linuxthreads_manager_pid);
1713+ }
1714+
1715+ return child_ops.to_insert_breakpoint (addr, contents_cache);
1716+ }
1717+
1718+ /* Remove a breakpoint */
1719+
1720+ static int
1721+ linuxthreads_remove_breakpoint (addr, contents_cache)
1722+ CORE_ADDR addr;
1723+ char *contents_cache;
1724+ {
1725+ if (linuxthreads_max && linuxthreads_manager_pid != 0)
1726+ {
1727+ linuxthreads_breakpoint_addr = addr;
1728+ iterate_active_threads (remove_breakpoint, 1);
1729+ remove_breakpoint (linuxthreads_manager_pid);
1730+ }
1731+
1732+ return child_ops.to_remove_breakpoint (addr, contents_cache);
1733+ }
1734+
1735+ /* Mark our target-struct as eligible for stray "run" and "attach" commands. */
1736+
1737+ static int
1738+ linuxthreads_can_run ()
1739+ {
1740+ return child_suppress_run;
1741+ }
1742+ \f
1743+ static void
1744+ init_linuxthreads_ops ()
1745+ {
1746+ linuxthreads_ops.to_shortname = "linuxthreads";
1747+ linuxthreads_ops.to_longname = "LINUX threads and pthread.";
1748+ linuxthreads_ops.to_doc = "LINUX threads and pthread support.";
1749+ linuxthreads_ops.to_attach = linuxthreads_attach;
1750+ linuxthreads_ops.to_detach = linuxthreads_detach;
1751+ linuxthreads_ops.to_resume = linuxthreads_resume;
1752+ linuxthreads_ops.to_wait = linuxthreads_wait;
1753+ linuxthreads_ops.to_kill = linuxthreads_kill;
1754+ linuxthreads_ops.to_can_run = linuxthreads_can_run;
1755+ linuxthreads_ops.to_stratum = thread_stratum;
1756+ linuxthreads_ops.to_insert_breakpoint = linuxthreads_insert_breakpoint;
1757+ linuxthreads_ops.to_remove_breakpoint = linuxthreads_remove_breakpoint;
1758+ linuxthreads_ops.to_create_inferior = linuxthreads_create_inferior;
1759+ linuxthreads_ops.to_mourn_inferior = linuxthreads_mourn_inferior;
1760+ linuxthreads_ops.to_thread_alive = linuxthreads_thread_alive;
1761+ linuxthreads_ops.to_magic = OPS_MAGIC;
1762+ }
1763+
1764+ void
1765+ _initialize_linuxthreads ()
1766+ {
1767+ struct sigaction sact;
1768+
1769+ init_linuxthreads_ops ();
1770+ add_target (&linuxthreads_ops);
1771+ child_suppress_run = 1;
1772+
1773+ /* Attach SIGCHLD handler */
1774+ sact.sa_handler = sigchld_handler;
1775+ sigemptyset (&sact.sa_mask);
1776+ sact.sa_flags = 0;
1777+ sigaction (SIGCHLD, &sact, NULL);
1778+
1779+ /* initialize SIGCHLD mask */
1780+ sigemptyset (&linuxthreads_wait_mask);
1781+ sigaddset (&linuxthreads_wait_mask, SIGCHLD);
1782+ }
1783diff -Ncr /home/kingdon/work/gdb/gdb/target.c ./gdb/target.c
1784*** /home/kingdon/work/gdb/gdb/target.c Thu Aug 12 11:13:38 1999
1785--- ./gdb/target.c Sat Aug 14 19:49:45 1999
1786***************
1787*** 1238,1243 ****
1788--- 1238,1244 ----
1789 {"SIG61", "Real-time event 61"},
1790 {"SIG62", "Real-time event 62"},
1791 {"SIG63", "Real-time event 63"},
1792+ {"SIG32", "Real-time event 32"},
1793
1794 #if defined(MACH) || defined(__MACH__)
1795 /* Mach exceptions */
1796***************
1797*** 1571,1578 ****
1798
1799 #if defined (REALTIME_LO)
1800 if (hostsig >= REALTIME_LO && hostsig < REALTIME_HI)
1801! return (enum target_signal)
1802! (hostsig - 33 + (int) TARGET_SIGNAL_REALTIME_33);
1803 #endif
1804 return TARGET_SIGNAL_UNKNOWN;
1805 }
1806--- 1572,1587 ----
1807
1808 #if defined (REALTIME_LO)
1809 if (hostsig >= REALTIME_LO && hostsig < REALTIME_HI)
1810! {
1811! /* This block of TARGET_SIGNAL_REALTIME value is in order. */
1812! if (33 <= hostsig && hostsig <= 63)
1813! return (enum target_signal)
1814! (hostsig - 33 + (int) TARGET_SIGNAL_REALTIME_33);
1815! else if (hostsig == 32)
1816! return TARGET_SIGNAL_REALTIME_32;
1817! else
1818! error ("GDB bug: target.c (target_signal_from_host): unrecognized real-time signal");
1819! }
1820 #endif
1821 return TARGET_SIGNAL_UNKNOWN;
1822 }
1823***************
1824*** 1619,1624 ****
1825--- 1628,1635 ----
1826 case TARGET_SIGNAL_PRIO:
1827 return SIGPRIO;
1828 #endif
1829+
1830+ case TARGET_SIGNAL_REALTIME_32: return 32; /* by definition */
1831
1832 /* Mach exceptions. Assumes that the values for EXC_ are positive! */
1833 #if defined (EXC_BAD_ACCESS) && defined (_NSIG)
1834diff -Ncr /home/kingdon/work/gdb/gdb/target.h ./gdb/target.h
1835*** /home/kingdon/work/gdb/gdb/target.h Thu Aug 12 11:13:38 1999
1836--- ./gdb/target.h Sat Aug 14 19:07:48 1999
1837***************
1838*** 48,54 ****
1839 file_stratum, /* Executable files, etc */
1840 core_stratum, /* Core dump files */
1841 download_stratum, /* Downloading of remote targets */
1842! process_stratum /* Executing processes */
1843 };
1844
1845 enum thread_control_capabilities {
1846--- 48,55 ----
1847 file_stratum, /* Executable files, etc */
1848 core_stratum, /* Core dump files */
1849 download_stratum, /* Downloading of remote targets */
1850! process_stratum, /* Executing processes */
1851! thread_stratum /* Executing threads */
1852 };
1853
1854 enum thread_control_capabilities {
1855***************
1856*** 214,219 ****
1857--- 215,227 ----
1858 TARGET_EXC_SOFTWARE = 80,
1859 TARGET_EXC_BREAKPOINT = 81,
1860 #endif
1861+
1862+ /* Yes, this pains me, too. But LynxOS didn't have SIG32, and now
1863+ Linux does, and we can't disturb the numbering, since it's part
1864+ of the protocol. Note that in some GDB's TARGET_SIGNAL_REALTIME_32
1865+ is number 76. */
1866+ TARGET_SIGNAL_REALTIME_32,
1867+
1868 /* Some signal we don't know about. */
1869 TARGET_SIGNAL_UNKNOWN,
1870
This page took 2.112432 seconds and 4 git commands to generate.