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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [gdb/] [thread-db.c] - Blame information for rev 1767

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

Line No. Rev Author Line
1 578 markom
/* 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 Linux, we must explicitly attach to any new threads.  */
41
 
42
/* FIXME: There is certainly some room for improvements:
43
   - Cache LWP ids.
44
   - Bypass libthread_db when fetching or storing registers for
45
   threads bound to a LWP.  */
46
 
47
/* This module's target vector.  */
48
static struct target_ops thread_db_ops;
49
 
50
/* The target vector that we call for things this module can't handle.  */
51
static struct target_ops *target_beneath;
52
 
53
/* Pointer to the next function on the objfile event chain.  */
54
static void (*target_new_objfile_chain) (struct objfile *objfile);
55
 
56
/* Non-zero if we're using this module's target vector.  */
57
static int using_thread_db;
58
 
59
/* Non-zero if we have to keep this module's target vector active
60
   across re-runs.  */
61
static int keep_thread_db;
62
 
63
/* Non-zero if we have determined the signals used by the threads
64
   library.  */
65
static int thread_signals;
66
static sigset_t thread_stop_set;
67
static sigset_t thread_print_set;
68
 
69
/* Structure that identifies the child process for the
70
   <proc_service.h> interface.  */
71
static struct ps_prochandle proc_handle;
72
 
73
/* Connection to the libthread_db library.  */
74
static td_thragent_t *thread_agent;
75
 
76
/* Pointers to the libthread_db functions.  */
77
 
78
static td_err_e (*td_init_p) (void);
79
 
80
static td_err_e (*td_ta_new_p) (struct ps_prochandle *ps, td_thragent_t **ta);
81
static td_err_e (*td_ta_map_id2thr_p) (const td_thragent_t *ta, thread_t pt,
82
                                       td_thrhandle_t *__th);
83
static td_err_e (*td_ta_map_lwp2thr_p) (const td_thragent_t *ta, lwpid_t lwpid,
84
                                        td_thrhandle_t *th);
85
static td_err_e (*td_ta_thr_iter_p) (const td_thragent_t *ta,
86
                                     td_thr_iter_f *callback,
87
                                     void *cbdata_p, td_thr_state_e state,
88
                                     int ti_pri, sigset_t *ti_sigmask_p,
89
                                     unsigned int ti_user_flags);
90
static td_err_e (*td_ta_event_addr_p) (const td_thragent_t *ta,
91
                                       td_event_e event, td_notify_t *ptr);
92
static td_err_e (*td_ta_set_event_p) (const td_thragent_t *ta,
93
                                      td_thr_events_t *event);
94
static td_err_e (*td_ta_event_getmsg_p) (const td_thragent_t *ta,
95
                                         td_event_msg_t *msg);
96
 
97
static td_err_e (*td_thr_validate_p) (const td_thrhandle_t *th);
98
static td_err_e (*td_thr_get_info_p) (const td_thrhandle_t *th,
99
                                      td_thrinfo_t *infop);
100
static td_err_e (*td_thr_getfpregs_p) (const td_thrhandle_t *th,
101
                                       gdb_prfpregset_t *regset);
102
static td_err_e (*td_thr_getgregs_p) (const td_thrhandle_t *th,
103
                                      prgregset_t gregs);
104
static td_err_e (*td_thr_setfpregs_p) (const td_thrhandle_t *th,
105
                                       const gdb_prfpregset_t *fpregs);
106
static td_err_e (*td_thr_setgregs_p) (const td_thrhandle_t *th,
107
                                      prgregset_t gregs);
108
static td_err_e (*td_thr_event_enable_p) (const td_thrhandle_t *th, int event);
109
 
110
/* Location of the thread creation event breakpoint.  The code at this
111
   location in the child process will be called by the pthread library
112
   whenever a new thread is created.  By setting a special breakpoint
113
   at this location, GDB can detect when a new thread is created.  We
114
   obtain this location via the td_ta_event_addr call.  */
115
static CORE_ADDR td_create_bp_addr;
116
 
117
/* Location of the thread death event breakpoint.  */
118
static CORE_ADDR td_death_bp_addr;
119
 
120
/* Prototypes for local functions.  */
121
static void thread_db_find_new_threads (void);
122
 
