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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [gdb-5.3/] [gdb/] [thread-db.c] - Blame information for rev 1773

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

Line No. Rev Author Line
1 1181 sfurman
/* libthread_db assisted debugging support, generic parts.
2
   Copyright 1999, 2000, 2001 Free Software Foundation, Inc.
3
 
4
   This file is part of GDB.
5
 
6
   This program is free software; you can redistribute it and/or modify
7
   it under the terms of the GNU General Public License as published by
8
   the Free Software Foundation; either version 2 of the License, or
9
   (at your option) any later version.
10
 
11
   This program is distributed in the hope that it will be useful,
12
   but WITHOUT ANY WARRANTY; without even the implied warranty of
13
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
   GNU General Public License for more details.
15
 
16
   You should have received a copy of the GNU General Public License
17
   along with this program; if not, write to the Free Software
18
   Foundation, Inc., 59 Temple Place - Suite 330,
19
   Boston, MA 02111-1307, USA.  */
20
 
21
#include "defs.h"
22
 
23
#include "gdb_assert.h"
24
#include <dlfcn.h>
25
#include "gdb_proc_service.h"
26
#include "gdb_thread_db.h"
27
 
28
#include "bfd.h"
29
#include "gdbthread.h"
30
#include "inferior.h"
31
#include "symfile.h"
32
#include "objfiles.h"
33
#include "target.h"
34
#include "regcache.h"
35
 
36
#ifndef LIBTHREAD_DB_SO
37
#define LIBTHREAD_DB_SO "libthread_db.so.1"
38
#endif
39
 
40
/* If we're running on GNU/Linux, we must explicitly attach to any new
41
   threads.  */
42
 
43
/* FIXME: There is certainly some room for improvements:
44
   - Cache LWP ids.
45
   - Bypass libthread_db when fetching or storing registers for
46
   threads bound to a LWP.  */
47
 
48
/* This module's target vector.  */
49
static struct target_ops thread_db_ops;
50
 
51
/* The target vector that we call for things this module can't handle.  */
52
static struct target_ops *target_beneath;
53
 
54
/* Pointer to the next function on the objfile event chain.  */
55
static void (*target_new_objfile_chain) (struct objfile *objfile);
56
 
57
/* Non-zero if we're using this module's target vector.  */
58
static int using_thread_db;
59
 
60
/* Non-zero if we have to keep this module's target vector active
61
   across re-runs.  */
62
static int keep_thread_db;
63
 
64
/* Non-zero if we have determined the signals used by the threads
65
   library.  */
66
static int thread_signals;
67
static sigset_t thread_stop_set;
68
static sigset_t thread_print_set;
69
 
70
/* Structure that identifies the child process for the
71
   <proc_service.h> interface.  */
72
static struct ps_prochandle proc_handle;
73
 
74
/* Connection to the libthread_db library.  */
75
static td_thragent_t *thread_agent;
76
 
77
/* Pointers to the libthread_db functions.  */
78
 
79
static td_err_e (*td_init_p) (void);
80
 
81
static td_err_e (*td_ta_new_p) (struct ps_prochandle *ps, td_thragent_t **ta);
82
static td_err_e (*td_ta_map_id2thr_p) (const td_thragent_t *ta, thread_t pt,
83
                                       td_thrhandle_t *__th);
84
static td_err_e (*td_ta_map_lwp2thr_p) (const td_thragent_t *ta, lwpid_t lwpid,
85
                                        td_thrhandle_t *th);
86
static td_err_e (*td_ta_thr_iter_p) (const td_thragent_t *ta,
87
                                     td_thr_iter_f *callback,
88
                                     void *cbdata_p, td_thr_state_e state,
89
                                     int ti_pri, sigset_t *ti_sigmask_p,
90
                                     unsigned int ti_user_flags);
91
static td_err_e (*td_ta_event_addr_p) (const td_thragent_t *ta,
92
                                       td_event_e event, td_notify_t *ptr);
93
static td_err_e (*td_ta_set_event_p) (const td_thragent_t *ta,
94
                                      td_thr_events_t *event);
95
static td_err_e (*td_ta_event_getmsg_p) (const td_thragent_t *ta,
96
                                         td_event_msg_t *msg);
97
 
98
static td_err_e (*td_thr_validate_p) (const td_thrhandle_t *th);
99
static td_err_e (*td_thr_get_info_p) (const td_thrhandle_t *th,
100
                                      td_thrinfo_t *infop);
101
static td_err_e (*td_thr_getfpregs_p) (const td_thrhandle_t *th,
102
                                       gdb_prfpregset_t *regset);
103
static td_err_e (*td_thr_getgregs_p) (const td_thrhandle_t *th,
104
                                      prgregset_t gregs);
105
static td_err_e (*td_thr_setfpregs_p) (const td_thrhandle_t *th,
106
                                       const gdb_prfpregset_t *fpregs);
107
static td_err_e (*td_thr_setgregs_p) (const td_thrhandle_t *th,
108
                                      prgregset_t gregs);
