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 /* Prototypes for supply_gregset etc. */
75 /* This struct is defined by us, but mainly used for the proc_service
76 interface. We don't have much use for it, except as a handy place
77 to get a real PID for memory accesses. */
90 static struct ps_prochandle main_ph
;
91 static td_thragent_t
*main_ta
;
92 static int sol_thread_active
= 0;
94 static void init_sol_thread_ops (void);
96 /* Default definitions: These must be defined in tm.h if they are to
97 be shared with a process module such as procfs. */
99 #define GET_PID(ptid) ptid_get_pid (ptid)
100 #define GET_LWP(ptid) ptid_get_lwp (ptid)
101 #define GET_THREAD(ptid) ptid_get_tid (ptid)
103 #define is_lwp(ptid) (GET_LWP (ptid) != 0)
104 #define is_thread(ptid) (GET_THREAD (ptid) != 0)
106 #define BUILD_LWP(lwp, pid) ptid_build (pid, lwp, 0)
107 #define BUILD_THREAD(tid, pid) ptid_build (pid, 0, tid)
109 /* Pointers to routines from libthread_db resolved by dlopen(). */
111 static void (*p_td_log
)(const int on_off
);
112 static td_err_e (*p_td_ta_new
)(const struct ps_prochandle
*ph_p
,
113 td_thragent_t
**ta_pp
);
114 static td_err_e (*p_td_ta_delete
)(td_thragent_t
*ta_p
);
115 static td_err_e (*p_td_init
)(void);
116 static td_err_e (*p_td_ta_get_ph
)(const td_thragent_t
*ta_p
,
117 struct ps_prochandle
**ph_pp
);
118 static td_err_e (*p_td_ta_get_nthreads
)(const td_thragent_t
*ta_p
,
120 static td_err_e (*p_td_ta_tsd_iter
)(const td_thragent_t
*ta_p
,
121 td_key_iter_f
*cb
, void *cbdata_p
);
122 static td_err_e (*p_td_ta_thr_iter
)(const td_thragent_t
*ta_p
,
123 td_thr_iter_f
*cb
, void *cbdata_p
,
124 td_thr_state_e state
, int ti_pri
,
125 sigset_t
*ti_sigmask_p
,
126 unsigned ti_user_flags
);
127 static td_err_e (*p_td_thr_validate
)(const td_thrhandle_t
*th_p
);
128 static td_err_e (*p_td_thr_tsd
)(const td_thrhandle_t
* th_p
,
129 const thread_key_t key
, void **data_pp
);
130 static td_err_e (*p_td_thr_get_info
)(const td_thrhandle_t
*th_p
,
132 static td_err_e (*p_td_thr_getfpregs
)(const td_thrhandle_t
*th_p
,
133 prfpregset_t
*fpregset
);
134 static td_err_e (*p_td_thr_getxregsize
)(const td_thrhandle_t
*th_p
,
136 static td_err_e (*p_td_thr_getxregs
)(const td_thrhandle_t
*th_p
,
137 const caddr_t xregset
);
138 static td_err_e (*p_td_thr_sigsetmask
)(const td_thrhandle_t
*th_p
,
139 const sigset_t ti_sigmask
);
140 static td_err_e (*p_td_thr_setprio
)(const td_thrhandle_t
*th_p
,
142 static td_err_e (*p_td_thr_setsigpending
)(const td_thrhandle_t
*th_p
,
143 const uchar_t ti_pending_flag
,
144 const sigset_t ti_pending
);
145 static td_err_e (*p_td_thr_setfpregs
)(const td_thrhandle_t
*th_p
,
146 const prfpregset_t
*fpregset
);
147 static td_err_e (*p_td_thr_setxregs
)(const td_thrhandle_t
*th_p
,
148 const caddr_t xregset
);
149 static td_err_e (*p_td_ta_map_id2thr
)(const td_thragent_t
*ta_p
,
151 td_thrhandle_t
*th_p
);
152 static td_err_e (*p_td_ta_map_lwp2thr
)(const td_thragent_t
*ta_p
,
154 td_thrhandle_t
*th_p
);
155 static td_err_e (*p_td_thr_getgregs
)(const td_thrhandle_t
*th_p
,
157 static td_err_e (*p_td_thr_setgregs
)(const td_thrhandle_t
*th_p
,
158 const prgregset_t regset
);
161 /* Return the libthread_db error string associated with ERRCODE. If
162 ERRCODE is unknown, return an appropriate message. */
165 td_err_string (td_err_e errcode
)
167 static struct string_map td_err_table
[] =
169 { TD_OK
, "generic \"call succeeded\"" },
170 { TD_ERR
, "generic error." },
171 { TD_NOTHR
, "no thread can be found to satisfy query" },
172 { TD_NOSV
, "no synch. variable can be found to satisfy query" },
173 { TD_NOLWP
, "no lwp can be found to satisfy query" },
174 { TD_BADPH
, "invalid process handle" },
175 { TD_BADTH
, "invalid thread handle" },
176 { TD_BADSH
, "invalid synchronization handle" },
177 { TD_BADTA
, "invalid thread agent" },
178 { TD_BADKEY
, "invalid key" },
179 { TD_NOMSG
, "td_thr_event_getmsg() called when there was no message" },
180 { TD_NOFPREGS
, "FPU register set not available for given thread" },
181 { TD_NOLIBTHREAD
, "application not linked with libthread" },
182 { TD_NOEVENT
, "requested event is not supported" },
183 { TD_NOCAPAB
, "capability not available" },
184 { TD_DBERR
, "Debugger service failed" },
185 { TD_NOAPLIC
, "Operation not applicable to" },
186 { TD_NOTSD
, "No thread specific data for this thread" },
187 { TD_MALLOC
, "Malloc failed" },
188 { TD_PARTIALREG
, "Only part of register set was written/read" },
189 { TD_NOXREGS
, "X register set not available for given thread" }
191 const int td_err_size
= sizeof td_err_table
/ sizeof (struct string_map
);
195 for (i
= 0; i
< td_err_size
; i
++)
196 if (td_err_table
[i
].num
== errcode
)
197 return td_err_table
[i
].str
;
199 sprintf (buf
, "Unknown libthread_db error code: %d", errcode
);
204 /* Return the libthread_db state string assicoated with STATECODE.
205 If STATECODE is unknown, return an appropriate message. */
208 td_state_string (td_thr_state_e statecode
)
210 static struct string_map td_thr_state_table
[] =
212 { TD_THR_ANY_STATE
, "any state" },
213 { TD_THR_UNKNOWN
, "unknown" },
214 { TD_THR_STOPPED
, "stopped" },
215 { TD_THR_RUN
, "run" },
216 { TD_THR_ACTIVE
, "active" },
217 { TD_THR_ZOMBIE
, "zombie" },
218 { TD_THR_SLEEP
, "sleep" },
219 { TD_THR_STOPPED_ASLEEP
, "stopped asleep" }
221 const int td_thr_state_table_size
=
222 sizeof td_thr_state_table
/ sizeof (struct string_map
);
226 for (i
= 0; i
< td_thr_state_table_size
; i
++)
227 if (td_thr_state_table
[i
].num
== statecode
)
228 return td_thr_state_table
[i
].str
;
230 sprintf (buf
, "Unknown libthread_db state code: %d", statecode
);
236 /* Convert a POSIX or Solaris thread ID into a LWP ID. If THREAD_ID
237 doesn't exist, that's an error. If it's an inactive thread, return
240 NOTE: This function probably shouldn't call error(). */
243 thread_to_lwp (ptid_t thread_id
, int default_lwp
)
249 if (is_lwp (thread_id
))
250 return thread_id
; /* It's already an LWP ID. */
252 /* It's a thread. Convert to LWP. */
254 val
= p_td_ta_map_id2thr (main_ta
, GET_THREAD (thread_id
), &th
);
256 return pid_to_ptid (-1); /* Thread must have terminated. */
257 else if (val
!= TD_OK
)
258 error (_("thread_to_lwp: td_ta_map_id2thr %s"), td_err_string (val
));
260 val
= p_td_thr_get_info (&th
, &ti
);
262 return pid_to_ptid (-1); /* Thread must have terminated. */
263 else if (val
!= TD_OK
)
264 error (_("thread_to_lwp: td_thr_get_info: %s"), td_err_string (val
));
266 if (ti
.ti_state
!= TD_THR_ACTIVE
)
268 if (default_lwp
!= -1)
269 return pid_to_ptid (default_lwp
);
270 error (_("thread_to_lwp: thread state not active: %s"),
271 td_state_string (ti
.ti_state
));
274 return BUILD_LWP (ti
.ti_lid
, PIDGET (thread_id
));
277 /* Convert an LWP ID into a POSIX or Solaris thread ID. If LWP_ID
278 doesn't exists, that's an error.
280 NOTE: This function probably shouldn't call error(). */
283 lwp_to_thread (ptid_t lwp
)
290 return lwp
; /* It's already a thread ID. */
292 /* It's an LWP. Convert it to a thread ID. */
294 if (!target_thread_alive (lwp
))
295 return pid_to_ptid (-1); /* Must be a defunct LPW. */
297 val
= p_td_ta_map_lwp2thr (main_ta
, GET_LWP (lwp
), &th
);
299 return pid_to_ptid (-1); /* Thread must have terminated. */
300 else if (val
!= TD_OK
)
301 error (_("lwp_to_thread: td_ta_map_lwp2thr: %s."), td_err_string (val
));
303 val
= p_td_thr_validate (&th
);
305 return lwp
; /* Unknown to libthread; just return LPW, */
306 else if (val
!= TD_OK
)
307 error (_("lwp_to_thread: td_thr_validate: %s."), td_err_string (val
));
309 val
= p_td_thr_get_info (&th
, &ti
);
311 return pid_to_ptid (-1); /* Thread must have terminated. */
312 else if (val
!= TD_OK
)
313 error (_("lwp_to_thread: td_thr_get_info: %s."), td_err_string (val
));
315 return BUILD_THREAD (ti
.ti_tid
, PIDGET (lwp
));
319 /* Most target vector functions from here on actually just pass
320 through to the layer beneath, as they don't need to do anything
321 specific for threads. */
323 /* Take a program previously attached to and detaches it. The program
324 resumes execution and will no longer stop on signals, etc. We'd
325 better not have left any breakpoints in the program or it'll die
326 when it hits one. For this to work, it may be necessary for the
327 process to have been previously attached. It *might* work if the
328 program was started via the normal ptrace (PTRACE_TRACEME). */
331 sol_thread_detach (struct target_ops
*ops
, char *args
, int from_tty
)
333 struct target_ops
*beneath
= find_target_beneath (ops
);
335 sol_thread_active
= 0;
336 inferior_ptid
= pid_to_ptid (PIDGET (main_ph
.ptid
));
338 beneath
->to_detach (beneath
, args
, from_tty
);
341 /* Resume execution of process PTID. If STEP is nozero, then just
342 single step it. If SIGNAL is nonzero, restart it with that signal
343 activated. We may have to convert PTID from a thread ID to an LWP
347 sol_thread_resume (struct target_ops
*ops
,
348 ptid_t ptid
, int step
, enum gdb_signal signo
)
350 struct cleanup
*old_chain
;
351 struct target_ops
*beneath
= find_target_beneath (ops
);
353 old_chain
= save_inferior_ptid ();
355 inferior_ptid
= thread_to_lwp (inferior_ptid
, PIDGET (main_ph
.ptid
));
356 if (PIDGET (inferior_ptid
) == -1)
357 inferior_ptid
= procfs_first_available ();
359 if (PIDGET (ptid
) != -1)
361 ptid_t save_ptid
= ptid
;
363 ptid
= thread_to_lwp (ptid
, -2);
364 if (PIDGET (ptid
) == -2) /* Inactive thread. */
365 error (_("This version of Solaris can't start inactive threads."));
366 if (info_verbose
&& PIDGET (ptid
) == -1)
367 warning (_("Specified thread %ld seems to have terminated"),
368 GET_THREAD (save_ptid
));
371 beneath
->to_resume (beneath
, ptid
, step
, signo
);
373 do_cleanups (old_chain
);
376 /* Wait for any threads to stop. We may have to convert PTID from a
377 thread ID to an LWP ID, and vice versa on the way out. */
380 sol_thread_wait (struct target_ops
*ops
,
381 ptid_t ptid
, struct target_waitstatus
*ourstatus
, int options
)
385 struct target_ops
*beneath
= find_target_beneath (ops
);
386 struct cleanup
*old_chain
;
388 save_ptid
= inferior_ptid
;
389 old_chain
= save_inferior_ptid ();
391 inferior_ptid
= thread_to_lwp (inferior_ptid
, PIDGET (main_ph
.ptid
));
392 if (PIDGET (inferior_ptid
) == -1)
393 inferior_ptid
= procfs_first_available ();
395 if (PIDGET (ptid
) != -1)
397 ptid_t save_ptid
= ptid
;
399 ptid
= thread_to_lwp (ptid
, -2);
400 if (PIDGET (ptid
) == -2) /* Inactive thread. */
401 error (_("This version of Solaris can't start inactive threads."));
402 if (info_verbose
&& PIDGET (ptid
) == -1)
403 warning (_("Specified thread %ld seems to have terminated"),
404 GET_THREAD (save_ptid
));
407 rtnval
= beneath
->to_wait (beneath
, ptid
, ourstatus
, options
);
409 if (ourstatus
->kind
!= TARGET_WAITKIND_EXITED
)
411 /* Map the LWP of interest back to the appropriate thread ID. */
412 rtnval
= lwp_to_thread (rtnval
);
413 if (PIDGET (rtnval
) == -1)
416 /* See if we have a new thread. */
417 if (is_thread (rtnval
)
418 && !ptid_equal (rtnval
, save_ptid
)
419 && (!in_thread_list (rtnval
)
420 || is_exited (rtnval
)))
424 /* During process initialization, we may get here without the thread
425 package being initialized, since that can only happen after we've
426 found the shared libs. */
428 do_cleanups (old_chain
);
434 sol_thread_fetch_registers (struct target_ops
*ops
,
435 struct regcache
*regcache
, int regnum
)
438 td_thrhandle_t thandle
;
441 prfpregset_t fpregset
;
442 gdb_gregset_t
*gregset_p
= &gregset
;
443 gdb_fpregset_t
*fpregset_p
= &fpregset
;
444 struct target_ops
*beneath
= find_target_beneath (ops
);
451 if (!is_thread (inferior_ptid
))
453 /* It's an LWP; pass the request on to the layer beneath. */
454 beneath
->to_fetch_registers (beneath
, regcache
, regnum
);
458 /* Solaris thread: convert INFERIOR_PTID into a td_thrhandle_t. */
459 thread
= GET_THREAD (inferior_ptid
);
461 error (_("sol_thread_fetch_registers: thread == 0"));
463 val
= p_td_ta_map_id2thr (main_ta
, thread
, &thandle
);
465 error (_("sol_thread_fetch_registers: td_ta_map_id2thr: %s"),
466 td_err_string (val
));
468 /* Get the general-purpose registers. */
470 val
= p_td_thr_getgregs (&thandle
, gregset
);
471 if (val
!= TD_OK
&& val
!= TD_PARTIALREG
)
472 error (_("sol_thread_fetch_registers: td_thr_getgregs %s"),
473 td_err_string (val
));
475 /* For SPARC, TD_PARTIALREG means that only %i0...%i7, %l0..%l7, %pc
476 and %sp are saved (by a thread context switch). */
478 /* And, now the floating-point registers. */
480 val
= p_td_thr_getfpregs (&thandle
, &fpregset
);
481 if (val
!= TD_OK
&& val
!= TD_NOFPREGS
)
482 error (_("sol_thread_fetch_registers: td_thr_getfpregs %s"),
483 td_err_string (val
));
485 /* Note that we must call supply_gregset and supply_fpregset *after*
486 calling the td routines because the td routines call ps_lget*
487 which affect the values stored in the registers array. */
489 supply_gregset (regcache
, (const gdb_gregset_t
*) gregset_p
);
490 supply_fpregset (regcache
, (const gdb_fpregset_t
*) fpregset_p
);
493 /* FIXME: libthread_db doesn't seem to handle this right. */
494 val
= td_thr_getxregsize (&thandle
, &xregsize
);
495 if (val
!= TD_OK
&& val
!= TD_NOXREGS
)
496 error (_("sol_thread_fetch_registers: td_thr_getxregsize %s"),
497 td_err_string (val
));
501 xregset
= alloca (xregsize
);
502 val
= td_thr_getxregs (&thandle
, xregset
);
504 error (_("sol_thread_fetch_registers: td_thr_getxregs %s"),
505 td_err_string (val
));
511 sol_thread_store_registers (struct target_ops
*ops
,
512 struct regcache
*regcache
, int regnum
)
515 td_thrhandle_t thandle
;
518 prfpregset_t fpregset
;
524 if (!is_thread (inferior_ptid
))
526 struct target_ops
*beneath
= find_target_beneath (ops
);
528 /* It's an LWP; pass the request on to the layer beneath. */
529 beneath
->to_store_registers (beneath
, regcache
, regnum
);
533 /* Solaris thread: convert INFERIOR_PTID into a td_thrhandle_t. */
534 thread
= GET_THREAD (inferior_ptid
);
536 val
= p_td_ta_map_id2thr (main_ta
, thread
, &thandle
);
538 error (_("sol_thread_store_registers: td_ta_map_id2thr %s"),
539 td_err_string (val
));
543 /* Not writing all the registers. */
544 char old_value
[MAX_REGISTER_SIZE
];
546 /* Save new register value. */
547 regcache_raw_collect (regcache
, regnum
, old_value
);
549 val
= p_td_thr_getgregs (&thandle
, gregset
);
551 error (_("sol_thread_store_registers: td_thr_getgregs %s"),
552 td_err_string (val
));
553 val
= p_td_thr_getfpregs (&thandle
, &fpregset
);
555 error (_("sol_thread_store_registers: td_thr_getfpregs %s"),
556 td_err_string (val
));
558 /* Restore new register value. */
559 regcache_raw_supply (regcache
, regnum
, old_value
);
562 /* FIXME: libthread_db doesn't seem to handle this right. */
563 val
= td_thr_getxregsize (&thandle
, &xregsize
);
564 if (val
!= TD_OK
&& val
!= TD_NOXREGS
)
565 error (_("sol_thread_store_registers: td_thr_getxregsize %s"),
566 td_err_string (val
));
570 xregset
= alloca (xregsize
);
571 val
= td_thr_getxregs (&thandle
, xregset
);
573 error (_("sol_thread_store_registers: td_thr_getxregs %s"),
574 td_err_string (val
));
579 fill_gregset (regcache
, (gdb_gregset_t
*) &gregset
, regnum
);
580 fill_fpregset (regcache
, (gdb_fpregset_t
*) &fpregset
, regnum
);
582 val
= p_td_thr_setgregs (&thandle
, gregset
);
584 error (_("sol_thread_store_registers: td_thr_setgregs %s"),
585 td_err_string (val
));
586 val
= p_td_thr_setfpregs (&thandle
, &fpregset
);
588 error (_("sol_thread_store_registers: td_thr_setfpregs %s"),
589 td_err_string (val
));
592 /* FIXME: libthread_db doesn't seem to handle this right. */
593 val
= td_thr_getxregsize (&thandle
, &xregsize
);
594 if (val
!= TD_OK
&& val
!= TD_NOXREGS
)
595 error (_("sol_thread_store_registers: td_thr_getxregsize %s"),
596 td_err_string (val
));
598 /* ??? Should probably do something about writing the xregs here,
599 but what are they? */
603 /* Perform partial transfers on OBJECT. See target_read_partial and
604 target_write_partial for details of each variant. One, and only
605 one, of readbuf or writebuf must be non-NULL. */
608 sol_thread_xfer_partial (struct target_ops
*ops
, enum target_object object
,
609 const char *annex
, gdb_byte
*readbuf
,
610 const gdb_byte
*writebuf
,
611 ULONGEST offset
, LONGEST len
)
614 struct cleanup
*old_chain
;
615 struct target_ops
*beneath
= find_target_beneath (ops
);
617 old_chain
= save_inferior_ptid ();
619 if (is_thread (inferior_ptid
) || !target_thread_alive (inferior_ptid
))
621 /* It's either a thread or an LWP that isn't alive. Any live
622 LWP will do so use the first available.
624 NOTE: We don't need to call switch_to_thread; we're just
626 inferior_ptid
= procfs_first_available ();
629 retval
= beneath
->to_xfer_partial (beneath
, object
, annex
,
630 readbuf
, writebuf
, offset
, len
);
632 do_cleanups (old_chain
);
638 check_for_thread_db (void)
643 /* Do nothing if we couldn't load libthread_db.so.1. */
644 if (p_td_ta_new
== NULL
)
647 if (sol_thread_active
)
648 /* Nothing to do. The thread library was already detected and the
649 target vector was already activated. */
652 /* Now, initialize libthread_db. This needs to be done after the
653 shared libraries are located because it needs information from
654 the user's thread library. */
659 warning (_("sol_thread_new_objfile: td_init: %s"), td_err_string (err
));
663 /* Now attempt to open a connection to the thread library. */
664 err
= p_td_ta_new (&main_ph
, &main_ta
);
668 /* No thread library was detected. */
672 printf_unfiltered (_("[Thread debugging using libthread_db enabled]\n"));
674 /* The thread library was detected. Activate the sol_thread target. */
675 push_target (&sol_thread_ops
);
676 sol_thread_active
= 1;
678 main_ph
.ptid
= inferior_ptid
; /* Save for xfer_memory. */
679 ptid
= lwp_to_thread (inferior_ptid
);
680 if (PIDGET (ptid
) != -1)
681 inferior_ptid
= ptid
;
683 target_find_new_threads ();
687 warning (_("Cannot initialize thread debugging library: %s"),
688 td_err_string (err
));
693 /* This routine is called whenever a new symbol table is read in, or
694 when all symbol tables are removed. libthread_db can only be
695 initialized when it finds the right variables in libthread.so.
696 Since it's a shared library, those variables don't show up until
697 the library gets mapped and the symbol table is read in. */
700 sol_thread_new_objfile (struct objfile
*objfile
)
703 check_for_thread_db ();
706 /* Clean up after the inferior dies. */
709 sol_thread_mourn_inferior (struct target_ops
*ops
)
711 struct target_ops
*beneath
= find_target_beneath (ops
);
713 sol_thread_active
= 0;
717 beneath
->to_mourn_inferior (beneath
);
720 /* Return true if PTID is still active in the inferior. */
723 sol_thread_alive (struct target_ops
*ops
, ptid_t ptid
)
725 if (is_thread (ptid
))
727 /* It's a (user-level) thread. */
732 pid
= GET_THREAD (ptid
);
733 if ((val
= p_td_ta_map_id2thr (main_ta
, pid
, &th
)) != TD_OK
)
734 return 0; /* Thread not found. */
735 if ((val
= p_td_thr_validate (&th
)) != TD_OK
)
736 return 0; /* Thread not valid. */
737 return 1; /* Known thread. */
741 struct target_ops
*beneath
= find_target_beneath (ops
);
743 /* It's an LPW; pass the request on to the layer below. */
744 return beneath
->to_thread_alive (beneath
, ptid
);
749 /* These routines implement the lower half of the thread_db interface,
750 i.e. the ps_* routines. */
752 /* Various versions of <proc_service.h> have slightly different
753 function prototypes. In particular, we have
756 struct ps_prochandle * const struct ps_prochandle *
761 Which one you have depends on the Solaris version and what patches
762 you've applied. On the theory that there are only two major
763 variants, we have configure check the prototype of ps_pdwrite (),
764 and use that info to make appropriate typedefs here. */
766 #ifdef PROC_SERVICE_IS_OLD
767 typedef const struct ps_prochandle
*gdb_ps_prochandle_t
;
768 typedef char *gdb_ps_read_buf_t
;
769 typedef char *gdb_ps_write_buf_t
;
770 typedef int gdb_ps_size_t
;
771 typedef psaddr_t gdb_ps_addr_t
;
773 typedef struct ps_prochandle
*gdb_ps_prochandle_t
;
774 typedef void *gdb_ps_read_buf_t
;
775 typedef const void *gdb_ps_write_buf_t
;
776 typedef size_t gdb_ps_size_t
;
777 typedef psaddr_t gdb_ps_addr_t
;
780 /* The next four routines are called by libthread_db to tell us to
781 stop and stop a particular process or lwp. Since GDB ensures that
782 these are all stopped by the time we call anything in thread_db,
783 these routines need to do nothing. */
788 ps_pstop (gdb_ps_prochandle_t ph
)
793 /* Process continue. */
796 ps_pcontinue (gdb_ps_prochandle_t ph
)
804 ps_lstop (gdb_ps_prochandle_t ph
, lwpid_t lwpid
)
812 ps_lcontinue (gdb_ps_prochandle_t ph
, lwpid_t lwpid
)
817 /* Looks up the symbol LD_SYMBOL_NAME in the debugger's symbol table. */
820 ps_pglobal_lookup (gdb_ps_prochandle_t ph
, const char *ld_object_name
,
821 const char *ld_symbol_name
, gdb_ps_addr_t
*ld_symbol_addr
)
823 struct minimal_symbol
*ms
;
825 ms
= lookup_minimal_symbol (ld_symbol_name
, NULL
, NULL
);
829 *ld_symbol_addr
= SYMBOL_VALUE_ADDRESS (ms
);
833 /* Common routine for reading and writing memory. */
836 rw_common (int dowrite
, const struct ps_prochandle
*ph
, gdb_ps_addr_t addr
,
840 struct cleanup
*old_chain
;
842 old_chain
= save_inferior_ptid ();
844 if (is_thread (inferior_ptid
) || !target_thread_alive (inferior_ptid
))
846 /* It's either a thread or an LWP that isn't alive. Any live
847 LWP will do so use the first available.
849 NOTE: We don't need to call switch_to_thread; we're just
851 inferior_ptid
= procfs_first_available ();
854 #if defined (__sparcv9)
855 /* For Sparc64 cross Sparc32, make sure the address has not been
856 accidentally sign-extended (or whatever) to beyond 32 bits. */
857 if (bfd_get_arch_size (exec_bfd
) == 32)
862 ret
= target_write_memory (addr
, buf
, size
);
864 ret
= target_read_memory (addr
, buf
, size
);
866 do_cleanups (old_chain
);
868 return (ret
== 0 ? PS_OK
: PS_ERR
);
871 /* Copies SIZE bytes from target process .data segment to debugger memory. */
874 ps_pdread (gdb_ps_prochandle_t ph
, gdb_ps_addr_t addr
,
875 gdb_ps_read_buf_t buf
, gdb_ps_size_t size
)
877 return rw_common (0, ph
, addr
, buf
, size
);
880 /* Copies SIZE bytes from debugger memory .data segment to target process. */
883 ps_pdwrite (gdb_ps_prochandle_t ph
, gdb_ps_addr_t addr
,
884 gdb_ps_write_buf_t buf
, gdb_ps_size_t size
)
886 return rw_common (1, ph
, addr
, (char *) buf
, size
);
889 /* Copies SIZE bytes from target process .text segment to debugger memory. */
892 ps_ptread (gdb_ps_prochandle_t ph
, gdb_ps_addr_t addr
,
893 gdb_ps_read_buf_t buf
, gdb_ps_size_t size
)
895 return rw_common (0, ph
, addr
, buf
, size
);
898 /* Copies SIZE bytes from debugger memory .text segment to target process. */
901 ps_ptwrite (gdb_ps_prochandle_t ph
, gdb_ps_addr_t addr
,
902 gdb_ps_write_buf_t buf
, gdb_ps_size_t size
)
904 return rw_common (1, ph
, addr
, (char *) buf
, size
);
907 /* Get general-purpose registers for LWP. */
910 ps_lgetregs (gdb_ps_prochandle_t ph
, lwpid_t lwpid
, prgregset_t gregset
)
912 struct cleanup
*old_chain
;
913 struct regcache
*regcache
;
915 old_chain
= save_inferior_ptid ();
917 inferior_ptid
= BUILD_LWP (lwpid
, PIDGET (inferior_ptid
));
918 regcache
= get_thread_arch_regcache (inferior_ptid
, target_gdbarch
);
920 target_fetch_registers (regcache
, -1);
921 fill_gregset (regcache
, (gdb_gregset_t
*) gregset
, -1);
923 do_cleanups (old_chain
);
928 /* Set general-purpose registers for LWP. */
931 ps_lsetregs (gdb_ps_prochandle_t ph
, lwpid_t lwpid
,
932 const prgregset_t gregset
)
934 struct cleanup
*old_chain
;
935 struct regcache
*regcache
;
937 old_chain
= save_inferior_ptid ();
939 inferior_ptid
= BUILD_LWP (lwpid
, PIDGET (inferior_ptid
));
940 regcache
= get_thread_arch_regcache (inferior_ptid
, target_gdbarch
);
942 supply_gregset (regcache
, (const gdb_gregset_t
*) gregset
);
943 target_store_registers (regcache
, -1);
945 do_cleanups (old_chain
);
950 /* Log a message (sends to gdb_stderr). */
953 ps_plog (const char *fmt
, ...)
957 va_start (args
, fmt
);
959 vfprintf_filtered (gdb_stderr
, fmt
, args
);
962 /* Get size of extra register set. Currently a noop. */
965 ps_lgetxregsize (gdb_ps_prochandle_t ph
, lwpid_t lwpid
, int *xregsize
)
972 val
= get_lwp_fd (ph
, lwpid
, &lwp_fd
);
976 if (ioctl (lwp_fd
, PIOCGXREGSIZE
, ®size
))
979 return PS_NOFREGS
; /* XXX Wrong code, but this is the closest
980 thing in proc_service.h */
982 print_sys_errmsg ("ps_lgetxregsize (): PIOCGXREGSIZE", errno
);
990 /* Get extra register set. Currently a noop. */
993 ps_lgetxregs (gdb_ps_prochandle_t ph
, lwpid_t lwpid
, caddr_t xregset
)
999 val
= get_lwp_fd (ph
, lwpid
, &lwp_fd
);
1003 if (ioctl (lwp_fd
, PIOCGXREG
, xregset
))
1005 print_sys_errmsg ("ps_lgetxregs (): PIOCGXREG", errno
);
1013 /* Set extra register set. Currently a noop. */
1016 ps_lsetxregs (gdb_ps_prochandle_t ph
, lwpid_t lwpid
, caddr_t xregset
)
1022 val
= get_lwp_fd (ph
, lwpid
, &lwp_fd
);
1026 if (ioctl (lwp_fd
, PIOCSXREG
, xregset
))
1028 print_sys_errmsg ("ps_lsetxregs (): PIOCSXREG", errno
);
1036 /* Get floating-point registers for LWP. */
1039 ps_lgetfpregs (gdb_ps_prochandle_t ph
, lwpid_t lwpid
,
1040 prfpregset_t
*fpregset
)
1042 struct cleanup
*old_chain
;
1043 struct regcache
*regcache
;
1045 old_chain
= save_inferior_ptid ();
1047 inferior_ptid
= BUILD_LWP (lwpid
, PIDGET (inferior_ptid
));
1048 regcache
= get_thread_arch_regcache (inferior_ptid
, target_gdbarch
);
1050 target_fetch_registers (regcache
, -1);
1051 fill_fpregset (regcache
, (gdb_fpregset_t
*) fpregset
, -1);
1053 do_cleanups (old_chain
);
1058 /* Set floating-point regs for LWP. */
1061 ps_lsetfpregs (gdb_ps_prochandle_t ph
, lwpid_t lwpid
,
1062 const prfpregset_t
* fpregset
)
1064 struct cleanup
*old_chain
;
1065 struct regcache
*regcache
;
1067 old_chain
= save_inferior_ptid ();
1069 inferior_ptid
= BUILD_LWP (lwpid
, PIDGET (inferior_ptid
));
1070 regcache
= get_thread_arch_regcache (inferior_ptid
, target_gdbarch
);
1072 supply_fpregset (regcache
, (const gdb_fpregset_t
*) fpregset
);
1073 target_store_registers (regcache
, -1);
1075 do_cleanups (old_chain
);
1080 #ifdef PR_MODEL_LP64
1081 /* Identify process as 32-bit or 64-bit. At the moment we're using
1082 BFD to do this. There might be a more Solaris-specific
1083 (e.g. procfs) method, but this ought to work. */
1086 ps_pdmodel (gdb_ps_prochandle_t ph
, int *data_model
)
1089 *data_model
= PR_MODEL_UNKNOWN
;
1090 else if (bfd_get_arch_size (exec_bfd
) == 32)
1091 *data_model
= PR_MODEL_ILP32
;
1093 *data_model
= PR_MODEL_LP64
;
1097 #endif /* PR_MODEL_LP64 */
1099 #if (defined(__i386__) || defined(__x86_64__)) && defined (sun)
1101 /* Reads the local descriptor table of a LWP.
1103 This function is necessary on x86-solaris only. Without it, the loading
1104 of libthread_db would fail because of ps_lgetLDT being undefined. */
1107 ps_lgetLDT (gdb_ps_prochandle_t ph
, lwpid_t lwpid
,
1110 /* NOTE: only used on Solaris, therefore OK to refer to procfs.c. */
1111 extern struct ssd
*procfs_find_LDT_entry (ptid_t
);
1114 /* FIXME: can't I get the process ID from the prochandle or
1117 if (PIDGET (inferior_ptid
) <= 0 || lwpid
<= 0)
1120 ret
= procfs_find_LDT_entry (BUILD_LWP (lwpid
, PIDGET (inferior_ptid
)));
1123 memcpy (pldt
, ret
, sizeof (struct ssd
));
1127 /* LDT not found. */
1133 /* Convert PTID to printable form. */
1136 solaris_pid_to_str (struct target_ops
*ops
, ptid_t ptid
)
1138 static char buf
[100];
1140 if (is_thread (ptid
))
1144 lwp
= thread_to_lwp (ptid
, -2);
1146 if (PIDGET (lwp
) == -1)
1147 sprintf (buf
, "Thread %ld (defunct)", GET_THREAD (ptid
));
1148 else if (PIDGET (lwp
) != -2)
1149 sprintf (buf
, "Thread %ld (LWP %ld)",
1150 GET_THREAD (ptid
), GET_LWP (lwp
));
1152 sprintf (buf
, "Thread %ld ", GET_THREAD (ptid
));
1154 else if (GET_LWP (ptid
) != 0)
1155 sprintf (buf
, "LWP %ld ", GET_LWP (ptid
));
1157 sprintf (buf
, "process %d ", PIDGET (ptid
));
1163 /* Worker bee for find_new_threads. Callback function that gets
1164 called once per user-level thread (i.e. not for LWP's). */
1167 sol_find_new_threads_callback (const td_thrhandle_t
*th
, void *ignored
)
1173 retval
= p_td_thr_get_info (th
, &ti
);
1174 if (retval
!= TD_OK
)
1177 ptid
= BUILD_THREAD (ti
.ti_tid
, PIDGET (inferior_ptid
));
1178 if (!in_thread_list (ptid
) || is_exited (ptid
))
1185 sol_find_new_threads (struct target_ops
*ops
)
1187 struct target_ops
*beneath
= find_target_beneath (ops
);
1189 /* First Find any new LWP's. */
1190 if (beneath
->to_find_new_threads
!= NULL
)
1191 beneath
->to_find_new_threads (beneath
);
1193 /* Then find any new user-level threads. */
1194 p_td_ta_thr_iter (main_ta
, sol_find_new_threads_callback
, (void *) 0,
1195 TD_THR_ANY_STATE
, TD_THR_LOWEST_PRIORITY
,
1196 TD_SIGNO_MASK
, TD_THR_ANY_USER_FLAGS
);
1199 /* Worker bee for the "info sol-thread" command. This is a callback
1200 function that gets called once for each Solaris user-level thread
1201 (i.e. not for LWPs) in the inferior. Print anything interesting
1202 that we can think of. */
1205 info_cb (const td_thrhandle_t
*th
, void *s
)
1210 ret
= p_td_thr_get_info (th
, &ti
);
1213 printf_filtered ("%s thread #%d, lwp %d, ",
1214 ti
.ti_type
== TD_THR_SYSTEM
? "system" : "user ",
1215 ti
.ti_tid
, ti
.ti_lid
);
1216 switch (ti
.ti_state
)
1219 case TD_THR_UNKNOWN
:
1220 printf_filtered ("<unknown state>");
1222 case TD_THR_STOPPED
:
1223 printf_filtered ("(stopped)");
1226 printf_filtered ("(run) ");
1229 printf_filtered ("(active) ");
1232 printf_filtered ("(zombie) ");
1235 printf_filtered ("(asleep) ");
1237 case TD_THR_STOPPED_ASLEEP
:
1238 printf_filtered ("(stopped asleep)");
1241 /* Print thr_create start function. */
1242 if (ti
.ti_startfunc
!= 0)
1244 struct minimal_symbol
*msym
;
1245 msym
= lookup_minimal_symbol_by_pc (ti
.ti_startfunc
);
1247 printf_filtered (" startfunc: %s\n",
1248 SYMBOL_PRINT_NAME (msym
));
1250 printf_filtered (" startfunc: %s\n",
1251 paddress (target_gdbarch
, ti
.ti_startfunc
));
1254 /* If thread is asleep, print function that went to sleep. */
1255 if (ti
.ti_state
== TD_THR_SLEEP
)
1257 struct minimal_symbol
*msym
;
1258 msym
= lookup_minimal_symbol_by_pc (ti
.ti_pc
);
1260 printf_filtered (" - Sleep func: %s\n",
1261 SYMBOL_PRINT_NAME (msym
));
1263 printf_filtered (" - Sleep func: %s\n",
1264 paddress (target_gdbarch
, ti
.ti_startfunc
));
1267 /* Wrap up line, if necessary. */
1268 if (ti
.ti_state
!= TD_THR_SLEEP
&& ti
.ti_startfunc
== 0)
1269 printf_filtered ("\n"); /* don't you hate counting newlines? */
1272 warning (_("info sol-thread: failed to get info for thread."));
1277 /* List some state about each Solaris user-level thread in the
1281 info_solthreads (char *args
, int from_tty
)
1283 p_td_ta_thr_iter (main_ta
, info_cb
, args
,
1284 TD_THR_ANY_STATE
, TD_THR_LOWEST_PRIORITY
,
1285 TD_SIGNO_MASK
, TD_THR_ANY_USER_FLAGS
);
1288 /* Callback routine used to find a thread based on the TID part of
1292 thread_db_find_thread_from_tid (struct thread_info
*thread
, void *data
)
1294 long *tid
= (long *) data
;
1296 if (ptid_get_tid (thread
->ptid
) == *tid
)
1303 sol_get_ada_task_ptid (long lwp
, long thread
)
1305 struct thread_info
*thread_info
=
1306 iterate_over_threads (thread_db_find_thread_from_tid
, &thread
);
1308 if (thread_info
== NULL
)
1310 /* The list of threads is probably not up to date. Find any
1311 thread that is missing from the list, and try again. */
1312 sol_find_new_threads (¤t_target
);
1313 thread_info
= iterate_over_threads (thread_db_find_thread_from_tid
,
1317 gdb_assert (thread_info
!= NULL
);
1319 return (thread_info
->ptid
);
1323 init_sol_thread_ops (void)
1325 sol_thread_ops
.to_shortname
= "solaris-threads";
1326 sol_thread_ops
.to_longname
= "Solaris threads and pthread.";
1327 sol_thread_ops
.to_doc
= "Solaris threads and pthread support.";
1328 sol_thread_ops
.to_detach
= sol_thread_detach
;
1329 sol_thread_ops
.to_resume
= sol_thread_resume
;
1330 sol_thread_ops
.to_wait
= sol_thread_wait
;
1331 sol_thread_ops
.to_fetch_registers
= sol_thread_fetch_registers
;
1332 sol_thread_ops
.to_store_registers
= sol_thread_store_registers
;
1333 sol_thread_ops
.to_xfer_partial
= sol_thread_xfer_partial
;
1334 sol_thread_ops
.to_mourn_inferior
= sol_thread_mourn_inferior
;
1335 sol_thread_ops
.to_thread_alive
= sol_thread_alive
;
1336 sol_thread_ops
.to_pid_to_str
= solaris_pid_to_str
;
1337 sol_thread_ops
.to_find_new_threads
= sol_find_new_threads
;
1338 sol_thread_ops
.to_stratum
= thread_stratum
;
1339 sol_thread_ops
.to_get_ada_task_ptid
= sol_get_ada_task_ptid
;
1340 sol_thread_ops
.to_magic
= OPS_MAGIC
;
1343 /* Silence -Wmissing-prototypes. */
1344 extern void _initialize_sol_thread (void);
1347 _initialize_sol_thread (void)
1351 init_sol_thread_ops ();
1353 dlhandle
= dlopen ("libthread_db.so.1", RTLD_NOW
);
1357 #define resolve(X) \
1358 if (!(p_##X = dlsym (dlhandle, #X))) \
1362 resolve (td_ta_new
);
1363 resolve (td_ta_delete
);
1365 resolve (td_ta_get_ph
);
1366 resolve (td_ta_get_nthreads
);
1367 resolve (td_ta_tsd_iter
);
1368 resolve (td_ta_thr_iter
);
1369 resolve (td_thr_validate
);
1370 resolve (td_thr_tsd
);
1371 resolve (td_thr_get_info
);
1372 resolve (td_thr_getfpregs
);
1373 resolve (td_thr_getxregsize
);
1374 resolve (td_thr_getxregs
);
1375 resolve (td_thr_sigsetmask
);
1376 resolve (td_thr_setprio
);
1377 resolve (td_thr_setsigpending
);
1378 resolve (td_thr_setfpregs
);
1379 resolve (td_thr_setxregs
);
1380 resolve (td_ta_map_id2thr
);
1381 resolve (td_ta_map_lwp2thr
);
1382 resolve (td_thr_getgregs
);
1383 resolve (td_thr_setgregs
);
1385 add_target (&sol_thread_ops
);
1387 add_cmd ("sol-threads", class_maintenance
, info_solthreads
,
1388 _("Show info on Solaris user threads."), &maintenanceinfolist
);
1390 /* Hook into new_objfile notification. */
1391 observer_attach_new_objfile (sol_thread_new_objfile
);
1395 fprintf_unfiltered (gdb_stderr
, "\
1396 [GDB will not be able to debug user-mode threads: %s]\n", dlerror ());