123
 
124
/* Building process ids.  */
125
 
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
 
139
struct private_thread_info
140
{
141
  /* Cached LWP id.  Must come first, see lin-lwp.c.  */
142
  lwpid_t lwpid;
143
};
144
 
145
 
146
static char *
147
thread_db_err_str (td_err_e err)
148
{
149
  static char buf[64];
150
 
151
  switch (err)
152
    {
153
    case TD_OK:
154
      return "generic 'call succeeded'";
155
    case TD_ERR:
156
      return "generic error";
157
    case TD_NOTHR:
158
      return "no thread to satisfy query";
159
    case TD_NOSV:
160
      return "no sync handle to satisfy query";
161
    case TD_NOLWP:
162
      return "no LWP to satisfy query";
163
    case TD_BADPH:
164
      return "invalid process handle";
165
    case TD_BADTH:
166
      return "invalid thread handle";
167
    case TD_BADSH:
168
      return "invalid synchronization handle";
169
    case TD_BADTA:
170
      return "invalid thread agent";
171
    case TD_BADKEY:
172
      return "invalid key";
173
    case TD_NOMSG:
174
      return "no event message for getmsg";
175
    case TD_NOFPREGS:
176
      return "FPU register set not available";
177
    case TD_NOLIBTHREAD:
178
      return "application not linked with libthread";
179
    case TD_NOEVENT:
180
      return "requested event is not supported";
181
    case TD_NOCAPAB:
182
      return "capability not available";
183
    case TD_DBERR:
184
      return "debugger service failed";
185
    case TD_NOAPLIC:
186
      return "operation not applicable to";
187
    case TD_NOTSD:
188
      return "no thread-specific data for this thread";
189
    case TD_MALLOC:
190
      return "malloc failed";
191
    case TD_PARTIALREG:
192
      return "only part of register set was written/read";
193
    case TD_NOXREGS:
194
      return "X register set not available for this thread";
195
    default:
196
      snprintf (buf, sizeof (buf), "unknown thread_db error '%d'", err);
197
      return buf;
198
    }
199
}
200
 
201
static char *
202
thread_db_state_str (td_thr_state_e state)
203
{
204
  static char buf[64];
205
 
206
  switch (state)
207
    {
208
    case TD_THR_STOPPED:
209
      return "stopped by debugger";
210
    case TD_THR_RUN:
211
      return "runnable";
212
    case TD_THR_ACTIVE:
213
      return "active";
214
    case TD_THR_ZOMBIE:
215
      return "zombie";
216
    case TD_THR_SLEEP:
217
      return "sleeping";
218
    case TD_THR_STOPPED_ASLEEP:
219
      return "stopped by debugger AND blocked";
220
    default:
221
      snprintf (buf, sizeof (buf), "unknown thread_db state %d", state);
222
      return buf;
223
    }
224
}
225
 
226
 
227
/* Convert between user-level thread ids and LWP ids.  */
228
 
229
static ptid_t
230
thread_from_lwp (ptid_t ptid)
231
{
232
  td_thrinfo_t ti;
233
  td_thrhandle_t th;
234
  td_err_e err;
235
 
236
  if (GET_LWP (ptid) == 0)
237
    ptid = BUILD_LWP (GET_PID (ptid), GET_PID (ptid));
238
 
239
  gdb_assert (is_lwp (ptid));
240
 
241
  err = td_ta_map_lwp2thr_p (thread_agent, GET_LWP (ptid), &th);
242
  if (err != TD_OK)
243
    error ("Cannot find user-level thread for LWP %d: %s",
244
           GET_LWP (ptid), thread_db_err_str (err));
245
 
246
  err = td_thr_get_info_p (&th, &ti);
247
  if (err != TD_OK)
248
    error ("Cannot get thread info: %s", thread_db_err_str (err));
249
 
250
  return BUILD_THREAD (ti.ti_tid, GET_PID (ptid));
251
}
252
 