109
static td_err_e (*td_thr_event_enable_p) (const td_thrhandle_t *th, int event);
110
 
111
/* Location of the thread creation event breakpoint.  The code at this
112
   location in the child process will be called by the pthread library
113
   whenever a new thread is created.  By setting a special breakpoint
114
   at this location, GDB can detect when a new thread is created.  We
115
   obtain this location via the td_ta_event_addr call.  */
116
static CORE_ADDR td_create_bp_addr;
117
 
118
/* Location of the thread death event breakpoint.  */
119
static CORE_ADDR td_death_bp_addr;
120
 
121
/* Prototypes for local functions.  */
122
static void thread_db_find_new_threads (void);
123
 
124
 
125
/* Building process ids.  */
126
 
127
#define GET_PID(ptid)           ptid_get_pid (ptid)
128
#define GET_LWP(ptid)           ptid_get_lwp (ptid)
129
#define GET_THREAD(ptid)        ptid_get_tid (ptid)
130
 
131
#define is_lwp(ptid)            (GET_LWP (ptid) != 0)
132
#define is_thread(ptid)         (GET_THREAD (ptid) != 0)
133
 
134
#define BUILD_LWP(lwp, pid)     ptid_build (pid, lwp, 0)
135
#define BUILD_THREAD(tid, pid)  ptid_build (pid, 0, tid)
136
 
137
 
138
struct private_thread_info
139
{
140
  /* Cached LWP id.  Must come first, see lin-lwp.c.  */
141
  lwpid_t lwpid;
142
};
143
 
144
 
145
static char *
146
thread_db_err_str (td_err_e err)
147
{
148
  static char buf[64];
149
 
150
  switch (err)
151
    {
152
    case TD_OK:
153
      return "generic 'call succeeded'";
154
    case TD_ERR:
155
      return "generic error";
156
    case TD_NOTHR:
157
      return "no thread to satisfy query";
158
    case TD_NOSV:
159
      return "no sync handle to satisfy query";
160
    case TD_NOLWP:
161
      return "no LWP to satisfy query";
162
    case TD_BADPH:
163
      return "invalid process handle";
164
    case TD_BADTH:
165
      return "invalid thread handle";
166
    case TD_BADSH:
167
      return "invalid synchronization handle";
168
    case TD_BADTA:
169
      return "invalid thread agent";
170
    case TD_BADKEY:
171
      return "invalid key";
172
    case TD_NOMSG:
173
      return "no event message for getmsg";
174
    case TD_NOFPREGS:
175
      return "FPU register set not available";
176
    case TD_NOLIBTHREAD:
177
      return "application not linked with libthread";
178
    case TD_NOEVENT:
179
      return "requested event is not supported";
180
    case TD_NOCAPAB:
181
      return "capability not available";
182
    case TD_DBERR:
183
      return "debugger service failed";
184
    case TD_NOAPLIC:
185
      return "operation not applicable to";
186
    case TD_NOTSD:
187
      return "no thread-specific data for this thread";
188
    case TD_MALLOC:
189
      return "malloc failed";
190
    case TD_PARTIALREG:
191
      return "only part of register set was written/read";
192
    case TD_NOXREGS:
193
      return "X register set not available for this thread";
194
    default:
195
      snprintf (buf, sizeof (buf), "unknown thread_db error '%d'", err);
196
      return buf;
197
    }
198
}
199
 
200
static char *
201
thread_db_state_str (td_thr_state_e state)
202
{
203
  static char buf[64];
204
 
205
  switch (state)
206
    {
207
    case TD_THR_STOPPED:
208
      return "stopped by debugger";
209
    case TD_THR_RUN:
210
      return "runnable";
211
    case TD_THR_ACTIVE:
212
      return "active";
213
    case TD_THR_ZOMBIE:
214
      return "zombie";
215
    case TD_THR_SLEEP:
216
      return "sleeping";
217
    case TD_THR_STOPPED_ASLEEP:
218
      return "stopped by debugger AND blocked";
219
    default:
220
      snprintf (buf, sizeof (buf), "unknown thread_db state %d", state);
221
      return buf;
222
    }
223
}
224
 
225
 
226
/* Convert between user-level thread ids and LWP ids.  */
227
 
228
static ptid_t
229
thread_from_lwp (ptid_t ptid)
230
{
231
  td_thrinfo_t ti;
232
  td_thrhandle_t th;
233
  td_err_e err;
234
 
235
  if (GET_LWP (ptid) == 0)
236
    ptid = BUILD_LWP (GET_PID (ptid), GET_PID (ptid));
237
 
238
  gdb_assert (is_lwp (ptid));
239
 
240
  err = td_ta_map_lwp2thr_p (thread_agent, GET_LWP (ptid), &th);
241
  if (err != TD_OK)
242
    error ("Cannot find user-level thread for LWP %ld: %s",
243
           GET_LWP (ptid), thread_db_err_str (err));
244
 
245
  err = td_thr_get_info_p (&th, &ti);
246
  if (err != TD_OK)
247
    error ("Cannot get thread info: %s", thread_db_err_str (err));
248
 
249
  return BUILD_THREAD (ti.ti_tid, GET_PID (ptid));
250
}
251
 
