OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gdb-7.1/] [gdb/] [gdbserver/] [thread-db.c] - Blame information for rev 833

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.