253
static ptid_t
254
lwp_from_thread (ptid_t ptid)
255
{
256
  td_thrinfo_t ti;
257
  td_thrhandle_t th;
258
  td_err_e err;
259
 
260
  if (! is_thread (ptid))
261
    return ptid;
262
 
263
  err = td_ta_map_id2thr_p (thread_agent, GET_THREAD (ptid), &th);
264
  if (err != TD_OK)
265
    error ("Cannot find thread %ld: %s",
266
           (long) GET_THREAD (ptid), thread_db_err_str (err));
267
 
268
  err = td_thr_get_info_p (&th, &ti);
269
  if (err != TD_OK)
270
    error ("Cannot get thread info: %s", thread_db_err_str (err));
271
 
272
  return BUILD_LWP (ti.ti_lid, GET_PID (ptid));
273
}
274
 
275
 
276
void
277
thread_db_init (struct target_ops *target)
278
{
279
  target_beneath = target;
280
}
281
 
282
static int
283
thread_db_load (void)
284
{
285
  void *handle;
286
  td_err_e err;
287
 
288
  handle = dlopen (LIBTHREAD_DB_SO, RTLD_NOW);
289
  if (handle == NULL)
290
    return 0;
291
 
292
  /* Initialize pointers to the dynamic library functions we will use.
293
     Essential functions first.  */
294
 
295
  td_init_p = dlsym (handle, "td_init");
296
  if (td_init_p == NULL)
297
    return 0;
298
 
299
  td_ta_new_p = dlsym (handle, "td_ta_new");
300
  if (td_ta_new_p == NULL)
301
    return 0;
302
 
303
  td_ta_map_id2thr_p = dlsym (handle, "td_ta_map_id2thr");
304
  if (td_ta_map_id2thr_p == NULL)
305
    return 0;
306
 
307
  td_ta_map_lwp2thr_p = dlsym (handle, "td_ta_map_lwp2thr");
308
  if (td_ta_map_lwp2thr_p == NULL)
309
    return 0;
310
 
311
  td_ta_thr_iter_p = dlsym (handle, "td_ta_thr_iter");
312
  if (td_ta_thr_iter_p == NULL)
313
    return 0;
314
 
315
  td_thr_validate_p = dlsym (handle, "td_thr_validate");
316
  if (td_thr_validate_p == NULL)
317
    return 0;
318
 
319
  td_thr_get_info_p = dlsym (handle, "td_thr_get_info");
320
  if (td_thr_get_info_p == NULL)
321
    return 0;
322
 
323
  td_thr_getfpregs_p = dlsym (handle, "td_thr_getfpregs");
324
  if (td_thr_getfpregs_p == NULL)
325
    return 0;
326
 
327
  td_thr_getgregs_p = dlsym (handle, "td_thr_getgregs");
328
  if (td_thr_getgregs_p == NULL)
329
    return 0;
330
 
331
  td_thr_setfpregs_p = dlsym (handle, "td_thr_setfpregs");
332
  if (td_thr_setfpregs_p == NULL)
333
    return 0;
334
 
335
  td_thr_setgregs_p = dlsym (handle, "td_thr_setgregs");
336
  if (td_thr_setgregs_p == NULL)
337
    return 0;
338
 
339
  /* Initialize the library.  */
340
  err = td_init_p ();
341
  if (err != TD_OK)
342
    {
343
      warning ("Cannot initialize libthread_db: %s", thread_db_err_str (err));
344
      return 0;
345
    }
346
 
347
  /* These are not essential.  */
348
  td_ta_event_addr_p = dlsym (handle, "td_ta_event_addr");
349
  td_ta_set_event_p = dlsym (handle, "td_ta_set_event");
350
  td_ta_event_getmsg_p = dlsym (handle, "td_ta_event_getmsg");
351
  td_thr_event_enable_p = dlsym (handle, "td_thr_event_enable");
352
 
353
  return 1;
354
}
355
 