252
static ptid_t
253
lwp_from_thread (ptid_t ptid)
254
{
255
  td_thrinfo_t ti;
256
  td_thrhandle_t th;
257
  td_err_e err;
258
 
259
  if (!is_thread (ptid))
260
    return ptid;
261
 
262
  err = td_ta_map_id2thr_p (thread_agent, GET_THREAD (ptid), &th);
263
  if (err != TD_OK)
264
    error ("Cannot find thread %ld: %s",
265
           (long) GET_THREAD (ptid), thread_db_err_str (err));
266
 
267
  err = td_thr_get_info_p (&th, &ti);
268
  if (err != TD_OK)
269
    error ("Cannot get thread info: %s", thread_db_err_str (err));
270
 
271
  return BUILD_LWP (ti.ti_lid, GET_PID (ptid));
272
}
273
 
274
 
275
void
276
thread_db_init (struct target_ops *target)
277
{
278
  target_beneath = target;
279
}
280
 
281
static int
282
thread_db_load (void)
283
{
284
  void *handle;
285
  td_err_e err;
286
 
287
  handle = dlopen (LIBTHREAD_DB_SO, RTLD_NOW);
288
  if (handle == NULL)
289
    return 0;
290
 
291
  /* Initialize pointers to the dynamic library functions we will use.
292
     Essential functions first.  */
293
 
294
  td_init_p = dlsym (handle, "td_init");
295
  if (td_init_p == NULL)
296
    return 0;
297
 
298
  td_ta_new_p = dlsym (handle, "td_ta_new");
299
  if (td_ta_new_p == NULL)
300
    return 0;
301
 
302
  td_ta_map_id2thr_p = dlsym (handle, "td_ta_map_id2thr");
303
  if (td_ta_map_id2thr_p == NULL)
304
    return 0;
305
 
306
  td_ta_map_lwp2thr_p = dlsym (handle, "td_ta_map_lwp2thr");
307
  if (td_ta_map_lwp2thr_p == NULL)
308
    return 0;
309
 
310
  td_ta_thr_iter_p = dlsym (handle, "td_ta_thr_iter");
311
  if (td_ta_thr_iter_p == NULL)
312
    return 0;
313
 
314
  td_thr_validate_p = dlsym (handle, "td_thr_validate");
315
  if (td_thr_validate_p == NULL)
316
    return 0;
317
 
318
  td_thr_get_info_p = dlsym (handle, "td_thr_get_info");
319
  if (td_thr_get_info_p == NULL)
320
    return 0;
321
 
322
  td_thr_getfpregs_p = dlsym (handle, "td_thr_getfpregs");
323
  if (td_thr_getfpregs_p == NULL)
324
    return 0;
325
 
326
  td_thr_getgregs_p = dlsym (handle, "td_thr_getgregs");
327
  if (td_thr_getgregs_p == NULL)
328
    return 0;
329
 
330
  td_thr_setfpregs_p = dlsym (handle, "td_thr_setfpregs");
331
  if (td_thr_setfpregs_p == NULL)
332
    return 0;
333
 
334
  td_thr_setgregs_p = dlsym (handle, "td_thr_setgregs");
335
  if (td_thr_setgregs_p == NULL)
336
    return 0;
337
 
338
  /* Initialize the library.  */
339
  err = td_init_p ();
340
  if (err != TD_OK)
341
    {
342
      warning ("Cannot initialize libthread_db: %s", thread_db_err_str (err));
343
      return 0;
344
    }
345
 
346
  /* These are not essential.  */
347
  td_ta_event_addr_p = dlsym (handle, "td_ta_event_addr");
348
  td_ta_set_event_p = dlsym (handle, "td_ta_set_event");
349
  td_ta_event_getmsg_p = dlsym (handle, "td_ta_event_getmsg");
350
  td_thr_event_enable_p = dlsym (handle, "td_thr_event_enable");
351
 
352
  return 1;
353
}
354
 
