1 /* Solaris threads debugging interface.
3 Copyright (C) 1996-2005, 2007-2012 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 3 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, see <http://www.gnu.org/licenses/>. */
20 /* This module implements a sort of half target that sits between the
21 machine-independent parts of GDB and the /proc interface (procfs.c)
22 to provide access to the Solaris user-mode thread implementation.
24 Solaris threads are true user-mode threads, which are invoked via
25 the thr_* and pthread_* (native and POSIX respectivly) interfaces.
26 These are mostly implemented in user-space, with all thread context
27 kept in various structures that live in the user's heap. These
28 should not be confused with lightweight processes (LWPs), which are
29 implemented by the kernel, and scheduled without explicit
30 intervention by the process.
32 Just to confuse things a little, Solaris threads (both native and
33 POSIX) are actually implemented using LWPs. In general, there are
34 going to be more threads than LWPs. There is no fixed
35 correspondence between a thread and an LWP. When a thread wants to
36 run, it gets scheduled onto the first available LWP and can
37 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
41 called libthread_db.so.1 (not to be confused with
42 libthread_db.so.0, which doesn't have a published interface). This
43 interface has an upper part, which it provides, and a lower part
44 which we provide. The upper part consists of the td_* routines,
45 which allow us to find all the threads, query their state, etc...
46 The lower part consists of all of the ps_*, which are used by the
47 td_* routines to read/write memory, manipulate LWPs, lookup
48 symbols, etc... The ps_* routines actually do most of their work
49 by calling functions in procfs.c. */
53 #include <proc_service.h>
54 #include <thread_db.h>
55 #include "gdbthread.h"
67 #include "gdb_string.h"
70 struct target_ops sol_thread_ops
;
72 extern char *procfs_pid_to_str (struct target_ops
*ops
, ptid_t ptid
);
74 /* Prototypes for supply_gregset etc. */
77 /* This struct is defined by us, but mainly used for the proc_service
78 interface. We don't have much use for it, except as a handy place
79 to get a real PID for memory accesses. */
92 static struct ps_prochandle main_ph
;
93 static td_thragent_t
*main_ta
;
94 static int sol_thread_active
= 0;
96 static void init_sol_thread_ops (void);
98 /* Default definitions: These must be defined in tm.h if they are to
99 be shared with a process module such as procfs. */
101 #define GET_PID(ptid) ptid_get_pid (ptid)
102 #define GET_LWP(ptid) ptid_get_lwp (ptid)
103 #define GET_THREAD(ptid) ptid_get_tid (ptid)
105 #define is_lwp(ptid) (GET_LWP (ptid) != 0)
106 #define is_thread(ptid) (GET_THREAD (ptid) != 0)
108 #define BUILD_LWP(lwp, pid) ptid_build (pid, lwp, 0)
109 #define BUILD_THREAD(tid, pid) ptid_build (pid, 0, tid)
111 /* Pointers to routines from libthread_db resolved by dlopen(). */
113 static void (*p_td_log
)(const int on_off
);
114 static td_err_e (*p_td_ta_new
)(const struct ps_prochandle
*ph_p
,
115 td_thragent_t
**ta_pp
);
116 static td_err_e (*p_td_ta_delete
)(td_thragent_t
*ta_p
);
117 static td_err_e (*p_td_init
)(void);
118 static td_err_e (*p_td_ta_get_ph
)(const td_thragent_t
*ta_p
,
119 struct ps_prochandle
**ph_pp
);
120 static td_err_e (*p_td_ta_get_nthreads
)(const td_thragent_t
*ta_p
,
122 static td_err_e (*p_td_ta_tsd_iter
)(const td_thragent_t
*ta_p
,
123 td_key_iter_f
*cb
, void *cbdata_p
);
124 static td_err_e (*p_td_ta_thr_iter
)(const td_thragent_t
*ta_p
,
125 td_thr_iter_f
*cb
, void *cbdata_p
,
126 td_thr_state_e state
, int ti_pri
,
127 sigset_t
*ti_sigmask_p
,
128 unsigned ti_user_flags
);
129 static td_err_e (*p_td_thr_validate
)(const td_thrhandle_t
*th_p
);
130 static td_err_e (*p_td_thr_tsd
)(const td_thrhandle_t
* th_p
,
131 const thread_key_t key
, void **data_pp
);
132 static td_err_e (*p_td_thr_get_info
)(const td_thrhandle_t
*th_p
,
134 static td_err_e (*p_td_thr_getfpregs
)(const td_thrhandle_t
*th_p
,
135 prfpregset_t
*fpregset
);
136 static td_err_e (*p_td_thr_getxregsize
)(const td_thrhandle_t
*th_p
,
138 static td_err_e (*p_td_thr_getxregs
)(const td_thrhandle_t
*th_p
,
139 const caddr_t xregset
);
140 static td_err_e (*p_td_thr_sigsetmask
)(const td_thrhandle_t
*th_p
,
141 const sigset_t ti_sigmask
);
142 static td_err_e (*p_td_thr_setprio
)(const td_thrhandle_t
*th_p
,
144 static td_err_e (*p_td_thr_setsigpending
)(const td_thrhandle_t
*th_p
,
145 const uchar_t ti_pending_flag
,
146 const sigset_t ti_pending
);
147 static td_err_e (*p_td_thr_setfpregs
)(const td_thrhandle_t
*th_p
,
148 const prfpregset_t
*fpregset
);
149 static td_err_e (*p_td_thr_setxregs
)(const td_thrhandle_t
*th_p
,
150 const caddr_t xregset
);
151 static td_err_e (*p_td_ta_map_id2thr
)(const td_thragent_t
*ta_p
,
153 td_thrhandle_t
*th_p
);
154 static td_err_e (*p_td_ta_map_lwp2thr
)(const td_thragent_t
*ta_p
,
156 td_thrhandle_t
*th_p
);
157 static td_err_e (*p_td_thr_getgregs
)(const td_thrhandle_t
*th_p
,
159 static td_err_e (*p_td_thr_setgregs
)(const td_thrhandle_t
*th_p
,
160 const prgregset_t regset
);
163 /* Return the libthread_db error string associated with ERRCODE. If
164 ERRCODE is unknown, return an appropriate message. */
167 td_err_string (td_err_e errcode
)
169 static struct string_map td_err_table
[] =
171 { TD_OK
, "generic \"call succeeded\"" },
172 { TD_ERR
, "generic error." },
173 { TD_NOTHR
, "no thread can be found to satisfy query" },
174 { TD_NOSV
, "no synch. variable can be found to satisfy query" },
175 { TD_NOLWP
, "no lwp can be found to satisfy query" },
176 { TD_BADPH
, "invalid process handle" },
177 { TD_BADTH
, "invalid thread handle" },
178 { TD_BADSH
, "invalid synchronization handle" },
179 { TD_BADTA
, "invalid thread agent" },
180 { TD_BADKEY
, "invalid key" },
181 { TD_NOMSG
, "td_thr_event_getmsg() called when there was no message" },
182 { TD_NOFPREGS
, "FPU register set not available for given thread" },
183 { TD_NOLIBTHREAD
, "application not linked with libthread" },
184 { TD_NOEVENT
, "requested event is not supported" },
185 { TD_NOCAPAB
, "capability not available" },
186 { TD_DBERR
, "Debugger service failed" },
187 { TD_NOAPLIC
, "Operation not applicable to" },
188 { TD_NOTSD
, "No thread specific data for this thread" },
189 { TD_MALLOC
, "Malloc failed" },
190 { TD_PARTIALREG
, "Only part of register set was written/read" },
191 { TD_NOXREGS
, "X register set not available for given thread" }
193 const int td_err_size
= sizeof td_err_table
/ sizeof (struct string_map
);
197 for (i
= 0; i
< td_err_size
; i
++)
198 if (td_err_table
[i
].num
== errcode
)
199 return td_err_table
[i
].str
;
201 sprintf (buf
, "Unknown libthread_db error code: %d", errcode
);
206 /* Return the libthread_db state string assicoated with STATECODE.
207 If STATECODE is unknown, return an appropriate message. */
210 td_state_string (td_thr_state_e statecode
)
212 static struct string_map td_thr_state_table
[] =
214 { TD_THR_ANY_STATE
, "any state" },
215 { TD_THR_UNKNOWN
, "unknown" },
216 { TD_THR_STOPPED
, "stopped" },
217 { TD_THR_RUN
, "run" },
218 { TD_THR_ACTIVE
, "active" },
219 { TD_THR_ZOMBIE
, "zombie" },
220 { TD_THR_SLEEP
, "sleep" },
221 { TD_THR_STOPPED_ASLEEP
, "stopped asleep" }
223 const int td_thr_state_table_size
=
224 sizeof td_thr_state_table
/ sizeof (struct string_map
);
228 for (i
= 0; i
< td_thr_state_table_size
; i
++)
229 if (td_thr_state_table
[i
].num
== statecode
)
230 return td_thr_state_table
[i
].str
;
232 sprintf (buf
, "Unknown libthread_db state code: %d", statecode
);
238 /* Convert a POSIX or Solaris thread ID into a LWP ID. If THREAD_ID
239 doesn't exist, that's an error. If it's an inactive thread, return
242 NOTE: This function probably shouldn't call error(). */
245 thread_to_lwp (ptid_t thread_id
, int default_lwp
)
251 if (is_lwp (thread_id
))
252 return thread_id
; /* It's already an LWP ID. */
254 /* It's a thread. Convert to LWP. */
256 val
= p_td_ta_map_id2thr (main_ta
, GET_THREAD (thread_id
), &th
);
258 return pid_to_ptid (-1); /* Thread must have terminated. */
259 else if (val
!= TD_OK
)
260 error (_("thread_to_lwp: td_ta_map_id2thr %s"), td_err_string (val
));
262 val
= p_td_thr_get_info (&th
, &ti
);
264 return pid_to_ptid (-1); /* Thread must have terminated. */
265 else if (val
!= TD_OK
)
266 error (_("thread_to_lwp: td_thr_get_info: %s"), td_err_string (val
));
268 if (ti
.ti_state
!= TD_THR_ACTIVE
)
270 if (default_lwp
!= -1)
271 return pid_to_ptid (default_lwp
);
272 error (_("thread_to_lwp: thread state not active: %s"),
273 td_state_string (ti
.ti_state
));
276 return BUILD_LWP (ti
.ti_lid
, PIDGET (thread_id
));
279 /* Convert an LWP ID into a POSIX or Solaris thread ID. If LWP_ID
280 doesn't exists, that's an error.
282 NOTE: This function probably shouldn't call error(). */
285 lwp_to_thread (ptid_t lwp
)
292 return lwp
; /* It's already a thread ID. */
294 /* It's an LWP. Convert it to a thread ID. */
296 if (!target_thread_alive (lwp
))
297 return pid_to_ptid (-1); /* Must be a defunct LPW. */
299 val
= p_td_ta_map_lwp2thr (main_ta
, GET_LWP (lwp
), &th
);
301 return pid_to_ptid (-1); /* Thread must have terminated. */
302 else if (val
!= TD_OK
)
303 error (_("lwp_to_thread: td_ta_map_lwp2thr: %s."), td_err_string (val
));
305 val
= p_td_thr_validate (&th
);
307 return lwp
; /* Unknown to libthread; just return LPW, */
308 else if (val
!= TD_OK
)
309 error (_("lwp_to_thread: td_thr_validate: %s."), td_err_string (val
));
311 val
= p_td_thr_get_info (&th
, &ti
);
313 return pid_to_ptid (-1); /* Thread must have terminated. */
314 else if (val
!= TD_OK
)
315 error (_("lwp_to_thread: td_thr_get_info: %s."), td_err_string (val
));
317 return BUILD_THREAD (ti
.ti_tid
, PIDGET (lwp
));
321 /* Most target vector functions from here on actually just pass
322 through to the layer beneath, as they don't need to do anything
323 specific for threads. */
325 /* Take a program previously attached to and detaches it. The program
326 resumes execution and will no longer stop on signals, etc. We'd
327 better not have left any breakpoints in the program or it'll die
328 when it hits one. For this to work, it may be necessary for the
329 process to have been previously attached. It *might* work if the
330 program was started via the normal ptrace (PTRACE_TRACEME). */
333 sol_thread_detach (struct target_ops
*ops
, char *args
, int from_tty
)
335 struct target_ops
*beneath
= find_target_beneath (ops
);
337 sol_thread_active
= 0;
338 inferior_ptid
= pid_to_ptid (PIDGET (main_ph
.ptid
));
340 beneath
->to_detach (beneath
, args
, from_tty
);
343 /* Resume execution of process PTID. If STEP is nozero, then just
344 single step it. If SIGNAL is nonzero, restart it with that signal
345 activated. We may have to convert PTID from a thread ID to an LWP
349 sol_thread_resume (struct target_ops
*ops
,
350 ptid_t ptid
, int step
, enum target_signal signo
)
352 struct cleanup
*old_chain
;
353 struct target_ops
*beneath
= find_target_beneath (ops
);
355 old_chain
= save_inferior_ptid ();
357 inferior_ptid
= thread_to_lwp (inferior_ptid
, PIDGET (main_ph
.ptid
));
358 if (PIDGET (inferior_ptid
) == -1)
359 inferior_ptid
= procfs_first_available ();
361 if (PIDGET (ptid
) != -1)
363 ptid_t save_ptid
= ptid
;
365 ptid
= thread_to_lwp (ptid
, -2);
366 if (PIDGET (ptid
) == -2) /* Inactive thread. */
367 error (_("This version of Solaris can't start inactive threads."));
368 if (info_verbose
&& PIDGET (ptid
) == -1)
369 warning (_("Specified thread %ld seems to have terminated"),
370 GET_THREAD (save_ptid
));
373 beneath
->to_resume (beneath
, ptid
, step
, signo
);
375 do_cleanups (old_chain
);
378 /* Wait for any threads to stop. We may have to convert PTID from a
379 thread ID to an LWP ID, and vice versa on the way out. */
382 sol_thread_wait (struct target_ops
*ops
,
383 ptid_t ptid
, struct target_waitstatus
*ourstatus
, int options
)
387 struct target_ops
*beneath
= find_target_beneath (ops
);
388 struct cleanup
*old_chain
;
390 save_ptid
= inferior_ptid
;
391 old_chain
= save_inferior_ptid ();
393 inferior_ptid
= thread_to_lwp (inferior_ptid
, PIDGET (main_ph
.ptid
));
394 if (PIDGET (inferior_ptid
) == -1)
395 inferior_ptid
= procfs_first_available ();
397 if (PIDGET (ptid
) != -1)
399 ptid_t save_ptid
= ptid
;
401 ptid
= thread_to_lwp (ptid
, -2);
402 if (PIDGET (ptid
) == -2) /* Inactive thread. */
403 error (_("This version of Solaris can't start inactive threads."));
404 if (info_verbose
&& PIDGET (ptid
) == -1)
405 warning (_("Specified thread %ld seems to have terminated"),
406 GET_THREAD (save_ptid
));
409 rtnval
= beneath
->to_wait (beneath
, ptid
, ourstatus
, options
);
411 if (ourstatus
->kind
!= TARGET_WAITKIND_EXITED
)
413 /* Map the LWP of interest back to the appropriate thread ID. */
414 rtnval
= lwp_to_thread (rtnval
);
415 if (PIDGET (rtnval
) == -1)
418 /* See if we have a new thread. */
419 if (is_thread (rtnval
)
420 && !ptid_equal (rtnval
, save_ptid
)
421 && (!in_thread_list (rtnval
)
422 || is_exited (rtnval
)))
426 /* During process initialization, we may get here without the thread
427 package being initialized, since that can only happen after we've
428 found the shared libs. */
430 do_cleanups (old_chain
);
436 sol_thread_fetch_registers (struct target_ops
*ops
,
437 struct regcache
*regcache
, int regnum
)
440 td_thrhandle_t thandle
;
443 prfpregset_t fpregset
;
444 gdb_gregset_t
*gregset_p
= &gregset
;
445 gdb_fpregset_t
*fpregset_p
= &fpregset
;
446 struct target_ops
*beneath
= find_target_beneath (ops
);
453 if (!is_thread (inferior_ptid
))
455 /* It's an LWP; pass the request on to the layer beneath. */
456 beneath
->to_fetch_registers (beneath
, regcache
, regnum
);
460 /* Solaris thread: convert INFERIOR_PTID into a td_thrhandle_t. */
461 thread
= GET_THREAD (inferior_ptid
);
463 error (_("sol_thread_fetch_registers: thread == 0"));
465 val
= p_td_ta_map_id2thr (main_ta
, thread
, &thandle
);
467 error (_("sol_thread_fetch_registers: td_ta_map_id2thr: %s"),
468 td_err_string (val
));
470 /* Get the general-purpose registers. */
472 val
= p_td_thr_getgregs (&thandle
, gregset
);
473 if (val
!= TD_OK
&& val
!= TD_PARTIALREG
)
474 error (_("sol_thread_fetch_registers: td_thr_getgregs %s"),
475 td_err_string (val
));
477 /* For SPARC, TD_PARTIALREG means that only %i0...%i7, %l0..%l7, %pc
478 and %sp are saved (by a thread context switch). */
480 /* And, now the floating-point registers. */
482 val
= p_td_thr_getfpregs (&thandle
, &fpregset
);
483 if (val
!= TD_OK
&& val
!= TD_NOFPREGS
)
484 error (_("sol_thread_fetch_registers: td_thr_getfpregs %s"),
485 td_err_string (val
));
487 /* Note that we must call supply_gregset and supply_fpregset *after*
488 calling the td routines because the td routines call ps_lget*
489 which affect the values stored in the registers array. */
491 supply_gregset (regcache
, (const gdb_gregset_t
*) gregset_p
);
492 supply_fpregset (regcache
, (const gdb_fpregset_t
*) fpregset_p
);
495 /* FIXME: libthread_db doesn't seem to handle this right. */
496 val
= td_thr_getxregsize (&thandle
, &xregsize
);
497 if (val
!= TD_OK
&& val
!= TD_NOXREGS
)
498 error (_("sol_thread_fetch_registers: td_thr_getxregsize %s"),
499 td_err_string (val
));
503 xregset
= alloca (xregsize
);
504 val
= td_thr_getxregs (&thandle
, xregset
);
506 error (_("sol_thread_fetch_registers: td_thr_getxregs %s"),
507 td_err_string (val
));
513 sol_thread_store_registers (struct target_ops
*ops
,
514 struct regcache
*regcache
, int regnum
)
517 td_thrhandle_t thandle
;
520 prfpregset_t fpregset
;
526 if (!is_thread (inferior_ptid
))
528 struct target_ops
*beneath
= find_target_beneath (ops
);
530 /* It's an LWP; pass the request on to the layer beneath. */
531 beneath
->to_store_registers (beneath
, regcache
, regnum
);
535 /* Solaris thread: convert INFERIOR_PTID into a td_thrhandle_t. */
536 thread
= GET_THREAD (inferior_ptid
);
538 val
= p_td_ta_map_id2thr (main_ta
, thread
, &thandle
);
540 error (_("sol_thread_store_registers: td_ta_map_id2thr %s"),
541 td_err_string (val
));
545 /* Not writing all the registers. */
546 char old_value
[MAX_REGISTER_SIZE
];
548 /* Save new register value. */
549 regcache_raw_collect (regcache
, regnum
, old_value
);
551 val
= p_td_thr_getgregs (&thandle
, gregset
);
553 error (_("sol_thread_store_registers: td_thr_getgregs %s"),
554 td_err_string (val
));
555 val
= p_td_thr_getfpregs (&thandle
, &fpregset
);
557 error (_("sol_thread_store_registers: td_thr_getfpregs %s"),
558 td_err_string (val
));
560 /* Restore new register value. */
561 regcache_raw_supply (regcache
, regnum
, old_value
);
564 /* FIXME: libthread_db doesn't seem to handle this right. */
565 val
= td_thr_getxregsize (&thandle
, &xregsize
);
566 if (val
!= TD_OK
&& val
!= TD_NOXREGS
)
567 error (_("sol_thread_store_registers: td_thr_getxregsize %s"),
568 td_err_string (val
));
572 xregset
= alloca (xregsize
);
573 val
= td_thr_getxregs (&thandle
, xregset
);
575 error (_("sol_thread_store_registers: td_thr_getxregs %s"),
576 td_err_string (val
));
581 fill_gregset (regcache
, (gdb_gregset_t
*) &gregset
, regnum
);
582 fill_fpregset (regcache
, (gdb_fpregset_t
*) &fpregset
, regnum
);
584 val
= p_td_thr_setgregs (&thandle
, gregset
);
586 error (_("sol_thread_store_registers: td_thr_setgregs %s"),
587 td_err_string (val
));
588 val
= p_td_thr_setfpregs (&thandle
, &fpregset
);
590 error (_("sol_thread_store_registers: td_thr_setfpregs %s"),
591 td_err_string (val
));
594 /* FIXME: libthread_db doesn't seem to handle this right. */
595 val
= td_thr_getxregsize (&thandle
, &xregsize
);
596 if (val
!= TD_OK
&& val
!= TD_NOXREGS
)
597 error (_("sol_thread_store_registers: td_thr_getxregsize %s"),
598 td_err_string (val
));
600 /* ??? Should probably do something about writing the xregs here,
601 but what are they? */
605 /* Perform partial transfers on OBJECT. See target_read_partial and
606 target_write_partial for details of each variant. One, and only
607 one, of readbuf or writebuf must be non-NULL. */
610 sol_thread_xfer_partial (struct target_ops
*ops
, enum target_object object
,
611 const char *annex
, gdb_byte
*readbuf
,
612 const gdb_byte
*writebuf
,
613 ULONGEST offset
, LONGEST len
)
616 struct cleanup
*old_chain
;
617 struct target_ops
*beneath
= find_target_beneath (ops
);
619 old_chain
= save_inferior_ptid ();
621 if (is_thread (inferior_ptid
) || !target_thread_alive (inferior_ptid
))
623 /* It's either a thread or an LWP that isn't alive. Any live
624 LWP will do so use the first available.
626 NOTE: We don't need to call switch_to_thread; we're just
628 inferior_ptid
= procfs_first_available ();
631 retval
= beneath
->to_xfer_partial (beneath
, object
, annex
,
632 readbuf
, writebuf
, offset
, len
);
634 do_cleanups (old_chain
);
640 check_for_thread_db (void)
645 /* Do nothing if we couldn't load libthread_db.so.1. */
646 if (p_td_ta_new
== NULL
)
649 if (sol_thread_active
)
650 /* Nothing to do. The thread library was already detected and the
651 target vector was already activated. */
654 /* Now, initialize libthread_db. This needs to be done after the
655 shared libraries are located because it needs information from
656 the user's thread library. */
661 warning (_("sol_thread_new_objfile: td_init: %s"), td_err_string (err
));
665 /* Now attempt to open a connection to the thread library. */
666 err
= p_td_ta_new (&main_ph
, &main_ta
);
670 /* No thread library was detected. */
674 printf_unfiltered (_("[Thread debugging using libthread_db enabled]\n"));
676 /* The thread library was detected. Activate the sol_thread target. */
677 push_target (&sol_thread_ops
);
678 sol_thread_active
= 1;
680 main_ph
.ptid
= inferior_ptid
; /* Save for xfer_memory. */
681 ptid
= lwp_to_thread (inferior_ptid
);
682 if (PIDGET (ptid
) != -1)
683 inferior_ptid
= ptid
;
685 target_find_new_threads ();
689 warning (_("Cannot initialize thread debugging library: %s"),
690 td_err_string (err
));
695 /* This routine is called whenever a new symbol table is read in, or
696 when all symbol tables are removed. libthread_db can only be
697 initialized when it finds the right variables in libthread.so.
698 Since it's a shared library, those variables don't show up until
699 the library gets mapped and the symbol table is read in. */
702 sol_thread_new_objfile (struct objfile
*objfile
)
705 check_for_thread_db ();
708 /* Clean up after the inferior dies. */
711 sol_thread_mourn_inferior (struct target_ops
*ops
)
713 struct target_ops
*beneath
= find_target_beneath (ops
);
715 sol_thread_active
= 0;
719 beneath
->to_mourn_inferior (beneath
);
722 /* Return true if PTID is still active in the inferior. */
725 sol_thread_alive (struct target_ops
*ops
, ptid_t ptid
)
727 if (is_thread (ptid
))
729 /* It's a (user-level) thread. */
734 pid
= GET_THREAD (ptid
);
735 if ((val
= p_td_ta_map_id2thr (main_ta
, pid
, &th
)) != TD_OK
)
736 return 0; /* Thread not found. */
737 if ((val
= p_td_thr_validate (&th
)) != TD_OK
)
738 return 0; /* Thread not valid. */
739 return 1; /* Known thread. */
743 struct target_ops
*beneath
= find_target_beneath (ops
);
745 /* It's an LPW; pass the request on to the layer below. */
746 return beneath
->to_thread_alive (beneath
, ptid
);
751 /* These routines implement the lower half of the thread_db interface,
752 i.e. the ps_* routines. */
754 /* Various versions of <proc_service.h> have slightly different
755 function prototypes. In particular, we have
758 struct ps_prochandle * const struct ps_prochandle *
763 Which one you have depends on the Solaris version and what patches
764 you've applied. On the theory that there are only two major
765 variants, we have configure check the prototype of ps_pdwrite (),
766 and use that info to make appropriate typedefs here. */
768 #ifdef PROC_SERVICE_IS_OLD
769 typedef const struct ps_prochandle
*gdb_ps_prochandle_t
;
770 typedef char *gdb_ps_read_buf_t
;
771 typedef char *gdb_ps_write_buf_t
;
772 typedef int gdb_ps_size_t
;
773 typedef psaddr_t gdb_ps_addr_t
;
775 typedef struct ps_prochandle
*gdb_ps_prochandle_t
;
776 typedef void *gdb_ps_read_buf_t
;
777 typedef const void *gdb_ps_write_buf_t
;
778 typedef size_t gdb_ps_size_t
;
779 typedef psaddr_t gdb_ps_addr_t
;
782 /* The next four routines are called by libthread_db to tell us to
783 stop and stop a particular process or lwp. Since GDB ensures that
784 these are all stopped by the time we call anything in thread_db,
785 these routines need to do nothing. */
790 ps_pstop (gdb_ps_prochandle_t ph
)
795 /* Process continue. */
798 ps_pcontinue (gdb_ps_prochandle_t ph
)
806 ps_lstop (gdb_ps_prochandle_t ph
, lwpid_t lwpid
)
814 ps_lcontinue (gdb_ps_prochandle_t ph
, lwpid_t lwpid
)
819 /* Looks up the symbol LD_SYMBOL_NAME in the debugger's symbol table. */
822 ps_pglobal_lookup (gdb_ps_prochandle_t ph
, const char *ld_object_name
,
823 const char *ld_symbol_name
, gdb_ps_addr_t
*ld_symbol_addr
)
825 struct minimal_symbol
*ms
;
827 ms
= lookup_minimal_symbol (ld_symbol_name
, NULL
, NULL
);
831 *ld_symbol_addr
= SYMBOL_VALUE_ADDRESS (ms
);
835 /* Common routine for reading and writing memory. */
838 rw_common (int dowrite
, const struct ps_prochandle
*ph
, gdb_ps_addr_t addr
,
842 struct cleanup
*old_chain
;
844 old_chain
= save_inferior_ptid ();
846 if (is_thread (inferior_ptid
) || !target_thread_alive (inferior_ptid
))
848 /* It's either a thread or an LWP that isn't alive. Any live
849 LWP will do so use the first available.
851 NOTE: We don't need to call switch_to_thread; we're just
853 inferior_ptid
= procfs_first_available ();
856 #if defined (__sparcv9)
857 /* For Sparc64 cross Sparc32, make sure the address has not been
858 accidentally sign-extended (or whatever) to beyond 32 bits. */
859 if (bfd_get_arch_size (exec_bfd
) == 32)
864 ret
= target_write_memory (addr
, buf
, size
);
866 ret
= target_read_memory (addr
, buf
, size
);
868 do_cleanups (old_chain
);
870 return (ret
== 0 ? PS_OK
: PS_ERR
);
873 /* Copies SIZE bytes from target process .data segment to debugger memory. */
876 ps_pdread (gdb_ps_prochandle_t ph
, gdb_ps_addr_t addr
,
877 gdb_ps_read_buf_t buf
, gdb_ps_size_t size
)
879 return rw_common (0, ph
, addr
, buf
, size
);
882 /* Copies SIZE bytes from debugger memory .data segment to target process. */
885 ps_pdwrite (gdb_ps_prochandle_t ph
, gdb_ps_addr_t addr
,
886 gdb_ps_write_buf_t buf
, gdb_ps_size_t size
)
888 return rw_common (1, ph
, addr
, (char *) buf
, size
);
891 /* Copies SIZE bytes from target process .text segment to debugger memory. */
894 ps_ptread (gdb_ps_prochandle_t ph
, gdb_ps_addr_t addr
,
895 gdb_ps_read_buf_t buf
, gdb_ps_size_t size
)
897 return rw_common (0, ph
, addr
, buf
, size
);
900 /* Copies SIZE bytes from debugger memory .text segment to target process. */
903 ps_ptwrite (gdb_ps_prochandle_t ph
, gdb_ps_addr_t addr
,
904 gdb_ps_write_buf_t buf
, gdb_ps_size_t size
)
906 return rw_common (1, ph
, addr
, (char *) buf
, size
);
909 /* Get general-purpose registers for LWP. */
912 ps_lgetregs (gdb_ps_prochandle_t ph
, lwpid_t lwpid
, prgregset_t gregset
)
914 struct cleanup
*old_chain
;
915 struct regcache
*regcache
;
917 old_chain
= save_inferior_ptid ();
919 inferior_ptid
= BUILD_LWP (lwpid
, PIDGET (inferior_ptid
));
920 regcache
= get_thread_arch_regcache (inferior_ptid
, target_gdbarch
);
922 target_fetch_registers (regcache
, -1);
923 fill_gregset (regcache
, (gdb_gregset_t
*) gregset
, -1);
925 do_cleanups (old_chain
);
930 /* Set general-purpose registers for LWP. */
933 ps_lsetregs (gdb_ps_prochandle_t ph
, lwpid_t lwpid
,
934 const prgregset_t gregset
)
936 struct cleanup
*old_chain
;
937 struct regcache
*regcache
;
939 old_chain
= save_inferior_ptid ();
941 inferior_ptid
= BUILD_LWP (lwpid
, PIDGET (inferior_ptid
));
942 regcache
= get_thread_arch_regcache (inferior_ptid
, target_gdbarch
);
944 supply_gregset (regcache
, (const gdb_gregset_t
*) gregset
);
945 target_store_registers (regcache
, -1);
947 do_cleanups (old_chain
);
952 /* Log a message (sends to gdb_stderr). */
955 ps_plog (const char *fmt
, ...)
959 va_start (args
, fmt
);
961 vfprintf_filtered (gdb_stderr
, fmt
, args
);
964 /* Get size of extra register set. Currently a noop. */
967 ps_lgetxregsize (gdb_ps_prochandle_t ph
, lwpid_t lwpid
, int *xregsize
)
974 val
= get_lwp_fd (ph
, lwpid
, &lwp_fd
);
978 if (ioctl (lwp_fd
, PIOCGXREGSIZE
, ®size
))
981 return PS_NOFREGS
; /* XXX Wrong code, but this is the closest
982 thing in proc_service.h */
984 print_sys_errmsg ("ps_lgetxregsize (): PIOCGXREGSIZE", errno
);
992 /* Get extra register set. Currently a noop. */
995 ps_lgetxregs (gdb_ps_prochandle_t ph
, lwpid_t lwpid
, caddr_t xregset
)
1001 val
= get_lwp_fd (ph
, lwpid
, &lwp_fd
);
1005 if (ioctl (lwp_fd
, PIOCGXREG
, xregset
))
1007 print_sys_errmsg ("ps_lgetxregs (): PIOCGXREG", errno
);
1015 /* Set extra register set. Currently a noop. */
1018 ps_lsetxregs (gdb_ps_prochandle_t ph
, lwpid_t lwpid
, caddr_t xregset
)
1024 val
= get_lwp_fd (ph
, lwpid
, &lwp_fd
);
1028 if (ioctl (lwp_fd
, PIOCSXREG
, xregset
))
1030 print_sys_errmsg ("ps_lsetxregs (): PIOCSXREG", errno
);
1038 /* Get floating-point registers for LWP. */
1041 ps_lgetfpregs (gdb_ps_prochandle_t ph
, lwpid_t lwpid
,
1042 prfpregset_t
*fpregset
)
1044 struct cleanup
*old_chain
;
1045 struct regcache
*regcache
;
1047 old_chain
= save_inferior_ptid ();
1049 inferior_ptid
= BUILD_LWP (lwpid
, PIDGET (inferior_ptid
));
1050 regcache
= get_thread_arch_regcache (inferior_ptid
, target_gdbarch
);
1052 target_fetch_registers (regcache
, -1);
1053 fill_fpregset (regcache
, (gdb_fpregset_t
*) fpregset
, -1);
1055 do_cleanups (old_chain
);
1060 /* Set floating-point regs for LWP. */
1063 ps_lsetfpregs (gdb_ps_prochandle_t ph
, lwpid_t lwpid
,
1064 const prfpregset_t
* fpregset
)
1066 struct cleanup
*old_chain
;
1067 struct regcache
*regcache
;
1069 old_chain
= save_inferior_ptid ();
1071 inferior_ptid
= BUILD_LWP (lwpid
, PIDGET (inferior_ptid
));
1072 regcache
= get_thread_arch_regcache (inferior_ptid
, target_gdbarch
);
1074 supply_fpregset (regcache
, (const gdb_fpregset_t
*) fpregset
);
1075 target_store_registers (regcache
, -1);
1077 do_cleanups (old_chain
);
1082 #ifdef PR_MODEL_LP64
1083 /* Identify process as 32-bit or 64-bit. At the moment we're using
1084 BFD to do this. There might be a more Solaris-specific
1085 (e.g. procfs) method, but this ought to work. */
1088 ps_pdmodel (gdb_ps_prochandle_t ph
, int *data_model
)
1091 *data_model
= PR_MODEL_UNKNOWN
;
1092 else if (bfd_get_arch_size (exec_bfd
) == 32)
1093 *data_model
= PR_MODEL_ILP32
;
1095 *data_model
= PR_MODEL_LP64
;
1099 #endif /* PR_MODEL_LP64 */
1101 #if (defined(__i386__) || defined(__x86_64__)) && defined (sun)
1103 /* Reads the local descriptor table of a LWP.
1105 This function is necessary on x86-solaris only. Without it, the loading
1106 of libthread_db would fail because of ps_lgetLDT being undefined. */
1109 ps_lgetLDT (gdb_ps_prochandle_t ph
, lwpid_t lwpid
,
1112 /* NOTE: only used on Solaris, therefore OK to refer to procfs.c. */
1113 extern struct ssd
*procfs_find_LDT_entry (ptid_t
);
1116 /* FIXME: can't I get the process ID from the prochandle or
1119 if (PIDGET (inferior_ptid
) <= 0 || lwpid
<= 0)
1122 ret
= procfs_find_LDT_entry (BUILD_LWP (lwpid
, PIDGET (inferior_ptid
)));
1125 memcpy (pldt
, ret
, sizeof (struct ssd
));
1129 /* LDT not found. */
1135 /* Convert PTID to printable form. */
1138 solaris_pid_to_str (struct target_ops
*ops
, ptid_t ptid
)
1140 static char buf
[100];
1142 if (is_thread (ptid
))
1146 lwp
= thread_to_lwp (ptid
, -2);
1148 if (PIDGET (lwp
) == -1)
1149 sprintf (buf
, "Thread %ld (defunct)", GET_THREAD (ptid
));
1150 else if (PIDGET (lwp
) != -2)
1151 sprintf (buf
, "Thread %ld (LWP %ld)",
1152 GET_THREAD (ptid
), GET_LWP (lwp
));
1154 sprintf (buf
, "Thread %ld ", GET_THREAD (ptid
));
1156 else if (GET_LWP (ptid
) != 0)
1157 sprintf (buf
, "LWP %ld ", GET_LWP (ptid
));
1159 sprintf (buf
, "process %d ", PIDGET (ptid
));
1165 /* Worker bee for find_new_threads. Callback function that gets
1166 called once per user-level thread (i.e. not for LWP's). */
1169 sol_find_new_threads_callback (const td_thrhandle_t
*th
, void *ignored
)
1175 retval
= p_td_thr_get_info (th
, &ti
);
1176 if (retval
!= TD_OK
)
1179 ptid
= BUILD_THREAD (ti
.ti_tid
, PIDGET (inferior_ptid
));
1180 if (!in_thread_list (ptid
) || is_exited (ptid
))
1187 sol_find_new_threads (struct target_ops
*ops
)
1189 struct target_ops
*beneath
= find_target_beneath (ops
);
1191 /* First Find any new LWP's. */
1192 if (beneath
->to_find_new_threads
!= NULL
)
1193 beneath
->to_find_new_threads (beneath
);
1195 /* Then find any new user-level threads. */
1196 p_td_ta_thr_iter (main_ta
, sol_find_new_threads_callback
, (void *) 0,
1197 TD_THR_ANY_STATE
, TD_THR_LOWEST_PRIORITY
,
1198 TD_SIGNO_MASK
, TD_THR_ANY_USER_FLAGS
);
1201 /* Worker bee for the "info sol-thread" command. This is a callback
1202 function that gets called once for each Solaris user-level thread
1203 (i.e. not for LWPs) in the inferior. Print anything interesting
1204 that we can think of. */
1207 info_cb (const td_thrhandle_t
*th
, void *s
)
1212 ret
= p_td_thr_get_info (th
, &ti
);
1215 printf_filtered ("%s thread #%d, lwp %d, ",
1216 ti
.ti_type
== TD_THR_SYSTEM
? "system" : "user ",
1217 ti
.ti_tid
, ti
.ti_lid
);
1218 switch (ti
.ti_state
)
1221 case TD_THR_UNKNOWN
:
1222 printf_filtered ("<unknown state>");
1224 case TD_THR_STOPPED
:
1225 printf_filtered ("(stopped)");
1228 printf_filtered ("(run) ");
1231 printf_filtered ("(active) ");
1234 printf_filtered ("(zombie) ");
1237 printf_filtered ("(asleep) ");
1239 case TD_THR_STOPPED_ASLEEP
:
1240 printf_filtered ("(stopped asleep)");
1243 /* Print thr_create start function. */
1244 if (ti
.ti_startfunc
!= 0)
1246 struct minimal_symbol
*msym
;
1247 msym
= lookup_minimal_symbol_by_pc (ti
.ti_startfunc
);
1249 printf_filtered (" startfunc: %s\n",
1250 SYMBOL_PRINT_NAME (msym
));
1252 printf_filtered (" startfunc: %s\n",
1253 paddress (target_gdbarch
, ti
.ti_startfunc
));
1256 /* If thread is asleep, print function that went to sleep. */
1257 if (ti
.ti_state
== TD_THR_SLEEP
)
1259 struct minimal_symbol
*msym
;
1260 msym
= lookup_minimal_symbol_by_pc (ti
.ti_pc
);
1262 printf_filtered (" - Sleep func: %s\n",
1263 SYMBOL_PRINT_NAME (msym
));
1265 printf_filtered (" - Sleep func: %s\n",
1266 paddress (target_gdbarch
, ti
.ti_startfunc
));
1269 /* Wrap up line, if necessary. */
1270 if (ti
.ti_state
!= TD_THR_SLEEP
&& ti
.ti_startfunc
== 0)
1271 printf_filtered ("\n"); /* don't you hate counting newlines? */
1274 warning (_("info sol-thread: failed to get info for thread."));
1279 /* List some state about each Solaris user-level thread in the
1283 info_solthreads (char *args
, int from_tty
)
1285 p_td_ta_thr_iter (main_ta
, info_cb
, args
,
1286 TD_THR_ANY_STATE
, TD_THR_LOWEST_PRIORITY
,
1287 TD_SIGNO_MASK
, TD_THR_ANY_USER_FLAGS
);
1290 /* Callback routine used to find a thread based on the TID part of
1294 thread_db_find_thread_from_tid (struct thread_info
*thread
, void *data
)
1296 long *tid
= (long *) data
;
1298 if (ptid_get_tid (thread
->ptid
) == *tid
)
1305 sol_get_ada_task_ptid (long lwp
, long thread
)
1307 struct thread_info
*thread_info
=
1308 iterate_over_threads (thread_db_find_thread_from_tid
, &thread
);
1310 if (thread_info
== NULL
)
1312 /* The list of threads is probably not up to date. Find any
1313 thread that is missing from the list, and try again. */
1314 sol_find_new_threads (¤t_target
);
1315 thread_info
= iterate_over_threads (thread_db_find_thread_from_tid
,
1319 gdb_assert (thread_info
!= NULL
);
1321 return (thread_info
->ptid
);
1325 init_sol_thread_ops (void)
1327 sol_thread_ops
.to_shortname
= "solaris-threads";
1328 sol_thread_ops
.to_longname
= "Solaris threads and pthread.";
1329 sol_thread_ops
.to_doc
= "Solaris threads and pthread support.";
1330 sol_thread_ops
.to_detach
= sol_thread_detach
;
1331 sol_thread_ops
.to_resume
= sol_thread_resume
;
1332 sol_thread_ops
.to_wait
= sol_thread_wait
;
1333 sol_thread_ops
.to_fetch_registers
= sol_thread_fetch_registers
;
1334 sol_thread_ops
.to_store_registers
= sol_thread_store_registers
;
1335 sol_thread_ops
.to_xfer_partial
= sol_thread_xfer_partial
;
1336 sol_thread_ops
.to_mourn_inferior
= sol_thread_mourn_inferior
;
1337 sol_thread_ops
.to_thread_alive
= sol_thread_alive
;
1338 sol_thread_ops
.to_pid_to_str
= solaris_pid_to_str
;
1339 sol_thread_ops
.to_find_new_threads
= sol_find_new_threads
;
1340 sol_thread_ops
.to_stratum
= thread_stratum
;
1341 sol_thread_ops
.to_get_ada_task_ptid
= sol_get_ada_task_ptid
;
1342 sol_thread_ops
.to_magic
= OPS_MAGIC
;
1346 _initialize_sol_thread (void)
1350 init_sol_thread_ops ();
1352 dlhandle
= dlopen ("libthread_db.so.1", RTLD_NOW
);
1356 #define resolve(X) \
1357 if (!(p_##X = dlsym (dlhandle, #X))) \
1361 resolve (td_ta_new
);
1362 resolve (td_ta_delete
);
1364 resolve (td_ta_get_ph
);
1365 resolve (td_ta_get_nthreads
);
1366 resolve (td_ta_tsd_iter
);
1367 resolve (td_ta_thr_iter
);
1368 resolve (td_thr_validate
);
1369 resolve (td_thr_tsd
);
1370 resolve (td_thr_get_info
);
1371 resolve (td_thr_getfpregs
);
1372 resolve (td_thr_getxregsize
);
1373 resolve (td_thr_getxregs
);
1374 resolve (td_thr_sigsetmask
);
1375 resolve (td_thr_setprio
);
1376 resolve (td_thr_setsigpending
);
1377 resolve (td_thr_setfpregs
);
1378 resolve (td_thr_setxregs
);
1379 resolve (td_ta_map_id2thr
);
1380 resolve (td_ta_map_lwp2thr
);
1381 resolve (td_thr_getgregs
);
1382 resolve (td_thr_setgregs
);
1384 add_target (&sol_thread_ops
);
1386 add_cmd ("sol-threads", class_maintenance
, info_solthreads
,
1387 _("Show info on Solaris user threads."), &maintenanceinfolist
);
1389 /* Hook into new_objfile notification. */
1390 observer_attach_new_objfile (sol_thread_new_objfile
);
1394 fprintf_unfiltered (gdb_stderr
, "\
1395 [GDB will not be able to debug user-mode threads: %s]\n", dlerror ());