356
static void
357
enable_thread_event_reporting (void)
358
{
359
  td_thr_events_t events;
360
  td_notify_t notify;
361
  td_err_e err;
362
 
363
  /* We cannot use the thread event reporting facility if these
364
     functions aren't available.  */
365
  if (td_ta_event_addr_p == NULL || td_ta_set_event_p == NULL
366
      || td_ta_event_getmsg_p == NULL || td_thr_event_enable_p == NULL)
367
    return;
368
 
369
  /* Set the process wide mask saying which events we're interested in.  */
370
  td_event_emptyset (&events);
371
  td_event_addset (&events, TD_CREATE);
372
#if 0
373
  /* FIXME: kettenis/2000-04-23: The event reporting facility is
374
     broken for TD_DEATH events in glibc 2.1.3, so don't enable it for
375
     now.  */
376
  td_event_addset (&events, TD_DEATH);
377
#endif
378
 
379
  err = td_ta_set_event_p (thread_agent, &events);
380
  if (err != TD_OK)
381
    {
382
      warning ("Unable to set global thread event mask: %s",
383
               thread_db_err_str (err));
384
      return;
385
    }
386
 
387
  /* Delete previous thread event breakpoints, if any.  */
388
  remove_thread_event_breakpoints ();
389
 
390
  /* Get address for thread creation breakpoint.  */
391
  err = td_ta_event_addr_p (thread_agent, TD_CREATE, &notify);
392
  if (err != TD_OK)
393
    {
394
      warning ("Unable to get location for thread creation breakpoint: %s",
395
               thread_db_err_str (err));
396
      return;
397
    }
398
 
399
  /* Set up the breakpoint.  */
400
  td_create_bp_addr = (CORE_ADDR) notify.u.bptaddr;
401
  create_thread_event_breakpoint (td_create_bp_addr);
402
 
403
  /* Get address for thread death breakpoint.  */
404
  err = td_ta_event_addr_p (thread_agent, TD_DEATH, &notify);
405
  if (err != TD_OK)
406
    {
407
      warning ("Unable to get location for thread creation breakpoint: %s",
408
               thread_db_err_str (err));
409
      return;
410
    }
411
 
412
  /* Set up the breakpoint.  */
413
  td_death_bp_addr = (CORE_ADDR) notify.u.bptaddr;
414
  create_thread_event_breakpoint (td_death_bp_addr);
415
}
416
 
417
static void
418
disable_thread_event_reporting (void)
419
{
420
  td_thr_events_t events;
421
 
422
  /* Set the process wide mask saying we aren't interested in any
423
     events anymore.  */
424
  td_event_emptyset (&events);
425
  td_ta_set_event_p (thread_agent, &events);
426
 
427
  /* Delete thread event breakpoints, if any.  */
428
  remove_thread_event_breakpoints ();
429
  td_create_bp_addr = 0;
430
  td_death_bp_addr = 0;
431
}
432
 
433
static void
434
check_thread_signals (void)
435
{
436
#ifdef GET_THREAD_SIGNALS
437
  if (! thread_signals)
438
    {
439
      sigset_t mask;
440
      int i;
441
 
442
      GET_THREAD_SIGNALS (&mask);
443
      sigemptyset (&thread_stop_set);
444
      sigemptyset (&thread_print_set);
445
 
446
      for (i = 1; i < NSIG; i++)
447
        {
448
          if (sigismember (&mask, i))
449
            {
450
              if (signal_stop_update (target_signal_from_host (i), 0))
451
                sigaddset (&thread_stop_set, i);
452
              if (signal_print_update (target_signal_from_host (i), 0))
453
                sigaddset (&thread_print_set, i);
454
              thread_signals = 1;
455
            }
456
        }
457
    }
458
#endif
459
}
460
 
461
static void
462
disable_thread_signals (void)
463
{
464
#ifdef GET_THREAD_SIGNALS
465
  if (thread_signals)
466
    {
467
      int i;
468
 
469
      for (i = 1; i < NSIG; i++)
470
        {
471
          if (sigismember (&thread_stop_set, i))
472
            signal_stop_update (target_signal_from_host (i), 1);
473
          if (sigismember (&thread_print_set, i))
474
            signal_print_update (target_signal_from_host (i), 1);
475
        }
476
 
477
      thread_signals = 0;
478
    }
479
#endif
480
}
481
 