355
static void
356
enable_thread_event_reporting (void)
357
{
358
  td_thr_events_t events;
359
  td_notify_t notify;
360
  td_err_e err;
361
 
362
  /* We cannot use the thread event reporting facility if these
363
     functions aren't available.  */
364
  if (td_ta_event_addr_p == NULL || td_ta_set_event_p == NULL
365
      || td_ta_event_getmsg_p == NULL || td_thr_event_enable_p == NULL)
366
    return;
367
 
368
  /* Set the process wide mask saying which events we're interested in.  */
369
  td_event_emptyset (&events);
370
  td_event_addset (&events, TD_CREATE);
371
#if 0
372
  /* FIXME: kettenis/2000-04-23: The event reporting facility is
373
     broken for TD_DEATH events in glibc 2.1.3, so don't enable it for
374
     now.  */
375
  td_event_addset (&events, TD_DEATH);
376
#endif
377
 
378
  err = td_ta_set_event_p (thread_agent, &events);
379
  if (err != TD_OK)
380
    {
381
      warning ("Unable to set global thread event mask: %s",
382
               thread_db_err_str (err));
383
      return;
384
    }
385
 
386
  /* Delete previous thread event breakpoints, if any.  */
387
  remove_thread_event_breakpoints ();
388
 
389
  /* Get address for thread creation breakpoint.  */
390
  err = td_ta_event_addr_p (thread_agent, TD_CREATE, &notify);
391
  if (err != TD_OK)
392
    {
393
      warning ("Unable to get location for thread creation breakpoint: %s",
394
               thread_db_err_str (err));
395
      return;
396
    }
397
 
398
  /* Set up the breakpoint.  */
399
  td_create_bp_addr = (CORE_ADDR) notify.u.bptaddr;
400
  create_thread_event_breakpoint (td_create_bp_addr);
401
 
402
  /* Get address for thread death breakpoint.  */
403
  err = td_ta_event_addr_p (thread_agent, TD_DEATH, &notify);
404
  if (err != TD_OK)
405
    {
406
      warning ("Unable to get location for thread death breakpoint: %s",
407
               thread_db_err_str (err));
408
      return;
409
    }
410
 
411
  /* Set up the breakpoint.  */
412
  td_death_bp_addr = (CORE_ADDR) notify.u.bptaddr;
413
  create_thread_event_breakpoint (td_death_bp_addr);
414
}
415
 
416
static void
417
disable_thread_event_reporting (void)
418
{
419
  td_thr_events_t events;
420
 
421
  /* Set the process wide mask saying we aren't interested in any
422
     events anymore.  */
423
  td_event_emptyset (&events);
424
  td_ta_set_event_p (thread_agent, &events);
425
 
426
  /* Delete thread event breakpoints, if any.  */
427
  remove_thread_event_breakpoints ();
428
  td_create_bp_addr = 0;
429
  td_death_bp_addr = 0;
430
}
431
 
432
static void
433
check_thread_signals (void)
434
{
435
#ifdef GET_THREAD_SIGNALS
436
  if (!thread_signals)
437
    {
438
      sigset_t mask;
439
      int i;
440
 
441
      GET_THREAD_SIGNALS (&mask);
442
      sigemptyset (&thread_stop_set);
443
      sigemptyset (&thread_print_set);
444
 
445
      for (i = 1; i < NSIG; i++)
446
        {
447
          if (sigismember (&mask, i))
448
            {
449
              if (signal_stop_update (target_signal_from_host (i), 0))
450
                sigaddset (&thread_stop_set, i);
451
              if (signal_print_update (target_signal_from_host (i), 0))
452
                sigaddset (&thread_print_set, i);
453
              thread_signals = 1;
454
            }
455
        }
456
    }
457
#endif
458
}
459
 
460
static void
461
disable_thread_signals (void)
462
{
463
#ifdef GET_THREAD_SIGNALS
464
  if (thread_signals)
465
    {
466
      int i;
467
 
468
      for (i = 1; i < NSIG; i++)
469
        {
470
          if (sigismember (&thread_stop_set, i))
471
            signal_stop_update (target_signal_from_host (i), 1);
472
          if (sigismember (&thread_print_set, i))
473
            signal_print_update (target_signal_from_host (i), 1);
474
        }
475
 
476
      thread_signals = 0;
477
    }
478
#endif
479
}
480
 
481
static void
482
thread_db_new_objfile (struct objfile *objfile)
483
{
484
  td_err_e err;
485
 
486
  /* Don't attempt to use thread_db on targets which can not run
487
     (core files).  */
488
  if (objfile == NULL || !target_has_execution)
489
    {
490
      /* All symbols have been discarded.  If the thread_db target is
491
         active, deactivate it now.  */
492
      if (using_thread_db)
493
        {
494
          gdb_assert (proc_handle.pid == 0);
495
          unpush_target (&thread_db_ops);
496
          using_thread_db = 0;
497
        }
498
 
499
      keep_thread_db = 0;
500
 
501
      goto quit;
502
    }
503
 
504
  if (using_thread_db)
505
    /* Nothing to do.  The thread library was already detected and the
506
       target vector was already activated.  */
507
    goto quit;
508
 
509
  /* Initialize the structure that identifies the child process.  Note
510
     that at this point there is no guarantee that we actually have a
511
     child process.  */
512
  proc_handle.pid = GET_PID (inferior_ptid);
513
 
514
  /* Now attempt to open a connection to the thread library.  */
515
  err = td_ta_new_p (&proc_handle, &thread_agent);
516
  switch (err)
517
    {
518
    case TD_NOLIBTHREAD:
519
      /* No thread library was detected.  */
520
      break;
521
 
522
    case TD_OK:
523
      /* The thread library was detected.  Activate the thread_db target.  */
524
      push_target (&thread_db_ops);
525
      using_thread_db = 1;
526
 
527
      /* If the thread library was detected in the main symbol file
528
         itself, we assume that the program was statically linked
529
         against the thread library and well have to keep this
530
         module's target vector activated until forever...  Well, at
531
         least until all symbols have been discarded anyway (see
532
         above).  */
533
      if (objfile == symfile_objfile)
534
        {
535
          gdb_assert (proc_handle.pid == 0);
536
          keep_thread_db = 1;
537
        }
538
 
539
      /* We can only poke around if there actually is a child process.
540
         If there is no child process alive, postpone the steps below
541
         until one has been created.  */
542
      if (proc_handle.pid != 0)
543
        {
544
          enable_thread_event_reporting ();
545
          thread_db_find_new_threads ();
546
        }
547
      break;
548
 
549
    default:
550
      warning ("Cannot initialize thread debugging library: %s",
551
               thread_db_err_str (err));
552
      break;
553
    }
554
 
555
 quit:
556
  if (target_new_objfile_chain)
557
    target_new_objfile_chain (objfile);
558
}
559
 
