1 /* Solaris threads debugging interface.
3 Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
4 2005 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 2 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, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 Boston, MA 02110-1301, USA. */
23 /* This module implements a sort of half target that sits between the
24 machine-independent parts of GDB and the /proc interface (procfs.c)
25 to provide access to the Solaris user-mode thread implementation.
27 Solaris threads are true user-mode threads, which are invoked via
28 the thr_* and pthread_* (native and POSIX respectivly) interfaces.
29 These are mostly implemented in user-space, with all thread context
30 kept in various structures that live in the user's heap. These
31 should not be confused with lightweight processes (LWPs), which are
32 implemented by the kernel, and scheduled without explicit
33 intervention by the process.
35 Just to confuse things a little, Solaris threads (both native and
36 POSIX) are actually implemented using LWPs. In general, there are
37 going to be more threads than LWPs. There is no fixed
38 correspondence between a thread and an LWP. When a thread wants to
39 run, it gets scheduled onto the first available LWP and can
40 therefore migrate from one LWP to another as time goes on. A
41 sleeping thread may not be associated with an LWP at all!
43 To make it possible to mess with threads, Sun provides a library
44 called libthread_db.so.1 (not to be confused with
45 libthread_db.so.0, which doesn't have a published interface). This
46 interface has an upper part, which it provides, and a lower part
47 which we provide. The upper part consists of the td_* routines,
48 which allow us to find all the threads, query their state, etc...
49 The lower part consists of all of the ps_*, which are used by the
50 td_* routines to read/write memory, manipulate LWPs, lookup
51 symbols, etc... The ps_* routines actually do most of their work
52 by calling functions in procfs.c. */
56 #include <proc_service.h>
57 #include <thread_db.h>
58 #include "gdbthread.h"
70 #include "gdb_string.h"
72 extern struct target_ops sol_thread_ops
; /* Forward declaration */
73 extern struct target_ops sol_core_ops
; /* Forward declaration */
75 /* place to store core_ops before we overwrite it */
76 static struct target_ops orig_core_ops
;
78 struct target_ops sol_thread_ops
;
79 struct target_ops sol_core_ops
;
81 extern int procfs_suppress_run
;
82 extern struct target_ops procfs_ops
; /* target vector for procfs.c */
83 extern struct target_ops core_ops
; /* target vector for corelow.c */
84 extern char *procfs_pid_to_str (ptid_t ptid
);
86 /* Prototypes for supply_gregset etc. */
89 /* This struct is defined by us, but mainly used for the proc_service
90 interface. We don't have much use for it, except as a handy place
91 to get a real PID for memory accesses. */
104 static struct ps_prochandle main_ph
;
105 static td_thragent_t
*main_ta
;
106 static int sol_thread_active
= 0;
108 static void sol_thread_resume (ptid_t ptid
, int step
, enum target_signal signo
);
109 static int sol_thread_alive (ptid_t ptid
);
110 static void sol_core_close (int quitting
);
112 static void init_sol_thread_ops (void);
113 static void init_sol_core_ops (void);
115 /* Default definitions: These must be defined in tm.h if they are to
116 be shared with a process module such as procfs. */
118 #define GET_PID(ptid) ptid_get_pid (ptid)
119 #define GET_LWP(ptid) ptid_get_lwp (ptid)
120 #define GET_THREAD(ptid) ptid_get_tid (ptid)
122 #define is_lwp(ptid) (GET_LWP (ptid) != 0)
123 #define is_thread(ptid) (GET_THREAD (ptid) != 0)
125 #define BUILD_LWP(lwp, pid) ptid_build (pid, lwp, 0)
126 #define BUILD_THREAD(tid, pid) ptid_build (pid, 0, tid)
128 /* Pointers to routines from libthread_db resolved by dlopen(). */
130 static void (*p_td_log
)(const int on_off
);
131 static td_err_e (*p_td_ta_new
)(const struct ps_prochandle
*ph_p
,
132 td_thragent_t
**ta_pp
);
133 static td_err_e (*p_td_ta_delete
)(td_thragent_t
*ta_p
);
134 static td_err_e (*p_td_init
)(void);
135 static td_err_e (*p_td_ta_get_ph
)(const td_thragent_t
*ta_p
,
136 struct ps_prochandle
**ph_pp
);
137 static td_err_e (*p_td_ta_get_nthreads
)(const td_thragent_t
*ta_p
,
139 static td_err_e (*p_td_ta_tsd_iter
)(const td_thragent_t
*ta_p
,
140 td_key_iter_f
*cb
, void *cbdata_p
);
141 static td_err_e (*p_td_ta_thr_iter
)(const td_thragent_t
*ta_p
,
142 td_thr_iter_f
*cb
, void *cbdata_p
,
143 td_thr_state_e state
, int ti_pri
,
144 sigset_t
*ti_sigmask_p
,
145 unsigned ti_user_flags
);
146 static td_err_e (*p_td_thr_validate
)(const td_thrhandle_t
*th_p
);
147 static td_err_e (*p_td_thr_tsd
)(const td_thrhandle_t
* th_p
,
148 const thread_key_t key
, void **data_pp
);
149 static td_err_e (*p_td_thr_get_info
)(const td_thrhandle_t
*th_p
,
151 static td_err_e (*p_td_thr_getfpregs
)(const td_thrhandle_t
*th_p
,
152 prfpregset_t
*fpregset
);
153 static td_err_e (*p_td_thr_getxregsize
)(const td_thrhandle_t
*th_p
,
155 static td_err_e (*p_td_thr_getxregs
)(const td_thrhandle_t
*th_p
,
156 const caddr_t xregset
);
157 static td_err_e (*p_td_thr_sigsetmask
)(const td_thrhandle_t
*th_p
,
158 const sigset_t ti_sigmask
);
159 static td_err_e (*p_td_thr_setprio
)(const td_thrhandle_t
*th_p
,
161 static td_err_e (*p_td_thr_setsigpending
)(const td_thrhandle_t
*th_p
,
162 const uchar_t ti_pending_flag
,
163 const sigset_t ti_pending
);
164 static td_err_e (*p_td_thr_setfpregs
)(const td_thrhandle_t
*th_p
,
165 const prfpregset_t
*fpregset
);
166 static td_err_e (*p_td_thr_setxregs
)(const td_thrhandle_t
*th_p
,
167 const caddr_t xregset
);
168 static td_err_e (*p_td_ta_map_id2thr
)(const td_thragent_t
*ta_p
,
170 td_thrhandle_t
*th_p
);
171 static td_err_e (*p_td_ta_map_lwp2thr
)(const td_thragent_t
*ta_p
,
173 td_thrhandle_t
*th_p
);
174 static td_err_e (*p_td_thr_getgregs
)(const td_thrhandle_t
*th_p
,
176 static td_err_e (*p_td_thr_setgregs
)(const td_thrhandle_t
*th_p
,
177 const prgregset_t regset
);
180 /* Return the libthread_db error string associated with ERRCODE. If
181 ERRCODE is unknown, return an appropriate message. */
184 td_err_string (td_err_e errcode
)
186 static struct string_map td_err_table
[] =
188 { TD_OK
, "generic \"call succeeded\"" },
189 { TD_ERR
, "generic error." },
190 { TD_NOTHR
, "no thread can be found to satisfy query" },
191 { TD_NOSV
, "no synch. variable can be found to satisfy query" },
192 { TD_NOLWP
, "no lwp can be found to satisfy query" },
193 { TD_BADPH
, "invalid process handle" },
194 { TD_BADTH
, "invalid thread handle" },
195 { TD_BADSH
, "invalid synchronization handle" },
196 { TD_BADTA
, "invalid thread agent" },
197 { TD_BADKEY
, "invalid key" },
198 { TD_NOMSG
, "td_thr_event_getmsg() called when there was no message" },
199 { TD_NOFPREGS
, "FPU register set not available for given thread" },
200 { TD_NOLIBTHREAD
, "application not linked with libthread" },
201 { TD_NOEVENT
, "requested event is not supported" },
202 { TD_NOCAPAB
, "capability not available" },
203 { TD_DBERR
, "Debugger service failed" },
204 { TD_NOAPLIC
, "Operation not applicable to" },
205 { TD_NOTSD
, "No thread specific data for this thread" },
206 { TD_MALLOC
, "Malloc failed" },
207 { TD_PARTIALREG
, "Only part of register set was written/read" },
208 { TD_NOXREGS
, "X register set not available for given thread" }
210 const int td_err_size
= sizeof td_err_table
/ sizeof (struct string_map
);
214 for (i
= 0; i
< td_err_size
; i
++)
215 if (td_err_table
[i
].num
== errcode
)
216 return td_err_table
[i
].str
;
218 sprintf (buf
, "Unknown libthread_db error code: %d", errcode
);
223 /* Return the the libthread_db state string assicoated with STATECODE.
224 If STATECODE is unknown, return an appropriate message. */
227 td_state_string (td_thr_state_e statecode
)
229 static struct string_map td_thr_state_table
[] =
231 { TD_THR_ANY_STATE
, "any state" },
232 { TD_THR_UNKNOWN
, "unknown" },
233 { TD_THR_STOPPED
, "stopped" },
234 { TD_THR_RUN
, "run" },
235 { TD_THR_ACTIVE
, "active" },
236 { TD_THR_ZOMBIE
, "zombie" },
237 { TD_THR_SLEEP
, "sleep" },
238 { TD_THR_STOPPED_ASLEEP
, "stopped asleep" }
240 const int td_thr_state_table_size
=
241 sizeof td_thr_state_table
/ sizeof (struct string_map
);
245 for (i
= 0; i
< td_thr_state_table_size
; i
++)
246 if (td_thr_state_table
[i
].num
== statecode
)
247 return td_thr_state_table
[i
].str
;
249 sprintf (buf
, "Unknown libthread_db state code: %d", statecode
);
255 /* Convert a POSIX or Solaris thread ID into a LWP ID. If THREAD_ID
256 doesn't exist, that's an error. If it's an inactive thread, return
259 NOTE: This function probably shouldn't call error(). */
262 thread_to_lwp (ptid_t thread_id
, int default_lwp
)
268 if (is_lwp (thread_id
))
269 return thread_id
; /* It's already an LWP ID. */
271 /* It's a thread. Convert to LWP. */
273 val
= p_td_ta_map_id2thr (main_ta
, GET_THREAD (thread_id
), &th
);
275 return pid_to_ptid (-1); /* Thread must have terminated. */
276 else if (val
!= TD_OK
)
277 error (_("thread_to_lwp: td_ta_map_id2thr %s"), td_err_string (val
));
279 val
= p_td_thr_get_info (&th
, &ti
);
281 return pid_to_ptid (-1); /* Thread must have terminated. */
282 else if (val
!= TD_OK
)
283 error (_("thread_to_lwp: td_thr_get_info: %s"), td_err_string (val
));
285 if (ti
.ti_state
!= TD_THR_ACTIVE
)
287 if (default_lwp
!= -1)
288 return pid_to_ptid (default_lwp
);
289 error (_("thread_to_lwp: thread state not active: %s"),
290 td_state_string (ti
.ti_state
));
293 return BUILD_LWP (ti
.ti_lid
, PIDGET (thread_id
));
296 /* Convert an LWP ID into a POSIX or Solaris thread ID. If LWP_ID
297 doesn't exists, that's an error.
299 NOTE: This function probably shouldn't call error(). */
302 lwp_to_thread (ptid_t lwp
)
309 return lwp
; /* It's already a thread ID. */
311 /* It's an LWP. Convert it to a thread ID. */
313 if (!sol_thread_alive (lwp
))
314 return pid_to_ptid (-1); /* Must be a defunct LPW. */
316 val
= p_td_ta_map_lwp2thr (main_ta
, GET_LWP (lwp
), &th
);
318 return pid_to_ptid (-1); /* Thread must have terminated. */
319 else if (val
!= TD_OK
)
320 error (_("lwp_to_thread: td_ta_map_lwp2thr: %s."), td_err_string (val
));
322 val
= p_td_thr_validate (&th
);
324 return lwp
; /* Unknown to libthread; just return LPW, */
325 else if (val
!= TD_OK
)
326 error (_("lwp_to_thread: td_thr_validate: %s."), td_err_string (val
));
328 val
= p_td_thr_get_info (&th
, &ti
);
330 return pid_to_ptid (-1); /* Thread must have terminated. */
331 else if (val
!= TD_OK
)
332 error (_("lwp_to_thread: td_thr_get_info: %s."), td_err_string (val
));
334 return BUILD_THREAD (ti
.ti_tid
, PIDGET (lwp
));
338 /* Most target vector functions from here on actually just pass
339 through to procfs.c, as they don't need to do anything specific for
343 sol_thread_open (char *arg
, int from_tty
)
345 procfs_ops
.to_open (arg
, from_tty
);
348 /* Attach to process PID, then initialize for debugging it and wait
349 for the trace-trap that results from attaching. */
352 sol_thread_attach (char *args
, int from_tty
)
354 procfs_ops
.to_attach (args
, from_tty
);
356 /* Must get symbols from shared libraries before libthread_db can run! */
357 solib_add (NULL
, from_tty
, (struct target_ops
*) 0, auto_solib_add
);
359 if (sol_thread_active
)
361 printf_filtered ("sol-thread active.\n");
362 main_ph
.ptid
= inferior_ptid
; /* Save for xfer_memory. */
363 push_target (&sol_thread_ops
);
364 inferior_ptid
= lwp_to_thread (inferior_ptid
);
365 if (PIDGET (inferior_ptid
) == -1)
366 inferior_ptid
= main_ph
.ptid
;
368 add_thread (inferior_ptid
);
371 /* FIXME: Might want to iterate over all the threads and register
375 /* Take a program previously attached to and detaches it. The program
376 resumes execution and will no longer stop on signals, etc. We'd
377 better not have left any breakpoints in the program or it'll die
378 when it hits one. For this to work, it may be necessary for the
379 process to have been previously attached. It *might* work if the
380 program was started via the normal ptrace (PTRACE_TRACEME). */
383 sol_thread_detach (char *args
, int from_tty
)
385 inferior_ptid
= pid_to_ptid (PIDGET (main_ph
.ptid
));
386 unpush_target (&sol_thread_ops
);
387 procfs_ops
.to_detach (args
, from_tty
);
390 /* Resume execution of process PTID. If STEP is nozero, then just
391 single step it. If SIGNAL is nonzero, restart it with that signal
392 activated. We may have to convert PTID from a thread ID to an LWP
396 sol_thread_resume (ptid_t ptid
, int step
, enum target_signal signo
)
398 struct cleanup
*old_chain
;
400 old_chain
= save_inferior_ptid ();
402 inferior_ptid
= thread_to_lwp (inferior_ptid
, PIDGET (main_ph
.ptid
));
403 if (PIDGET (inferior_ptid
) == -1)
404 inferior_ptid
= procfs_first_available ();
406 if (PIDGET (ptid
) != -1)
408 ptid_t save_ptid
= ptid
;
410 ptid
= thread_to_lwp (ptid
, -2);
411 if (PIDGET (ptid
) == -2) /* Inactive thread. */
412 error (_("This version of Solaris can't start inactive threads."));
413 if (info_verbose
&& PIDGET (ptid
) == -1)
414 warning (_("Specified thread %ld seems to have terminated"),
415 GET_THREAD (save_ptid
));
418 procfs_ops
.to_resume (ptid
, step
, signo
);
420 do_cleanups (old_chain
);
423 /* Wait for any threads to stop. We may have to convert PIID from a
424 thread ID to an LWP ID, and vice versa on the way out. */
427 sol_thread_wait (ptid_t ptid
, struct target_waitstatus
*ourstatus
)
431 struct cleanup
*old_chain
;
433 save_ptid
= inferior_ptid
;
434 old_chain
= save_inferior_ptid ();
436 inferior_ptid
= thread_to_lwp (inferior_ptid
, PIDGET (main_ph
.ptid
));
437 if (PIDGET (inferior_ptid
) == -1)
438 inferior_ptid
= procfs_first_available ();
440 if (PIDGET (ptid
) != -1)
442 ptid_t save_ptid
= ptid
;
444 ptid
= thread_to_lwp (ptid
, -2);
445 if (PIDGET (ptid
) == -2) /* Inactive thread. */
446 error (_("This version of Solaris can't start inactive threads."));
447 if (info_verbose
&& PIDGET (ptid
) == -1)
448 warning (_("Specified thread %ld seems to have terminated"),
449 GET_THREAD (save_ptid
));
452 rtnval
= procfs_ops
.to_wait (ptid
, ourstatus
);
454 if (ourstatus
->kind
!= TARGET_WAITKIND_EXITED
)
456 /* Map the LWP of interest back to the appropriate thread ID. */
457 rtnval
= lwp_to_thread (rtnval
);
458 if (PIDGET (rtnval
) == -1)
461 /* See if we have a new thread. */
462 if (is_thread (rtnval
)
463 && !ptid_equal (rtnval
, save_ptid
)
464 && !in_thread_list (rtnval
))
466 printf_filtered ("[New %s]\n", target_pid_to_str (rtnval
));
471 /* During process initialization, we may get here without the thread
472 package being initialized, since that can only happen after we've
473 found the shared libs. */
475 do_cleanups (old_chain
);
481 sol_thread_fetch_registers (int regnum
)
484 td_thrhandle_t thandle
;
487 prfpregset_t fpregset
;
493 if (!is_thread (inferior_ptid
))
495 /* It's an LWP; pass the request on to procfs. */
496 if (target_has_execution
)
497 procfs_ops
.to_fetch_registers (regnum
);
499 orig_core_ops
.to_fetch_registers (regnum
);
503 /* Solaris thread: convert INFERIOR_PTID into a td_thrhandle_t. */
504 thread
= GET_THREAD (inferior_ptid
);
506 error (_("sol_thread_fetch_registers: thread == 0"));
508 val
= p_td_ta_map_id2thr (main_ta
, thread
, &thandle
);
510 error (_("sol_thread_fetch_registers: td_ta_map_id2thr: %s"),
511 td_err_string (val
));
513 /* Get the general-purpose registers. */
515 val
= p_td_thr_getgregs (&thandle
, gregset
);
516 if (val
!= TD_OK
&& val
!= TD_PARTIALREG
)
517 error (_("sol_thread_fetch_registers: td_thr_getgregs %s"),
518 td_err_string (val
));
520 /* For SPARC, TD_PARTIALREG means that only %i0...%i7, %l0..%l7, %pc
521 and %sp are saved (by a thread context switch). */
523 /* And, now the floating-point registers. */
525 val
= p_td_thr_getfpregs (&thandle
, &fpregset
);
526 if (val
!= TD_OK
&& val
!= TD_NOFPREGS
)
527 error (_("sol_thread_fetch_registers: td_thr_getfpregs %s"),
528 td_err_string (val
));
530 /* Note that we must call supply_gregset and supply_fpregset *after*
531 calling the td routines because the td routines call ps_lget*
532 which affect the values stored in the registers array. */
534 supply_gregset ((gdb_gregset_t
*) &gregset
);
535 supply_fpregset ((gdb_fpregset_t
*) &fpregset
);
538 /* FIXME: libthread_db doesn't seem to handle this right. */
539 val
= td_thr_getxregsize (&thandle
, &xregsize
);
540 if (val
!= TD_OK
&& val
!= TD_NOXREGS
)
541 error (_("sol_thread_fetch_registers: td_thr_getxregsize %s"),
542 td_err_string (val
));
546 xregset
= alloca (xregsize
);
547 val
= td_thr_getxregs (&thandle
, xregset
);
549 error (_("sol_thread_fetch_registers: td_thr_getxregs %s"),
550 td_err_string (val
));
556 sol_thread_store_registers (int regnum
)
559 td_thrhandle_t thandle
;
562 prfpregset_t fpregset
;
568 if (!is_thread (inferior_ptid
))
570 /* It's an LWP; pass the request on to procfs.c. */
571 procfs_ops
.to_store_registers (regnum
);
575 /* Solaris thread: convert INFERIOR_PTID into a td_thrhandle_t. */
576 thread
= GET_THREAD (inferior_ptid
);
578 val
= p_td_ta_map_id2thr (main_ta
, thread
, &thandle
);
580 error (_("sol_thread_store_registers: td_ta_map_id2thr %s"),
581 td_err_string (val
));
585 /* Not writing all the registers. */
586 char old_value
[MAX_REGISTER_SIZE
];
588 /* Save new register value. */
589 regcache_raw_collect (current_regcache
, regnum
, old_value
);
591 val
= p_td_thr_getgregs (&thandle
, gregset
);
593 error (_("sol_thread_store_registers: td_thr_getgregs %s"),
594 td_err_string (val
));
595 val
= p_td_thr_getfpregs (&thandle
, &fpregset
);
597 error (_("sol_thread_store_registers: td_thr_getfpregs %s"),
598 td_err_string (val
));
600 /* Restore new register value. */
601 regcache_raw_supply (current_regcache
, regnum
, old_value
);
604 /* FIXME: libthread_db doesn't seem to handle this right. */
605 val
= td_thr_getxregsize (&thandle
, &xregsize
);
606 if (val
!= TD_OK
&& val
!= TD_NOXREGS
)
607 error (_("sol_thread_store_registers: td_thr_getxregsize %s"),
608 td_err_string (val
));
612 xregset
= alloca (xregsize
);
613 val
= td_thr_getxregs (&thandle
, xregset
);
615 error (_("sol_thread_store_registers: td_thr_getxregs %s"),
616 td_err_string (val
));
621 fill_gregset ((gdb_gregset_t
*) &gregset
, regnum
);
622 fill_fpregset ((gdb_fpregset_t
*) &fpregset
, regnum
);
624 val
= p_td_thr_setgregs (&thandle
, gregset
);
626 error (_("sol_thread_store_registers: td_thr_setgregs %s"),
627 td_err_string (val
));
628 val
= p_td_thr_setfpregs (&thandle
, &fpregset
);
630 error (_("sol_thread_store_registers: td_thr_setfpregs %s"),
631 td_err_string (val
));
634 /* FIXME: libthread_db doesn't seem to handle this right. */
635 val
= td_thr_getxregsize (&thandle
, &xregsize
);
636 if (val
!= TD_OK
&& val
!= TD_NOXREGS
)
637 error (_("sol_thread_store_registers: td_thr_getxregsize %s"),
638 td_err_string (val
));
640 /* ??? Should probably do something about writing the xregs here,
641 but what are they? */
645 /* Get ready to modify the registers array. On machines which store
646 individual registers, this doesn't need to do anything. On
647 machines which store all the registers in one fell swoop, this
648 makes sure that registers contains all the registers from the
649 program being debugged. */
652 sol_thread_prepare_to_store (void)
654 procfs_ops
.to_prepare_to_store ();
657 /* Transfer LEN bytes between GDB address MYADDR and target address
658 MEMADDR. If DOWRITE is non-zero, transfer them to the target,
659 otherwise transfer them from the target. TARGET is unused.
661 Returns the number of bytes transferred. */
664 sol_thread_xfer_memory (CORE_ADDR memaddr
, gdb_byte
*myaddr
, int len
,
665 int dowrite
, struct mem_attrib
*attrib
,
666 struct target_ops
*target
)
669 struct cleanup
*old_chain
;
671 old_chain
= save_inferior_ptid ();
673 if (is_thread (inferior_ptid
) || !target_thread_alive (inferior_ptid
))
675 /* It's either a thread or an LWP that isn't alive. Any live
676 LWP will do so use the first available.
678 NOTE: We don't need to call switch_to_thread; we're just
680 inferior_ptid
= procfs_first_available ();
683 if (target_has_execution
)
684 retval
= procfs_ops
.deprecated_xfer_memory (memaddr
, myaddr
, len
,
685 dowrite
, attrib
, target
);
687 retval
= orig_core_ops
.deprecated_xfer_memory (memaddr
, myaddr
, len
,
688 dowrite
, attrib
, target
);
690 do_cleanups (old_chain
);
695 /* Perform partial transfers on OBJECT. See target_read_partial and
696 target_write_partial for details of each variant. One, and only
697 one, of readbuf or writebuf must be non-NULL. */
700 sol_thread_xfer_partial (struct target_ops
*ops
, enum target_object object
,
701 const char *annex
, gdb_byte
*readbuf
,
702 const gdb_byte
*writebuf
,
703 ULONGEST offset
, LONGEST len
)
706 struct cleanup
*old_chain
;
708 old_chain
= save_inferior_ptid ();
710 if (is_thread (inferior_ptid
) || !target_thread_alive (inferior_ptid
))
712 /* It's either a thread or an LWP that isn't alive. Any live
713 LWP will do so use the first available.
715 NOTE: We don't need to call switch_to_thread; we're just
717 inferior_ptid
= procfs_first_available ();
720 if (target_has_execution
)
721 retval
= procfs_ops
.to_xfer_partial (ops
, object
, annex
,
722 readbuf
, writebuf
, offset
, len
);
724 retval
= orig_core_ops
.to_xfer_partial (ops
, object
, annex
,
725 readbuf
, writebuf
, offset
, len
);
727 do_cleanups (old_chain
);
732 /* Print status information about what we're accessing. */
735 sol_thread_files_info (struct target_ops
*ignore
)
737 procfs_ops
.to_files_info (ignore
);
741 sol_thread_kill_inferior (void)
743 procfs_ops
.to_kill ();
747 sol_thread_notice_signals (ptid_t ptid
)
749 procfs_ops
.to_notice_signals (pid_to_ptid (PIDGET (ptid
)));
752 /* Fork an inferior process, and start debugging it with /proc. */
755 sol_thread_create_inferior (char *exec_file
, char *allargs
, char **env
,
758 procfs_ops
.to_create_inferior (exec_file
, allargs
, env
, from_tty
);
760 if (sol_thread_active
&& !ptid_equal (inferior_ptid
, null_ptid
))
762 /* Save for xfer_memory. */
763 main_ph
.ptid
= inferior_ptid
;
765 push_target (&sol_thread_ops
);
767 inferior_ptid
= lwp_to_thread (inferior_ptid
);
768 if (PIDGET (inferior_ptid
) == -1)
769 inferior_ptid
= main_ph
.ptid
;
771 if (!in_thread_list (inferior_ptid
))
772 add_thread (inferior_ptid
);
776 /* This routine is called whenever a new symbol table is read in, or
777 when all symbol tables are removed. libthread_db can only be
778 initialized when it finds the right variables in libthread.so.
779 Since it's a shared library, those variables don't show up until
780 the library gets mapped and the symbol table is read in.
782 This new_objfile event is managed by a chained function pointer.
783 It is the callee's responsability to call the next client on the
786 /* Saved pointer to previous owner of the new_objfile event. */
787 static void (*target_new_objfile_chain
) (struct objfile
*);
790 sol_thread_new_objfile (struct objfile
*objfile
)
796 sol_thread_active
= 0;
800 /* Don't do anything if init failed to resolve the libthread_db
802 if (!procfs_suppress_run
)
805 /* Now, initialize libthread_db. This needs to be done after the
806 shared libraries are located because it needs information from
807 the user's thread library. */
812 warning (_("sol_thread_new_objfile: td_init: %s"), td_err_string (val
));
816 val
= p_td_ta_new (&main_ph
, &main_ta
);
817 if (val
== TD_NOLIBTHREAD
)
819 else if (val
!= TD_OK
)
821 warning (_("sol_thread_new_objfile: td_ta_new: %s"), td_err_string (val
));
825 sol_thread_active
= 1;
828 /* Call predecessor on chain, if any. */
829 if (target_new_objfile_chain
)
830 target_new_objfile_chain (objfile
);
833 /* Clean up after the inferior dies. */
836 sol_thread_mourn_inferior (void)
838 unpush_target (&sol_thread_ops
);
839 procfs_ops
.to_mourn_inferior ();
842 /* Mark our target-struct as eligible for stray "run" and "attach"
846 sol_thread_can_run (void)
848 return procfs_suppress_run
;
855 sol_thread_alive - test thread for "aliveness"
859 static bool sol_thread_alive (ptid_t ptid);
863 returns true if thread still active in inferior.
867 /* Return true if PTID is still active in the inferior. */
870 sol_thread_alive (ptid_t ptid
)
872 if (is_thread (ptid
))
874 /* It's a (user-level) thread. */
879 pid
= GET_THREAD (ptid
);
880 if ((val
= p_td_ta_map_id2thr (main_ta
, pid
, &th
)) != TD_OK
)
881 return 0; /* Thread not found. */
882 if ((val
= p_td_thr_validate (&th
)) != TD_OK
)
883 return 0; /* Thread not valid. */
884 return 1; /* Known thread. */
888 /* It's an LPW; pass the request on to procfs. */
889 if (target_has_execution
)
890 return procfs_ops
.to_thread_alive (ptid
);
892 return orig_core_ops
.to_thread_alive (ptid
);
897 sol_thread_stop (void)
899 procfs_ops
.to_stop ();
902 /* These routines implement the lower half of the thread_db interface,
903 i.e. the ps_* routines. */
905 /* Various versions of <proc_service.h> have slightly different
906 function prototypes. In particular, we have
909 struct ps_prochandle * const struct ps_prochandle *
914 Which one you have depends on the Solaris version and what patches
915 you've applied. On the theory that there are only two major
916 variants, we have configure check the prototype of ps_pdwrite (),
917 and use that info to make appropriate typedefs here. */
919 #ifdef PROC_SERVICE_IS_OLD
920 typedef const struct ps_prochandle
*gdb_ps_prochandle_t
;
921 typedef char *gdb_ps_read_buf_t
;
922 typedef char *gdb_ps_write_buf_t
;
923 typedef int gdb_ps_size_t
;
924 typedef paddr_t gdb_ps_addr_t
;
926 typedef struct ps_prochandle
*gdb_ps_prochandle_t
;
927 typedef void *gdb_ps_read_buf_t
;
928 typedef const void *gdb_ps_write_buf_t
;
929 typedef size_t gdb_ps_size_t
;
930 typedef psaddr_t gdb_ps_addr_t
;
933 /* The next four routines are called by libthread_db to tell us to
934 stop and stop a particular process or lwp. Since GDB ensures that
935 these are all stopped by the time we call anything in thread_db,
936 these routines need to do nothing. */
941 ps_pstop (gdb_ps_prochandle_t ph
)
946 /* Process continue. */
949 ps_pcontinue (gdb_ps_prochandle_t ph
)
957 ps_lstop (gdb_ps_prochandle_t ph
, lwpid_t lwpid
)
965 ps_lcontinue (gdb_ps_prochandle_t ph
, lwpid_t lwpid
)
970 /* Looks up the symbol LD_SYMBOL_NAME in the debugger's symbol table. */
973 ps_pglobal_lookup (gdb_ps_prochandle_t ph
, const char *ld_object_name
,
974 const char *ld_symbol_name
, gdb_ps_addr_t
*ld_symbol_addr
)
976 struct minimal_symbol
*ms
;
978 ms
= lookup_minimal_symbol (ld_symbol_name
, NULL
, NULL
);
982 *ld_symbol_addr
= SYMBOL_VALUE_ADDRESS (ms
);
986 /* Common routine for reading and writing memory. */
989 rw_common (int dowrite
, const struct ps_prochandle
*ph
, gdb_ps_addr_t addr
,
992 struct cleanup
*old_chain
;
994 old_chain
= save_inferior_ptid ();
996 if (is_thread (inferior_ptid
) || !target_thread_alive (inferior_ptid
))
998 /* It's either a thread or an LWP that isn't alive. Any live
999 LWP will do so use the first available.
1001 NOTE: We don't need to call switch_to_thread; we're just
1003 inferior_ptid
= procfs_first_available ();
1006 #if defined (__sparcv9)
1007 /* For Sparc64 cross Sparc32, make sure the address has not been
1008 accidentally sign-extended (or whatever) to beyond 32 bits. */
1009 if (bfd_get_arch_size (exec_bfd
) == 32)
1017 /* FIXME: passing 0 as attrib argument. */
1018 if (target_has_execution
)
1019 cc
= procfs_ops
.deprecated_xfer_memory (addr
, buf
, size
,
1020 dowrite
, 0, &procfs_ops
);
1022 cc
= orig_core_ops
.deprecated_xfer_memory (addr
, buf
, size
,
1023 dowrite
, 0, &core_ops
);
1028 print_sys_errmsg ("rw_common (): read", errno
);
1030 print_sys_errmsg ("rw_common (): write", errno
);
1032 do_cleanups (old_chain
);
1039 warning (_("rw_common (): unable to read at addr 0x%lx"),
1042 warning (_("rw_common (): unable to write at addr 0x%lx"),
1045 do_cleanups (old_chain
);
1054 do_cleanups (old_chain
);
1059 /* Copies SIZE bytes from target process .data segment to debugger memory. */
1062 ps_pdread (gdb_ps_prochandle_t ph
, gdb_ps_addr_t addr
,
1063 gdb_ps_read_buf_t buf
, gdb_ps_size_t size
)
1065 return rw_common (0, ph
, addr
, buf
, size
);
1068 /* Copies SIZE bytes from debugger memory .data segment to target process. */
1071 ps_pdwrite (gdb_ps_prochandle_t ph
, gdb_ps_addr_t addr
,
1072 gdb_ps_write_buf_t buf
, gdb_ps_size_t size
)
1074 return rw_common (1, ph
, addr
, (char *) buf
, size
);
1077 /* Copies SIZE bytes from target process .text segment to debugger memory. */
1080 ps_ptread (gdb_ps_prochandle_t ph
, gdb_ps_addr_t addr
,
1081 gdb_ps_read_buf_t buf
, gdb_ps_size_t size
)
1083 return rw_common (0, ph
, addr
, buf
, size
);
1086 /* Copies SIZE bytes from debugger memory .text segment to target process. */
1089 ps_ptwrite (gdb_ps_prochandle_t ph
, gdb_ps_addr_t addr
,
1090 gdb_ps_write_buf_t buf
, gdb_ps_size_t size
)
1092 return rw_common (1, ph
, addr
, (char *) buf
, size
);
1095 /* Get general-purpose registers for LWP. */
1098 ps_lgetregs (gdb_ps_prochandle_t ph
, lwpid_t lwpid
, prgregset_t gregset
)
1100 struct cleanup
*old_chain
;
1102 old_chain
= save_inferior_ptid ();
1104 inferior_ptid
= BUILD_LWP (lwpid
, PIDGET (inferior_ptid
));
1106 if (target_has_execution
)
1107 procfs_ops
.to_fetch_registers (-1);
1109 orig_core_ops
.to_fetch_registers (-1);
1110 fill_gregset ((gdb_gregset_t
*) gregset
, -1);
1112 do_cleanups (old_chain
);
1117 /* Set general-purpose registers for LWP. */
1120 ps_lsetregs (gdb_ps_prochandle_t ph
, lwpid_t lwpid
,
1121 const prgregset_t gregset
)
1123 struct cleanup
*old_chain
;
1125 old_chain
= save_inferior_ptid ();
1127 inferior_ptid
= BUILD_LWP (lwpid
, PIDGET (inferior_ptid
));
1129 supply_gregset ((gdb_gregset_t
*) gregset
);
1130 if (target_has_execution
)
1131 procfs_ops
.to_store_registers (-1);
1133 orig_core_ops
.to_store_registers (-1);
1135 do_cleanups (old_chain
);
1140 /* Log a message (sends to gdb_stderr). */
1143 ps_plog (const char *fmt
, ...)
1147 va_start (args
, fmt
);
1149 vfprintf_filtered (gdb_stderr
, fmt
, args
);
1152 /* Get size of extra register set. Currently a noop. */
1155 ps_lgetxregsize (gdb_ps_prochandle_t ph
, lwpid_t lwpid
, int *xregsize
)
1162 val
= get_lwp_fd (ph
, lwpid
, &lwp_fd
);
1166 if (ioctl (lwp_fd
, PIOCGXREGSIZE
, ®size
))
1168 if (errno
== EINVAL
)
1169 return PS_NOFREGS
; /* XXX Wrong code, but this is the closest
1170 thing in proc_service.h */
1172 print_sys_errmsg ("ps_lgetxregsize (): PIOCGXREGSIZE", errno
);
1180 /* Get extra register set. Currently a noop. */
1183 ps_lgetxregs (gdb_ps_prochandle_t ph
, lwpid_t lwpid
, caddr_t xregset
)
1189 val
= get_lwp_fd (ph
, lwpid
, &lwp_fd
);
1193 if (ioctl (lwp_fd
, PIOCGXREG
, xregset
))
1195 print_sys_errmsg ("ps_lgetxregs (): PIOCGXREG", errno
);
1203 /* Set extra register set. Currently a noop. */
1206 ps_lsetxregs (gdb_ps_prochandle_t ph
, lwpid_t lwpid
, caddr_t xregset
)
1212 val
= get_lwp_fd (ph
, lwpid
, &lwp_fd
);
1216 if (ioctl (lwp_fd
, PIOCSXREG
, xregset
))
1218 print_sys_errmsg ("ps_lsetxregs (): PIOCSXREG", errno
);
1226 /* Get floating-point registers for LWP. */
1229 ps_lgetfpregs (gdb_ps_prochandle_t ph
, lwpid_t lwpid
,
1230 prfpregset_t
*fpregset
)
1232 struct cleanup
*old_chain
;
1234 old_chain
= save_inferior_ptid ();
1236 inferior_ptid
= BUILD_LWP (lwpid
, PIDGET (inferior_ptid
));
1238 if (target_has_execution
)
1239 procfs_ops
.to_fetch_registers (-1);
1241 orig_core_ops
.to_fetch_registers (-1);
1242 fill_fpregset ((gdb_fpregset_t
*) fpregset
, -1);
1244 do_cleanups (old_chain
);
1249 /* Set floating-point regs for LWP */
1252 ps_lsetfpregs (gdb_ps_prochandle_t ph
, lwpid_t lwpid
,
1253 const prfpregset_t
* fpregset
)
1255 struct cleanup
*old_chain
;
1257 old_chain
= save_inferior_ptid ();
1259 inferior_ptid
= BUILD_LWP (lwpid
, PIDGET (inferior_ptid
));
1261 supply_fpregset ((gdb_fpregset_t
*) fpregset
);
1262 if (target_has_execution
)
1263 procfs_ops
.to_store_registers (-1);
1265 orig_core_ops
.to_store_registers (-1);
1267 do_cleanups (old_chain
);
1272 #ifdef PR_MODEL_LP64
1273 /* Identify process as 32-bit or 64-bit. At the moment we're using
1274 BFD to do this. There might be a more Solaris-specific
1275 (e.g. procfs) method, but this ought to work. */
1278 ps_pdmodel (gdb_ps_prochandle_t ph
, int *data_model
)
1281 *data_model
= PR_MODEL_UNKNOWN
;
1282 else if (bfd_get_arch_size (exec_bfd
) == 32)
1283 *data_model
= PR_MODEL_ILP32
;
1285 *data_model
= PR_MODEL_LP64
;
1289 #endif /* PR_MODEL_LP64 */
1291 #ifdef TM_I386SOL2_H
1293 /* Reads the local descriptor table of a LWP. */
1296 ps_lgetLDT (gdb_ps_prochandle_t ph
, lwpid_t lwpid
,
1299 /* NOTE: only used on Solaris, therefore OK to refer to procfs.c. */
1300 extern struct ssd
*procfs_find_LDT_entry (ptid_t
);
1303 /* FIXME: can't I get the process ID from the prochandle or
1306 if (PIDGET (inferior_ptid
) <= 0 || lwpid
<= 0)
1309 ret
= procfs_find_LDT_entry (BUILD_LWP (lwpid
, PIDGET (inferior_ptid
)));
1312 memcpy (pldt
, ret
, sizeof (struct ssd
));
1316 /* LDT not found. */
1319 #endif /* TM_I386SOL2_H */
1322 /* Convert PTID to printable form. */
1325 solaris_pid_to_str (ptid_t ptid
)
1327 static char buf
[100];
1329 /* In case init failed to resolve the libthread_db library. */
1330 if (!procfs_suppress_run
)
1331 return procfs_pid_to_str (ptid
);
1333 if (is_thread (ptid
))
1337 lwp
= thread_to_lwp (ptid
, -2);
1339 if (PIDGET (lwp
) == -1)
1340 sprintf (buf
, "Thread %ld (defunct)", GET_THREAD (ptid
));
1341 else if (PIDGET (lwp
) != -2)
1342 sprintf (buf
, "Thread %ld (LWP %ld)",
1343 GET_THREAD (ptid
), GET_LWP (lwp
));
1345 sprintf (buf
, "Thread %ld ", GET_THREAD (ptid
));
1347 else if (GET_LWP (ptid
) != 0)
1348 sprintf (buf
, "LWP %ld ", GET_LWP (ptid
));
1350 sprintf (buf
, "process %d ", PIDGET (ptid
));
1356 /* Worker bee for find_new_threads. Callback function that gets
1357 called once per user-level thread (i.e. not for LWP's). */
1360 sol_find_new_threads_callback (const td_thrhandle_t
*th
, void *ignored
)
1366 retval
= p_td_thr_get_info (th
, &ti
);
1367 if (retval
!= TD_OK
)
1370 ptid
= BUILD_THREAD (ti
.ti_tid
, PIDGET (inferior_ptid
));
1371 if (!in_thread_list (ptid
))
1378 sol_find_new_threads (void)
1380 /* Don't do anything if init failed to resolve the libthread_db
1382 if (!procfs_suppress_run
)
1385 if (PIDGET (inferior_ptid
) == -1)
1387 printf_filtered ("No process.\n");
1391 /* First Find any new LWP's. */
1392 procfs_ops
.to_find_new_threads ();
1394 /* Then find any new user-level threads. */
1395 p_td_ta_thr_iter (main_ta
, sol_find_new_threads_callback
, (void *) 0,
1396 TD_THR_ANY_STATE
, TD_THR_LOWEST_PRIORITY
,
1397 TD_SIGNO_MASK
, TD_THR_ANY_USER_FLAGS
);
1401 sol_core_open (char *filename
, int from_tty
)
1403 orig_core_ops
.to_open (filename
, from_tty
);
1407 sol_core_close (int quitting
)
1409 orig_core_ops
.to_close (quitting
);
1413 sol_core_detach (char *args
, int from_tty
)
1415 unpush_target (&core_ops
);
1416 orig_core_ops
.to_detach (args
, from_tty
);
1420 sol_core_files_info (struct target_ops
*t
)
1422 orig_core_ops
.to_files_info (t
);
1425 /* Worker bee for the "info sol-thread" command. This is a callback
1426 function that gets called once for each Solaris user-level thread
1427 (i.e. not for LWPs) in the inferior. Print anything interesting
1428 that we can think of. */
1431 info_cb (const td_thrhandle_t
*th
, void *s
)
1436 ret
= p_td_thr_get_info (th
, &ti
);
1439 printf_filtered ("%s thread #%d, lwp %d, ",
1440 ti
.ti_type
== TD_THR_SYSTEM
? "system" : "user ",
1441 ti
.ti_tid
, ti
.ti_lid
);
1442 switch (ti
.ti_state
)
1445 case TD_THR_UNKNOWN
:
1446 printf_filtered ("<unknown state>");
1448 case TD_THR_STOPPED
:
1449 printf_filtered ("(stopped)");
1452 printf_filtered ("(run) ");
1455 printf_filtered ("(active) ");
1458 printf_filtered ("(zombie) ");
1461 printf_filtered ("(asleep) ");
1463 case TD_THR_STOPPED_ASLEEP
:
1464 printf_filtered ("(stopped asleep)");
1467 /* Print thr_create start function. */
1468 if (ti
.ti_startfunc
!= 0)
1470 struct minimal_symbol
*msym
;
1471 msym
= lookup_minimal_symbol_by_pc (ti
.ti_startfunc
);
1473 printf_filtered (" startfunc: %s\n",
1474 DEPRECATED_SYMBOL_NAME (msym
));
1476 printf_filtered (" startfunc: 0x%s\n", paddr (ti
.ti_startfunc
));
1479 /* If thread is asleep, print function that went to sleep. */
1480 if (ti
.ti_state
== TD_THR_SLEEP
)
1482 struct minimal_symbol
*msym
;
1483 msym
= lookup_minimal_symbol_by_pc (ti
.ti_pc
);
1485 printf_filtered (" - Sleep func: %s\n",
1486 DEPRECATED_SYMBOL_NAME (msym
));
1488 printf_filtered (" - Sleep func: 0x%s\n", paddr (ti
.ti_startfunc
));
1491 /* Wrap up line, if necessary. */
1492 if (ti
.ti_state
!= TD_THR_SLEEP
&& ti
.ti_startfunc
== 0)
1493 printf_filtered ("\n"); /* don't you hate counting newlines? */
1496 warning (_("info sol-thread: failed to get info for thread."));
1501 /* List some state about each Solaris user-level thread in the
1505 info_solthreads (char *args
, int from_tty
)
1507 p_td_ta_thr_iter (main_ta
, info_cb
, args
,
1508 TD_THR_ANY_STATE
, TD_THR_LOWEST_PRIORITY
,
1509 TD_SIGNO_MASK
, TD_THR_ANY_USER_FLAGS
);
1513 sol_find_memory_regions (int (*func
) (CORE_ADDR
, unsigned long,
1514 int, int, int, void *),
1517 return procfs_ops
.to_find_memory_regions (func
, data
);
1521 sol_make_note_section (bfd
*obfd
, int *note_size
)
1523 return procfs_ops
.to_make_corefile_notes (obfd
, note_size
);
1527 ignore (struct bp_target_info
*bp_tgt
)
1533 init_sol_thread_ops (void)
1535 sol_thread_ops
.to_shortname
= "solaris-threads";
1536 sol_thread_ops
.to_longname
= "Solaris threads and pthread.";
1537 sol_thread_ops
.to_doc
= "Solaris threads and pthread support.";
1538 sol_thread_ops
.to_open
= sol_thread_open
;
1539 sol_thread_ops
.to_attach
= sol_thread_attach
;
1540 sol_thread_ops
.to_detach
= sol_thread_detach
;
1541 sol_thread_ops
.to_resume
= sol_thread_resume
;
1542 sol_thread_ops
.to_wait
= sol_thread_wait
;
1543 sol_thread_ops
.to_fetch_registers
= sol_thread_fetch_registers
;
1544 sol_thread_ops
.to_store_registers
= sol_thread_store_registers
;
1545 sol_thread_ops
.to_prepare_to_store
= sol_thread_prepare_to_store
;
1546 sol_thread_ops
.deprecated_xfer_memory
= sol_thread_xfer_memory
;
1547 sol_thread_ops
.to_xfer_partial
= sol_thread_xfer_partial
;
1548 sol_thread_ops
.to_files_info
= sol_thread_files_info
;
1549 sol_thread_ops
.to_insert_breakpoint
= memory_insert_breakpoint
;
1550 sol_thread_ops
.to_remove_breakpoint
= memory_remove_breakpoint
;
1551 sol_thread_ops
.to_terminal_init
= terminal_init_inferior
;
1552 sol_thread_ops
.to_terminal_inferior
= terminal_inferior
;
1553 sol_thread_ops
.to_terminal_ours_for_output
= terminal_ours_for_output
;
1554 sol_thread_ops
.to_terminal_ours
= terminal_ours
;
1555 sol_thread_ops
.to_terminal_save_ours
= terminal_save_ours
;
1556 sol_thread_ops
.to_terminal_info
= child_terminal_info
;
1557 sol_thread_ops
.to_kill
= sol_thread_kill_inferior
;
1558 sol_thread_ops
.to_create_inferior
= sol_thread_create_inferior
;
1559 sol_thread_ops
.to_mourn_inferior
= sol_thread_mourn_inferior
;
1560 sol_thread_ops
.to_can_run
= sol_thread_can_run
;
1561 sol_thread_ops
.to_notice_signals
= sol_thread_notice_signals
;
1562 sol_thread_ops
.to_thread_alive
= sol_thread_alive
;
1563 sol_thread_ops
.to_pid_to_str
= solaris_pid_to_str
;
1564 sol_thread_ops
.to_find_new_threads
= sol_find_new_threads
;
1565 sol_thread_ops
.to_stop
= sol_thread_stop
;
1566 sol_thread_ops
.to_stratum
= process_stratum
;
1567 sol_thread_ops
.to_has_all_memory
= 1;
1568 sol_thread_ops
.to_has_memory
= 1;
1569 sol_thread_ops
.to_has_stack
= 1;
1570 sol_thread_ops
.to_has_registers
= 1;
1571 sol_thread_ops
.to_has_execution
= 1;
1572 sol_thread_ops
.to_has_thread_control
= tc_none
;
1573 sol_thread_ops
.to_find_memory_regions
= sol_find_memory_regions
;
1574 sol_thread_ops
.to_make_corefile_notes
= sol_make_note_section
;
1575 sol_thread_ops
.to_magic
= OPS_MAGIC
;
1579 init_sol_core_ops (void)
1581 sol_core_ops
.to_shortname
= "solaris-core";
1582 sol_core_ops
.to_longname
= "Solaris core threads and pthread.";
1583 sol_core_ops
.to_doc
= "Solaris threads and pthread support for core files.";
1584 sol_core_ops
.to_open
= sol_core_open
;
1585 sol_core_ops
.to_close
= sol_core_close
;
1586 sol_core_ops
.to_attach
= sol_thread_attach
;
1587 sol_core_ops
.to_detach
= sol_core_detach
;
1588 sol_core_ops
.to_fetch_registers
= sol_thread_fetch_registers
;
1589 sol_core_ops
.deprecated_xfer_memory
= sol_thread_xfer_memory
;
1590 sol_core_ops
.to_xfer_partial
= sol_thread_xfer_partial
;
1591 sol_core_ops
.to_files_info
= sol_core_files_info
;
1592 sol_core_ops
.to_insert_breakpoint
= ignore
;
1593 sol_core_ops
.to_remove_breakpoint
= ignore
;
1594 sol_core_ops
.to_create_inferior
= sol_thread_create_inferior
;
1595 sol_core_ops
.to_stratum
= core_stratum
;
1596 sol_core_ops
.to_has_memory
= 1;
1597 sol_core_ops
.to_has_stack
= 1;
1598 sol_core_ops
.to_has_registers
= 1;
1599 sol_core_ops
.to_has_thread_control
= tc_none
;
1600 sol_core_ops
.to_thread_alive
= sol_thread_alive
;
1601 sol_core_ops
.to_pid_to_str
= solaris_pid_to_str
;
1602 /* On Solaris/x86, when debugging a threaded core file from process
1603 <n>, the following causes "info threads" to produce "procfs:
1604 couldn't find pid <n> in procinfo list" where <n> is the pid of
1605 the process that produced the core file. Disable it for now. */
1607 sol_core_ops
.to_find_new_threads
= sol_find_new_threads
;
1609 sol_core_ops
.to_magic
= OPS_MAGIC
;
1612 /* We suppress the call to add_target of core_ops in corelow because
1613 if there are two targets in the stratum core_stratum,
1614 find_core_target won't know which one to return. See corelow.c for
1615 an additonal comment on coreops_suppress_target. */
1616 int coreops_suppress_target
= 1;
1619 _initialize_sol_thread (void)
1623 init_sol_thread_ops ();
1624 init_sol_core_ops ();
1626 dlhandle
= dlopen ("libthread_db.so.1", RTLD_NOW
);
1630 #define resolve(X) \
1631 if (!(p_##X = dlsym (dlhandle, #X))) \
1635 resolve (td_ta_new
);
1636 resolve (td_ta_delete
);
1638 resolve (td_ta_get_ph
);
1639 resolve (td_ta_get_nthreads
);
1640 resolve (td_ta_tsd_iter
);
1641 resolve (td_ta_thr_iter
);
1642 resolve (td_thr_validate
);
1643 resolve (td_thr_tsd
);
1644 resolve (td_thr_get_info
);
1645 resolve (td_thr_getfpregs
);
1646 resolve (td_thr_getxregsize
);
1647 resolve (td_thr_getxregs
);
1648 resolve (td_thr_sigsetmask
);
1649 resolve (td_thr_setprio
);
1650 resolve (td_thr_setsigpending
);
1651 resolve (td_thr_setfpregs
);
1652 resolve (td_thr_setxregs
);
1653 resolve (td_ta_map_id2thr
);
1654 resolve (td_ta_map_lwp2thr
);
1655 resolve (td_thr_getgregs
);
1656 resolve (td_thr_setgregs
);
1658 add_target (&sol_thread_ops
);
1660 procfs_suppress_run
= 1;
1662 add_cmd ("sol-threads", class_maintenance
, info_solthreads
,
1663 _("Show info on Solaris user threads."), &maintenanceinfolist
);
1665 memcpy (&orig_core_ops
, &core_ops
, sizeof (struct target_ops
));
1666 memcpy (&core_ops
, &sol_core_ops
, sizeof (struct target_ops
));
1667 add_target (&core_ops
);
1669 /* Hook into new_objfile notification. */
1670 target_new_objfile_chain
= deprecated_target_new_objfile_hook
;
1671 deprecated_target_new_objfile_hook
= sol_thread_new_objfile
;
1675 fprintf_unfiltered (gdb_stderr
, "\
1676 [GDB will not be able to debug user-mode threads: %s]\n", dlerror ());
1681 /* Allow the user to debug non-threaded core files. */
1682 add_target (&core_ops
);