482
static void
483
thread_db_new_objfile (struct objfile *objfile)
484
{
485
  td_err_e err;
486
 
487
  if (objfile == NULL)
488
    {
489
      /* All symbols have been discarded.  If the thread_db target is
490
         active, deactivate it now.  */
491
      if (using_thread_db)
492
        {
493
          gdb_assert (proc_handle.pid == 0);
494
          unpush_target (&thread_db_ops);
495
          using_thread_db = 0;
496
        }
497
 
498
      keep_thread_db = 0;
499
 
500
      goto quit;
501
    }
502
 
503
  if (using_thread_db)
504
    /* Nothing to do.  The thread library was already detected and the
505
       target vector was already activated.  */
506
    goto quit;
507
 
508
  /* Initialize the structure that identifies the child process.  Note
509
     that at this point there is no guarantee that we actually have a
510
     child process.  */
511
  proc_handle.pid = GET_PID (inferior_ptid);
512
 
513
  /* Now attempt to open a connection to the thread library.  */
514
  err = td_ta_new_p (&proc_handle, &thread_agent);
515
  switch (err)
516
    {
517
    case TD_NOLIBTHREAD:
518
      /* No thread library was detected.  */
519
      break;
520
 
521
    case TD_OK:
522
      /* The thread library was detected.  Activate the thread_db target.  */
523
      push_target (&thread_db_ops);
524
      using_thread_db = 1;
525
 
526
      /* If the thread library was detected in the main symbol file
527
         itself, we assume that the program was statically linked
528
         against the thread library and well have to keep this
529
         module's target vector activated until forever...  Well, at
530
         least until all symbols have been discarded anyway (see
531
         above).  */
532
      if (objfile == symfile_objfile)
533
        {
534
          gdb_assert (proc_handle.pid == 0);
535
          keep_thread_db = 1;
536
        }
537
 
538
      /* We can only poke around if there actually is a child process.
539
         If there is no child process alive, postpone the steps below
540
         until one has been created.  */
541
      if (proc_handle.pid != 0)
542
        {
543
          enable_thread_event_reporting ();
544
          thread_db_find_new_threads ();
545
        }
546
      break;
547
 
548
    default:
549
      warning ("Cannot initialize thread debugging library: %s",
550
               thread_db_err_str (err));
551
      break;
552
    }
553
 
554
 quit:
555
  if (target_new_objfile_chain)
556
    target_new_objfile_chain (objfile);
557
}
558
 
559
static void
560
attach_thread (ptid_t ptid, const td_thrhandle_t *th_p,
561
               const td_thrinfo_t *ti_p, int verbose)
562
{
563
  struct thread_info *tp;
564
  td_err_e err;
565
 
566
  check_thread_signals ();
567
 
568
  if (verbose)
569
    printf_unfiltered ("[New %s]\n", target_pid_to_str (ptid));
570
 
571
  /* Add the thread to GDB's thread list.  */
572
  tp = add_thread (ptid);
573
  tp->private = xmalloc (sizeof (struct private_thread_info));
574
  tp->private->lwpid = ti_p->ti_lid;
575
 
576
  if (ti_p->ti_state == TD_THR_UNKNOWN ||
577
      ti_p->ti_state == TD_THR_ZOMBIE)
578
    return;/* A zombie thread -- do not attach. */
579
 
580
  /* Under 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 ||
920
          ti.ti_state == TD_THR_ZOMBIE)
921
        return 0;        /* A zombie thread. */
922
 
923
      return 1;
924
    }
925
 
926
  if (target_beneath->to_thread_alive)
927
    return target_beneath->to_thread_alive (ptid);
928
 
929
  return 0;
930
}
931
 
932
static int
933
find_new_threads_callback (const td_thrhandle_t *th_p, void *data)
934
{
935
  td_thrinfo_t ti;
936
  td_err_e err;
937
  ptid_t ptid;
938
 
939
  err = td_thr_get_info_p (th_p, &ti);
940
  if (err != TD_OK)
941
    error ("Cannot get thread info: %s", thread_db_err_str (err));
942
 
943
  if (ti.ti_state == TD_THR_UNKNOWN ||
944
      ti.ti_state == TD_THR_ZOMBIE)
945
 
946
    return 0;    /* A zombie -- ignore. */
947
 
948
  ptid = BUILD_THREAD (ti.ti_tid, GET_PID (inferior_ptid));
949
 
950
  if (! in_thread_list (ptid))
951
    attach_thread (ptid, th_p, &ti, 1);
952
 
953
  return 0;
954
}
955
 