560
static void
561
attach_thread (ptid_t ptid, const td_thrhandle_t *th_p,
562
               const td_thrinfo_t *ti_p, int verbose)
563
{
564
  struct thread_info *tp;
565
  td_err_e err;
566
 
567
  check_thread_signals ();
568
 
569
  if (verbose)
570
    printf_unfiltered ("[New %s]\n", target_pid_to_str (ptid));
571
 
572
  /* Add the thread to GDB's thread list.  */
573
  tp = add_thread (ptid);
574
  tp->private = xmalloc (sizeof (struct private_thread_info));
575
  tp->private->lwpid = ti_p->ti_lid;
576
 
577
  if (ti_p->ti_state == TD_THR_UNKNOWN || ti_p->ti_state == TD_THR_ZOMBIE)
578
    return;                     /* A zombie thread -- do not attach.  */
579
 
580
  /* Under GNU/Linux, we have to attach to each and every thread.  */
581
#ifdef ATTACH_LWP
582
  ATTACH_LWP (BUILD_LWP (ti_p->ti_lid, GET_PID (ptid)), 0);
583
#endif
584
 
585
  /* Enable thread event reporting for this thread.  */
586
  err = td_thr_event_enable_p (th_p, 1);
587
  if (err != TD_OK)
588
    error ("Cannot enable thread event reporting for %s: %s",
589
           target_pid_to_str (ptid), thread_db_err_str (err));
590
}
591
 
592
static void
593
thread_db_attach (char *args, int from_tty)
594
{
595
  target_beneath->to_attach (args, from_tty);
596
 
597
  /* Destroy thread info; it's no longer valid.  */
598
  init_thread_list ();
599
 
600
  /* The child process is now the actual multi-threaded
601
     program.  Snatch its process ID...  */
602
  proc_handle.pid = GET_PID (inferior_ptid);
603
 
604
  /* ...and perform the remaining initialization steps.  */
605
  enable_thread_event_reporting ();
606
  thread_db_find_new_threads();
607
}
608
 
609
static void
610
detach_thread (ptid_t ptid, int verbose)
611
{
612
  if (verbose)
613
    printf_unfiltered ("[%s exited]\n", target_pid_to_str (ptid));
614
}
615
 
616
static void
617
thread_db_detach (char *args, int from_tty)
618
{
619
  disable_thread_event_reporting ();
620
 
621
  /* There's no need to save & restore inferior_ptid here, since the
622
     inferior is supposed to be survive this function call.  */
623
  inferior_ptid = lwp_from_thread (inferior_ptid);
624
 
625
  /* Forget about the child's process ID.  We shouldn't need it
626
     anymore.  */
627
  proc_handle.pid = 0;
628
 
629
  target_beneath->to_detach (args, from_tty);
630
}
631
 
632
static void
633
thread_db_resume (ptid_t ptid, int step, enum target_signal signo)
634
{
635
  struct cleanup *old_chain = save_inferior_ptid ();
636
 
637
  if (GET_PID (ptid) == -1)
638
    inferior_ptid = lwp_from_thread (inferior_ptid);
639
  else if (is_thread (ptid))
640
    ptid = lwp_from_thread (ptid);
641
 
642
  target_beneath->to_resume (ptid, step, signo);
643
 
644
  do_cleanups (old_chain);
645
}
646
 
647
/* Check if PID is currently stopped at the location of a thread event
648
   breakpoint location.  If it is, read the event message and act upon
649
   the event.  */
650
 
