2009-10-28 Paul Pluzhnikov <ppluzhnikov@google.com>
[external/binutils.git] / gdb / gdbserver / thread-db.c
1 /* Thread management interface, for the remote server for GDB.
2    Copyright (C) 2002, 2004, 2005, 2006, 2007, 2008, 2009
3    Free Software Foundation, Inc.
4
5    Contributed by MontaVista Software.
6
7    This file is part of GDB.
8
9    This program is free software; you can redistribute it and/or modify
10    it under the terms of the GNU General Public License as published by
11    the Free Software Foundation; either version 3 of the License, or
12    (at your option) any later version.
13
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License for more details.
18
19    You should have received a copy of the GNU General Public License
20    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
21
22 #include "server.h"
23
24 #include "linux-low.h"
25
26 extern int debug_threads;
27
28 static int thread_db_use_events;
29
30 #include "gdb_proc_service.h"
31 #include "../gdb_thread_db.h"
32
33 #include <dlfcn.h>
34 #include <stdint.h>
35 #include <limits.h>
36 #include <ctype.h>
37
38 struct thread_db
39 {
40   /* Structure that identifies the child process for the
41      <proc_service.h> interface.  */
42   struct ps_prochandle proc_handle;
43
44   /* Connection to the libthread_db library.  */
45   td_thragent_t *thread_agent;
46
47   /* Handle of the libthread_db from dlopen.  */
48   void *handle;
49
50   /* Addresses of libthread_db functions.  */
51   td_err_e (*td_ta_new_p) (struct ps_prochandle * ps, td_thragent_t **ta);
52   td_err_e (*td_ta_event_getmsg_p) (const td_thragent_t *ta,
53                                     td_event_msg_t *msg);
54   td_err_e (*td_ta_set_event_p) (const td_thragent_t *ta,
55                                  td_thr_events_t *event);
56   td_err_e (*td_ta_event_addr_p) (const td_thragent_t *ta,
57                                   td_event_e event, td_notify_t *ptr);
58   td_err_e (*td_ta_map_lwp2thr_p) (const td_thragent_t *ta, lwpid_t lwpid,
59                                    td_thrhandle_t *th);
60   td_err_e (*td_thr_get_info_p) (const td_thrhandle_t *th,
61                                  td_thrinfo_t *infop);
62   td_err_e (*td_thr_event_enable_p) (const td_thrhandle_t *th, int event);
63   td_err_e (*td_ta_thr_iter_p) (const td_thragent_t *ta,
64                                 td_thr_iter_f *callback, void *cbdata_p,
65                                 td_thr_state_e state, int ti_pri,
66                                 sigset_t *ti_sigmask_p,
67                                 unsigned int ti_user_flags);
68   td_err_e (*td_thr_tls_get_addr_p) (const td_thrhandle_t *th,
69                                      void *map_address,
70                                      size_t offset, void **address);
71   const char ** (*td_symbol_list_p) (void);
72 };
73
74 static char *libthread_db_search_path;
75
76 static int find_one_thread (ptid_t);
77 static int find_new_threads_callback (const td_thrhandle_t *th_p, void *data);
78
79 static const char *
80 thread_db_err_str (td_err_e err)
81 {
82   static char buf[64];
83
84   switch (err)
85     {
86     case TD_OK:
87       return "generic 'call succeeded'";
88     case TD_ERR:
89       return "generic error";
90     case TD_NOTHR:
91       return "no thread to satisfy query";
92     case TD_NOSV:
93       return "no sync handle to satisfy query";
94     case TD_NOLWP:
95       return "no LWP to satisfy query";
96     case TD_BADPH:
97       return "invalid process handle";
98     case TD_BADTH:
99       return "invalid thread handle";
100     case TD_BADSH:
101       return "invalid synchronization handle";
102     case TD_BADTA:
103       return "invalid thread agent";
104     case TD_BADKEY:
105       return "invalid key";
106     case TD_NOMSG:
107       return "no event message for getmsg";
108     case TD_NOFPREGS:
109       return "FPU register set not available";
110     case TD_NOLIBTHREAD:
111       return "application not linked with libthread";
112     case TD_NOEVENT:
113       return "requested event is not supported";
114     case TD_NOCAPAB:
115       return "capability not available";
116     case TD_DBERR:
117       return "debugger service failed";
118     case TD_NOAPLIC:
119       return "operation not applicable to";
120     case TD_NOTSD:
121       return "no thread-specific data for this thread";
122     case TD_MALLOC:
123       return "malloc failed";
124     case TD_PARTIALREG:
125       return "only part of register set was written/read";
126     case TD_NOXREGS:
127       return "X register set not available for this thread";
128 #ifdef HAVE_TD_VERSION
129     case TD_VERSION:
130       return "version mismatch between libthread_db and libpthread";
131 #endif
132     default:
133       snprintf (buf, sizeof (buf), "unknown thread_db error '%d'", err);
134       return buf;
135     }
136 }
137
138 #if 0
139 static char *
140 thread_db_state_str (td_thr_state_e state)
141 {
142   static char buf[64];
143
144   switch (state)
145     {
146     case TD_THR_STOPPED:
147       return "stopped by debugger";
148     case TD_THR_RUN:
149       return "runnable";
150     case TD_THR_ACTIVE:
151       return "active";
152     case TD_THR_ZOMBIE:
153       return "zombie";
154     case TD_THR_SLEEP:
155       return "sleeping";
156     case TD_THR_STOPPED_ASLEEP:
157       return "stopped by debugger AND blocked";
158     default:
159       snprintf (buf, sizeof (buf), "unknown thread_db state %d", state);
160       return buf;
161     }
162 }
163 #endif
164
165 static int
166 thread_db_create_event (CORE_ADDR where)
167 {
168   td_event_msg_t msg;
169   td_err_e err;
170   struct lwp_info *lwp;
171   struct thread_db *thread_db = current_process ()->private->thread_db;
172
173   if (thread_db->td_ta_event_getmsg_p == NULL)
174     fatal ("unexpected thread_db->td_ta_event_getmsg_p == NULL");
175
176   if (debug_threads)
177     fprintf (stderr, "Thread creation event.\n");
178
179   /* FIXME: This assumes we don't get another event.
180      In the LinuxThreads implementation, this is safe,
181      because all events come from the manager thread
182      (except for its own creation, of course).  */
183   err = thread_db->td_ta_event_getmsg_p (thread_db->thread_agent, &msg);
184   if (err != TD_OK)
185     fprintf (stderr, "thread getmsg err: %s\n",
186              thread_db_err_str (err));
187
188   /* If we do not know about the main thread yet, this would be a good time to
189      find it.  We need to do this to pick up the main thread before any newly
190      created threads.  */
191   lwp = get_thread_lwp (current_inferior);
192   if (lwp->thread_known == 0)
193     find_one_thread (lwp->head.id);
194
195   /* msg.event == TD_EVENT_CREATE */
196
197   find_new_threads_callback (msg.th_p, NULL);
198
199   return 0;
200 }
201
202 static int
203 thread_db_enable_reporting ()
204 {
205   td_thr_events_t events;
206   td_notify_t notify;
207   td_err_e err;
208   struct thread_db *thread_db = current_process ()->private->thread_db;
209
210   if (thread_db->td_ta_set_event_p == NULL
211       || thread_db->td_ta_event_addr_p == NULL
212       || thread_db->td_ta_event_getmsg_p == NULL)
213     /* This libthread_db is missing required support.  */
214     return 0;
215
216   /* Set the process wide mask saying which events we're interested in.  */
217   td_event_emptyset (&events);
218   td_event_addset (&events, TD_CREATE);
219
220   err = thread_db->td_ta_set_event_p (thread_db->thread_agent, &events);
221   if (err != TD_OK)
222     {
223       warning ("Unable to set global thread event mask: %s",
224                thread_db_err_str (err));
225       return 0;
226     }
227
228   /* Get address for thread creation breakpoint.  */
229   err = thread_db->td_ta_event_addr_p (thread_db->thread_agent, TD_CREATE,
230                                        &notify);
231   if (err != TD_OK)
232     {
233       warning ("Unable to get location for thread creation breakpoint: %s",
234                thread_db_err_str (err));
235       return 0;
236     }
237   set_breakpoint_at ((CORE_ADDR) (unsigned long) notify.u.bptaddr,
238                      thread_db_create_event);
239
240   return 1;
241 }
242
243 static int
244 find_one_thread (ptid_t ptid)
245 {
246   td_thrhandle_t th;
247   td_thrinfo_t ti;
248   td_err_e err;
249   struct thread_info *inferior;
250   struct lwp_info *lwp;
251   struct thread_db *thread_db = current_process ()->private->thread_db;
252   int lwpid = ptid_get_lwp (ptid);
253
254   inferior = (struct thread_info *) find_inferior_id (&all_threads, ptid);
255   lwp = get_thread_lwp (inferior);
256   if (lwp->thread_known)
257     return 1;
258
259   /* Get information about this thread.  */
260   err = thread_db->td_ta_map_lwp2thr_p (thread_db->thread_agent, lwpid, &th);
261   if (err != TD_OK)
262     error ("Cannot get thread handle for LWP %d: %s",
263            lwpid, thread_db_err_str (err));
264
265   err = thread_db->td_thr_get_info_p (&th, &ti);
266   if (err != TD_OK)
267     error ("Cannot get thread info for LWP %d: %s",
268            lwpid, thread_db_err_str (err));
269
270   if (debug_threads)
271     fprintf (stderr, "Found thread %ld (LWP %d)\n",
272              ti.ti_tid, ti.ti_lid);
273
274   if (lwpid != ti.ti_lid)
275     {
276       warning ("PID mismatch!  Expected %ld, got %ld",
277                (long) lwpid, (long) ti.ti_lid);
278       return 0;
279     }
280
281   if (thread_db_use_events)
282     {
283       err = thread_db->td_thr_event_enable_p (&th, 1);
284       if (err != TD_OK)
285         error ("Cannot enable thread event reporting for %d: %s",
286                ti.ti_lid, thread_db_err_str (err));
287     }
288
289   /* If the new thread ID is zero, a final thread ID will be available
290      later.  Do not enable thread debugging yet.  */
291   if (ti.ti_tid == 0)
292     return 0;
293
294   lwp->thread_known = 1;
295   lwp->th = th;
296
297   return 1;
298 }
299
300 /* Attach a thread.  Return true on success.  */
301
302 static int
303 attach_thread (const td_thrhandle_t *th_p, td_thrinfo_t *ti_p)
304 {
305   struct lwp_info *lwp;
306
307   if (debug_threads)
308     fprintf (stderr, "Attaching to thread %ld (LWP %d)\n",
309              ti_p->ti_tid, ti_p->ti_lid);
310   linux_attach_lwp (ti_p->ti_lid);
311   lwp = find_lwp_pid (pid_to_ptid (ti_p->ti_lid));
312   if (lwp == NULL)
313     {
314       warning ("Could not attach to thread %ld (LWP %d)\n",
315                ti_p->ti_tid, ti_p->ti_lid);
316       return 0;
317     }
318
319   lwp->thread_known = 1;
320   lwp->th = *th_p;
321
322   if (thread_db_use_events)
323     {
324       td_err_e err;
325       struct thread_db *thread_db = current_process ()->private->thread_db;
326
327       err = thread_db->td_thr_event_enable_p (th_p, 1);
328       if (err != TD_OK)
329         error ("Cannot enable thread event reporting for %d: %s",
330                ti_p->ti_lid, thread_db_err_str (err));
331     }
332
333   return 1;
334 }
335
336 /* Attach thread if we haven't seen it yet.
337    Increment *COUNTER if we have attached a new thread.
338    Return false on failure.  */
339
340 static int
341 maybe_attach_thread (const td_thrhandle_t *th_p, td_thrinfo_t *ti_p,
342                      int *counter)
343 {
344   struct lwp_info *lwp;
345
346   lwp = find_lwp_pid (pid_to_ptid (ti_p->ti_lid));
347   if (lwp != NULL)
348     return 1;
349
350   if (!attach_thread (th_p, ti_p))
351     return 0;
352
353   if (counter != NULL)
354     *counter += 1;
355
356   return 1;
357 }
358
359 static int
360 find_new_threads_callback (const td_thrhandle_t *th_p, void *data)
361 {
362   td_thrinfo_t ti;
363   td_err_e err;
364   struct thread_db *thread_db = current_process ()->private->thread_db;
365
366   err = thread_db->td_thr_get_info_p (th_p, &ti);
367   if (err != TD_OK)
368     error ("Cannot get thread info: %s", thread_db_err_str (err));
369
370   /* Check for zombies.  */
371   if (ti.ti_state == TD_THR_UNKNOWN || ti.ti_state == TD_THR_ZOMBIE)
372     return 0;
373
374   if (!maybe_attach_thread (th_p, &ti, (int *) data))
375     {
376       /* Terminate iteration early: we might be looking at stale data in
377          the inferior.  The thread_db_find_new_threads will retry.  */
378       return 1;
379     }
380
381   return 0;
382 }
383
384 static void
385 thread_db_find_new_threads (void)
386 {
387   td_err_e err;
388   ptid_t ptid = ((struct inferior_list_entry *) current_inferior)->id;
389   struct thread_db *thread_db = current_process ()->private->thread_db;
390   int loop, iteration;
391
392   /* This function is only called when we first initialize thread_db.
393      First locate the initial thread.  If it is not ready for
394      debugging yet, then stop.  */
395   if (find_one_thread (ptid) == 0)
396     return;
397
398   /* Require 4 successive iterations which do not find any new threads.
399      The 4 is a heuristic: there is an inherent race here, and I have
400      seen that 2 iterations in a row are not always sufficient to
401      "capture" all threads.  */
402   for (loop = 0, iteration = 0; loop < 4; ++loop, ++iteration)
403     {
404       int new_thread_count = 0;
405
406       /* Iterate over all user-space threads to discover new threads.  */
407       err = thread_db->td_ta_thr_iter_p (thread_db->thread_agent,
408                                          find_new_threads_callback,
409                                          &new_thread_count,
410                                          TD_THR_ANY_STATE, TD_THR_LOWEST_PRIORITY,
411                                          TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS);
412       if (debug_threads)
413         fprintf (stderr, "Found %d threads in iteration %d.\n",
414                  new_thread_count, iteration);
415
416       if (new_thread_count != 0)
417         {
418           /* Found new threads.  Restart iteration from beginning.  */
419           loop = -1;
420         }
421     }
422   if (err != TD_OK)
423     error ("Cannot find new threads: %s", thread_db_err_str (err));
424 }
425
426 /* Cache all future symbols that thread_db might request.  We can not
427    request symbols at arbitrary states in the remote protocol, only
428    when the client tells us that new symbols are available.  So when
429    we load the thread library, make sure to check the entire list.  */
430
431 static void
432 thread_db_look_up_symbols (void)
433 {
434   struct thread_db *thread_db = current_process ()->private->thread_db;
435   const char **sym_list;
436   CORE_ADDR unused;
437
438   for (sym_list = thread_db->td_symbol_list_p (); *sym_list; sym_list++)
439     look_up_one_symbol (*sym_list, &unused);
440 }
441
442 int
443 thread_db_get_tls_address (struct thread_info *thread, CORE_ADDR offset,
444                            CORE_ADDR load_module, CORE_ADDR *address)
445 {
446   psaddr_t addr;
447   td_err_e err;
448   struct lwp_info *lwp;
449   struct thread_info *saved_inferior;
450   struct process_info *proc;
451   struct thread_db *thread_db;
452
453   proc = get_thread_process (thread);
454   thread_db = proc->private->thread_db;
455
456   /* If the thread layer is not (yet) initialized, fail.  */
457   if (!proc->all_symbols_looked_up)
458     return TD_ERR;
459
460   if (thread_db->td_thr_tls_get_addr_p == NULL)
461     return -1;
462
463   lwp = get_thread_lwp (thread);
464   if (!lwp->thread_known)
465     find_one_thread (lwp->head.id);
466   if (!lwp->thread_known)
467     return TD_NOTHR;
468
469   saved_inferior = current_inferior;
470   current_inferior = thread;
471   /* Note the cast through uintptr_t: this interface only works if
472      a target address fits in a psaddr_t, which is a host pointer.
473      So a 32-bit debugger can not access 64-bit TLS through this.  */
474   err = thread_db->td_thr_tls_get_addr_p (&lwp->th,
475                                           (psaddr_t) (uintptr_t) load_module,
476                                           offset, &addr);
477   current_inferior = saved_inferior;
478   if (err == TD_OK)
479     {
480       *address = (CORE_ADDR) (uintptr_t) addr;
481       return 0;
482     }
483   else
484     return err;
485 }
486
487 static int
488 try_thread_db_load_1 (void *handle)
489 {
490   td_err_e err;
491   struct thread_db tdb;
492   struct process_info *proc = current_process ();
493
494   if (proc->private->thread_db != NULL)
495     fatal ("unexpected: proc->private->thread_db != NULL");
496
497   tdb.handle = handle;
498
499   /* Initialize pointers to the dynamic library functions we will use.
500      Essential functions first.  */
501
502 #define CHK(required, a)                                        \
503   do                                                            \
504     {                                                           \
505       if ((a) == NULL)                                          \
506         {                                                       \
507           if (debug_threads)                                    \
508             fprintf (stderr, "dlsym: %s\n", dlerror ());        \
509           if (required)                                         \
510             return 0;                                           \
511         }                                                       \
512     }                                                           \
513   while (0)
514
515   CHK (1, tdb.td_ta_new_p = dlsym (handle, "td_ta_new"));
516
517   /* Attempt to open a connection to the thread library.  */
518   err = tdb.td_ta_new_p (&tdb.proc_handle, &tdb.thread_agent);
519   if (err != TD_OK)
520     {
521       if (debug_threads)
522         fprintf (stderr, "td_ta_new(): %s\n", thread_db_err_str (err));
523       return 0;
524     }
525
526   CHK (1, tdb.td_ta_map_lwp2thr_p = dlsym (handle, "td_ta_map_lwp2thr"));
527   CHK (1, tdb.td_thr_get_info_p = dlsym (handle, "td_thr_get_info"));
528   CHK (1, tdb.td_ta_thr_iter_p = dlsym (handle, "td_ta_thr_iter"));
529   CHK (1, tdb.td_symbol_list_p = dlsym (handle, "td_symbol_list"));
530
531   /* This is required only when thread_db_use_events is on.  */
532   CHK (thread_db_use_events,
533        tdb.td_thr_event_enable_p = dlsym (handle, "td_thr_event_enable"));
534
535   /* These are not essential.  */
536   CHK (0, tdb.td_ta_event_addr_p = dlsym (handle, "td_ta_event_addr"));
537   CHK (0, tdb.td_ta_set_event_p = dlsym (handle, "td_ta_set_event"));
538   CHK (0, tdb.td_ta_event_getmsg_p = dlsym (handle, "td_ta_event_getmsg"));
539   CHK (0, tdb.td_thr_tls_get_addr_p = dlsym (handle, "td_thr_tls_get_addr"));
540
541 #undef CHK
542
543   proc->private->thread_db = xmalloc (sizeof (tdb));
544   memcpy (proc->private->thread_db, &tdb, sizeof (tdb));
545
546   return 1;
547 }
548
549 /* Lookup a library in which given symbol resides.
550    Note: this is looking in the GDBSERVER process, not in the inferior.
551    Returns library name, or NULL.  */
552
553 static const char *
554 dladdr_to_soname (const void *addr)
555 {
556   Dl_info info;
557
558   if (dladdr (addr, &info) != 0)
559     return info.dli_fname;
560   return NULL;
561 }
562
563 static int
564 try_thread_db_load (const char *library)
565 {
566   void *handle;
567
568   if (debug_threads)
569     fprintf (stderr, "Trying host libthread_db library: %s.\n",
570              library);
571   handle = dlopen (library, RTLD_NOW);
572   if (handle == NULL)
573     {
574       if (debug_threads)
575         fprintf (stderr, "dlopen failed: %s.\n", dlerror ());
576       return 0;
577     }
578
579   if (debug_threads && strchr (library, '/') == NULL)
580     {
581       void *td_init;
582
583       td_init = dlsym (handle, "td_init");
584       if (td_init != NULL)
585         {
586           const char *const libpath = dladdr_to_soname (td_init);
587
588           if (libpath != NULL)
589             fprintf (stderr, "Host %s resolved to: %s.\n",
590                      library, libpath);
591         }
592     }
593
594   if (try_thread_db_load_1 (handle))
595     return 1;
596
597   /* This library "refused" to work on current inferior.  */
598   dlclose (handle);
599   return 0;
600 }
601
602 static int
603 thread_db_load_search (void)
604 {
605   char path[PATH_MAX];
606   const char *search_path;
607   int rc = 0;
608
609   if (libthread_db_search_path == NULL)
610     libthread_db_search_path = xstrdup (LIBTHREAD_DB_SEARCH_PATH);
611
612   search_path = libthread_db_search_path;
613   while (*search_path)
614     {
615       const char *end = strchr (search_path, ':');
616       if (end)
617         {
618           size_t len = end - search_path;
619           if (len + 1 + strlen (LIBTHREAD_DB_SO) + 1 > sizeof (path))
620             {
621               char *cp = xmalloc (len + 1);
622               memcpy (cp, search_path, len);
623               cp[len] = '\0';
624               warning ("libthread_db_search_path component too long, "
625                        "ignored: %s.", cp);
626               free (cp);
627               search_path += len + 1;
628               continue;
629             }
630           memcpy (path, search_path, len);
631           path[len] = '\0';
632           search_path += len + 1;
633         }
634       else
635         {
636           size_t len = strlen (search_path);
637
638           if (len + 1 + strlen (LIBTHREAD_DB_SO) + 1 > sizeof (path))
639             {
640               warning ("libthread_db_search_path component too long,"
641                        " ignored: %s.", search_path);
642               break;
643             }
644           memcpy (path, search_path, len + 1);
645           search_path += len;
646         }
647       strcat (path, "/");
648       strcat (path, LIBTHREAD_DB_SO);
649       if (debug_threads)
650         fprintf (stderr, "thread_db_load_search trying %s\n", path);
651       if (try_thread_db_load (path))
652         {
653           rc = 1;
654           break;
655         }
656     }
657   if (rc == 0)
658     rc = try_thread_db_load (LIBTHREAD_DB_SO);
659
660   if (debug_threads)
661     fprintf (stderr, "thread_db_load_search returning %d\n", rc);
662   return rc;
663 }
664
665 int
666 thread_db_init (int use_events)
667 {
668   struct process_info *proc = current_process ();
669
670   /* FIXME drow/2004-10-16: This is the "overall process ID", which
671      GNU/Linux calls tgid, "thread group ID".  When we support
672      attaching to threads, the original thread may not be the correct
673      thread.  We would have to get the process ID from /proc for NPTL.
674      For LinuxThreads we could do something similar: follow the chain
675      of parent processes until we find the highest one we're attached
676      to, and use its tgid.
677
678      This isn't the only place in gdbserver that assumes that the first
679      process in the list is the thread group leader.  */
680
681   thread_db_use_events = use_events;
682
683   if (thread_db_load_search ())
684     {
685       if (use_events && thread_db_enable_reporting () == 0)
686         {
687           /* Keep trying; maybe event reporting will work later.  */
688           thread_db_free (proc);
689           return 0;
690         }
691       thread_db_find_new_threads ();
692       thread_db_look_up_symbols ();
693       proc->all_symbols_looked_up = 1;
694       return 1;
695     }
696
697   return 0;
698 }
699
700 /* Disconnect from libthread_db and free resources.  */
701
702 void
703 thread_db_free (struct process_info *proc)
704 {
705   struct thread_db *thread_db = proc->private->thread_db;
706   if (thread_db)
707     {
708       td_err_e (*td_ta_delete_p) (td_thragent_t *);
709
710       td_ta_delete_p = dlsym (thread_db->handle, "td_ta_delete");
711       if (td_ta_delete_p != NULL)
712         (*td_ta_delete_p) (thread_db->thread_agent);
713
714       dlclose (thread_db->handle);
715       free (thread_db);
716       proc->private->thread_db = NULL;
717     }
718 }
719
720 /* Handle "set libthread-db-search-path" monitor command and return 1.
721    For any other command, return 0.  */
722
723 int
724 thread_db_handle_monitor_command (char *mon)
725 {
726   if (strncmp (mon, "set libthread-db-search-path ", 29) == 0)
727     {
728       const char *cp = mon + 29;
729
730       if (libthread_db_search_path != NULL)
731         free (libthread_db_search_path);
732
733       /* Skip leading space (if any).  */
734       while (isspace (*cp))
735         ++cp;
736
737       libthread_db_search_path = xstrdup (cp);
738
739       monitor_output ("libthread-db-search-path set to `");
740       monitor_output (libthread_db_search_path);
741       monitor_output ("'\n");
742       return 1;
743     }
744
745   /* Tell server.c to perform default processing.  */
746   return 0;
747 }