956
static void
957
thread_db_find_new_threads (void)
958
{
959
  td_err_e err;
960
 
961
  /* Iterate over all user-space threads to discover new threads.  */
962
  err = td_ta_thr_iter_p (thread_agent, find_new_threads_callback, NULL,
963
                          TD_THR_ANY_STATE, TD_THR_LOWEST_PRIORITY,
964
                          TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS);
965
  if (err != TD_OK)
966
    error ("Cannot find new threads: %s", thread_db_err_str (err));
967
}
968
 
969
static char *
970
thread_db_pid_to_str (ptid_t ptid)
971
{
972
  if (is_thread (ptid))
973
    {
974
      static char buf[64];
975
      td_thrhandle_t th;
976
      td_thrinfo_t ti;
977
      td_err_e err;
978
 
979
      err = td_ta_map_id2thr_p (thread_agent, GET_THREAD (ptid), &th);
980
      if (err != TD_OK)
981
        error ("Cannot find thread %ld: %s",
982
               (long) GET_THREAD (ptid), thread_db_err_str (err));
983
 
984
      err = td_thr_get_info_p (&th, &ti);
985
      if (err != TD_OK)
986
        error ("Cannot get thread info for thread %ld: %s",
987
               (long) GET_THREAD (ptid), thread_db_err_str (err));
988
 
989
      if (ti.ti_state == TD_THR_ACTIVE && ti.ti_lid != 0)
990
        {
991
          snprintf (buf, sizeof (buf), "Thread %ld (LWP %d)",
992
                    (long) ti.ti_tid, ti.ti_lid);
993
        }
994
      else
995
        {
996
          snprintf (buf, sizeof (buf), "Thread %ld (%s)",
997
                    (long) ti.ti_tid, thread_db_state_str (ti.ti_state));
998
        }
999
 
1000
      return buf;
1001
    }
1002
 
1003
  if (target_beneath->to_pid_to_str (ptid))
1004
    return target_beneath->to_pid_to_str (ptid);
1005
 
1006
  return normal_pid_to_str (ptid);
1007
}
1008
 
1009
static void
1010
init_thread_db_ops (void)
1011
{
1012
  thread_db_ops.to_shortname = "multi-thread";
1013
  thread_db_ops.to_longname = "multi-threaded child process.";
1014
  thread_db_ops.to_doc = "Threads and pthreads support.";
1015
  thread_db_ops.to_attach = thread_db_attach;
1016
  thread_db_ops.to_detach = thread_db_detach;
1017
  thread_db_ops.to_resume = thread_db_resume;
1018
  thread_db_ops.to_wait = thread_db_wait;
1019
  thread_db_ops.to_fetch_registers = thread_db_fetch_registers;
1020
  thread_db_ops.to_store_registers = thread_db_store_registers;
1021
  thread_db_ops.to_xfer_memory = thread_db_xfer_memory;
1022
  thread_db_ops.to_kill = thread_db_kill;
1023
  thread_db_ops.to_create_inferior = thread_db_create_inferior;
1024
  thread_db_ops.to_post_startup_inferior = thread_db_post_startup_inferior;
1025
  thread_db_ops.to_mourn_inferior = thread_db_mourn_inferior;
1026
  thread_db_ops.to_thread_alive = thread_db_thread_alive;
1027
  thread_db_ops.to_find_new_threads = thread_db_find_new_threads;
1028
  thread_db_ops.to_pid_to_str = thread_db_pid_to_str;
1029
  thread_db_ops.to_stratum = thread_stratum;
1030
  thread_db_ops.to_has_thread_control = tc_schedlock;
1031
  thread_db_ops.to_magic = OPS_MAGIC;
1032
}
1033
 
1034
void
1035
_initialize_thread_db (void)
1036
{
1037
  /* Only initialize the module if we can load libthread_db.  */
1038
  if (thread_db_load ())
1039
    {
1040
      init_thread_db_ops ();
1041
      add_target (&thread_db_ops);
1042
 
1043
      /* Add ourselves to objfile event chain.  */
1044
      target_new_objfile_chain = target_new_objfile_hook;
1045
      target_new_objfile_hook = thread_db_new_objfile;
1046
    }
1047
}

powered by: WebSVN 2.1.0

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