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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [gdb-7.2/] [gdb/] [gdbserver/] [thread-db.c] - Blame information for rev 861

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

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

powered by: WebSVN 2.1.0

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