1 /* Solaris threads debugging interface.
3 Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
4 2007, 2008, 2009 Free Software Foundation, Inc.
6 This file is part of GDB.
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>. */
21 /* This module implements a sort of half target that sits between the
22 machine-independent parts of GDB and the /proc interface (procfs.c)
23 to provide access to the Solaris user-mode thread implementation.
25 Solaris threads are true user-mode threads, which are invoked via
26 the thr_* and pthread_* (native and POSIX respectivly) interfaces.
27 These are mostly implemented in user-space, with all thread context
28 kept in various structures that live in the user's heap. These
29 should not be confused with lightweight processes (LWPs), which are
30 implemented by the kernel, and scheduled without explicit
31 intervention by the process.
33 Just to confuse things a little, Solaris threads (both native and
34 POSIX) are actually implemented using LWPs. In general, there are
35 going to be more threads than LWPs. There is no fixed
36 correspondence between a thread and an LWP. When a thread wants to
37 run, it gets scheduled onto the first available LWP and can
38 therefore migrate from one LWP to another as time goes on. A
39 sleeping thread may not be associated with an LWP at all!
41 To make it possible to mess with threads, Sun provides a library
42 called libthread_db.so.1 (not to be confused with
43 libthread_db.so.0, which doesn't have a published interface). This
44 interface has an upper part, which it provides, and a lower part
45 which we provide. The upper part consists of the td_* routines,
46 which allow us to find all the threads, query their state, etc...
47 The lower part consists of all of the ps_*, which are used by the
48 td_* routines to read/write memory, manipulate LWPs, lookup
49 symbols, etc... The ps_* routines actually do most of their work
50 by calling functions in procfs.c. */
54 #include <proc_service.h>
55 #include <thread_db.h>
56 #include "gdbthread.h"
69 #include "gdb_string.h"
71 struct target_ops sol_thread_ops
;
73 extern char *procfs_pid_to_str (struct target_ops
*ops
, ptid_t ptid
);
75 /* Prototypes for supply_gregset etc. */
78 /* This struct is defined by us, but mainly used for the proc_service
79 interface. We don't have much use for it, except as a handy place
80 to get a real PID for memory accesses. */
93 static struct ps_prochandle main_ph
;
94 static td_thragent_t
*main_ta
;
95 static int sol_thread_active
= 0;
97 static void init_sol_thread_ops (void);
99 /* Default definitions: These must be defined in tm.h if they are to
100 be shared with a process module such as procfs. */
102 #define GET_PID(ptid) ptid_get_pid (ptid)
103 #define GET_LWP(ptid) ptid_get_lwp (ptid)
104 #define GET_THREAD(ptid) ptid_get_tid (ptid)
106 #define is_lwp(ptid) (GET_LWP (ptid) != 0)
107 #define is_thread(ptid) (GET_THREAD (ptid) != 0)
109 #define BUILD_LWP(lwp, pid) ptid_build (pid, lwp, 0)
110 #define BUILD_THREAD(tid, pid) ptid_build (pid, 0, tid)
112 /* Pointers to routines from libthread_db resolved by dlopen(). */
114 static void (*p_td_log
)(const int on_off
);
115 static td_err_e (*p_td_ta_new
)(const struct ps_prochandle
*ph_p
,
116 td_thragent_t
**ta_pp
);
117 static td_err_e (*p_td_ta_delete
)(td_thragent_t
*ta_p
);
118 static td_err_e (*p_td_init
)(void);
119 static td_err_e (*p_td_ta_get_ph
)(const td_thragent_t
*ta_p
,
120 struct ps_prochandle
**ph_pp
);
121 static td_err_e (*p_td_ta_get_nthreads
)(const td_thragent_t
*ta_p
,
123 static td_err_e (*p_td_ta_tsd_iter
)(const td_thragent_t
*ta_p
,
124 td_key_iter_f
*cb
, void *cbdata_p
);
125 static td_err_e (*p_td_ta_thr_iter
)(const td_thragent_t
*ta_p
,
126 td_thr_iter_f
*cb
, void *cbdata_p
,
127 td_thr_state_e state
, int ti_pri
,
128 sigset_t
*ti_sigmask_p
,
129 unsigned ti_user_flags
);
130 static td_err_e (*p_td_thr_validate
)(const td_thrhandle_t
*th_p
);
131 static td_err_e (*p_td_thr_tsd
)(const td_thrhandle_t
* th_p
,
132 const thread_key_t key
, void **data_pp
);
133 static td_err_e (*p_td_thr_get_info
)(const td_thrhandle_t
*th_p
,
135 static td_err_e (*p_td_thr_getfpregs
)(const td_thrhandle_t
*th_p
,
136 prfpregset_t
*fpregset
);
137 static td_err_e (*p_td_thr_getxregsize
)(const td_thrhandle_t
*th_p
,
139 static td_err_e (*p_td_thr_getxregs
)(const td_thrhandle_t
*th_p
,
140 const caddr_t xregset
);
141 static td_err_e (*p_td_thr_sigsetmask
)(const td_thrhandle_t
*th_p
,
142 const sigset_t ti_sigmask
);
143 static td_err_e (*p_td_thr_setprio
)(const td_thrhandle_t
*th_p
,
145 static td_err_e (*p_td_thr_setsigpending
)(const td_thrhandle_t
*th_p
,
146 const uchar_t ti_pending_flag
,
147 const sigset_t ti_pending
);
148 static td_err_e (*p_td_thr_setfpregs
)(const td_thrhandle_t
*th_p
,
149 const prfpregset_t
*fpregset
);
150 static td_err_e (*p_td_thr_setxregs
)(const td_thrhandle_t
*th_p
,
151 const caddr_t xregset
);
152 static td_err_e (*p_td_ta_map_id2thr
)(const td_thragent_t
*ta_p
,
154 td_thrhandle_t
*th_p
);
155 static td_err_e (*p_td_ta_map_lwp2thr
)(const td_thragent_t
*ta_p
,
157 td_thrhandle_t
*th_p
);
158 static td_err_e (*p_td_thr_getgregs
)(const td_thrhandle_t
*th_p
,
160 static td_err_e (*p_td_thr_setgregs
)(const td_thrhandle_t
*th_p
,
161 const prgregset_t regset
);
164 /* Return the libthread_db error string associated with ERRCODE. If
165 ERRCODE is unknown, return an appropriate message. */
168 td_err_string (td_err_e errcode
)
170 static struct string_map td_err_table
[] =
172 { TD_OK
, "generic \"call succeeded\"" },
173 { TD_ERR
, "generic error." },
174 { TD_NOTHR
, "no thread can be found to satisfy query" },
175 { TD_NOSV
, "no synch. variable can be found to satisfy query" },
176 { TD_NOLWP
, "no lwp can be found to satisfy query" },
177 { TD_BADPH
, "invalid process handle" },
178 { TD_BADTH
, "invalid thread handle" },
179 { TD_BADSH
, "invalid synchronization handle" },
180 { TD_BADTA
, "invalid thread agent" },
181 { TD_BADKEY
, "invalid key" },
182 { TD_NOMSG
, "td_thr_event_getmsg() called when there was no message" },
183 { TD_NOFPREGS
, "FPU register set not available for given thread" },
184 { TD_NOLIBTHREAD
, "application not linked with libthread" },
185 { TD_NOEVENT
, "requested event is not supported" },
186 { TD_NOCAPAB
, "capability not available" },
187 { TD_DBERR
, "Debugger service failed" },
188 { TD_NOAPLIC
, "Operation not applicable to" },
189 { TD_NOTSD
, "No thread specific data for this thread" },
190 { TD_MALLOC
, "Malloc failed" },
191 { TD_PARTIALREG
, "Only part of register set was written/read" },
192 { TD_NOXREGS
, "X register set not available for given thread" }
194 const int td_err_size
= sizeof td_err_table
/ sizeof (struct string_map
);
198 for (i
= 0; i
< td_err_size
; i
++)
199 if (td_err_table
[i
].num
== errcode
)
200 return td_err_table
[i
].str
;
202 sprintf (buf
, "Unknown libthread_db error code: %d", errcode
);
207 /* Return the the libthread_db state string assicoated with STATECODE.
208 If STATECODE is unknown, return an appropriate message. */
211 td_state_string (td_thr_state_e statecode
)
213 static struct string_map td_thr_state_table
[] =
215 { TD_THR_ANY_STATE
, "any state" },
216 { TD_THR_UNKNOWN
, "unknown" },
217 { TD_THR_STOPPED
, "stopped" },
218 { TD_THR_RUN
, "run" },
219 { TD_THR_ACTIVE
, "active" },
220 { TD_THR_ZOMBIE
, "zombie" },
221 { TD_THR_SLEEP
, "sleep" },
222 { TD_THR_STOPPED_ASLEEP
, "stopped asleep" }
224 const int td_thr_state_table_size
=
225 sizeof td_thr_state_table
/ sizeof (struct string_map
);
229 for (i
= 0; i
< td_thr_state_table_size
; i
++)
230 if (td_thr_state_table
[i
].num
== statecode
)
231 return td_thr_state_table
[i
].str
;
233 sprintf (buf
, "Unknown libthread_db state code: %d", statecode
);
239 /* Convert a POSIX or Solaris thread ID into a LWP ID. If THREAD_ID
240 doesn't exist, that's an error. If it's an inactive thread, return
243 NOTE: This function probably shouldn't call error(). */
246 thread_to_lwp (ptid_t thread_id
, int default_lwp
)
252 if (is_lwp (thread_id
))
253 return thread_id
; /* It's already an LWP ID. */
255 /* It's a thread. Convert to LWP. */
257 val
= p_td_ta_map_id2thr (main_ta
, GET_THREAD (thread_id
), &th
);
259 return pid_to_ptid (-1); /* Thread must have terminated. */
260 else if (val
!= TD_OK
)
261 error (_("thread_to_lwp: td_ta_map_id2thr %s"), td_err_string (val
));
263 val
= p_td_thr_get_info (&th
, &ti
);
265 return pid_to_ptid (-1); /* Thread must have terminated. */
266 else if (val
!= TD_OK
)
267 error (_("thread_to_lwp: td_thr_get_info: %s"), td_err_string (val
));
269 if (ti
.ti_state
!= TD_THR_ACTIVE
)
271 if (default_lwp
!= -1)
272 return pid_to_ptid (default_lwp
);
273 error (_("thread_to_lwp: thread state not active: %s"),
274 td_state_string (ti
.ti_state
));
277 return BUILD_LWP (ti
.ti_lid
, PIDGET (thread_id
));
280 /* Convert an LWP ID into a POSIX or Solaris thread ID. If LWP_ID
281 doesn't exists, that's an error.
283 NOTE: This function probably shouldn't call error(). */
286 lwp_to_thread (ptid_t lwp
)
293 return lwp
; /* It's already a thread ID. */
295 /* It's an LWP. Convert it to a thread ID. */
297 if (!target_thread_alive (lwp
))
298 return pid_to_ptid (-1); /* Must be a defunct LPW. */
300 val
= p_td_ta_map_lwp2thr (main_ta
, GET_LWP (lwp
), &th
);
302 return pid_to_ptid (-1); /* Thread must have terminated. */
303 else if (val
!= TD_OK
)
304 error (_("lwp_to_thread: td_ta_map_lwp2thr: %s."), td_err_string (val
));
306 val
= p_td_thr_validate (&th
);
308 return lwp
; /* Unknown to libthread; just return LPW, */
309 else if (val
!= TD_OK
)
310 error (_("lwp_to_thread: td_thr_validate: %s."), td_err_string (val
));
312 val
= p_td_thr_get_info (&th
, &ti
);
314 return pid_to_ptid (-1); /* Thread must have terminated. */
315 else if (val
!= TD_OK
)
316 error (_("lwp_to_thread: td_thr_get_info: %s."), td_err_string (val
));
318 return BUILD_THREAD (ti
.ti_tid
, PIDGET (lwp
));
322 /* Most target vector functions from here on actually just pass
323 through to the layer beneath, as they don't need to do anything
324 specific for threads. */
326 /* Take a program previously attached to and detaches it. The program
327 resumes execution and will no longer stop on signals, etc. We'd
328 better not have left any breakpoints in the program or it'll die
329 when it hits one. For this to work, it may be necessary for the
330 process to have been previously attached. It *might* work if the
331 program was started via the normal ptrace (PTRACE_TRACEME). */
334 sol_thread_detach (struct target_ops
*ops
, char *args
, int from_tty
)
336 struct target_ops
*beneath
= find_target_beneath (ops
);
338 sol_thread_active
= 0;
339 inferior_ptid
= pid_to_ptid (PIDGET (main_ph
.ptid
));
341 beneath
->to_detach (beneath
, args
, from_tty
);
344 /* Resume execution of process PTID. If STEP is nozero, then just
345 single step it. If SIGNAL is nonzero, restart it with that signal
346 activated. We may have to convert PTID from a thread ID to an LWP
350 sol_thread_resume (struct target_ops
*ops
,
351 ptid_t ptid
, int step
, enum target_signal signo
)
353 struct cleanup
*old_chain
;
354 struct target_ops
*beneath
= find_target_beneath (ops
);
356 old_chain
= save_inferior_ptid ();
358 inferior_ptid
= thread_to_lwp (inferior_ptid
, PIDGET (main_ph
.ptid
));
359 if (PIDGET (inferior_ptid
) == -1)
360 inferior_ptid
= procfs_first_available ();
362 if (PIDGET (ptid
) != -1)
364 ptid_t save_ptid
= ptid
;
366 ptid
= thread_to_lwp (ptid
, -2);
367 if (PIDGET (ptid
) == -2) /* Inactive thread. */
368 error (_("This version of Solaris can't start inactive threads."));
369 if (info_verbose
&& PIDGET (ptid
) == -1)
370 warning (_("Specified thread %ld seems to have terminated"),
371 GET_THREAD (save_ptid
));
374 beneath
->to_resume (beneath
, ptid
, step
, signo
);
376 do_cleanups (old_chain
);
379 /* Wait for any threads to stop. We may have to convert PTID from a
380 thread ID to an LWP ID, and vice versa on the way out. */
383 sol_thread_wait (struct target_ops
*ops
,
384 ptid_t ptid
, struct target_waitstatus
*ourstatus
)
388 struct target_ops
*beneath
= find_target_beneath (ops
);
389 struct cleanup
*old_chain
;
391 save_ptid
= inferior_ptid
;
392 old_chain
= save_inferior_ptid ();
394 inferior_ptid
= thread_to_lwp (inferior_ptid
, PIDGET (main_ph
.ptid
));
395 if (PIDGET (inferior_ptid
) == -1)
396 inferior_ptid
= procfs_first_available ();
398 if (PIDGET (ptid
) != -1)
400 ptid_t save_ptid
= ptid
;
402 ptid
= thread_to_lwp (ptid
, -2);
403 if (PIDGET (ptid
) == -2) /* Inactive thread. */
404 error (_("This version of Solaris can't start inactive threads."));
405 if (info_verbose
&& PIDGET (ptid
) == -1)
406 warning (_("Specified thread %ld seems to have terminated"),
407 GET_THREAD (save_ptid
));
410 rtnval
= beneath
->to_wait (beneath
, ptid
, ourstatus
);
412 if (ourstatus
->kind
!= TARGET_WAITKIND_EXITED
)
414 /* Map the LWP of interest back to the appropriate thread ID. */
415 rtnval
= lwp_to_thread (rtnval
);
416 if (PIDGET (rtnval
) == -1)
419 /* See if we have a new thread. */
420 if (is_thread (rtnval
)
421 && !ptid_equal (rtnval
, save_ptid
)
422 && (!in_thread_list (rtnval
)
423 || is_exited (rtnval
)))
427 /* During process initialization, we may get here without the thread
428 package being initialized, since that can only happen after we've
429 found the shared libs. */
431 do_cleanups (old_chain
);
437 sol_thread_fetch_registers (struct target_ops
*ops
,
438 struct regcache
*regcache
, int regnum
)
441 td_thrhandle_t thandle
;
444 prfpregset_t fpregset
;
445 gdb_gregset_t
*gregset_p
= &gregset
;
446 gdb_fpregset_t
*fpregset_p
= &fpregset
;
447 struct target_ops
*beneath
= find_target_beneath (ops
);
454 if (!is_thread (inferior_ptid
))
456 /* It's an LWP; pass the request on to the layer beneath. */
457 beneath
->to_fetch_registers (beneath
, regcache
, regnum
);
461 /* Solaris thread: convert INFERIOR_PTID into a td_thrhandle_t. */
462 thread
= GET_THREAD (inferior_ptid
);
464 error (_("sol_thread_fetch_registers: thread == 0"));
466 val
= p_td_ta_map_id2thr (main_ta
, thread
, &thandle
);
468 error (_("sol_thread_fetch_registers: td_ta_map_id2thr: %s"),
469 td_err_string (val
));
471 /* Get the general-purpose registers. */
473 val
= p_td_thr_getgregs (&thandle
, gregset
);
474 if (val
!= TD_OK
&& val
!= TD_PARTIALREG
)
475 error (_("sol_thread_fetch_registers: td_thr_getgregs %s"),
476 td_err_string (val
));
478 /* For SPARC, TD_PARTIALREG means that only %i0...%i7, %l0..%l7, %pc
479 and %sp are saved (by a thread context switch). */
481 /* And, now the floating-point registers. */
483 val
= p_td_thr_getfpregs (&thandle
, &fpregset
);
484 if (val
!= TD_OK
&& val
!= TD_NOFPREGS
)
485 error (_("sol_thread_fetch_registers: td_thr_getfpregs %s"),
486 td_err_string (val
));
488 /* Note that we must call supply_gregset and supply_fpregset *after*
489 calling the td routines because the td routines call ps_lget*
490 which affect the values stored in the registers array. */
492 supply_gregset (regcache
, (const gdb_gregset_t
*) gregset_p
);
493 supply_fpregset (regcache
, (const gdb_fpregset_t
*) fpregset_p
);
496 /* FIXME: libthread_db doesn't seem to handle this right. */
497 val
= td_thr_getxregsize (&thandle
, &xregsize
);
498 if (val
!= TD_OK
&& val
!= TD_NOXREGS
)
499 error (_("sol_thread_fetch_registers: td_thr_getxregsize %s"),
500 td_err_string (val
));
504 xregset
= alloca (xregsize
);
505 val
= td_thr_getxregs (&thandle
, xregset
);
507 error (_("sol_thread_fetch_registers: td_thr_getxregs %s"),
508 td_err_string (val
));
514 sol_thread_store_registers (struct target_ops
*ops
,
515 struct regcache
*regcache
, int regnum
)
518 td_thrhandle_t thandle
;
521 prfpregset_t fpregset
;
527 if (!is_thread (inferior_ptid
))
529 struct target_ops
*beneath
= find_target_beneath (ops
);
531 /* It's an LWP; pass the request on to the layer beneath. */
532 beneath
->to_store_registers (beneath
, regcache
, regnum
);
536 /* Solaris thread: convert INFERIOR_PTID into a td_thrhandle_t. */
537 thread
= GET_THREAD (inferior_ptid
);
539 val
= p_td_ta_map_id2thr (main_ta
, thread
, &thandle
);
541 error (_("sol_thread_store_registers: td_ta_map_id2thr %s"),
542 td_err_string (val
));
546 /* Not writing all the registers. */
547 char old_value
[MAX_REGISTER_SIZE
];
549 /* Save new register value. */
550 regcache_raw_collect (regcache
, regnum
, old_value
);
552 val
= p_td_thr_getgregs (&thandle
, gregset
);
554 error (_("sol_thread_store_registers: td_thr_getgregs %s"),
555 td_err_string (val
));
556 val
= p_td_thr_getfpregs (&thandle
, &fpregset
);
558 error (_("sol_thread_store_registers: td_thr_getfpregs %s"),
559 td_err_string (val
));
561 /* Restore new register value. */
562 regcache_raw_supply (regcache
, regnum
, old_value
);
565 /* FIXME: libthread_db doesn't seem to handle this right. */
566 val
= td_thr_getxregsize (&thandle
, &xregsize
);
567 if (val
!= TD_OK
&& val
!= TD_NOXREGS
)
568 error (_("sol_thread_store_registers: td_thr_getxregsize %s"),
569 td_err_string (val
));
573 xregset
= alloca (xregsize
);
574 val
= td_thr_getxregs (&thandle
, xregset
);
576 error (_("sol_thread_store_registers: td_thr_getxregs %s"),
577 td_err_string (val
));
582 fill_gregset (regcache
, (gdb_gregset_t
*) &gregset
, regnum
);
583 fill_fpregset (regcache
, (gdb_fpregset_t
*) &fpregset
, regnum
);
585 val
= p_td_thr_setgregs (&thandle
, gregset
);
587 error (_("sol_thread_store_registers: td_thr_setgregs %s"),
588 td_err_string (val
));
589 val
= p_td_thr_setfpregs (&thandle
, &fpregset
);
591 error (_("sol_thread_store_registers: td_thr_setfpregs %s"),
592 td_err_string (val
));
595 /* FIXME: libthread_db doesn't seem to handle this right. */
596 val
= td_thr_getxregsize (&thandle
, &xregsize
);
597 if (val
!= TD_OK
&& val
!= TD_NOXREGS
)
598 error (_("sol_thread_store_registers: td_thr_getxregsize %s"),
599 td_err_string (val
));
601 /* ??? Should probably do something about writing the xregs here,
602 but what are they? */
606 /* Perform partial transfers on OBJECT. See target_read_partial and
607 target_write_partial for details of each variant. One, and only
608 one, of readbuf or writebuf must be non-NULL. */
611 sol_thread_xfer_partial (struct target_ops
*ops
, enum target_object object
,
612 const char *annex
, gdb_byte
*readbuf
,
613 const gdb_byte
*writebuf
,
614 ULONGEST offset
, LONGEST len
)
617 struct cleanup
*old_chain
;
618 struct target_ops
*beneath
= find_target_beneath (ops
);
620 old_chain
= save_inferior_ptid ();
622 if (is_thread (inferior_ptid
) || !target_thread_alive (inferior_ptid
))
624 /* It's either a thread or an LWP that isn't alive. Any live
625 LWP will do so use the first available.
627 NOTE: We don't need to call switch_to_thread; we're just
629 inferior_ptid
= procfs_first_available ();
632 retval
= beneath
->to_xfer_partial (beneath
, object
, annex
,
633 readbuf
, writebuf
, offset
, len
);
635 do_cleanups (old_chain
);
641 check_for_thread_db (void)
646 /* Do nothing if we couldn't load libthread_db.so.1. */
647 if (p_td_ta_new
== NULL
)
650 if (sol_thread_active
)
651 /* Nothing to do. The thread library was already detected and the
652 target vector was already activated. */
655 /* Now, initialize libthread_db. This needs to be done after the
656 shared libraries are located because it needs information from
657 the user's thread library. */
662 warning (_("sol_thread_new_objfile: td_init: %s"), td_err_string (err
));
666 /* Now attempt to open a connection to the thread library. */
667 err
= p_td_ta_new (&main_ph
, &main_ta
);
671 /* No thread library was detected. */
675 printf_unfiltered (_("[Thread debugging using libthread_db enabled]\n"));
677 /* The thread library was detected. Activate the sol_thread target. */
678 push_target (&sol_thread_ops
);
679 sol_thread_active
= 1;
681 main_ph
.ptid
= inferior_ptid
; /* Save for xfer_memory. */
682 ptid
= lwp_to_thread (inferior_ptid
);
683 if (PIDGET (ptid
) != -1)
684 inferior_ptid
= ptid
;
686 target_find_new_threads ();
690 warning (_("Cannot initialize thread debugging library: %s"),
691 td_err_string (err
));
696 /* This routine is called whenever a new symbol table is read in, or
697 when all symbol tables are removed. libthread_db can only be
698 initialized when it finds the right variables in libthread.so.
699 Since it's a shared library, those variables don't show up until
700 the library gets mapped and the symbol table is read in. */
703 sol_thread_new_objfile (struct objfile
*objfile
)
706 check_for_thread_db ();
709 /* Clean up after the inferior dies. */
712 sol_thread_mourn_inferior (struct target_ops
*ops
)
714 struct target_ops
*beneath
= find_target_beneath (ops
);
716 sol_thread_active
= 0;
720 beneath
->to_mourn_inferior (beneath
);
723 /* Return true if PTID is still active in the inferior. */
726 sol_thread_alive (struct target_ops
*ops
, ptid_t ptid
)
728 if (is_thread (ptid
))
730 /* It's a (user-level) thread. */
735 pid
= GET_THREAD (ptid
);
736 if ((val
= p_td_ta_map_id2thr (main_ta
, pid
, &th
)) != TD_OK
)
737 return 0; /* Thread not found. */
738 if ((val
= p_td_thr_validate (&th
)) != TD_OK
)
739 return 0; /* Thread not valid. */
740 return 1; /* Known thread. */
744 struct target_ops
*beneath
= find_target_beneath (ops
);
746 /* It's an LPW; pass the request on to the layer below. */
747 return beneath
->to_thread_alive (beneath
, ptid
);
752 /* These routines implement the lower half of the thread_db interface,
753 i.e. the ps_* routines. */
755 /* Various versions of <proc_service.h> have slightly different
756 function prototypes. In particular, we have
759 struct ps_prochandle * const struct ps_prochandle *
764 Which one you have depends on the Solaris version and what patches
765 you've applied. On the theory that there are only two major
766 variants, we have configure check the prototype of ps_pdwrite (),
767 and use that info to make appropriate typedefs here. */
769 #ifdef PROC_SERVICE_IS_OLD
770 typedef const struct ps_prochandle
*gdb_ps_prochandle_t
;
771 typedef char *gdb_ps_read_buf_t
;
772 typedef char *gdb_ps_write_buf_t
;
773 typedef int gdb_ps_size_t
;
774 typedef psaddr_t gdb_ps_addr_t
;
776 typedef struct ps_prochandle
*gdb_ps_prochandle_t
;
777 typedef void *gdb_ps_read_buf_t
;
778 typedef const void *gdb_ps_write_buf_t
;
779 typedef size_t gdb_ps_size_t
;
780 typedef psaddr_t gdb_ps_addr_t
;
783 /* The next four routines are called by libthread_db to tell us to
784 stop and stop a particular process or lwp. Since GDB ensures that
785 these are all stopped by the time we call anything in thread_db,
786 these routines need to do nothing. */
791 ps_pstop (gdb_ps_prochandle_t ph
)
796 /* Process continue. */
799 ps_pcontinue (gdb_ps_prochandle_t ph
)
807 ps_lstop (gdb_ps_prochandle_t ph
, lwpid_t lwpid
)
815 ps_lcontinue (gdb_ps_prochandle_t ph
, lwpid_t lwpid
)
820 /* Looks up the symbol LD_SYMBOL_NAME in the debugger's symbol table. */
823 ps_pglobal_lookup (gdb_ps_prochandle_t ph
, const char *ld_object_name
,
824 const char *ld_symbol_name
, gdb_ps_addr_t
*ld_symbol_addr
)
826 struct minimal_symbol
*ms
;
828 ms
= lookup_minimal_symbol (ld_symbol_name
, NULL
, NULL
);
832 *ld_symbol_addr
= SYMBOL_VALUE_ADDRESS (ms
);
836 /* Common routine for reading and writing memory. */
839 rw_common (int dowrite
, const struct ps_prochandle
*ph
, gdb_ps_addr_t addr
,
843 struct cleanup
*old_chain
;
845 old_chain
= save_inferior_ptid ();
847 if (is_thread (inferior_ptid
) || !target_thread_alive (inferior_ptid
))
849 /* It's either a thread or an LWP that isn't alive. Any live
850 LWP will do so use the first available.
852 NOTE: We don't need to call switch_to_thread; we're just
854 inferior_ptid
= procfs_first_available ();
857 #if defined (__sparcv9)
858 /* For Sparc64 cross Sparc32, make sure the address has not been
859 accidentally sign-extended (or whatever) to beyond 32 bits. */
860 if (bfd_get_arch_size (exec_bfd
) == 32)
865 ret
= target_write_memory (addr
, buf
, size
);
867 ret
= target_read_memory (addr
, buf
, size
);
869 do_cleanups (old_chain
);
871 return (ret
== 0 ? PS_OK
: PS_ERR
);
874 /* Copies SIZE bytes from target process .data segment to debugger memory. */
877 ps_pdread (gdb_ps_prochandle_t ph
, gdb_ps_addr_t addr
,
878 gdb_ps_read_buf_t buf
, gdb_ps_size_t size
)
880 return rw_common (0, ph
, addr
, buf
, size
);
883 /* Copies SIZE bytes from debugger memory .data segment to target process. */
886 ps_pdwrite (gdb_ps_prochandle_t ph
, gdb_ps_addr_t addr
,
887 gdb_ps_write_buf_t buf
, gdb_ps_size_t size
)
889 return rw_common (1, ph
, addr
, (char *) buf
, size
);
892 /* Copies SIZE bytes from target process .text segment to debugger memory. */
895 ps_ptread (gdb_ps_prochandle_t ph
, gdb_ps_addr_t addr
,
896 gdb_ps_read_buf_t buf
, gdb_ps_size_t size
)
898 return rw_common (0, ph
, addr
, buf
, size
);
901 /* Copies SIZE bytes from debugger memory .text segment to target process. */
904 ps_ptwrite (gdb_ps_prochandle_t ph
, gdb_ps_addr_t addr
,
905 gdb_ps_write_buf_t buf
, gdb_ps_size_t size
)
907 return rw_common (1, ph
, addr
, (char *) buf
, size
);
910 /* Get general-purpose registers for LWP. */
913 ps_lgetregs (gdb_ps_prochandle_t ph
, lwpid_t lwpid
, prgregset_t gregset
)
915 struct cleanup
*old_chain
;
916 struct regcache
*regcache
;
918 old_chain
= save_inferior_ptid ();
920 inferior_ptid
= BUILD_LWP (lwpid
, PIDGET (inferior_ptid
));
921 regcache
= get_thread_regcache (inferior_ptid
);
923 target_fetch_registers (regcache
, -1);
924 fill_gregset (regcache
, (gdb_gregset_t
*) gregset
, -1);
926 do_cleanups (old_chain
);
931 /* Set general-purpose registers for LWP. */
934 ps_lsetregs (gdb_ps_prochandle_t ph
, lwpid_t lwpid
,
935 const prgregset_t gregset
)
937 struct cleanup
*old_chain
;
938 struct regcache
*regcache
;
940 old_chain
= save_inferior_ptid ();
942 inferior_ptid
= BUILD_LWP (lwpid
, PIDGET (inferior_ptid
));
943 regcache
= get_thread_regcache (inferior_ptid
);
945 supply_gregset (regcache
, (const gdb_gregset_t
*) gregset
);
946 target_store_registers (regcache
, -1);
948 do_cleanups (old_chain
);
953 /* Log a message (sends to gdb_stderr). */
956 ps_plog (const char *fmt
, ...)
960 va_start (args
, fmt
);
962 vfprintf_filtered (gdb_stderr
, fmt
, args
);
965 /* Get size of extra register set. Currently a noop. */
968 ps_lgetxregsize (gdb_ps_prochandle_t ph
, lwpid_t lwpid
, int *xregsize
)
975 val
= get_lwp_fd (ph
, lwpid
, &lwp_fd
);
979 if (ioctl (lwp_fd
, PIOCGXREGSIZE
, ®size
))
982 return PS_NOFREGS
; /* XXX Wrong code, but this is the closest
983 thing in proc_service.h */
985 print_sys_errmsg ("ps_lgetxregsize (): PIOCGXREGSIZE", errno
);
993 /* Get extra register set. Currently a noop. */
996 ps_lgetxregs (gdb_ps_prochandle_t ph
, lwpid_t lwpid
, caddr_t xregset
)
1002 val
= get_lwp_fd (ph
, lwpid
, &lwp_fd
);
1006 if (ioctl (lwp_fd
, PIOCGXREG
, xregset
))
1008 print_sys_errmsg ("ps_lgetxregs (): PIOCGXREG", errno
);
1016 /* Set extra register set. Currently a noop. */
1019 ps_lsetxregs (gdb_ps_prochandle_t ph
, lwpid_t lwpid
, caddr_t xregset
)
1025 val
= get_lwp_fd (ph
, lwpid
, &lwp_fd
);
1029 if (ioctl (lwp_fd
, PIOCSXREG
, xregset
))
1031 print_sys_errmsg ("ps_lsetxregs (): PIOCSXREG", errno
);
1039 /* Get floating-point registers for LWP. */
1042 ps_lgetfpregs (gdb_ps_prochandle_t ph
, lwpid_t lwpid
,
1043 prfpregset_t
*fpregset
)
1045 struct cleanup
*old_chain
;
1046 struct regcache
*regcache
;
1048 old_chain
= save_inferior_ptid ();
1050 inferior_ptid
= BUILD_LWP (lwpid
, PIDGET (inferior_ptid
));
1051 regcache
= get_thread_regcache (inferior_ptid
);
1053 target_fetch_registers (regcache
, -1);
1054 fill_fpregset (regcache
, (gdb_fpregset_t
*) fpregset
, -1);
1056 do_cleanups (old_chain
);
1061 /* Set floating-point regs for LWP */
1064 ps_lsetfpregs (gdb_ps_prochandle_t ph
, lwpid_t lwpid
,
1065 const prfpregset_t
* fpregset
)
1067 struct cleanup
*old_chain
;
1068 struct regcache
*regcache
;
1070 old_chain
= save_inferior_ptid ();
1072 inferior_ptid
= BUILD_LWP (lwpid
, PIDGET (inferior_ptid
));
1073 regcache
= get_thread_regcache (inferior_ptid
);
1075 supply_fpregset (regcache
, (const gdb_fpregset_t
*) fpregset
);
1076 target_store_registers (regcache
, -1);
1078 do_cleanups (old_chain
);
1083 #ifdef PR_MODEL_LP64
1084 /* Identify process as 32-bit or 64-bit. At the moment we're using
1085 BFD to do this. There might be a more Solaris-specific
1086 (e.g. procfs) method, but this ought to work. */
1089 ps_pdmodel (gdb_ps_prochandle_t ph
, int *data_model
)
1092 *data_model
= PR_MODEL_UNKNOWN
;
1093 else if (bfd_get_arch_size (exec_bfd
) == 32)
1094 *data_model
= PR_MODEL_ILP32
;
1096 *data_model
= PR_MODEL_LP64
;
1100 #endif /* PR_MODEL_LP64 */
1102 #if (defined(__i386__) || defined(__x86_64__)) && defined (sun)
1104 /* Reads the local descriptor table of a LWP.
1106 This function is necessary on x86-solaris only. Without it, the loading
1107 of libthread_db would fail because of ps_lgetLDT being undefined. */
1110 ps_lgetLDT (gdb_ps_prochandle_t ph
, lwpid_t lwpid
,
1113 /* NOTE: only used on Solaris, therefore OK to refer to procfs.c. */
1114 extern struct ssd
*procfs_find_LDT_entry (ptid_t
);
1117 /* FIXME: can't I get the process ID from the prochandle or
1120 if (PIDGET (inferior_ptid
) <= 0 || lwpid
<= 0)
1123 ret
= procfs_find_LDT_entry (BUILD_LWP (lwpid
, PIDGET (inferior_ptid
)));
1126 memcpy (pldt
, ret
, sizeof (struct ssd
));
1130 /* LDT not found. */
1136 /* Convert PTID to printable form. */
1139 solaris_pid_to_str (struct target_ops
*ops
, ptid_t ptid
)
1141 static char buf
[100];
1143 if (is_thread (ptid
))
1147 lwp
= thread_to_lwp (ptid
, -2);
1149 if (PIDGET (lwp
) == -1)
1150 sprintf (buf
, "Thread %ld (defunct)", GET_THREAD (ptid
));
1151 else if (PIDGET (lwp
) != -2)
1152 sprintf (buf
, "Thread %ld (LWP %ld)",
1153 GET_THREAD (ptid
), GET_LWP (lwp
));
1155 sprintf (buf
, "Thread %ld ", GET_THREAD (ptid
));
1157 else if (GET_LWP (ptid
) != 0)
1158 sprintf (buf
, "LWP %ld ", GET_LWP (ptid
));
1160 sprintf (buf
, "process %d ", PIDGET (ptid
));
1166 /* Worker bee for find_new_threads. Callback function that gets
1167 called once per user-level thread (i.e. not for LWP's). */
1170 sol_find_new_threads_callback (const td_thrhandle_t
*th
, void *ignored
)
1176 retval
= p_td_thr_get_info (th
, &ti
);
1177 if (retval
!= TD_OK
)
1180 ptid
= BUILD_THREAD (ti
.ti_tid
, PIDGET (inferior_ptid
));
1181 if (!in_thread_list (ptid
) || is_exited (ptid
))
1188 sol_find_new_threads (struct target_ops
*ops
)
1190 struct target_ops
*beneath
= find_target_beneath (ops
);
1192 /* First Find any new LWP's. */
1193 if (beneath
->to_find_new_threads
!= NULL
)
1194 beneath
->to_find_new_threads (beneath
);
1196 /* Then find any new user-level threads. */
1197 p_td_ta_thr_iter (main_ta
, sol_find_new_threads_callback
, (void *) 0,
1198 TD_THR_ANY_STATE
, TD_THR_LOWEST_PRIORITY
,
1199 TD_SIGNO_MASK
, TD_THR_ANY_USER_FLAGS
);
1202 /* Worker bee for the "info sol-thread" command. This is a callback
1203 function that gets called once for each Solaris user-level thread
1204 (i.e. not for LWPs) in the inferior. Print anything interesting
1205 that we can think of. */
1208 info_cb (const td_thrhandle_t
*th
, void *s
)
1213 ret
= p_td_thr_get_info (th
, &ti
);
1216 printf_filtered ("%s thread #%d, lwp %d, ",
1217 ti
.ti_type
== TD_THR_SYSTEM
? "system" : "user ",
1218 ti
.ti_tid
, ti
.ti_lid
);
1219 switch (ti
.ti_state
)
1222 case TD_THR_UNKNOWN
:
1223 printf_filtered ("<unknown state>");
1225 case TD_THR_STOPPED
:
1226 printf_filtered ("(stopped)");
1229 printf_filtered ("(run) ");
1232 printf_filtered ("(active) ");
1235 printf_filtered ("(zombie) ");
1238 printf_filtered ("(asleep) ");
1240 case TD_THR_STOPPED_ASLEEP
:
1241 printf_filtered ("(stopped asleep)");
1244 /* Print thr_create start function. */
1245 if (ti
.ti_startfunc
!= 0)
1247 struct minimal_symbol
*msym
;
1248 msym
= lookup_minimal_symbol_by_pc (ti
.ti_startfunc
);
1250 printf_filtered (" startfunc: %s\n",
1251 SYMBOL_PRINT_NAME (msym
));
1253 printf_filtered (" startfunc: 0x%s\n", paddr (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: 0x%s\n", paddr (ti
.ti_startfunc
));
1268 /* Wrap up line, if necessary. */
1269 if (ti
.ti_state
!= TD_THR_SLEEP
&& ti
.ti_startfunc
== 0)
1270 printf_filtered ("\n"); /* don't you hate counting newlines? */
1273 warning (_("info sol-thread: failed to get info for thread."));
1278 /* List some state about each Solaris user-level thread in the
1282 info_solthreads (char *args
, int from_tty
)
1284 p_td_ta_thr_iter (main_ta
, info_cb
, args
,
1285 TD_THR_ANY_STATE
, TD_THR_LOWEST_PRIORITY
,
1286 TD_SIGNO_MASK
, TD_THR_ANY_USER_FLAGS
);
1290 init_sol_thread_ops (void)
1292 sol_thread_ops
.to_shortname
= "solaris-threads";
1293 sol_thread_ops
.to_longname
= "Solaris threads and pthread.";
1294 sol_thread_ops
.to_doc
= "Solaris threads and pthread support.";
1295 sol_thread_ops
.to_detach
= sol_thread_detach
;
1296 sol_thread_ops
.to_resume
= sol_thread_resume
;
1297 sol_thread_ops
.to_wait
= sol_thread_wait
;
1298 sol_thread_ops
.to_fetch_registers
= sol_thread_fetch_registers
;
1299 sol_thread_ops
.to_store_registers
= sol_thread_store_registers
;
1300 sol_thread_ops
.to_xfer_partial
= sol_thread_xfer_partial
;
1301 sol_thread_ops
.to_mourn_inferior
= sol_thread_mourn_inferior
;
1302 sol_thread_ops
.to_thread_alive
= sol_thread_alive
;
1303 sol_thread_ops
.to_pid_to_str
= solaris_pid_to_str
;
1304 sol_thread_ops
.to_find_new_threads
= sol_find_new_threads
;
1305 sol_thread_ops
.to_stratum
= thread_stratum
;
1306 sol_thread_ops
.to_magic
= OPS_MAGIC
;
1310 _initialize_sol_thread (void)
1314 init_sol_thread_ops ();
1316 dlhandle
= dlopen ("libthread_db.so.1", RTLD_NOW
);
1320 #define resolve(X) \
1321 if (!(p_##X = dlsym (dlhandle, #X))) \
1325 resolve (td_ta_new
);
1326 resolve (td_ta_delete
);
1328 resolve (td_ta_get_ph
);
1329 resolve (td_ta_get_nthreads
);
1330 resolve (td_ta_tsd_iter
);
1331 resolve (td_ta_thr_iter
);
1332 resolve (td_thr_validate
);
1333 resolve (td_thr_tsd
);
1334 resolve (td_thr_get_info
);
1335 resolve (td_thr_getfpregs
);
1336 resolve (td_thr_getxregsize
);
1337 resolve (td_thr_getxregs
);
1338 resolve (td_thr_sigsetmask
);
1339 resolve (td_thr_setprio
);
1340 resolve (td_thr_setsigpending
);
1341 resolve (td_thr_setfpregs
);
1342 resolve (td_thr_setxregs
);
1343 resolve (td_ta_map_id2thr
);
1344 resolve (td_ta_map_lwp2thr
);
1345 resolve (td_thr_getgregs
);
1346 resolve (td_thr_setgregs
);
1348 add_target (&sol_thread_ops
);
1350 add_cmd ("sol-threads", class_maintenance
, info_solthreads
,
1351 _("Show info on Solaris user threads."), &maintenanceinfolist
);
1353 /* Hook into new_objfile notification. */
1354 observer_attach_new_objfile (sol_thread_new_objfile
);
1358 fprintf_unfiltered (gdb_stderr
, "\
1359 [GDB will not be able to debug user-mode threads: %s]\n", dlerror ());