651
static void
652
check_event (ptid_t ptid)
653
{
654
  td_event_msg_t msg;
655
  td_thrinfo_t ti;
656
  td_err_e err;
657
  CORE_ADDR stop_pc;
658
 
659
  /* Bail out early if we're not at a thread event breakpoint.  */
660
  stop_pc = read_pc_pid (ptid) - DECR_PC_AFTER_BREAK;
661
  if (stop_pc != td_create_bp_addr && stop_pc != td_death_bp_addr)
662
    return;
663
 
664
  err = td_ta_event_getmsg_p (thread_agent, &msg);
665
  if (err != TD_OK)
666
    {
667
      if (err == TD_NOMSG)
668
        return;
669
 
670
      error ("Cannot get thread event message: %s", thread_db_err_str (err));
671
    }
672
 
673
  err = td_thr_get_info_p (msg.th_p, &ti);
674
  if (err != TD_OK)
675
    error ("Cannot get thread info: %s", thread_db_err_str (err));
676
 
677
  ptid = BUILD_THREAD (ti.ti_tid, GET_PID (ptid));
678
 
679
  switch (msg.event)
680
    {
681
    case TD_CREATE:
682
#if 0
683
      /* FIXME: kettenis/2000-08-26: Since we use td_ta_event_getmsg,
684
         there is no guarantee that the breakpoint will match the
685
         event.  Should we use td_thr_event_getmsg instead?  */
686
 
687
      if (stop_pc != td_create_bp_addr)
688
        error ("Thread creation event doesn't match breakpoint.");
689
#endif
690
 
691
      /* We may already know about this thread, for instance when the
692
         user has issued the `info threads' command before the SIGTRAP
693
         for hitting the thread creation breakpoint was reported.  */
694
      if (!in_thread_list (ptid))
695
        attach_thread (ptid, msg.th_p, &ti, 1);
696
      return;
697
 
698
    case TD_DEATH:
699
#if 0
700
      /* FIXME: See TD_CREATE.  */
701
 
702
      if (stop_pc != td_death_bp_addr)
703
        error ("Thread death event doesn't match breakpoint.");
704
#endif
705
 
706
      if (!in_thread_list (ptid))
707
        error ("Spurious thread death event.");
708
 
709
      detach_thread (ptid, 1);
710
      return;
711
 
712
    default:
713
      error ("Spurious thread event.");
714
    }
715
}
716
 
717
static ptid_t
718
thread_db_wait (ptid_t ptid, struct target_waitstatus *ourstatus)
719
{
720
  extern ptid_t trap_ptid;
721
 
722
  if (GET_PID (ptid) != -1 && is_thread (ptid))
723
    ptid = lwp_from_thread (ptid);
724
 
725
  ptid = target_beneath->to_wait (ptid, ourstatus);
726
 
727
  if (proc_handle.pid == 0)
728
    /* The current child process isn't the actual multi-threaded
729
       program yet, so don't try to do any special thread-specific
730
       post-processing and bail out early.  */
731
    return ptid;
732
 
733
  if (ourstatus->kind == TARGET_WAITKIND_EXITED)
734
    return pid_to_ptid (-1);
735
 
736
  if (ourstatus->kind == TARGET_WAITKIND_STOPPED
737
      && ourstatus->value.sig == TARGET_SIGNAL_TRAP)
738
    /* Check for a thread event.  */
739
    check_event (ptid);
740
 
741
  if (!ptid_equal (trap_ptid, null_ptid))
742
    trap_ptid = thread_from_lwp (trap_ptid);
743
 
744
  return thread_from_lwp (ptid);
745
}
746
 
747
static int
748
thread_db_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
749
                       struct mem_attrib *attrib,
750
                       struct target_ops *target)
751
{
752
  struct cleanup *old_chain = save_inferior_ptid ();
753
  int xfer;
754
 
755
  if (is_thread (inferior_ptid))
756
    {
757
      /* FIXME: This seems to be necessary to make sure breakpoints
758
         are removed.  */
759
      if (!target_thread_alive (inferior_ptid))
760
        inferior_ptid = pid_to_ptid (GET_PID (inferior_ptid));
761
      else
762
        inferior_ptid = lwp_from_thread (inferior_ptid);
763
    }
764
 
765
  xfer = target_beneath->to_xfer_memory (memaddr, myaddr, len, write, attrib, target);
766
 
767
  do_cleanups (old_chain);
768
  return xfer;
769
}
770
 
771
static void
772
thread_db_fetch_registers (int regno)
773
{
774
  td_thrhandle_t th;
775
  prgregset_t gregset;
776
  gdb_prfpregset_t fpregset;
777
  td_err_e err;
778
 
779
  if (!is_thread (inferior_ptid))
780
    {
781
      /* Pass the request to the target beneath us.  */
782
      target_beneath->to_fetch_registers (regno);
783
      return;
784
    }
785
 
786
  err = td_ta_map_id2thr_p (thread_agent, GET_THREAD (inferior_ptid), &th);
787
  if (err != TD_OK)
788
    error ("Cannot find thread %ld: %s",
789
           (long) GET_THREAD (inferior_ptid), thread_db_err_str (err));
790
 
791
  err = td_thr_getgregs_p (&th, gregset);
792
  if (err != TD_OK)
793
    error ("Cannot fetch general-purpose registers for thread %ld: %s",
794
           (long) GET_THREAD (inferior_ptid), thread_db_err_str (err));
795
 
796
  err = td_thr_getfpregs_p (&th, &fpregset);
797
  if (err != TD_OK)
798
    error ("Cannot get floating-point registers for thread %ld: %s",
799
           (long) GET_THREAD (inferior_ptid), thread_db_err_str (err));
800
 
801
  /* Note that we must call supply_gregset after calling the thread_db
802
     routines because the thread_db routines call ps_lgetgregs and
803
     friends which clobber GDB's register cache.  */
804
  supply_gregset ((gdb_gregset_t *) gregset);
805
  supply_fpregset (&fpregset);
806
}
807
 
