xref: /netbsd-src/external/gpl3/gdb.old/dist/gdb/sol-thread.c (revision bdc22b2e01993381dcefeff2bc9b56ca75a4235c)
1 /* Solaris threads debugging interface.
2 
3    Copyright (C) 1996-2016 Free Software Foundation, Inc.
4 
5    This file is part of GDB.
6 
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.
11 
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.
16 
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/>.  */
19 
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.
23 
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.
31 
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!
39 
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.  */
50 
51 #include "defs.h"
52 #include <thread.h>
53 #include <proc_service.h>
54 #include <thread_db.h>
55 #include "gdbthread.h"
56 #include "target.h"
57 #include "inferior.h"
58 #include <fcntl.h>
59 #include <sys/stat.h>
60 #include <dlfcn.h>
61 #include "gdbcmd.h"
62 #include "gdbcore.h"
63 #include "regcache.h"
64 #include "solib.h"
65 #include "symfile.h"
66 #include "observer.h"
67 #include "procfs.h"
68 #include "symtab.h"
69 #include "minsyms.h"
70 #include "objfiles.h"
71 
72 struct target_ops sol_thread_ops;
73 
74 /* Prototypes for supply_gregset etc.  */
75 #include "gregset.h"
76 
77 /* This struct is defined by us, but mainly used for the proc_service
78    interface.  We don't have much use for it, except as a handy place
79    to get a real PID for memory accesses.  */
80 
81 struct ps_prochandle
82 {
83   ptid_t ptid;
84 };
85 
86 struct string_map
87 {
88   int num;
89   char *str;
90 };
91 
92 static struct ps_prochandle main_ph;
93 static td_thragent_t *main_ta;
94 static int sol_thread_active = 0;
95 
96 static void init_sol_thread_ops (void);
97 
98 /* Default definitions: These must be defined in tm.h if they are to
99    be shared with a process module such as procfs.  */
100 
101 /* Pointers to routines from libthread_db resolved by dlopen().  */
102 
103 static void (*p_td_log)(const int on_off);
104 static td_err_e (*p_td_ta_new)(const struct ps_prochandle *ph_p,
105 			       td_thragent_t **ta_pp);
106 static td_err_e (*p_td_ta_delete)(td_thragent_t *ta_p);
107 static td_err_e (*p_td_init)(void);
108 static td_err_e (*p_td_ta_get_ph)(const td_thragent_t *ta_p,
109 				  struct ps_prochandle **ph_pp);
110 static td_err_e (*p_td_ta_get_nthreads)(const td_thragent_t *ta_p,
111 					int *nthread_p);
112 static td_err_e (*p_td_ta_tsd_iter)(const td_thragent_t *ta_p,
113 				    td_key_iter_f *cb, void *cbdata_p);
114 static td_err_e (*p_td_ta_thr_iter)(const td_thragent_t *ta_p,
115 				    td_thr_iter_f *cb, void *cbdata_p,
116 				    td_thr_state_e state, int ti_pri,
117 				    sigset_t *ti_sigmask_p,
118 				    unsigned ti_user_flags);
119 static td_err_e (*p_td_thr_validate)(const td_thrhandle_t *th_p);
120 static td_err_e (*p_td_thr_tsd)(const td_thrhandle_t * th_p,
121 				const thread_key_t key, void **data_pp);
122 static td_err_e (*p_td_thr_get_info)(const td_thrhandle_t *th_p,
123 				     td_thrinfo_t *ti_p);
124 static td_err_e (*p_td_thr_getfpregs)(const td_thrhandle_t *th_p,
125 				      prfpregset_t *fpregset);
126 static td_err_e (*p_td_thr_getxregsize)(const td_thrhandle_t *th_p,
127 					int *xregsize);
128 static td_err_e (*p_td_thr_getxregs)(const td_thrhandle_t *th_p,
129 				     const caddr_t xregset);
130 static td_err_e (*p_td_thr_sigsetmask)(const td_thrhandle_t *th_p,
131 				       const sigset_t ti_sigmask);
132 static td_err_e (*p_td_thr_setprio)(const td_thrhandle_t *th_p,
133 				    const int ti_pri);
134 static td_err_e (*p_td_thr_setsigpending)(const td_thrhandle_t *th_p,
135 					  const uchar_t ti_pending_flag,
136 					  const sigset_t ti_pending);
137 static td_err_e (*p_td_thr_setfpregs)(const td_thrhandle_t *th_p,
138 				      const prfpregset_t *fpregset);
139 static td_err_e (*p_td_thr_setxregs)(const td_thrhandle_t *th_p,
140 				     const caddr_t xregset);
141 static td_err_e (*p_td_ta_map_id2thr)(const td_thragent_t *ta_p,
142 				      thread_t tid,
143 				      td_thrhandle_t *th_p);
144 static td_err_e (*p_td_ta_map_lwp2thr)(const td_thragent_t *ta_p,
145 				       lwpid_t lwpid,
146 				       td_thrhandle_t *th_p);
147 static td_err_e (*p_td_thr_getgregs)(const td_thrhandle_t *th_p,
148 				     prgregset_t regset);
149 static td_err_e (*p_td_thr_setgregs)(const td_thrhandle_t *th_p,
150 				     const prgregset_t regset);
151 
152 
153 /* Return the libthread_db error string associated with ERRCODE.  If
154    ERRCODE is unknown, return an appropriate message.  */
155 
156 static char *
157 td_err_string (td_err_e errcode)
158 {
159   static struct string_map td_err_table[] =
160   {
161     { TD_OK, "generic \"call succeeded\"" },
162     { TD_ERR, "generic error." },
163     { TD_NOTHR, "no thread can be found to satisfy query" },
164     { TD_NOSV, "no synch. variable can be found to satisfy query" },
165     { TD_NOLWP, "no lwp can be found to satisfy query" },
166     { TD_BADPH, "invalid process handle" },
167     { TD_BADTH, "invalid thread handle" },
168     { TD_BADSH, "invalid synchronization handle" },
169     { TD_BADTA, "invalid thread agent" },
170     { TD_BADKEY, "invalid key" },
171     { TD_NOMSG, "td_thr_event_getmsg() called when there was no message" },
172     { TD_NOFPREGS, "FPU register set not available for given thread" },
173     { TD_NOLIBTHREAD, "application not linked with libthread" },
174     { TD_NOEVENT, "requested event is not supported" },
175     { TD_NOCAPAB, "capability not available" },
176     { TD_DBERR, "Debugger service failed" },
177     { TD_NOAPLIC, "Operation not applicable to" },
178     { TD_NOTSD, "No thread specific data for this thread" },
179     { TD_MALLOC, "Malloc failed" },
180     { TD_PARTIALREG, "Only part of register set was written/read" },
181     { TD_NOXREGS, "X register set not available for given thread" }
182   };
183   const int td_err_size = sizeof td_err_table / sizeof (struct string_map);
184   int i;
185   static char buf[50];
186 
187   for (i = 0; i < td_err_size; i++)
188     if (td_err_table[i].num == errcode)
189       return td_err_table[i].str;
190 
191   xsnprintf (buf, sizeof (buf), "Unknown libthread_db error code: %d",
192 	     errcode);
193 
194   return buf;
195 }
196 
197 /* Return the libthread_db state string assicoated with STATECODE.
198    If STATECODE is unknown, return an appropriate message.  */
199 
200 static char *
201 td_state_string (td_thr_state_e statecode)
202 {
203   static struct string_map td_thr_state_table[] =
204   {
205     { TD_THR_ANY_STATE, "any state" },
206     { TD_THR_UNKNOWN, "unknown" },
207     { TD_THR_STOPPED, "stopped" },
208     { TD_THR_RUN, "run" },
209     { TD_THR_ACTIVE, "active" },
210     { TD_THR_ZOMBIE, "zombie" },
211     { TD_THR_SLEEP, "sleep" },
212     { TD_THR_STOPPED_ASLEEP, "stopped asleep" }
213   };
214   const int td_thr_state_table_size =
215     sizeof td_thr_state_table / sizeof (struct string_map);
216   int i;
217   static char buf[50];
218 
219   for (i = 0; i < td_thr_state_table_size; i++)
220     if (td_thr_state_table[i].num == statecode)
221       return td_thr_state_table[i].str;
222 
223   xsnprintf (buf, sizeof (buf), "Unknown libthread_db state code: %d",
224 	     statecode);
225 
226   return buf;
227 }
228 
229 
230 /* Convert a POSIX or Solaris thread ID into a LWP ID.  If THREAD_ID
231    doesn't exist, that's an error.  If it's an inactive thread, return
232    DEFAULT_LWP.
233 
234    NOTE: This function probably shouldn't call error().  */
235 
236 static ptid_t
237 thread_to_lwp (ptid_t thread_id, int default_lwp)
238 {
239   td_thrinfo_t ti;
240   td_thrhandle_t th;
241   td_err_e val;
242 
243   if (ptid_lwp_p (thread_id))
244     return thread_id;		/* It's already an LWP ID.  */
245 
246   /* It's a thread.  Convert to LWP.  */
247 
248   val = p_td_ta_map_id2thr (main_ta, ptid_get_tid (thread_id), &th);
249   if (val == TD_NOTHR)
250     return pid_to_ptid (-1);	/* Thread must have terminated.  */
251   else if (val != TD_OK)
252     error (_("thread_to_lwp: td_ta_map_id2thr %s"), td_err_string (val));
253 
254   val = p_td_thr_get_info (&th, &ti);
255   if (val == TD_NOTHR)
256     return pid_to_ptid (-1);	/* Thread must have terminated.  */
257   else if (val != TD_OK)
258     error (_("thread_to_lwp: td_thr_get_info: %s"), td_err_string (val));
259 
260   if (ti.ti_state != TD_THR_ACTIVE)
261     {
262       if (default_lwp != -1)
263 	return pid_to_ptid (default_lwp);
264       error (_("thread_to_lwp: thread state not active: %s"),
265 	     td_state_string (ti.ti_state));
266     }
267 
268   return ptid_build (ptid_get_pid (thread_id), ti.ti_lid, 0);
269 }
270 
271 /* Convert an LWP ID into a POSIX or Solaris thread ID.  If LWP_ID
272    doesn't exists, that's an error.
273 
274    NOTE: This function probably shouldn't call error().  */
275 
276 static ptid_t
277 lwp_to_thread (ptid_t lwp)
278 {
279   td_thrinfo_t ti;
280   td_thrhandle_t th;
281   td_err_e val;
282 
283   if (ptid_tid_p (lwp))
284     return lwp;			/* It's already a thread ID.  */
285 
286   /* It's an LWP.  Convert it to a thread ID.  */
287 
288   if (!target_thread_alive (lwp))
289     return pid_to_ptid (-1);	/* Must be a defunct LPW.  */
290 
291   val = p_td_ta_map_lwp2thr (main_ta, ptid_get_lwp (lwp), &th);
292   if (val == TD_NOTHR)
293     return pid_to_ptid (-1);	/* Thread must have terminated.  */
294   else if (val != TD_OK)
295     error (_("lwp_to_thread: td_ta_map_lwp2thr: %s."), td_err_string (val));
296 
297   val = p_td_thr_validate (&th);
298   if (val == TD_NOTHR)
299     return lwp;			/* Unknown to libthread; just return LPW,  */
300   else if (val != TD_OK)
301     error (_("lwp_to_thread: td_thr_validate: %s."), td_err_string (val));
302 
303   val = p_td_thr_get_info (&th, &ti);
304   if (val == TD_NOTHR)
305     return pid_to_ptid (-1);	/* Thread must have terminated.  */
306   else if (val != TD_OK)
307     error (_("lwp_to_thread: td_thr_get_info: %s."), td_err_string (val));
308 
309   return ptid_build (ptid_get_pid (lwp), 0 , ti.ti_tid);
310 }
311 
312 
313 /* Most target vector functions from here on actually just pass
314    through to the layer beneath, as they don't need to do anything
315    specific for threads.  */
316 
317 /* Take a program previously attached to and detaches it.  The program
318    resumes execution and will no longer stop on signals, etc.  We'd
319    better not have left any breakpoints in the program or it'll die
320    when it hits one.  For this to work, it may be necessary for the
321    process to have been previously attached.  It *might* work if the
322    program was started via the normal ptrace (PTRACE_TRACEME).  */
323 
324 static void
325 sol_thread_detach (struct target_ops *ops, const char *args, int from_tty)
326 {
327   struct target_ops *beneath = find_target_beneath (ops);
328 
329   sol_thread_active = 0;
330   inferior_ptid = pid_to_ptid (ptid_get_pid (main_ph.ptid));
331   unpush_target (ops);
332   beneath->to_detach (beneath, args, from_tty);
333 }
334 
335 /* Resume execution of process PTID.  If STEP is nozero, then just
336    single step it.  If SIGNAL is nonzero, restart it with that signal
337    activated.  We may have to convert PTID from a thread ID to an LWP
338    ID for procfs.  */
339 
340 static void
341 sol_thread_resume (struct target_ops *ops,
342 		   ptid_t ptid, int step, enum gdb_signal signo)
343 {
344   struct cleanup *old_chain;
345   struct target_ops *beneath = find_target_beneath (ops);
346 
347   old_chain = save_inferior_ptid ();
348 
349   inferior_ptid = thread_to_lwp (inferior_ptid, ptid_get_pid (main_ph.ptid));
350   if (ptid_get_pid (inferior_ptid) == -1)
351     inferior_ptid = procfs_first_available ();
352 
353   if (ptid_get_pid (ptid) != -1)
354     {
355       ptid_t save_ptid = ptid;
356 
357       ptid = thread_to_lwp (ptid, -2);
358       if (ptid_get_pid (ptid) == -2)		/* Inactive thread.  */
359 	error (_("This version of Solaris can't start inactive threads."));
360       if (info_verbose && ptid_get_pid (ptid) == -1)
361 	warning (_("Specified thread %ld seems to have terminated"),
362 		 ptid_get_tid (save_ptid));
363     }
364 
365   beneath->to_resume (beneath, ptid, step, signo);
366 
367   do_cleanups (old_chain);
368 }
369 
370 /* Wait for any threads to stop.  We may have to convert PTID from a
371    thread ID to an LWP ID, and vice versa on the way out.  */
372 
373 static ptid_t
374 sol_thread_wait (struct target_ops *ops,
375 		 ptid_t ptid, struct target_waitstatus *ourstatus, int options)
376 {
377   ptid_t rtnval;
378   ptid_t save_ptid;
379   struct target_ops *beneath = find_target_beneath (ops);
380   struct cleanup *old_chain;
381 
382   save_ptid = inferior_ptid;
383   old_chain = save_inferior_ptid ();
384 
385   inferior_ptid = thread_to_lwp (inferior_ptid, ptid_get_pid (main_ph.ptid));
386   if (ptid_get_pid (inferior_ptid) == -1)
387     inferior_ptid = procfs_first_available ();
388 
389   if (ptid_get_pid (ptid) != -1)
390     {
391       ptid_t save_ptid = ptid;
392 
393       ptid = thread_to_lwp (ptid, -2);
394       if (ptid_get_pid (ptid) == -2)		/* Inactive thread.  */
395 	error (_("This version of Solaris can't start inactive threads."));
396       if (info_verbose && ptid_get_pid (ptid) == -1)
397 	warning (_("Specified thread %ld seems to have terminated"),
398 		 ptid_get_tid (save_ptid));
399     }
400 
401   rtnval = beneath->to_wait (beneath, ptid, ourstatus, options);
402 
403   if (ourstatus->kind != TARGET_WAITKIND_EXITED)
404     {
405       /* Map the LWP of interest back to the appropriate thread ID.  */
406       rtnval = lwp_to_thread (rtnval);
407       if (ptid_get_pid (rtnval) == -1)
408 	rtnval = save_ptid;
409 
410       /* See if we have a new thread.  */
411       if (ptid_tid_p (rtnval)
412 	  && !ptid_equal (rtnval, save_ptid)
413 	  && (!in_thread_list (rtnval)
414 	      || is_exited (rtnval)))
415 	add_thread (rtnval);
416     }
417 
418   /* During process initialization, we may get here without the thread
419      package being initialized, since that can only happen after we've
420      found the shared libs.  */
421 
422   do_cleanups (old_chain);
423 
424   return rtnval;
425 }
426 
427 static void
428 sol_thread_fetch_registers (struct target_ops *ops,
429 			    struct regcache *regcache, int regnum)
430 {
431   thread_t thread;
432   td_thrhandle_t thandle;
433   td_err_e val;
434   prgregset_t gregset;
435   prfpregset_t fpregset;
436   gdb_gregset_t *gregset_p = &gregset;
437   gdb_fpregset_t *fpregset_p = &fpregset;
438   struct target_ops *beneath = find_target_beneath (ops);
439 
440   if (!ptid_tid_p (inferior_ptid))
441     {
442       /* It's an LWP; pass the request on to the layer beneath.  */
443       beneath->to_fetch_registers (beneath, regcache, regnum);
444       return;
445     }
446 
447   /* Solaris thread: convert INFERIOR_PTID into a td_thrhandle_t.  */
448   thread = ptid_get_tid (inferior_ptid);
449   if (thread == 0)
450     error (_("sol_thread_fetch_registers: thread == 0"));
451 
452   val = p_td_ta_map_id2thr (main_ta, thread, &thandle);
453   if (val != TD_OK)
454     error (_("sol_thread_fetch_registers: td_ta_map_id2thr: %s"),
455 	   td_err_string (val));
456 
457   /* Get the general-purpose registers.  */
458 
459   val = p_td_thr_getgregs (&thandle, gregset);
460   if (val != TD_OK && val != TD_PARTIALREG)
461     error (_("sol_thread_fetch_registers: td_thr_getgregs %s"),
462 	   td_err_string (val));
463 
464   /* For SPARC, TD_PARTIALREG means that only %i0...%i7, %l0..%l7, %pc
465      and %sp are saved (by a thread context switch).  */
466 
467   /* And, now the floating-point registers.  */
468 
469   val = p_td_thr_getfpregs (&thandle, &fpregset);
470   if (val != TD_OK && val != TD_NOFPREGS)
471     error (_("sol_thread_fetch_registers: td_thr_getfpregs %s"),
472 	   td_err_string (val));
473 
474   /* Note that we must call supply_gregset and supply_fpregset *after*
475      calling the td routines because the td routines call ps_lget*
476      which affect the values stored in the registers array.  */
477 
478   supply_gregset (regcache, (const gdb_gregset_t *) gregset_p);
479   supply_fpregset (regcache, (const gdb_fpregset_t *) fpregset_p);
480 }
481 
482 static void
483 sol_thread_store_registers (struct target_ops *ops,
484 			    struct regcache *regcache, int regnum)
485 {
486   thread_t thread;
487   td_thrhandle_t thandle;
488   td_err_e val;
489   prgregset_t gregset;
490   prfpregset_t fpregset;
491 
492   if (!ptid_tid_p (inferior_ptid))
493     {
494       struct target_ops *beneath = find_target_beneath (ops);
495 
496       /* It's an LWP; pass the request on to the layer beneath.  */
497       beneath->to_store_registers (beneath, regcache, regnum);
498       return;
499     }
500 
501   /* Solaris thread: convert INFERIOR_PTID into a td_thrhandle_t.  */
502   thread = ptid_get_tid (inferior_ptid);
503 
504   val = p_td_ta_map_id2thr (main_ta, thread, &thandle);
505   if (val != TD_OK)
506     error (_("sol_thread_store_registers: td_ta_map_id2thr %s"),
507 	   td_err_string (val));
508 
509   if (regnum != -1)
510     {
511       /* Not writing all the registers.  */
512       char old_value[MAX_REGISTER_SIZE];
513 
514       /* Save new register value.  */
515       regcache_raw_collect (regcache, regnum, old_value);
516 
517       val = p_td_thr_getgregs (&thandle, gregset);
518       if (val != TD_OK)
519 	error (_("sol_thread_store_registers: td_thr_getgregs %s"),
520 	       td_err_string (val));
521       val = p_td_thr_getfpregs (&thandle, &fpregset);
522       if (val != TD_OK)
523 	error (_("sol_thread_store_registers: td_thr_getfpregs %s"),
524 	       td_err_string (val));
525 
526       /* Restore new register value.  */
527       regcache_raw_supply (regcache, regnum, old_value);
528     }
529 
530   fill_gregset (regcache, (gdb_gregset_t *) &gregset, regnum);
531   fill_fpregset (regcache, (gdb_fpregset_t *) &fpregset, regnum);
532 
533   val = p_td_thr_setgregs (&thandle, gregset);
534   if (val != TD_OK)
535     error (_("sol_thread_store_registers: td_thr_setgregs %s"),
536 	   td_err_string (val));
537   val = p_td_thr_setfpregs (&thandle, &fpregset);
538   if (val != TD_OK)
539     error (_("sol_thread_store_registers: td_thr_setfpregs %s"),
540 	   td_err_string (val));
541 }
542 
543 /* Perform partial transfers on OBJECT.  See target_read_partial and
544    target_write_partial for details of each variant.  One, and only
545    one, of readbuf or writebuf must be non-NULL.  */
546 
547 static enum target_xfer_status
548 sol_thread_xfer_partial (struct target_ops *ops, enum target_object object,
549 			  const char *annex, gdb_byte *readbuf,
550 			  const gdb_byte *writebuf,
551 			 ULONGEST offset, ULONGEST len, ULONGEST *xfered_len)
552 {
553   enum target_xfer_status retval;
554   struct cleanup *old_chain;
555   struct target_ops *beneath = find_target_beneath (ops);
556 
557   old_chain = save_inferior_ptid ();
558 
559   if (ptid_tid_p (inferior_ptid) || !target_thread_alive (inferior_ptid))
560     {
561       /* It's either a thread or an LWP that isn't alive.  Any live
562          LWP will do so use the first available.
563 
564 	 NOTE: We don't need to call switch_to_thread; we're just
565 	 reading memory.  */
566       inferior_ptid = procfs_first_available ();
567     }
568 
569   retval = beneath->to_xfer_partial (beneath, object, annex, readbuf,
570 				     writebuf, offset, len, xfered_len);
571 
572   do_cleanups (old_chain);
573 
574   return retval;
575 }
576 
577 static void
578 check_for_thread_db (void)
579 {
580   td_err_e err;
581   ptid_t ptid;
582 
583   /* Don't attempt to use thread_db for remote targets.  */
584   if (!(target_can_run (&current_target) || core_bfd))
585     return;
586 
587   /* Do nothing if we couldn't load libthread_db.so.1.  */
588   if (p_td_ta_new == NULL)
589     return;
590 
591   if (sol_thread_active)
592     /* Nothing to do.  The thread library was already detected and the
593        target vector was already activated.  */
594     return;
595 
596   /* Now, initialize libthread_db.  This needs to be done after the
597      shared libraries are located because it needs information from
598      the user's thread library.  */
599 
600   err = p_td_init ();
601   if (err != TD_OK)
602     {
603       warning (_("sol_thread_new_objfile: td_init: %s"), td_err_string (err));
604       return;
605     }
606 
607   /* Now attempt to open a connection to the thread library.  */
608   err = p_td_ta_new (&main_ph, &main_ta);
609   switch (err)
610     {
611     case TD_NOLIBTHREAD:
612       /* No thread library was detected.  */
613       break;
614 
615     case TD_OK:
616       printf_unfiltered (_("[Thread debugging using libthread_db enabled]\n"));
617 
618       /* The thread library was detected.  Activate the sol_thread target.  */
619       push_target (&sol_thread_ops);
620       sol_thread_active = 1;
621 
622       main_ph.ptid = inferior_ptid; /* Save for xfer_memory.  */
623       ptid = lwp_to_thread (inferior_ptid);
624       if (ptid_get_pid (ptid) != -1)
625 	inferior_ptid = ptid;
626 
627       target_update_thread_list ();
628       break;
629 
630     default:
631       warning (_("Cannot initialize thread debugging library: %s"),
632 	       td_err_string (err));
633       break;
634     }
635 }
636 
637 /* This routine is called whenever a new symbol table is read in, or
638    when all symbol tables are removed.  libthread_db can only be
639    initialized when it finds the right variables in libthread.so.
640    Since it's a shared library, those variables don't show up until
641    the library gets mapped and the symbol table is read in.  */
642 
643 static void
644 sol_thread_new_objfile (struct objfile *objfile)
645 {
646   if (objfile != NULL)
647     check_for_thread_db ();
648 }
649 
650 /* Clean up after the inferior dies.  */
651 
652 static void
653 sol_thread_mourn_inferior (struct target_ops *ops)
654 {
655   struct target_ops *beneath = find_target_beneath (ops);
656 
657   sol_thread_active = 0;
658 
659   unpush_target (ops);
660 
661   beneath->to_mourn_inferior (beneath);
662 }
663 
664 /* Return true if PTID is still active in the inferior.  */
665 
666 static int
667 sol_thread_alive (struct target_ops *ops, ptid_t ptid)
668 {
669   if (ptid_tid_p (ptid))
670     {
671       /* It's a (user-level) thread.  */
672       td_err_e val;
673       td_thrhandle_t th;
674       int pid;
675 
676       pid = ptid_get_tid (ptid);
677       if ((val = p_td_ta_map_id2thr (main_ta, pid, &th)) != TD_OK)
678 	return 0;		/* Thread not found.  */
679       if ((val = p_td_thr_validate (&th)) != TD_OK)
680 	return 0;		/* Thread not valid.  */
681       return 1;			/* Known thread.  */
682     }
683   else
684     {
685       struct target_ops *beneath = find_target_beneath (ops);
686 
687       /* It's an LPW; pass the request on to the layer below.  */
688       return beneath->to_thread_alive (beneath, ptid);
689     }
690 }
691 
692 
693 /* These routines implement the lower half of the thread_db interface,
694    i.e. the ps_* routines.  */
695 
696 /* Various versions of <proc_service.h> have slightly different
697    function prototypes.  In particular, we have
698 
699    NEWER                        OLDER
700    struct ps_prochandle *       const struct ps_prochandle *
701    void*                        char*
702    const void*          	char*
703    int                  	size_t
704 
705    Which one you have depends on the Solaris version and what patches
706    you've applied.  On the theory that there are only two major
707    variants, we have configure check the prototype of ps_pdwrite (),
708    and use that info to make appropriate typedefs here.  */
709 
710 #ifdef PROC_SERVICE_IS_OLD
711 typedef const struct ps_prochandle *gdb_ps_prochandle_t;
712 typedef char *gdb_ps_read_buf_t;
713 typedef char *gdb_ps_write_buf_t;
714 typedef int gdb_ps_size_t;
715 typedef psaddr_t gdb_ps_addr_t;
716 #else
717 typedef struct ps_prochandle *gdb_ps_prochandle_t;
718 typedef void *gdb_ps_read_buf_t;
719 typedef const void *gdb_ps_write_buf_t;
720 typedef size_t gdb_ps_size_t;
721 typedef psaddr_t gdb_ps_addr_t;
722 #endif
723 
724 /* The next four routines are called by libthread_db to tell us to
725    stop and stop a particular process or lwp.  Since GDB ensures that
726    these are all stopped by the time we call anything in thread_db,
727    these routines need to do nothing.  */
728 
729 /* Process stop.  */
730 
731 ps_err_e
732 ps_pstop (gdb_ps_prochandle_t ph)
733 {
734   return PS_OK;
735 }
736 
737 /* Process continue.  */
738 
739 ps_err_e
740 ps_pcontinue (gdb_ps_prochandle_t ph)
741 {
742   return PS_OK;
743 }
744 
745 /* LWP stop.  */
746 
747 ps_err_e
748 ps_lstop (gdb_ps_prochandle_t ph, lwpid_t lwpid)
749 {
750   return PS_OK;
751 }
752 
753 /* LWP continue.  */
754 
755 ps_err_e
756 ps_lcontinue (gdb_ps_prochandle_t ph, lwpid_t lwpid)
757 {
758   return PS_OK;
759 }
760 
761 /* Looks up the symbol LD_SYMBOL_NAME in the debugger's symbol table.  */
762 
763 ps_err_e
764 ps_pglobal_lookup (gdb_ps_prochandle_t ph, const char *ld_object_name,
765 		   const char *ld_symbol_name, gdb_ps_addr_t *ld_symbol_addr)
766 {
767   struct bound_minimal_symbol ms;
768 
769   ms = lookup_minimal_symbol (ld_symbol_name, NULL, NULL);
770   if (!ms.minsym)
771     return PS_NOSYM;
772 
773   *ld_symbol_addr = BMSYMBOL_VALUE_ADDRESS (ms);
774   return PS_OK;
775 }
776 
777 /* Common routine for reading and writing memory.  */
778 
779 static ps_err_e
780 rw_common (int dowrite, const struct ps_prochandle *ph, gdb_ps_addr_t addr,
781 	   gdb_byte *buf, int size)
782 {
783   int ret;
784   struct cleanup *old_chain;
785 
786   old_chain = save_inferior_ptid ();
787 
788   if (ptid_tid_p (inferior_ptid) || !target_thread_alive (inferior_ptid))
789     {
790       /* It's either a thread or an LWP that isn't alive.  Any live
791          LWP will do so use the first available.
792 
793 	 NOTE: We don't need to call switch_to_thread; we're just
794 	 reading memory.  */
795       inferior_ptid = procfs_first_available ();
796     }
797 
798 #if defined (__sparcv9)
799   /* For Sparc64 cross Sparc32, make sure the address has not been
800      accidentally sign-extended (or whatever) to beyond 32 bits.  */
801   if (bfd_get_arch_size (exec_bfd) == 32)
802     addr &= 0xffffffff;
803 #endif
804 
805   if (dowrite)
806     ret = target_write_memory (addr, (gdb_byte *) buf, size);
807   else
808     ret = target_read_memory (addr, (gdb_byte *) buf, size);
809 
810   do_cleanups (old_chain);
811 
812   return (ret == 0 ? PS_OK : PS_ERR);
813 }
814 
815 /* Copies SIZE bytes from target process .data segment to debugger memory.  */
816 
817 ps_err_e
818 ps_pdread (gdb_ps_prochandle_t ph, gdb_ps_addr_t addr,
819 	   gdb_ps_read_buf_t buf, gdb_ps_size_t size)
820 {
821   return rw_common (0, ph, addr, buf, size);
822 }
823 
824 /* Copies SIZE bytes from debugger memory .data segment to target process.  */
825 
826 ps_err_e
827 ps_pdwrite (gdb_ps_prochandle_t ph, gdb_ps_addr_t addr,
828 	    gdb_ps_write_buf_t buf, gdb_ps_size_t size)
829 {
830   return rw_common (1, ph, addr, (gdb_byte *) buf, size);
831 }
832 
833 /* Copies SIZE bytes from target process .text segment to debugger memory.  */
834 
835 ps_err_e
836 ps_ptread (gdb_ps_prochandle_t ph, gdb_ps_addr_t addr,
837 	   gdb_ps_read_buf_t buf, gdb_ps_size_t size)
838 {
839   return rw_common (0, ph, addr, buf, size);
840 }
841 
842 /* Copies SIZE bytes from debugger memory .text segment to target process.  */
843 
844 ps_err_e
845 ps_ptwrite (gdb_ps_prochandle_t ph, gdb_ps_addr_t addr,
846 	    gdb_ps_write_buf_t buf, gdb_ps_size_t size)
847 {
848   return rw_common (1, ph, addr, (gdb_byte *) buf, size);
849 }
850 
851 /* Get general-purpose registers for LWP.  */
852 
853 ps_err_e
854 ps_lgetregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, prgregset_t gregset)
855 {
856   struct cleanup *old_chain;
857   struct regcache *regcache;
858 
859   old_chain = save_inferior_ptid ();
860 
861   inferior_ptid = ptid_build (ptid_get_pid (inferior_ptid), lwpid, 0);
862   regcache = get_thread_arch_regcache (inferior_ptid, target_gdbarch ());
863 
864   target_fetch_registers (regcache, -1);
865   fill_gregset (regcache, (gdb_gregset_t *) gregset, -1);
866 
867   do_cleanups (old_chain);
868 
869   return PS_OK;
870 }
871 
872 /* Set general-purpose registers for LWP.  */
873 
874 ps_err_e
875 ps_lsetregs (gdb_ps_prochandle_t ph, lwpid_t lwpid,
876 	     const prgregset_t gregset)
877 {
878   struct cleanup *old_chain;
879   struct regcache *regcache;
880 
881   old_chain = save_inferior_ptid ();
882 
883   inferior_ptid = ptid_build (ptid_get_pid (inferior_ptid), lwpid, 0);
884   regcache = get_thread_arch_regcache (inferior_ptid, target_gdbarch ());
885 
886   supply_gregset (regcache, (const gdb_gregset_t *) gregset);
887   target_store_registers (regcache, -1);
888 
889   do_cleanups (old_chain);
890 
891   return PS_OK;
892 }
893 
894 /* Log a message (sends to gdb_stderr).  */
895 
896 void
897 ps_plog (const char *fmt, ...)
898 {
899   va_list args;
900 
901   va_start (args, fmt);
902 
903   vfprintf_filtered (gdb_stderr, fmt, args);
904 }
905 
906 /* Get size of extra register set.  Currently a noop.  */
907 
908 ps_err_e
909 ps_lgetxregsize (gdb_ps_prochandle_t ph, lwpid_t lwpid, int *xregsize)
910 {
911   return PS_OK;
912 }
913 
914 /* Get extra register set.  Currently a noop.  */
915 
916 ps_err_e
917 ps_lgetxregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, caddr_t xregset)
918 {
919   return PS_OK;
920 }
921 
922 /* Set extra register set.  Currently a noop.  */
923 
924 ps_err_e
925 ps_lsetxregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, caddr_t xregset)
926 {
927   return PS_OK;
928 }
929 
930 /* Get floating-point registers for LWP.  */
931 
932 ps_err_e
933 ps_lgetfpregs (gdb_ps_prochandle_t ph, lwpid_t lwpid,
934 	       prfpregset_t *fpregset)
935 {
936   struct cleanup *old_chain;
937   struct regcache *regcache;
938 
939   old_chain = save_inferior_ptid ();
940 
941   inferior_ptid = ptid_build (ptid_get_pid (inferior_ptid), lwpid, 0);
942   regcache = get_thread_arch_regcache (inferior_ptid, target_gdbarch ());
943 
944   target_fetch_registers (regcache, -1);
945   fill_fpregset (regcache, (gdb_fpregset_t *) fpregset, -1);
946 
947   do_cleanups (old_chain);
948 
949   return PS_OK;
950 }
951 
952 /* Set floating-point regs for LWP.  */
953 
954 ps_err_e
955 ps_lsetfpregs (gdb_ps_prochandle_t ph, lwpid_t lwpid,
956 	       const prfpregset_t * fpregset)
957 {
958   struct cleanup *old_chain;
959   struct regcache *regcache;
960 
961   old_chain = save_inferior_ptid ();
962 
963   inferior_ptid = ptid_build (ptid_get_pid (inferior_ptid), lwpid, 0);
964   regcache = get_thread_arch_regcache (inferior_ptid, target_gdbarch ());
965 
966   supply_fpregset (regcache, (const gdb_fpregset_t *) fpregset);
967   target_store_registers (regcache, -1);
968 
969   do_cleanups (old_chain);
970 
971   return PS_OK;
972 }
973 
974 #ifdef PR_MODEL_LP64
975 /* Identify process as 32-bit or 64-bit.  At the moment we're using
976    BFD to do this.  There might be a more Solaris-specific
977    (e.g. procfs) method, but this ought to work.  */
978 
979 ps_err_e
980 ps_pdmodel (gdb_ps_prochandle_t ph, int *data_model)
981 {
982   if (exec_bfd == 0)
983     *data_model = PR_MODEL_UNKNOWN;
984   else if (bfd_get_arch_size (exec_bfd) == 32)
985     *data_model = PR_MODEL_ILP32;
986   else
987     *data_model = PR_MODEL_LP64;
988 
989   return PS_OK;
990 }
991 #endif /* PR_MODEL_LP64 */
992 
993 #if (defined(__i386__) || defined(__x86_64__)) && defined (sun)
994 
995 /* Reads the local descriptor table of a LWP.
996 
997    This function is necessary on x86-solaris only.  Without it, the loading
998    of libthread_db would fail because of ps_lgetLDT being undefined.  */
999 
1000 ps_err_e
1001 ps_lgetLDT (gdb_ps_prochandle_t ph, lwpid_t lwpid,
1002 	    struct ssd *pldt)
1003 {
1004   /* NOTE: only used on Solaris, therefore OK to refer to procfs.c.  */
1005   struct ssd *ret;
1006 
1007   /* FIXME: can't I get the process ID from the prochandle or
1008      something?  */
1009 
1010   if (ptid_get_pid (inferior_ptid) <= 0 || lwpid <= 0)
1011     return PS_BADLID;
1012 
1013   ret = procfs_find_LDT_entry (ptid_build (ptid_get_pid (inferior_ptid),
1014 			       lwpid, 0));
1015   if (ret)
1016     {
1017       memcpy (pldt, ret, sizeof (struct ssd));
1018       return PS_OK;
1019     }
1020   else
1021     /* LDT not found.  */
1022     return PS_ERR;
1023 }
1024 #endif
1025 
1026 
1027 /* Convert PTID to printable form.  */
1028 
1029 static char *
1030 solaris_pid_to_str (struct target_ops *ops, ptid_t ptid)
1031 {
1032   static char buf[100];
1033 
1034   if (ptid_tid_p (ptid))
1035     {
1036       ptid_t lwp;
1037 
1038       lwp = thread_to_lwp (ptid, -2);
1039 
1040       if (ptid_get_pid (lwp) == -1)
1041 	xsnprintf (buf, sizeof (buf), "Thread %ld (defunct)",
1042 		   ptid_get_tid (ptid));
1043       else if (ptid_get_pid (lwp) != -2)
1044 	xsnprintf (buf, sizeof (buf), "Thread %ld (LWP %ld)",
1045 		 ptid_get_tid (ptid), ptid_get_lwp (lwp));
1046       else
1047 	xsnprintf (buf, sizeof (buf), "Thread %ld        ",
1048 		   ptid_get_tid (ptid));
1049     }
1050   else if (ptid_get_lwp (ptid) != 0)
1051     xsnprintf (buf, sizeof (buf), "LWP    %ld        ", ptid_get_lwp (ptid));
1052   else
1053     xsnprintf (buf, sizeof (buf), "process %d    ", ptid_get_pid (ptid));
1054 
1055   return buf;
1056 }
1057 
1058 
1059 /* Worker bee for update_thread_list.  Callback function that gets
1060    called once per user-level thread (i.e. not for LWP's).  */
1061 
1062 static int
1063 sol_update_thread_list_callback (const td_thrhandle_t *th, void *ignored)
1064 {
1065   td_err_e retval;
1066   td_thrinfo_t ti;
1067   ptid_t ptid;
1068 
1069   retval = p_td_thr_get_info (th, &ti);
1070   if (retval != TD_OK)
1071     return -1;
1072 
1073   ptid = ptid_build (ptid_get_pid (inferior_ptid), 0, ti.ti_tid);
1074   if (!in_thread_list (ptid) || is_exited (ptid))
1075     add_thread (ptid);
1076 
1077   return 0;
1078 }
1079 
1080 static void
1081 sol_update_thread_list (struct target_ops *ops)
1082 {
1083   struct target_ops *beneath = find_target_beneath (ops);
1084 
1085   /* Delete dead threads.  */
1086   prune_threads ();
1087 
1088   /* Find any new LWP's.  */
1089   beneath->to_update_thread_list (beneath);
1090 
1091   /* Then find any new user-level threads.  */
1092   p_td_ta_thr_iter (main_ta, sol_update_thread_list_callback, (void *) 0,
1093 		    TD_THR_ANY_STATE, TD_THR_LOWEST_PRIORITY,
1094 		    TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS);
1095 }
1096 
1097 /* Worker bee for the "info sol-thread" command.  This is a callback
1098    function that gets called once for each Solaris user-level thread
1099    (i.e. not for LWPs) in the inferior.  Print anything interesting
1100    that we can think of.  */
1101 
1102 static int
1103 info_cb (const td_thrhandle_t *th, void *s)
1104 {
1105   td_err_e ret;
1106   td_thrinfo_t ti;
1107 
1108   ret = p_td_thr_get_info (th, &ti);
1109   if (ret == TD_OK)
1110     {
1111       printf_filtered ("%s thread #%d, lwp %d, ",
1112 		       ti.ti_type == TD_THR_SYSTEM ? "system" : "user  ",
1113 		       ti.ti_tid, ti.ti_lid);
1114       switch (ti.ti_state)
1115 	{
1116 	default:
1117 	case TD_THR_UNKNOWN:
1118 	  printf_filtered ("<unknown state>");
1119 	  break;
1120 	case TD_THR_STOPPED:
1121 	  printf_filtered ("(stopped)");
1122 	  break;
1123 	case TD_THR_RUN:
1124 	  printf_filtered ("(run)    ");
1125 	  break;
1126 	case TD_THR_ACTIVE:
1127 	  printf_filtered ("(active) ");
1128 	  break;
1129 	case TD_THR_ZOMBIE:
1130 	  printf_filtered ("(zombie) ");
1131 	  break;
1132 	case TD_THR_SLEEP:
1133 	  printf_filtered ("(asleep) ");
1134 	  break;
1135 	case TD_THR_STOPPED_ASLEEP:
1136 	  printf_filtered ("(stopped asleep)");
1137 	  break;
1138 	}
1139       /* Print thr_create start function.  */
1140       if (ti.ti_startfunc != 0)
1141 	{
1142 	  const struct bound_minimal_symbol msym
1143 	    = lookup_minimal_symbol_by_pc (ti.ti_startfunc);
1144 
1145 	  printf_filtered ("   startfunc=%s",
1146 			   msym.minsym
1147 			   ? MSYMBOL_PRINT_NAME (msym.minsym)
1148 			   : paddress (target_gdbarch (), ti.ti_startfunc));
1149 	}
1150 
1151       /* If thread is asleep, print function that went to sleep.  */
1152       if (ti.ti_state == TD_THR_SLEEP)
1153 	{
1154 	  const struct bound_minimal_symbol msym
1155 	    = lookup_minimal_symbol_by_pc (ti.ti_pc);
1156 
1157 	  printf_filtered ("   sleepfunc=%s",
1158 			   msym.minsym
1159 			   ? MSYMBOL_PRINT_NAME (msym.minsym)
1160 			   : paddress (target_gdbarch (), ti.ti_pc));
1161 	}
1162 
1163       printf_filtered ("\n");
1164     }
1165   else
1166     warning (_("info sol-thread: failed to get info for thread."));
1167 
1168   return 0;
1169 }
1170 
1171 /* List some state about each Solaris user-level thread in the
1172    inferior.  */
1173 
1174 static void
1175 info_solthreads (char *args, int from_tty)
1176 {
1177   p_td_ta_thr_iter (main_ta, info_cb, args,
1178 		    TD_THR_ANY_STATE, TD_THR_LOWEST_PRIORITY,
1179 		    TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS);
1180 }
1181 
1182 /* Callback routine used to find a thread based on the TID part of
1183    its PTID.  */
1184 
1185 static int
1186 thread_db_find_thread_from_tid (struct thread_info *thread, void *data)
1187 {
1188   long *tid = (long *) data;
1189 
1190   if (ptid_get_tid (thread->ptid) == *tid)
1191     return 1;
1192 
1193   return 0;
1194 }
1195 
1196 static ptid_t
1197 sol_get_ada_task_ptid (struct target_ops *self, long lwp, long thread)
1198 {
1199   struct thread_info *thread_info =
1200     iterate_over_threads (thread_db_find_thread_from_tid, &thread);
1201 
1202   if (thread_info == NULL)
1203     {
1204       /* The list of threads is probably not up to date.  Find any
1205          thread that is missing from the list, and try again.  */
1206       sol_update_thread_list (&current_target);
1207       thread_info = iterate_over_threads (thread_db_find_thread_from_tid,
1208                                           &thread);
1209     }
1210 
1211   gdb_assert (thread_info != NULL);
1212 
1213   return (thread_info->ptid);
1214 }
1215 
1216 static void
1217 init_sol_thread_ops (void)
1218 {
1219   sol_thread_ops.to_shortname = "solaris-threads";
1220   sol_thread_ops.to_longname = "Solaris threads and pthread.";
1221   sol_thread_ops.to_doc = "Solaris threads and pthread support.";
1222   sol_thread_ops.to_detach = sol_thread_detach;
1223   sol_thread_ops.to_resume = sol_thread_resume;
1224   sol_thread_ops.to_wait = sol_thread_wait;
1225   sol_thread_ops.to_fetch_registers = sol_thread_fetch_registers;
1226   sol_thread_ops.to_store_registers = sol_thread_store_registers;
1227   sol_thread_ops.to_xfer_partial = sol_thread_xfer_partial;
1228   sol_thread_ops.to_mourn_inferior = sol_thread_mourn_inferior;
1229   sol_thread_ops.to_thread_alive = sol_thread_alive;
1230   sol_thread_ops.to_pid_to_str = solaris_pid_to_str;
1231   sol_thread_ops.to_update_thread_list = sol_update_thread_list;
1232   sol_thread_ops.to_stratum = thread_stratum;
1233   sol_thread_ops.to_get_ada_task_ptid = sol_get_ada_task_ptid;
1234   sol_thread_ops.to_magic = OPS_MAGIC;
1235 }
1236 
1237 /* Silence -Wmissing-prototypes.  */
1238 extern void _initialize_sol_thread (void);
1239 
1240 void
1241 _initialize_sol_thread (void)
1242 {
1243   void *dlhandle;
1244 
1245   init_sol_thread_ops ();
1246 
1247   dlhandle = dlopen ("libthread_db.so.1", RTLD_NOW);
1248   if (!dlhandle)
1249     goto die;
1250 
1251 #define resolve(X) \
1252   if (!(p_##X = dlsym (dlhandle, #X))) \
1253     goto die;
1254 
1255   resolve (td_log);
1256   resolve (td_ta_new);
1257   resolve (td_ta_delete);
1258   resolve (td_init);
1259   resolve (td_ta_get_ph);
1260   resolve (td_ta_get_nthreads);
1261   resolve (td_ta_tsd_iter);
1262   resolve (td_ta_thr_iter);
1263   resolve (td_thr_validate);
1264   resolve (td_thr_tsd);
1265   resolve (td_thr_get_info);
1266   resolve (td_thr_getfpregs);
1267   resolve (td_thr_getxregsize);
1268   resolve (td_thr_getxregs);
1269   resolve (td_thr_sigsetmask);
1270   resolve (td_thr_setprio);
1271   resolve (td_thr_setsigpending);
1272   resolve (td_thr_setfpregs);
1273   resolve (td_thr_setxregs);
1274   resolve (td_ta_map_id2thr);
1275   resolve (td_ta_map_lwp2thr);
1276   resolve (td_thr_getgregs);
1277   resolve (td_thr_setgregs);
1278 
1279   complete_target_initialization (&sol_thread_ops);
1280 
1281   add_cmd ("sol-threads", class_maintenance, info_solthreads,
1282 	   _("Show info on Solaris user threads."), &maintenanceinfolist);
1283 
1284   /* Hook into new_objfile notification.  */
1285   observer_attach_new_objfile (sol_thread_new_objfile);
1286   return;
1287 
1288  die:
1289   fprintf_unfiltered (gdb_stderr, "\
1290 [GDB will not be able to debug user-mode threads: %s]\n", dlerror ());
1291 
1292   if (dlhandle)
1293     dlclose (dlhandle);
1294 
1295   return;
1296 }
1297