1 /* Low level interface for debugging Solaris threads for GDB, the GNU debugger.
2 Copyright 1996, 1997, 1998, 1999, 2000, 2001
3 Free Software Foundation, Inc.
5 This file is part of GDB.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
22 /* This module implements a sort of half target that sits between the
23 machine-independent parts of GDB and the /proc interface (procfs.c) to
24 provide access to the Solaris user-mode thread implementation.
26 Solaris threads are true user-mode threads, which are invoked via the thr_*
27 and pthread_* (native and Posix respectivly) interfaces. These are mostly
28 implemented in user-space, with all thread context kept in various
29 structures that live in the user's heap. These should not be confused with
30 lightweight processes (LWPs), which are implemented by the kernel, and
31 scheduled without explicit intervention by the process.
33 Just to confuse things a little, Solaris threads (both native and Posix) are
34 actually implemented using LWPs. In general, there are going to be more
35 threads than LWPs. There is no fixed correspondence between a thread and an
36 LWP. When a thread wants to run, it gets scheduled onto the first available
37 LWP and can therefore migrate from one LWP to another as time goes on. A
38 sleeping thread may not be associated with an LWP at all!
40 To make it possible to mess with threads, Sun provides a library called
41 libthread_db.so.1 (not to be confused with libthread_db.so.0, which doesn't
42 have a published interface). This interface has an upper part, which it
43 provides, and a lower part which I provide. The upper part consists of the
44 td_* routines, which allow me to find all the threads, query their state,
45 etc... The lower part consists of all of the ps_*, which are used by the
46 td_* routines to read/write memory, manipulate LWPs, lookup symbols, etc...
47 The ps_* routines actually do most of their work by calling functions in
52 #include <proc_service.h>
53 #include <thread_db.h>
54 #include "gdbthread.h"
64 extern struct target_ops sol_thread_ops
; /* Forward declaration */
65 extern struct target_ops sol_core_ops
; /* Forward declaration */
67 /* place to store core_ops before we overwrite it */
68 static struct target_ops orig_core_ops
;
70 struct target_ops sol_thread_ops
;
71 struct target_ops sol_core_ops
;
73 extern int procfs_suppress_run
;
74 extern struct target_ops procfs_ops
; /* target vector for procfs.c */
75 extern struct target_ops core_ops
; /* target vector for corelow.c */
76 extern char *procfs_pid_to_str (ptid_t ptid
);
78 /* Prototypes for supply_gregset etc. */
81 /* This struct is defined by us, but mainly used for the proc_service interface.
82 We don't have much use for it, except as a handy place to get a real pid
83 for memory accesses. */
96 static struct ps_prochandle main_ph
;
97 static td_thragent_t
*main_ta
;
98 static int sol_thread_active
= 0;
100 static char *td_err_string (td_err_e errcode
);
101 static char *td_state_string (td_thr_state_e statecode
);
102 static ptid_t
thread_to_lwp (ptid_t thread_id
, int default_lwp
);
103 static void sol_thread_resume (ptid_t ptid
, int step
, enum target_signal signo
);
104 static ptid_t
lwp_to_thread (ptid_t lwp
);
105 static int sol_thread_alive (ptid_t ptid
);
106 static void sol_core_close (int quitting
);
108 static void init_sol_thread_ops (void);
109 static void init_sol_core_ops (void);
111 /* Default definitions: These must be defined in tm.h
112 if they are to be shared with a process module such as procfs. */
114 #define THREAD_FLAG 0x80000000
115 #define is_thread(ARG) (((ARG) & THREAD_FLAG) != 0)
116 #define is_lwp(ARG) (((ARG) & THREAD_FLAG) == 0)
117 #define GET_LWP(PID) TIDGET (PID)
118 #define GET_THREAD(PID) TIDGET (PID)
119 #define BUILD_LWP(TID, PID) MERGEPID (PID, TID)
121 #define BUILD_THREAD(TID, PID) (MERGEPID (PID, TID) | THREAD_FLAG)
123 /* Pointers to routines from lithread_db resolved by dlopen() */
125 static void (*p_td_log
) (const int on_off
);
126 static td_err_e (*p_td_ta_new
) (const struct ps_prochandle
* ph_p
,
127 td_thragent_t
** ta_pp
);
128 static td_err_e (*p_td_ta_delete
) (td_thragent_t
* ta_p
);
129 static td_err_e (*p_td_init
) (void);
130 static td_err_e (*p_td_ta_get_ph
) (const td_thragent_t
* ta_p
,
131 struct ps_prochandle
** ph_pp
);
132 static td_err_e (*p_td_ta_get_nthreads
) (const td_thragent_t
* ta_p
,
134 static td_err_e (*p_td_ta_tsd_iter
) (const td_thragent_t
* ta_p
,
137 static td_err_e (*p_td_ta_thr_iter
) (const td_thragent_t
* ta_p
,
140 td_thr_state_e state
,
142 sigset_t
* ti_sigmask_p
,
143 unsigned ti_user_flags
);
144 static td_err_e (*p_td_thr_validate
) (const td_thrhandle_t
* th_p
);
145 static td_err_e (*p_td_thr_tsd
) (const td_thrhandle_t
* th_p
,
146 const thread_key_t key
,
148 static td_err_e (*p_td_thr_get_info
) (const td_thrhandle_t
* th_p
,
149 td_thrinfo_t
* ti_p
);
150 static td_err_e (*p_td_thr_getfpregs
) (const td_thrhandle_t
* th_p
,
151 prfpregset_t
* fpregset
);
152 static td_err_e (*p_td_thr_getxregsize
) (const td_thrhandle_t
* th_p
,
154 static td_err_e (*p_td_thr_getxregs
) (const td_thrhandle_t
* th_p
,
155 const caddr_t xregset
);
156 static td_err_e (*p_td_thr_sigsetmask
) (const td_thrhandle_t
* th_p
,
157 const sigset_t ti_sigmask
);
158 static td_err_e (*p_td_thr_setprio
) (const td_thrhandle_t
* th_p
,
160 static td_err_e (*p_td_thr_setsigpending
) (const td_thrhandle_t
* th_p
,
161 const uchar_t ti_pending_flag
,
162 const sigset_t ti_pending
);
163 static td_err_e (*p_td_thr_setfpregs
) (const td_thrhandle_t
* th_p
,
164 const prfpregset_t
* fpregset
);
165 static td_err_e (*p_td_thr_setxregs
) (const td_thrhandle_t
* th_p
,
166 const caddr_t xregset
);
167 static td_err_e (*p_td_ta_map_id2thr
) (const td_thragent_t
* ta_p
,
169 td_thrhandle_t
* th_p
);
170 static td_err_e (*p_td_ta_map_lwp2thr
) (const td_thragent_t
* ta_p
,
172 td_thrhandle_t
* th_p
);
173 static td_err_e (*p_td_thr_getgregs
) (const td_thrhandle_t
* th_p
,
175 static td_err_e (*p_td_thr_setgregs
) (const td_thrhandle_t
* th_p
,
176 const prgregset_t regset
);
182 td_err_string - Convert a thread_db error code to a string
186 char * td_err_string (errcode)
190 Return the thread_db error string associated with errcode. If errcode
191 is unknown, then return a message.
196 td_err_string (td_err_e errcode
)
198 static struct string_map
201 {TD_OK
, "generic \"call succeeded\""},
202 {TD_ERR
, "generic error."},
203 {TD_NOTHR
, "no thread can be found to satisfy query"},
204 {TD_NOSV
, "no synch. variable can be found to satisfy query"},
205 {TD_NOLWP
, "no lwp can be found to satisfy query"},
206 {TD_BADPH
, "invalid process handle"},
207 {TD_BADTH
, "invalid thread handle"},
208 {TD_BADSH
, "invalid synchronization handle"},
209 {TD_BADTA
, "invalid thread agent"},
210 {TD_BADKEY
, "invalid key"},
211 {TD_NOMSG
, "td_thr_event_getmsg() called when there was no message"},
212 {TD_NOFPREGS
, "FPU register set not available for given thread"},
213 {TD_NOLIBTHREAD
, "application not linked with libthread"},
214 {TD_NOEVENT
, "requested event is not supported"},
215 {TD_NOCAPAB
, "capability not available"},
216 {TD_DBERR
, "Debugger service failed"},
217 {TD_NOAPLIC
, "Operation not applicable to"},
218 {TD_NOTSD
, "No thread specific data for this thread"},
219 {TD_MALLOC
, "Malloc failed"},
220 {TD_PARTIALREG
, "Only part of register set was written/read"},
221 {TD_NOXREGS
, "X register set not available for given thread"}
223 const int td_err_size
= sizeof td_err_table
/ sizeof (struct string_map
);
227 for (i
= 0; i
< td_err_size
; i
++)
228 if (td_err_table
[i
].num
== errcode
)
229 return td_err_table
[i
].str
;
231 sprintf (buf
, "Unknown thread_db error code: %d", errcode
);
240 td_state_string - Convert a thread_db state code to a string
244 char * td_state_string (statecode)
248 Return the thread_db state string associated with statecode. If
249 statecode is unknown, then return a message.
254 td_state_string (td_thr_state_e statecode
)
256 static struct string_map
257 td_thr_state_table
[] =
259 {TD_THR_ANY_STATE
, "any state"},
260 {TD_THR_UNKNOWN
, "unknown"},
261 {TD_THR_STOPPED
, "stopped"},
263 {TD_THR_ACTIVE
, "active"},
264 {TD_THR_ZOMBIE
, "zombie"},
265 {TD_THR_SLEEP
, "sleep"},
266 {TD_THR_STOPPED_ASLEEP
, "stopped asleep"}
268 const int td_thr_state_table_size
= sizeof td_thr_state_table
/ sizeof (struct string_map
);
272 for (i
= 0; i
< td_thr_state_table_size
; i
++)
273 if (td_thr_state_table
[i
].num
== statecode
)
274 return td_thr_state_table
[i
].str
;
276 sprintf (buf
, "Unknown thread_db state code: %d", statecode
);
285 thread_to_lwp - Convert a Posix or Solaris thread id to a LWP id.
289 tpid_t thread_to_lwp (thread_id, default_lwp)
293 This function converts a Posix or Solaris thread id to a lightweight
294 process id. If thread_id is non-existent, that's an error. If it's
295 an inactive thread, then we return default_lwp.
299 This function probably shouldn't call error()...
304 thread_to_lwp (ptid_t thread_id
, int default_lwp
)
310 if (is_lwp (thread_id
))
311 return thread_id
; /* It's already an LWP id */
313 /* It's a thread. Convert to lwp */
315 val
= p_td_ta_map_id2thr (main_ta
, GET_THREAD (thread_id
), &th
);
317 return pid_to_ptid (-1); /* thread must have terminated */
318 else if (val
!= TD_OK
)
319 error ("thread_to_lwp: td_ta_map_id2thr %s", td_err_string (val
));
321 val
= p_td_thr_get_info (&th
, &ti
);
323 return pid_to_ptid (-1); /* thread must have terminated */
324 else if (val
!= TD_OK
)
325 error ("thread_to_lwp: td_thr_get_info: %s", td_err_string (val
));
327 if (ti
.ti_state
!= TD_THR_ACTIVE
)
329 if (default_lwp
!= -1)
330 return pid_to_ptid (default_lwp
);
331 error ("thread_to_lwp: thread state not active: %s",
332 td_state_string (ti
.ti_state
));
335 return BUILD_LWP (ti
.ti_lid
, PIDGET (thread_id
));
342 lwp_to_thread - Convert a LWP id to a Posix or Solaris thread id.
346 int lwp_to_thread (lwp_id)
350 This function converts a lightweight process id to a Posix or Solaris
351 thread id. If thread_id is non-existent, that's an error.
355 This function probably shouldn't call error()...
360 lwp_to_thread (ptid_t lwp
)
367 return lwp
; /* It's already a thread id */
369 /* It's an lwp. Convert it to a thread id. */
371 if (!sol_thread_alive (lwp
))
372 return pid_to_ptid (-1); /* defunct lwp */
374 val
= p_td_ta_map_lwp2thr (main_ta
, GET_LWP (lwp
), &th
);
376 return pid_to_ptid (-1); /* thread must have terminated */
377 else if (val
!= TD_OK
)
378 error ("lwp_to_thread: td_ta_map_lwp2thr: %s.", td_err_string (val
));
380 val
= p_td_thr_validate (&th
);
382 return lwp
; /* libthread doesn't know about it;
384 else if (val
!= TD_OK
)
385 error ("lwp_to_thread: td_thr_validate: %s.", td_err_string (val
));
387 val
= p_td_thr_get_info (&th
, &ti
);
389 return pid_to_ptid (-1); /* thread must have terminated */
390 else if (val
!= TD_OK
)
391 error ("lwp_to_thread: td_thr_get_info: %s.", td_err_string (val
));
393 return BUILD_THREAD (ti
.ti_tid
, PIDGET (lwp
));
397 /* Most target vector functions from here on actually just pass through to
398 procfs.c, as they don't need to do anything specific for threads. */
403 sol_thread_open (char *arg
, int from_tty
)
405 procfs_ops
.to_open (arg
, from_tty
);
408 /* Attach to process PID, then initialize for debugging it
409 and wait for the trace-trap that results from attaching. */
412 sol_thread_attach (char *args
, int from_tty
)
414 procfs_ops
.to_attach (args
, from_tty
);
416 /* Must get symbols from solibs before libthread_db can run! */
417 SOLIB_ADD ((char *) 0, from_tty
, (struct target_ops
*) 0);
419 if (sol_thread_active
)
421 printf_filtered ("sol-thread active.\n");
422 main_ph
.ptid
= inferior_ptid
; /* Save for xfer_memory */
423 push_target (&sol_thread_ops
);
424 inferior_ptid
= lwp_to_thread (inferior_ptid
);
425 if (PIDGET (inferior_ptid
) == -1)
426 inferior_ptid
= main_ph
.ptid
;
428 add_thread (inferior_ptid
);
430 /* XXX - might want to iterate over all the threads and register them. */
433 /* Take a program previously attached to and detaches it.
434 The program resumes execution and will no longer stop
435 on signals, etc. We'd better not have left any breakpoints
436 in the program or it'll die when it hits one. For this
437 to work, it may be necessary for the process to have been
438 previously attached. It *might* work if the program was
439 started via the normal ptrace (PTRACE_TRACEME). */
442 sol_thread_detach (char *args
, int from_tty
)
444 inferior_ptid
= pid_to_ptid (PIDGET (main_ph
.ptid
));
445 unpush_target (&sol_thread_ops
);
446 procfs_ops
.to_detach (args
, from_tty
);
449 /* Resume execution of process PID. If STEP is nozero, then
450 just single step it. If SIGNAL is nonzero, restart it with that
451 signal activated. We may have to convert pid from a thread-id to an LWP id
455 sol_thread_resume (ptid_t ptid
, int step
, enum target_signal signo
)
457 struct cleanup
*old_chain
;
459 old_chain
= save_inferior_ptid ();
461 inferior_ptid
= thread_to_lwp (inferior_ptid
, PIDGET (main_ph
.ptid
));
462 if (PIDGET (inferior_ptid
) == -1)
463 inferior_ptid
= procfs_first_available ();
465 if (PIDGET (ptid
) != -1)
467 ptid_t save_ptid
= ptid
;
469 ptid
= thread_to_lwp (ptid
, -2);
470 if (PIDGET (ptid
) == -2) /* Inactive thread */
471 error ("This version of Solaris can't start inactive threads.");
472 if (info_verbose
&& PIDGET (ptid
) == -1)
473 warning ("Specified thread %ld seems to have terminated",
474 GET_THREAD (save_ptid
));
477 procfs_ops
.to_resume (ptid
, step
, signo
);
479 do_cleanups (old_chain
);
482 /* Wait for any threads to stop. We may have to convert PID from a thread id
483 to a LWP id, and vice versa on the way out. */
486 sol_thread_wait (ptid_t ptid
, struct target_waitstatus
*ourstatus
)
490 struct cleanup
*old_chain
;
492 save_ptid
= inferior_ptid
;
493 old_chain
= save_inferior_ptid ();
495 inferior_ptid
= thread_to_lwp (inferior_ptid
, PIDGET (main_ph
.ptid
));
496 if (PIDGET (inferior_ptid
) == -1)
497 inferior_ptid
= procfs_first_available ();
499 if (PIDGET (ptid
) != -1)
501 ptid_t save_ptid
= ptid
;
503 ptid
= thread_to_lwp (ptid
, -2);
504 if (PIDGET (ptid
) == -2) /* Inactive thread */
505 error ("This version of Solaris can't start inactive threads.");
506 if (info_verbose
&& PIDGET (ptid
) == -1)
507 warning ("Specified thread %ld seems to have terminated",
508 GET_THREAD (save_ptid
));
511 rtnval
= procfs_ops
.to_wait (ptid
, ourstatus
);
513 if (ourstatus
->kind
!= TARGET_WAITKIND_EXITED
)
515 /* Map the LWP of interest back to the appropriate thread ID */
516 rtnval
= lwp_to_thread (rtnval
);
517 if (PIDGET (rtnval
) == -1)
520 /* See if we have a new thread */
521 if (is_thread (rtnval
)
522 && !ptid_equal (rtnval
, save_ptid
)
523 && !in_thread_list (rtnval
))
525 printf_filtered ("[New %s]\n", target_pid_to_str (rtnval
));
530 /* During process initialization, we may get here without the thread package
531 being initialized, since that can only happen after we've found the shared
534 do_cleanups (old_chain
);
540 sol_thread_fetch_registers (int regno
)
543 td_thrhandle_t thandle
;
546 prfpregset_t fpregset
;
552 if (!is_thread (inferior_ptid
))
553 { /* LWP: pass the request on to procfs.c */
554 if (target_has_execution
)
555 procfs_ops
.to_fetch_registers (regno
);
557 orig_core_ops
.to_fetch_registers (regno
);
561 /* Solaris thread: convert inferior_ptid into a td_thrhandle_t */
563 thread
= GET_THREAD (inferior_ptid
);
566 error ("sol_thread_fetch_registers: thread == 0");
568 val
= p_td_ta_map_id2thr (main_ta
, thread
, &thandle
);
570 error ("sol_thread_fetch_registers: td_ta_map_id2thr: %s",
571 td_err_string (val
));
573 /* Get the integer regs */
575 val
= p_td_thr_getgregs (&thandle
, gregset
);
577 && val
!= TD_PARTIALREG
)
578 error ("sol_thread_fetch_registers: td_thr_getgregs %s",
579 td_err_string (val
));
581 /* For the sparc, TD_PARTIALREG means that only i0->i7, l0->l7, pc and sp
582 are saved (by a thread context switch). */
584 /* And, now the fp regs */
586 val
= p_td_thr_getfpregs (&thandle
, &fpregset
);
588 && val
!= TD_NOFPREGS
)
589 error ("sol_thread_fetch_registers: td_thr_getfpregs %s",
590 td_err_string (val
));
592 /* Note that we must call supply_{g fp}regset *after* calling the td routines
593 because the td routines call ps_lget* which affect the values stored in the
596 supply_gregset ((gdb_gregset_t
*) &gregset
);
597 supply_fpregset ((gdb_fpregset_t
*) &fpregset
);
600 /* thread_db doesn't seem to handle this right */
601 val
= td_thr_getxregsize (&thandle
, &xregsize
);
602 if (val
!= TD_OK
&& val
!= TD_NOXREGS
)
603 error ("sol_thread_fetch_registers: td_thr_getxregsize %s",
604 td_err_string (val
));
608 xregset
= alloca (xregsize
);
609 val
= td_thr_getxregs (&thandle
, xregset
);
611 error ("sol_thread_fetch_registers: td_thr_getxregs %s",
612 td_err_string (val
));
618 sol_thread_store_registers (int regno
)
621 td_thrhandle_t thandle
;
624 prfpregset_t fpregset
;
630 if (!is_thread (inferior_ptid
))
631 { /* LWP: pass the request on to procfs.c */
632 procfs_ops
.to_store_registers (regno
);
636 /* Solaris thread: convert inferior_ptid into a td_thrhandle_t */
638 thread
= GET_THREAD (inferior_ptid
);
640 val
= p_td_ta_map_id2thr (main_ta
, thread
, &thandle
);
642 error ("sol_thread_store_registers: td_ta_map_id2thr %s",
643 td_err_string (val
));
646 { /* Not writing all the regs */
647 /* save new register value */
648 char* old_value
= (char*) alloca (REGISTER_SIZE
);
649 memcpy (old_value
, ®isters
[REGISTER_BYTE (regno
)], REGISTER_SIZE
);
651 val
= p_td_thr_getgregs (&thandle
, gregset
);
653 error ("sol_thread_store_registers: td_thr_getgregs %s",
654 td_err_string (val
));
655 val
= p_td_thr_getfpregs (&thandle
, &fpregset
);
657 error ("sol_thread_store_registers: td_thr_getfpregs %s",
658 td_err_string (val
));
660 /* restore new register value */
661 memcpy (®isters
[REGISTER_BYTE (regno
)], old_value
, REGISTER_SIZE
);
664 /* thread_db doesn't seem to handle this right */
665 val
= td_thr_getxregsize (&thandle
, &xregsize
);
666 if (val
!= TD_OK
&& val
!= TD_NOXREGS
)
667 error ("sol_thread_store_registers: td_thr_getxregsize %s",
668 td_err_string (val
));
672 xregset
= alloca (xregsize
);
673 val
= td_thr_getxregs (&thandle
, xregset
);
675 error ("sol_thread_store_registers: td_thr_getxregs %s",
676 td_err_string (val
));
681 fill_gregset ((gdb_gregset_t
*) &gregset
, regno
);
682 fill_fpregset ((gdb_fpregset_t
*) &fpregset
, regno
);
684 val
= p_td_thr_setgregs (&thandle
, gregset
);
686 error ("sol_thread_store_registers: td_thr_setgregs %s",
687 td_err_string (val
));
688 val
= p_td_thr_setfpregs (&thandle
, &fpregset
);
690 error ("sol_thread_store_registers: td_thr_setfpregs %s",
691 td_err_string (val
));
694 /* thread_db doesn't seem to handle this right */
695 val
= td_thr_getxregsize (&thandle
, &xregsize
);
696 if (val
!= TD_OK
&& val
!= TD_NOXREGS
)
697 error ("sol_thread_store_registers: td_thr_getxregsize %s",
698 td_err_string (val
));
700 /* Should probably do something about writing the xregs here, but what are
705 /* Get ready to modify the registers array. On machines which store
706 individual registers, this doesn't need to do anything. On machines
707 which store all the registers in one fell swoop, this makes sure
708 that registers contains all the registers from the program being
712 sol_thread_prepare_to_store (void)
714 procfs_ops
.to_prepare_to_store ();
717 /* Transfer LEN bytes between GDB address MYADDR and target address
718 MEMADDR. If DOWRITE is non-zero, transfer them to the target,
719 otherwise transfer them from the target. TARGET is unused.
721 Returns the number of bytes transferred. */
724 sol_thread_xfer_memory (CORE_ADDR memaddr
, char *myaddr
, int len
, int dowrite
,
725 struct mem_attrib
*attrib
,
726 struct target_ops
*target
)
729 struct cleanup
*old_chain
;
731 old_chain
= save_inferior_ptid ();
733 if (is_thread (inferior_ptid
) || /* A thread */
734 !target_thread_alive (inferior_ptid
)) /* An lwp, but not alive */
735 inferior_ptid
= procfs_first_available (); /* Find any live lwp. */
736 /* Note: don't need to call switch_to_thread; we're just reading memory. */
738 if (target_has_execution
)
739 retval
= procfs_ops
.to_xfer_memory (memaddr
, myaddr
, len
,
740 dowrite
, attrib
, target
);
742 retval
= orig_core_ops
.to_xfer_memory (memaddr
, myaddr
, len
,
743 dowrite
, attrib
, target
);
745 do_cleanups (old_chain
);
750 /* Print status information about what we're accessing. */
753 sol_thread_files_info (struct target_ops
*ignore
)
755 procfs_ops
.to_files_info (ignore
);
759 sol_thread_kill_inferior (void)
761 procfs_ops
.to_kill ();
765 sol_thread_notice_signals (ptid_t ptid
)
767 procfs_ops
.to_notice_signals (pid_to_ptid (PIDGET (ptid
)));
770 /* Fork an inferior process, and start debugging it with /proc. */
773 sol_thread_create_inferior (char *exec_file
, char *allargs
, char **env
)
775 procfs_ops
.to_create_inferior (exec_file
, allargs
, env
);
777 if (sol_thread_active
&& !ptid_equal (inferior_ptid
, null_ptid
))
779 main_ph
.ptid
= inferior_ptid
; /* Save for xfer_memory */
781 push_target (&sol_thread_ops
);
783 inferior_ptid
= lwp_to_thread (inferior_ptid
);
784 if (PIDGET (inferior_ptid
) == -1)
785 inferior_ptid
= main_ph
.ptid
;
787 if (!in_thread_list (inferior_ptid
))
788 add_thread (inferior_ptid
);
792 /* This routine is called whenever a new symbol table is read in, or when all
793 symbol tables are removed. libthread_db can only be initialized when it
794 finds the right variables in libthread.so. Since it's a shared library,
795 those variables don't show up until the library gets mapped and the symbol
798 /* This new_objfile event is now managed by a chained function pointer.
799 * It is the callee's responsability to call the next client on the chain.
802 /* Saved pointer to previous owner of the new_objfile event. */
803 static void (*target_new_objfile_chain
) (struct objfile
*);
806 sol_thread_new_objfile (struct objfile
*objfile
)
812 sol_thread_active
= 0;
816 /* don't do anything if init failed to resolve the libthread_db library */
817 if (!procfs_suppress_run
)
820 /* Now, initialize the thread debugging library. This needs to be done after
821 the shared libraries are located because it needs information from the
822 user's thread library. */
827 warning ("sol_thread_new_objfile: td_init: %s", td_err_string (val
));
831 val
= p_td_ta_new (&main_ph
, &main_ta
);
832 if (val
== TD_NOLIBTHREAD
)
834 else if (val
!= TD_OK
)
836 warning ("sol_thread_new_objfile: td_ta_new: %s", td_err_string (val
));
840 sol_thread_active
= 1;
842 /* Call predecessor on chain, if any. */
843 if (target_new_objfile_chain
)
844 target_new_objfile_chain (objfile
);
847 /* Clean up after the inferior dies. */
850 sol_thread_mourn_inferior (void)
852 unpush_target (&sol_thread_ops
);
853 procfs_ops
.to_mourn_inferior ();
856 /* Mark our target-struct as eligible for stray "run" and "attach" commands. */
859 sol_thread_can_run (void)
861 return procfs_suppress_run
;
868 sol_thread_alive - test thread for "aliveness"
872 static bool sol_thread_alive (ptid_t ptid);
876 returns true if thread still active in inferior.
881 sol_thread_alive (ptid_t ptid
)
883 if (is_thread (ptid
)) /* non-kernel thread */
889 pid
= GET_THREAD (ptid
);
890 if ((val
= p_td_ta_map_id2thr (main_ta
, pid
, &th
)) != TD_OK
)
891 return 0; /* thread not found */
892 if ((val
= p_td_thr_validate (&th
)) != TD_OK
)
893 return 0; /* thread not valid */
894 return 1; /* known thread: return true */
897 /* kernel thread (LWP): let procfs test it */
899 if (target_has_execution
)
900 return procfs_ops
.to_thread_alive (ptid
);
902 return orig_core_ops
.to_thread_alive (ptid
);
907 sol_thread_stop (void)
909 procfs_ops
.to_stop ();
912 /* These routines implement the lower half of the thread_db interface. Ie: the
915 /* Various versions of <proc_service.h> have slightly
916 different function prototypes. In particular, we have
919 struct ps_prochandle * const struct ps_prochandle *
924 Which one you have depends on solaris version and what
925 patches you've applied. On the theory that there are
926 only two major variants, we have configure check the
927 prototype of ps_pdwrite (), and use that info to make
928 appropriate typedefs here. */
930 #ifdef PROC_SERVICE_IS_OLD
931 typedef const struct ps_prochandle
*gdb_ps_prochandle_t
;
932 typedef char *gdb_ps_read_buf_t
;
933 typedef char *gdb_ps_write_buf_t
;
934 typedef int gdb_ps_size_t
;
935 typedef paddr_t gdb_ps_addr_t
;
937 typedef struct ps_prochandle
*gdb_ps_prochandle_t
;
938 typedef void *gdb_ps_read_buf_t
;
939 typedef const void *gdb_ps_write_buf_t
;
940 typedef size_t gdb_ps_size_t
;
941 typedef psaddr_t gdb_ps_addr_t
;
945 /* The next four routines are called by thread_db to tell us to stop and stop
946 a particular process or lwp. Since GDB ensures that these are all stopped
947 by the time we call anything in thread_db, these routines need to do
953 ps_pstop (gdb_ps_prochandle_t ph
)
958 /* Process continue */
961 ps_pcontinue (gdb_ps_prochandle_t ph
)
969 ps_lstop (gdb_ps_prochandle_t ph
, lwpid_t lwpid
)
977 ps_lcontinue (gdb_ps_prochandle_t ph
, lwpid_t lwpid
)
982 /* Looks up the symbol LD_SYMBOL_NAME in the debugger's symbol table. */
985 ps_pglobal_lookup (gdb_ps_prochandle_t ph
, const char *ld_object_name
,
986 const char *ld_symbol_name
, gdb_ps_addr_t
* ld_symbol_addr
)
988 struct minimal_symbol
*ms
;
990 ms
= lookup_minimal_symbol (ld_symbol_name
, NULL
, NULL
);
995 *ld_symbol_addr
= SYMBOL_VALUE_ADDRESS (ms
);
1000 /* Common routine for reading and writing memory. */
1003 rw_common (int dowrite
, const struct ps_prochandle
*ph
, gdb_ps_addr_t addr
,
1004 char *buf
, int size
)
1006 struct cleanup
*old_chain
;
1008 old_chain
= save_inferior_ptid ();
1010 if (is_thread (inferior_ptid
) || /* A thread */
1011 !target_thread_alive (inferior_ptid
)) /* An lwp, but not alive */
1012 inferior_ptid
= procfs_first_available (); /* Find any live lwp. */
1013 /* Note: don't need to call switch_to_thread; we're just reading memory. */
1015 #if defined (__sparcv9)
1016 /* For Sparc64 cross Sparc32, make sure the address has not been
1017 accidentally sign-extended (or whatever) to beyond 32 bits. */
1018 if (bfd_get_arch_size (exec_bfd
) == 32)
1026 /* FIXME: passing 0 as attrib argument. */
1027 if (target_has_execution
)
1028 cc
= procfs_ops
.to_xfer_memory (addr
, buf
, size
,
1029 dowrite
, 0, &procfs_ops
);
1031 cc
= orig_core_ops
.to_xfer_memory (addr
, buf
, size
,
1032 dowrite
, 0, &core_ops
);
1037 print_sys_errmsg ("rw_common (): read", errno
);
1039 print_sys_errmsg ("rw_common (): write", errno
);
1041 do_cleanups (old_chain
);
1048 warning ("rw_common (): unable to read at addr 0x%lx",
1051 warning ("rw_common (): unable to write at addr 0x%lx",
1054 do_cleanups (old_chain
);
1063 do_cleanups (old_chain
);
1068 /* Copies SIZE bytes from target process .data segment to debugger memory. */
1071 ps_pdread (gdb_ps_prochandle_t ph
, gdb_ps_addr_t addr
,
1072 gdb_ps_read_buf_t buf
, gdb_ps_size_t size
)
1074 return rw_common (0, ph
, addr
, buf
, size
);
1077 /* Copies SIZE bytes from debugger memory .data segment to target process. */
1080 ps_pdwrite (gdb_ps_prochandle_t ph
, gdb_ps_addr_t addr
,
1081 gdb_ps_write_buf_t buf
, gdb_ps_size_t size
)
1083 return rw_common (1, ph
, addr
, (char *) buf
, size
);
1086 /* Copies SIZE bytes from target process .text segment to debugger memory. */
1089 ps_ptread (gdb_ps_prochandle_t ph
, gdb_ps_addr_t addr
,
1090 gdb_ps_read_buf_t buf
, gdb_ps_size_t size
)
1092 return rw_common (0, ph
, addr
, buf
, size
);
1095 /* Copies SIZE bytes from debugger memory .text segment to target process. */
1098 ps_ptwrite (gdb_ps_prochandle_t ph
, gdb_ps_addr_t addr
,
1099 gdb_ps_write_buf_t buf
, gdb_ps_size_t size
)
1101 return rw_common (1, ph
, addr
, (char *) buf
, size
);
1104 /* Get integer regs for LWP */
1107 ps_lgetregs (gdb_ps_prochandle_t ph
, lwpid_t lwpid
,
1108 prgregset_t gregset
)
1110 struct cleanup
*old_chain
;
1112 old_chain
= save_inferior_ptid ();
1114 inferior_ptid
= BUILD_LWP (lwpid
, PIDGET (inferior_ptid
));
1116 if (target_has_execution
)
1117 procfs_ops
.to_fetch_registers (-1);
1119 orig_core_ops
.to_fetch_registers (-1);
1120 fill_gregset ((gdb_gregset_t
*) gregset
, -1);
1122 do_cleanups (old_chain
);
1127 /* Set integer regs for LWP */
1130 ps_lsetregs (gdb_ps_prochandle_t ph
, lwpid_t lwpid
,
1131 const prgregset_t gregset
)
1133 struct cleanup
*old_chain
;
1135 old_chain
= save_inferior_ptid ();
1137 inferior_ptid
= BUILD_LWP (lwpid
, PIDGET (inferior_ptid
));
1139 supply_gregset ((gdb_gregset_t
*) gregset
);
1140 if (target_has_execution
)
1141 procfs_ops
.to_store_registers (-1);
1143 orig_core_ops
.to_store_registers (-1);
1145 do_cleanups (old_chain
);
1150 /* Log a message (sends to gdb_stderr). */
1153 ps_plog (const char *fmt
,...)
1157 va_start (args
, fmt
);
1159 vfprintf_filtered (gdb_stderr
, fmt
, args
);
1162 /* Get size of extra register set. Currently a noop. */
1165 ps_lgetxregsize (gdb_ps_prochandle_t ph
, lwpid_t lwpid
, int *xregsize
)
1172 val
= get_lwp_fd (ph
, lwpid
, &lwp_fd
);
1176 if (ioctl (lwp_fd
, PIOCGXREGSIZE
, ®size
))
1178 if (errno
== EINVAL
)
1179 return PS_NOFREGS
; /* XXX Wrong code, but this is the closest
1180 thing in proc_service.h */
1182 print_sys_errmsg ("ps_lgetxregsize (): PIOCGXREGSIZE", errno
);
1190 /* Get extra register set. Currently a noop. */
1193 ps_lgetxregs (gdb_ps_prochandle_t ph
, lwpid_t lwpid
, caddr_t xregset
)
1199 val
= get_lwp_fd (ph
, lwpid
, &lwp_fd
);
1203 if (ioctl (lwp_fd
, PIOCGXREG
, xregset
))
1205 print_sys_errmsg ("ps_lgetxregs (): PIOCGXREG", errno
);
1213 /* Set extra register set. Currently a noop. */
1216 ps_lsetxregs (gdb_ps_prochandle_t ph
, lwpid_t lwpid
, caddr_t xregset
)
1222 val
= get_lwp_fd (ph
, lwpid
, &lwp_fd
);
1226 if (ioctl (lwp_fd
, PIOCSXREG
, xregset
))
1228 print_sys_errmsg ("ps_lsetxregs (): PIOCSXREG", errno
);
1236 /* Get floating-point regs for LWP */
1239 ps_lgetfpregs (gdb_ps_prochandle_t ph
, lwpid_t lwpid
,
1240 prfpregset_t
* fpregset
)
1242 struct cleanup
*old_chain
;
1244 old_chain
= save_inferior_ptid ();
1246 inferior_ptid
= BUILD_LWP (lwpid
, PIDGET (inferior_ptid
));
1248 if (target_has_execution
)
1249 procfs_ops
.to_fetch_registers (-1);
1251 orig_core_ops
.to_fetch_registers (-1);
1252 fill_fpregset ((gdb_fpregset_t
*) fpregset
, -1);
1254 do_cleanups (old_chain
);
1259 /* Set floating-point regs for LWP */
1262 ps_lsetfpregs (gdb_ps_prochandle_t ph
, lwpid_t lwpid
,
1263 const prfpregset_t
* fpregset
)
1265 struct cleanup
*old_chain
;
1267 old_chain
= save_inferior_ptid ();
1269 inferior_ptid
= BUILD_LWP (lwpid
, PIDGET (inferior_ptid
));
1271 supply_fpregset ((gdb_fpregset_t
*) fpregset
);
1272 if (target_has_execution
)
1273 procfs_ops
.to_store_registers (-1);
1275 orig_core_ops
.to_store_registers (-1);
1277 do_cleanups (old_chain
);
1282 #ifdef PR_MODEL_LP64
1283 /* Identify process as 32-bit or 64-bit.
1284 At the moment I'm using bfd to do this.
1285 There might be a more solaris-specific (eg. procfs) method,
1286 but this ought to work. */
1289 ps_pdmodel (gdb_ps_prochandle_t ph
, int *data_model
)
1292 *data_model
= PR_MODEL_UNKNOWN
;
1293 else if (bfd_get_arch_size (exec_bfd
) == 32)
1294 *data_model
= PR_MODEL_ILP32
;
1296 *data_model
= PR_MODEL_LP64
;
1300 #endif /* PR_MODEL_LP64 */
1302 #ifdef TM_I386SOL2_H
1304 /* Reads the local descriptor table of a LWP. */
1307 ps_lgetLDT (gdb_ps_prochandle_t ph
, lwpid_t lwpid
,
1310 /* NOTE: only used on Solaris, therefore OK to refer to procfs.c */
1311 extern struct ssd
*procfs_find_LDT_entry (ptid_t
);
1314 /* FIXME: can't I get the process ID from the prochandle or something?
1317 if (PIDGET (inferior_ptid
) <= 0 || lwpid
<= 0)
1320 ret
= procfs_find_LDT_entry (BUILD_LWP (lwpid
, PIDGET (inferior_ptid
)));
1323 memcpy (pldt
, ret
, sizeof (struct ssd
));
1326 else /* LDT not found. */
1329 #endif /* TM_I386SOL2_H */
1331 /* Convert a pid to printable form. */
1334 solaris_pid_to_str (ptid_t ptid
)
1336 static char buf
[100];
1338 /* in case init failed to resolve the libthread_db library */
1339 if (!procfs_suppress_run
)
1340 return procfs_pid_to_str (ptid
);
1342 if (is_thread (ptid
))
1346 lwp
= thread_to_lwp (ptid
, -2);
1348 if (PIDGET (lwp
) == -1)
1349 sprintf (buf
, "Thread %ld (defunct)", GET_THREAD (ptid
));
1350 else if (PIDGET (lwp
) != -2)
1351 sprintf (buf
, "Thread %ld (LWP %ld)", GET_THREAD (ptid
), GET_LWP (lwp
));
1353 sprintf (buf
, "Thread %ld ", GET_THREAD (ptid
));
1355 else if (GET_LWP (ptid
) != 0)
1356 sprintf (buf
, "LWP %ld ", GET_LWP (ptid
));
1358 sprintf (buf
, "process %d ", PIDGET (ptid
));
1364 /* Worker bee for find_new_threads
1365 Callback function that gets called once per USER thread (i.e., not
1369 sol_find_new_threads_callback (const td_thrhandle_t
*th
, void *ignored
)
1375 if ((retval
= p_td_thr_get_info (th
, &ti
)) != TD_OK
)
1379 ptid
= BUILD_THREAD (ti
.ti_tid
, PIDGET (inferior_ptid
));
1380 if (!in_thread_list (ptid
))
1387 sol_find_new_threads (void)
1389 /* don't do anything if init failed to resolve the libthread_db library */
1390 if (!procfs_suppress_run
)
1393 if (PIDGET (inferior_ptid
) == -1)
1395 printf_filtered ("No process.\n");
1398 procfs_ops
.to_find_new_threads (); /* first find new kernel threads */
1399 p_td_ta_thr_iter (main_ta
, sol_find_new_threads_callback
, (void *) 0,
1400 TD_THR_ANY_STATE
, TD_THR_LOWEST_PRIORITY
,
1401 TD_SIGNO_MASK
, TD_THR_ANY_USER_FLAGS
);
1405 sol_core_open (char *filename
, int from_tty
)
1407 orig_core_ops
.to_open (filename
, from_tty
);
1411 sol_core_close (int quitting
)
1413 orig_core_ops
.to_close (quitting
);
1417 sol_core_detach (char *args
, int from_tty
)
1419 unpush_target (&core_ops
);
1420 orig_core_ops
.to_detach (args
, from_tty
);
1424 sol_core_files_info (struct target_ops
*t
)
1426 orig_core_ops
.to_files_info (t
);
1429 /* Worker bee for info sol-thread command. This is a callback function that
1430 gets called once for each Solaris thread (ie. not kernel thread) in the
1431 inferior. Print anything interesting that we can think of. */
1434 info_cb (const td_thrhandle_t
*th
, void *s
)
1439 if ((ret
= p_td_thr_get_info (th
, &ti
)) == TD_OK
)
1441 printf_filtered ("%s thread #%d, lwp %d, ",
1442 ti
.ti_type
== TD_THR_SYSTEM
? "system" : "user ",
1443 ti
.ti_tid
, ti
.ti_lid
);
1444 switch (ti
.ti_state
)
1447 case TD_THR_UNKNOWN
:
1448 printf_filtered ("<unknown state>");
1450 case TD_THR_STOPPED
:
1451 printf_filtered ("(stopped)");
1454 printf_filtered ("(run) ");
1457 printf_filtered ("(active) ");
1460 printf_filtered ("(zombie) ");
1463 printf_filtered ("(asleep) ");
1465 case TD_THR_STOPPED_ASLEEP
:
1466 printf_filtered ("(stopped asleep)");
1469 /* Print thr_create start function: */
1470 if (ti
.ti_startfunc
!= 0)
1472 struct minimal_symbol
*msym
;
1473 msym
= lookup_minimal_symbol_by_pc (ti
.ti_startfunc
);
1475 printf_filtered (" startfunc: %s\n", SYMBOL_NAME (msym
));
1477 printf_filtered (" startfunc: 0x%s\n", paddr (ti
.ti_startfunc
));
1480 /* If thread is asleep, print function that went to sleep: */
1481 if (ti
.ti_state
== TD_THR_SLEEP
)
1483 struct minimal_symbol
*msym
;
1484 msym
= lookup_minimal_symbol_by_pc (ti
.ti_pc
);
1486 printf_filtered (" - Sleep func: %s\n", SYMBOL_NAME (msym
));
1488 printf_filtered (" - Sleep func: 0x%s\n", paddr (ti
.ti_startfunc
));
1491 /* Wrap up line, if necessary */
1492 if (ti
.ti_state
!= TD_THR_SLEEP
&& ti
.ti_startfunc
== 0)
1493 printf_filtered ("\n"); /* don't you hate counting newlines? */
1496 warning ("info sol-thread: failed to get info for thread.");
1501 /* List some state about each Solaris user thread in the inferior. */
1504 info_solthreads (char *args
, int from_tty
)
1506 p_td_ta_thr_iter (main_ta
, info_cb
, args
,
1507 TD_THR_ANY_STATE
, TD_THR_LOWEST_PRIORITY
,
1508 TD_SIGNO_MASK
, TD_THR_ANY_USER_FLAGS
);
1512 ignore (CORE_ADDR addr
, char *contents
)
1519 init_sol_thread_ops (void)
1521 sol_thread_ops
.to_shortname
= "solaris-threads";
1522 sol_thread_ops
.to_longname
= "Solaris threads and pthread.";
1523 sol_thread_ops
.to_doc
= "Solaris threads and pthread support.";
1524 sol_thread_ops
.to_open
= sol_thread_open
;
1525 sol_thread_ops
.to_close
= 0;
1526 sol_thread_ops
.to_attach
= sol_thread_attach
;
1527 sol_thread_ops
.to_detach
= sol_thread_detach
;
1528 sol_thread_ops
.to_resume
= sol_thread_resume
;
1529 sol_thread_ops
.to_wait
= sol_thread_wait
;
1530 sol_thread_ops
.to_fetch_registers
= sol_thread_fetch_registers
;
1531 sol_thread_ops
.to_store_registers
= sol_thread_store_registers
;
1532 sol_thread_ops
.to_prepare_to_store
= sol_thread_prepare_to_store
;
1533 sol_thread_ops
.to_xfer_memory
= sol_thread_xfer_memory
;
1534 sol_thread_ops
.to_files_info
= sol_thread_files_info
;
1535 sol_thread_ops
.to_insert_breakpoint
= memory_insert_breakpoint
;
1536 sol_thread_ops
.to_remove_breakpoint
= memory_remove_breakpoint
;
1537 sol_thread_ops
.to_terminal_init
= terminal_init_inferior
;
1538 sol_thread_ops
.to_terminal_inferior
= terminal_inferior
;
1539 sol_thread_ops
.to_terminal_ours_for_output
= terminal_ours_for_output
;
1540 sol_thread_ops
.to_terminal_ours
= terminal_ours
;
1541 sol_thread_ops
.to_terminal_info
= child_terminal_info
;
1542 sol_thread_ops
.to_kill
= sol_thread_kill_inferior
;
1543 sol_thread_ops
.to_load
= 0;
1544 sol_thread_ops
.to_lookup_symbol
= 0;
1545 sol_thread_ops
.to_create_inferior
= sol_thread_create_inferior
;
1546 sol_thread_ops
.to_mourn_inferior
= sol_thread_mourn_inferior
;
1547 sol_thread_ops
.to_can_run
= sol_thread_can_run
;
1548 sol_thread_ops
.to_notice_signals
= sol_thread_notice_signals
;
1549 sol_thread_ops
.to_thread_alive
= sol_thread_alive
;
1550 sol_thread_ops
.to_pid_to_str
= solaris_pid_to_str
;
1551 sol_thread_ops
.to_find_new_threads
= sol_find_new_threads
;
1552 sol_thread_ops
.to_stop
= sol_thread_stop
;
1553 sol_thread_ops
.to_stratum
= process_stratum
;
1554 sol_thread_ops
.to_has_all_memory
= 1;
1555 sol_thread_ops
.to_has_memory
= 1;
1556 sol_thread_ops
.to_has_stack
= 1;
1557 sol_thread_ops
.to_has_registers
= 1;
1558 sol_thread_ops
.to_has_execution
= 1;
1559 sol_thread_ops
.to_has_thread_control
= tc_none
;
1560 sol_thread_ops
.to_sections
= 0;
1561 sol_thread_ops
.to_sections_end
= 0;
1562 sol_thread_ops
.to_magic
= OPS_MAGIC
;
1567 init_sol_core_ops (void)
1569 sol_core_ops
.to_shortname
= "solaris-core";
1570 sol_core_ops
.to_longname
= "Solaris core threads and pthread.";
1571 sol_core_ops
.to_doc
= "Solaris threads and pthread support for core files.";
1572 sol_core_ops
.to_open
= sol_core_open
;
1573 sol_core_ops
.to_close
= sol_core_close
;
1574 sol_core_ops
.to_attach
= sol_thread_attach
;
1575 sol_core_ops
.to_detach
= sol_core_detach
;
1576 /* sol_core_ops.to_resume = 0; */
1577 /* sol_core_ops.to_wait = 0; */
1578 sol_core_ops
.to_fetch_registers
= sol_thread_fetch_registers
;
1579 /* sol_core_ops.to_store_registers = 0; */
1580 /* sol_core_ops.to_prepare_to_store = 0; */
1581 sol_core_ops
.to_xfer_memory
= sol_thread_xfer_memory
;
1582 sol_core_ops
.to_files_info
= sol_core_files_info
;
1583 sol_core_ops
.to_insert_breakpoint
= ignore
;
1584 sol_core_ops
.to_remove_breakpoint
= ignore
;
1585 /* sol_core_ops.to_terminal_init = 0; */
1586 /* sol_core_ops.to_terminal_inferior = 0; */
1587 /* sol_core_ops.to_terminal_ours_for_output = 0; */
1588 /* sol_core_ops.to_terminal_ours = 0; */
1589 /* sol_core_ops.to_terminal_info = 0; */
1590 /* sol_core_ops.to_kill = 0; */
1591 /* sol_core_ops.to_load = 0; */
1592 /* sol_core_ops.to_lookup_symbol = 0; */
1593 sol_core_ops
.to_create_inferior
= sol_thread_create_inferior
;
1594 sol_core_ops
.to_stratum
= core_stratum
;
1595 sol_core_ops
.to_has_all_memory
= 0;
1596 sol_core_ops
.to_has_memory
= 1;
1597 sol_core_ops
.to_has_stack
= 1;
1598 sol_core_ops
.to_has_registers
= 1;
1599 sol_core_ops
.to_has_execution
= 0;
1600 sol_core_ops
.to_has_thread_control
= tc_none
;
1601 sol_core_ops
.to_thread_alive
= sol_thread_alive
;
1602 sol_core_ops
.to_pid_to_str
= solaris_pid_to_str
;
1603 /* On Solaris/x86, when debugging a threaded core file from process <n>,
1604 the following causes "info threads" to produce "procfs: couldn't find pid
1605 <n> in procinfo list" where <n> is the pid of the process that produced
1606 the core file. Disable it for now. */
1607 /* sol_core_ops.to_find_new_threads = sol_find_new_threads; */
1608 sol_core_ops
.to_sections
= 0;
1609 sol_core_ops
.to_sections_end
= 0;
1610 sol_core_ops
.to_magic
= OPS_MAGIC
;
1613 /* we suppress the call to add_target of core_ops in corelow because
1614 if there are two targets in the stratum core_stratum, find_core_target
1615 won't know which one to return. see corelow.c for an additonal
1616 comment on coreops_suppress_target. */
1617 int coreops_suppress_target
= 1;
1620 _initialize_sol_thread (void)
1624 init_sol_thread_ops ();
1625 init_sol_core_ops ();
1627 dlhandle
= dlopen ("libthread_db.so.1", RTLD_NOW
);
1631 #define resolve(X) \
1632 if (!(p_##X = dlsym (dlhandle, #X))) \
1636 resolve (td_ta_new
);
1637 resolve (td_ta_delete
);
1639 resolve (td_ta_get_ph
);
1640 resolve (td_ta_get_nthreads
);
1641 resolve (td_ta_tsd_iter
);
1642 resolve (td_ta_thr_iter
);
1643 resolve (td_thr_validate
);
1644 resolve (td_thr_tsd
);
1645 resolve (td_thr_get_info
);
1646 resolve (td_thr_getfpregs
);
1647 resolve (td_thr_getxregsize
);
1648 resolve (td_thr_getxregs
);
1649 resolve (td_thr_sigsetmask
);
1650 resolve (td_thr_setprio
);
1651 resolve (td_thr_setsigpending
);
1652 resolve (td_thr_setfpregs
);
1653 resolve (td_thr_setxregs
);
1654 resolve (td_ta_map_id2thr
);
1655 resolve (td_ta_map_lwp2thr
);
1656 resolve (td_thr_getgregs
);
1657 resolve (td_thr_setgregs
);
1659 add_target (&sol_thread_ops
);
1661 procfs_suppress_run
= 1;
1663 add_cmd ("sol-threads", class_maintenance
, info_solthreads
,
1664 "Show info on Solaris user threads.\n", &maintenanceinfolist
);
1666 memcpy (&orig_core_ops
, &core_ops
, sizeof (struct target_ops
));
1667 memcpy (&core_ops
, &sol_core_ops
, sizeof (struct target_ops
));
1668 add_target (&core_ops
);
1670 /* Hook into new_objfile notification. */
1671 target_new_objfile_chain
= target_new_objfile_hook
;
1672 target_new_objfile_hook
= sol_thread_new_objfile
;
1677 fprintf_unfiltered (gdb_stderr
, "[GDB will not be able to debug user-mode threads: %s]\n", dlerror ());
1682 /* allow the user to debug non-threaded core files */
1683 add_target (&core_ops
);