808
static void
809
thread_db_store_registers (int regno)
810
{
811
  td_thrhandle_t th;
812
  prgregset_t gregset;
813
  gdb_prfpregset_t fpregset;
814
  td_err_e err;
815
 
816
  if (!is_thread (inferior_ptid))
817
    {
818
      /* Pass the request to the target beneath us.  */
819
      target_beneath->to_store_registers (regno);
820
      return;
821
    }
822
 
823
  err = td_ta_map_id2thr_p (thread_agent, GET_THREAD (inferior_ptid), &th);
824
  if (err != TD_OK)
825
    error ("Cannot find thread %ld: %s",
826
           (long) GET_THREAD (inferior_ptid), thread_db_err_str (err));
827
 
828
  if (regno != -1)
829
    {
830
      char raw[MAX_REGISTER_RAW_SIZE];
831
 
832
      read_register_gen (regno, raw);
833
      thread_db_fetch_registers (-1);
834
      supply_register (regno, raw);
835
    }
836
 
837
  fill_gregset ((gdb_gregset_t *) gregset, -1);
838
  fill_fpregset (&fpregset, -1);
839
 
840
  err = td_thr_setgregs_p (&th, gregset);
841
  if (err != TD_OK)
842
    error ("Cannot store general-purpose registers for thread %ld: %s",
843
           (long) GET_THREAD (inferior_ptid), thread_db_err_str (err));
844
  err = td_thr_setfpregs_p (&th, &fpregset);
845
  if (err != TD_OK)
846
    error ("Cannot store floating-point registers  for thread %ld: %s",
847
           (long) GET_THREAD (inferior_ptid), thread_db_err_str (err));
848
}
849
 
850
static void
851
thread_db_kill (void)
852
{
853
  /* There's no need to save & restore inferior_ptid here, since the
854
     inferior isn't supposed to survive this function call.  */
855
  inferior_ptid = lwp_from_thread (inferior_ptid);
856
  target_beneath->to_kill ();
857
}
858
 
859
static void
860
thread_db_create_inferior (char *exec_file, char *allargs, char **env)
861
{
862
  if (!keep_thread_db)
863
    {
864
      unpush_target (&thread_db_ops);
865
      using_thread_db = 0;
866
    }
867
 
868
  target_beneath->to_create_inferior (exec_file, allargs, env);
869
}
870
 
871
static void
872
thread_db_post_startup_inferior (ptid_t ptid)
873
{
874
  if (proc_handle.pid == 0)
875
    {
876
      /* The child process is now the actual multi-threaded
877
         program.  Snatch its process ID...  */
878
      proc_handle.pid = GET_PID (ptid);
879
 
880
      /* ...and perform the remaining initialization steps.  */
881
      enable_thread_event_reporting ();
882
      thread_db_find_new_threads ();
883
    }
884
}
885
 
886
static void
887
thread_db_mourn_inferior (void)
888
{
889
  remove_thread_event_breakpoints ();
890
 
891
  /* Forget about the child's process ID.  We shouldn't need it
892
     anymore.  */
893
  proc_handle.pid = 0;
894
 
895
  target_beneath->to_mourn_inferior ();
896
}
897
 
898
static int
899
thread_db_thread_alive (ptid_t ptid)
900
{
901
  td_thrhandle_t th;
902
  td_thrinfo_t ti;
903
  td_err_e err;
904
 
905
  if (is_thread (ptid))
906
    {
907
      err = td_ta_map_id2thr_p (thread_agent, GET_THREAD (ptid), &th);
908
      if (err != TD_OK)
909
        return 0;
910
 
911
      err = td_thr_validate_p (&th);
912
      if (err != TD_OK)
913
        return 0;
914
 
915
      err = td_thr_get_info_p (&th, &ti);
916
      if (err != TD_OK)
917
        return 0;
918
 
919
      if (ti.ti_state == TD_THR_UNKNOWN || ti.ti_state == TD_THR_ZOMBIE)
920
        return 0;                /* A zombie thread.  */
921
 
922
      return 1;
923
    }
924
 
925
  if (target_beneath->to_thread_alive)
926
    return target_beneath->to_thread_alive (ptid);
927
 
928
  return 0;
929
}
930
 
931
static int
932
find_new_threads_callback (const td_thrhandle_t *th_p, void *data)
933
{
934
  td_thrinfo_t ti;
935
  td_err_e err;
936
  ptid_t ptid;
937
 
938
  err = td_thr_get_info_p (th_p, &ti);
939
  if (err != TD_OK)
940
    error ("Cannot get thread info: %s", thread_db_err_str (err));
941
 
942
  if (ti.ti_state == TD_THR_UNKNOWN || ti.ti_state == TD_THR_ZOMBIE)
943
    return 0;                    /* A zombie -- ignore.  */
944
 
945
  ptid = BUILD_THREAD (ti.ti_tid, GET_PID (inferior_ptid));
946
 
947
  if (!in_thread_list (ptid))
948
    attach_thread (ptid, th_p, &ti, 1);
949
 
950
  return 0;
951
}
952
 
953
static void
954
thread_db_find_new_threads (void)
955
{
956
  td_err_e err;
957
 
958
  /* Iterate over all user-space threads to discover new threads.  */
959
  err = td_ta_thr_iter_p (thread_agent, find_new_threads_callback, NULL,
960
                          TD_THR_ANY_STATE, TD_THR_LOWEST_PRIORITY,
961
                          TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS);
962
  if (err != TD_OK)
963
    error ("Cannot find new threads: %s", thread_db_err_str (err));
964
}
965
 
966
static char *
967
thread_db_pid_to_str (ptid_t ptid)
968
{
969
  if (is_thread (ptid))
970
    {
971
      static char buf[64];
972
      td_thrhandle_t th;
973
      td_thrinfo_t ti;
974
      td_err_e err;
975
 
976
      err = td_ta_map_id2thr_p (thread_agent, GET_THREAD (ptid), &th);
977
      if (err != TD_OK)
978
        error ("Cannot find thread %ld: %s",
979
               (long) GET_THREAD (ptid), thread_db_err_str (err));
980
 
981
      err = td_thr_get_info_p (&th, &ti);
982
      if (err != TD_OK)
983
        error ("Cannot get thread info for thread %ld: %s",
984
               (long) GET_THREAD (ptid), thread_db_err_str (err));
985
 
986
      if (ti.ti_state == TD_THR_ACTIVE && ti.ti_lid != 0)
987
        {
988
          snprintf (buf, sizeof (buf), "Thread %ld (LWP %d)",
989
                    (long) ti.ti_tid, ti.ti_lid);
990
        }
991
      else
992
        {
993
          snprintf (buf, sizeof (buf), "Thread %ld (%s)",
994
                    (long) ti.ti_tid, thread_db_state_str (ti.ti_state));
995
        }
996
 
997
      return buf;
998
    }
999
 
1000
  if (target_beneath->to_pid_to_str (ptid))
1001
    return target_beneath->to_pid_to_str (ptid);
1002
 
1003
  return normal_pid_to_str (ptid);
1004
}
1005
 
1006
static void
1007
init_thread_db_ops (void)
1008
{
1009
  thread_db_ops.to_shortname = "multi-thread";
1010
  thread_db_ops.to_longname = "multi-threaded child process.";
1011
  thread_db_ops.to_doc = "Threads and pthreads support.";
1012
  thread_db_ops.to_attach = thread_db_attach;
1013
  thread_db_ops.to_detach = thread_db_detach;
1014
  thread_db_ops.to_resume = thread_db_resume;
1015
  thread_db_ops.to_wait = thread_db_wait;
1016
  thread_db_ops.to_fetch_registers = thread_db_fetch_registers;
1017
  thread_db_ops.to_store_registers = thread_db_store_registers;
1018
  thread_db_ops.to_xfer_memory = thread_db_xfer_memory;
1019
  thread_db_ops.to_kill = thread_db_kill;
1020
  thread_db_ops.to_create_inferior = thread_db_create_inferior;
1021
  thread_db_ops.to_post_startup_inferior = thread_db_post_startup_inferior;
1022
  thread_db_ops.to_mourn_inferior = thread_db_mourn_inferior;
1023
  thread_db_ops.to_thread_alive = thread_db_thread_alive;
1024
  thread_db_ops.to_find_new_threads = thread_db_find_new_threads;
1025
  thread_db_ops.to_pid_to_str = thread_db_pid_to_str;
1026
  thread_db_ops.to_stratum = thread_stratum;
1027
  thread_db_ops.to_has_thread_control = tc_schedlock;
1028
  thread_db_ops.to_magic = OPS_MAGIC;
1029
}
1030
 
1031
void
1032
_initialize_thread_db (void)
1033
{
1034
  /* Only initialize the module if we can load libthread_db.  */
1035
  if (thread_db_load ())
1036
    {
1037
      init_thread_db_ops ();
1038
      add_target (&thread_db_ops);
1039
 
1040
      /* Add ourselves to objfile event chain.  */
1041
      target_new_objfile_chain = target_new_objfile_hook;
1042
      target_new_objfile_hook = thread_db_new_objfile;
1043
    }
1044
}

powered by: WebSVN 2.1.0

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