1 /* Low-level child interface to ttrace.
3 Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009
4 Free Software Foundation, Inc.
6 This file is part of GDB.
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>. */
23 /* The ttrace(2) system call didn't exist before HP-UX 10.30. Don't
24 try to compile this code unless we have it. */
29 #include "gdbthread.h"
33 #include "gdb_assert.h"
34 #include "gdb_string.h"
36 #include <sys/ttrace.h>
39 #include "inf-child.h"
40 #include "inf-ttrace.h"
42 /* HACK: Save the ttrace ops returned by inf_ttrace_target. */
43 static struct target_ops
*ttrace_ops_hack
;
46 /* HP-UX uses a threading model where each user-space thread
47 corresponds to a kernel thread. These kernel threads are called
48 lwps. The ttrace(2) interface gives us almost full control over
49 the threads, which makes it very easy to support them in GDB. We
50 identify the threads by process ID and lwp ID. The ttrace(2) also
51 provides us with a thread's user ID (in the `tts_user_tid' member
52 of `ttstate_t') but we don't use that (yet) as it isn't necessary
53 to uniquely label the thread. */
55 /* Number of active lwps. */
56 static int inf_ttrace_num_lwps
;
59 /* On HP-UX versions that have the ttrace(2) system call, we can
60 implement "hardware" watchpoints by fiddling with the protection of
61 pages in the address space that contain the variable being watched.
62 In order to implement this, we keep a dictionary of pages for which
63 we have changed the protection. */
65 struct inf_ttrace_page
67 CORE_ADDR addr
; /* Page address. */
68 int prot
; /* Protection. */
69 int refcount
; /* Reference count. */
70 struct inf_ttrace_page
*next
;
71 struct inf_ttrace_page
*prev
;
74 struct inf_ttrace_page_dict
76 struct inf_ttrace_page buckets
[128];
77 int pagesize
; /* Page size. */
78 int count
; /* Number of pages in this dictionary. */
79 } inf_ttrace_page_dict
;
81 struct inf_ttrace_private_thread_info
86 /* Number of lwps that are currently in a system call. */
87 static int inf_ttrace_num_lwps_in_syscall
;
89 /* Flag to indicate whether we should re-enable page protections after
91 static int inf_ttrace_reenable_page_protections
;
93 /* Enable system call events for process PID. */
96 inf_ttrace_enable_syscall_events (pid_t pid
)
101 gdb_assert (inf_ttrace_num_lwps_in_syscall
== 0);
103 if (ttrace (TT_PROC_GET_EVENT_MASK
, pid
, 0,
104 (uintptr_t)&tte
, sizeof tte
, 0) == -1)
105 perror_with_name (("ttrace"));
107 tte
.tte_events
|= (TTEVT_SYSCALL_ENTRY
| TTEVT_SYSCALL_RETURN
);
109 if (ttrace (TT_PROC_SET_EVENT_MASK
, pid
, 0,
110 (uintptr_t)&tte
, sizeof tte
, 0) == -1)
111 perror_with_name (("ttrace"));
113 if (ttrace (TT_PROC_GET_FIRST_LWP_STATE
, pid
, 0,
114 (uintptr_t)&tts
, sizeof tts
, 0) == -1)
115 perror_with_name (("ttrace"));
117 if (tts
.tts_flags
& TTS_INSYSCALL
)
118 inf_ttrace_num_lwps_in_syscall
++;
120 /* FIXME: Handle multiple threads. */
123 /* Disable system call events for process PID. */
126 inf_ttrace_disable_syscall_events (pid_t pid
)
130 gdb_assert (inf_ttrace_page_dict
.count
== 0);
132 if (ttrace (TT_PROC_GET_EVENT_MASK
, pid
, 0,
133 (uintptr_t)&tte
, sizeof tte
, 0) == -1)
134 perror_with_name (("ttrace"));
136 tte
.tte_events
&= ~(TTEVT_SYSCALL_ENTRY
| TTEVT_SYSCALL_RETURN
);
138 if (ttrace (TT_PROC_SET_EVENT_MASK
, pid
, 0,
139 (uintptr_t)&tte
, sizeof tte
, 0) == -1)
140 perror_with_name (("ttrace"));
142 inf_ttrace_num_lwps_in_syscall
= 0;
145 /* Get information about the page at address ADDR for process PID from
148 static struct inf_ttrace_page
*
149 inf_ttrace_get_page (pid_t pid
, CORE_ADDR addr
)
151 const int num_buckets
= ARRAY_SIZE (inf_ttrace_page_dict
.buckets
);
152 const int pagesize
= inf_ttrace_page_dict
.pagesize
;
154 struct inf_ttrace_page
*page
;
156 bucket
= (addr
/ pagesize
) % num_buckets
;
157 page
= &inf_ttrace_page_dict
.buckets
[bucket
];
160 if (page
->addr
== addr
)
169 /* Add the page at address ADDR for process PID to the dictionary. */
171 static struct inf_ttrace_page
*
172 inf_ttrace_add_page (pid_t pid
, CORE_ADDR addr
)
174 const int num_buckets
= ARRAY_SIZE (inf_ttrace_page_dict
.buckets
);
175 const int pagesize
= inf_ttrace_page_dict
.pagesize
;
177 struct inf_ttrace_page
*page
;
178 struct inf_ttrace_page
*prev
= NULL
;
180 bucket
= (addr
/ pagesize
) % num_buckets
;
181 page
= &inf_ttrace_page_dict
.buckets
[bucket
];
184 if (page
->addr
== addr
)
195 if (ttrace (TT_PROC_GET_MPROTECT
, pid
, 0,
196 addr
, 0, (uintptr_t)&prot
) == -1)
197 perror_with_name (("ttrace"));
199 page
= XMALLOC (struct inf_ttrace_page
);
208 inf_ttrace_page_dict
.count
++;
209 if (inf_ttrace_page_dict
.count
== 1)
210 inf_ttrace_enable_syscall_events (pid
);
212 if (inf_ttrace_num_lwps_in_syscall
== 0)
214 if (ttrace (TT_PROC_SET_MPROTECT
, pid
, 0,
215 addr
, pagesize
, prot
& ~PROT_WRITE
) == -1)
216 perror_with_name (("ttrace"));
223 /* Insert the page at address ADDR of process PID to the dictionary. */
226 inf_ttrace_insert_page (pid_t pid
, CORE_ADDR addr
)
228 struct inf_ttrace_page
*page
;
230 page
= inf_ttrace_get_page (pid
, addr
);
232 page
= inf_ttrace_add_page (pid
, addr
);
237 /* Remove the page at address ADDR of process PID from the dictionary. */
240 inf_ttrace_remove_page (pid_t pid
, CORE_ADDR addr
)
242 const int pagesize
= inf_ttrace_page_dict
.pagesize
;
243 struct inf_ttrace_page
*page
;
245 page
= inf_ttrace_get_page (pid
, addr
);
248 gdb_assert (page
->refcount
>= 0);
250 if (page
->refcount
== 0)
252 if (inf_ttrace_num_lwps_in_syscall
== 0)
254 if (ttrace (TT_PROC_SET_MPROTECT
, pid
, 0,
255 addr
, pagesize
, page
->prot
) == -1)
256 perror_with_name (("ttrace"));
259 inf_ttrace_page_dict
.count
--;
260 if (inf_ttrace_page_dict
.count
== 0)
261 inf_ttrace_disable_syscall_events (pid
);
263 page
->prev
->next
= page
->next
;
265 page
->next
->prev
= page
->prev
;
271 /* Mask the bits in PROT from the page protections that are currently
272 in the dictionary for process PID. */
275 inf_ttrace_mask_page_protections (pid_t pid
, int prot
)
277 const int num_buckets
= ARRAY_SIZE (inf_ttrace_page_dict
.buckets
);
278 const int pagesize
= inf_ttrace_page_dict
.pagesize
;
281 for (bucket
= 0; bucket
< num_buckets
; bucket
++)
283 struct inf_ttrace_page
*page
;
285 page
= inf_ttrace_page_dict
.buckets
[bucket
].next
;
288 if (ttrace (TT_PROC_SET_MPROTECT
, pid
, 0,
289 page
->addr
, pagesize
, page
->prot
& ~prot
) == -1)
290 perror_with_name (("ttrace"));
297 /* Write-protect the pages in the dictionary for process PID. */
300 inf_ttrace_enable_page_protections (pid_t pid
)
302 inf_ttrace_mask_page_protections (pid
, PROT_WRITE
);
305 /* Restore the protection of the pages in the dictionary for process
309 inf_ttrace_disable_page_protections (pid_t pid
)
311 inf_ttrace_mask_page_protections (pid
, 0);
314 /* Insert a "hardware" watchpoint for LEN bytes at address ADDR of
318 inf_ttrace_insert_watchpoint (CORE_ADDR addr
, int len
, int type
)
320 const int pagesize
= inf_ttrace_page_dict
.pagesize
;
321 pid_t pid
= ptid_get_pid (inferior_ptid
);
326 gdb_assert (type
== hw_write
);
328 page_addr
= (addr
/ pagesize
) * pagesize
;
329 num_pages
= (len
+ pagesize
- 1) / pagesize
;
331 for (page
= 0; page
< num_pages
; page
++, page_addr
+= pagesize
)
332 inf_ttrace_insert_page (pid
, page_addr
);
337 /* Remove a "hardware" watchpoint for LEN bytes at address ADDR of
341 inf_ttrace_remove_watchpoint (CORE_ADDR addr
, int len
, int type
)
343 const int pagesize
= inf_ttrace_page_dict
.pagesize
;
344 pid_t pid
= ptid_get_pid (inferior_ptid
);
349 gdb_assert (type
== hw_write
);
351 page_addr
= (addr
/ pagesize
) * pagesize
;
352 num_pages
= (len
+ pagesize
- 1) / pagesize
;
354 for (page
= 0; page
< num_pages
; page
++, page_addr
+= pagesize
)
355 inf_ttrace_remove_page (pid
, page_addr
);
361 inf_ttrace_can_use_hw_breakpoint (int type
, int len
, int ot
)
363 return (type
== bp_hardware_watchpoint
);
367 inf_ttrace_region_ok_for_hw_watchpoint (CORE_ADDR addr
, int len
)
372 /* Return non-zero if the current inferior was (potentially) stopped
373 by hitting a "hardware" watchpoint. */
376 inf_ttrace_stopped_by_watchpoint (void)
378 pid_t pid
= ptid_get_pid (inferior_ptid
);
379 lwpid_t lwpid
= ptid_get_lwp (inferior_ptid
);
382 if (inf_ttrace_page_dict
.count
> 0)
384 if (ttrace (TT_LWP_GET_STATE
, pid
, lwpid
,
385 (uintptr_t)&tts
, sizeof tts
, 0) == -1)
386 perror_with_name (("ttrace"));
388 if (tts
.tts_event
== TTEVT_SIGNAL
389 && tts
.tts_u
.tts_signal
.tts_signo
== SIGBUS
)
391 const int pagesize
= inf_ttrace_page_dict
.pagesize
;
392 void *addr
= tts
.tts_u
.tts_signal
.tts_siginfo
.si_addr
;
393 CORE_ADDR page_addr
= ((uintptr_t)addr
/ pagesize
) * pagesize
;
395 if (inf_ttrace_get_page (pid
, page_addr
))
404 /* When tracking a vfork(2), we cannot detach from the parent until
405 after the child has called exec(3) or has exited. If we are still
406 attached to the parent, this variable will be set to the process ID
407 of the parent. Otherwise it will be set to zero. */
408 static pid_t inf_ttrace_vfork_ppid
= -1;
411 inf_ttrace_follow_fork (struct target_ops
*ops
, int follow_child
)
414 lwpid_t lwpid
, flwpid
;
416 struct thread_info
*last_tp
= NULL
;
417 struct breakpoint
*step_resume_breakpoint
= NULL
;
418 CORE_ADDR step_range_start
= 0, step_range_end
= 0;
419 struct frame_id step_frame_id
= null_frame_id
;
421 /* FIXME: kettenis/20050720: This stuff should really be passed as
422 an argument by our caller. */
425 struct target_waitstatus status
;
427 get_last_target_status (&ptid
, &status
);
428 gdb_assert (status
.kind
== TARGET_WAITKIND_FORKED
429 || status
.kind
== TARGET_WAITKIND_VFORKED
);
431 pid
= ptid_get_pid (ptid
);
432 lwpid
= ptid_get_lwp (ptid
);
433 last_tp
= find_thread_pid (ptid
);
436 /* Get all important details that core GDB doesn't (and shouldn't)
438 if (ttrace (TT_LWP_GET_STATE
, pid
, lwpid
,
439 (uintptr_t)&tts
, sizeof tts
, 0) == -1)
440 perror_with_name (("ttrace"));
442 gdb_assert (tts
.tts_event
== TTEVT_FORK
|| tts
.tts_event
== TTEVT_VFORK
);
444 if (tts
.tts_u
.tts_fork
.tts_isparent
)
447 lwpid
= tts
.tts_lwpid
;
448 fpid
= tts
.tts_u
.tts_fork
.tts_fpid
;
449 flwpid
= tts
.tts_u
.tts_fork
.tts_flwpid
;
453 pid
= tts
.tts_u
.tts_fork
.tts_fpid
;
454 lwpid
= tts
.tts_u
.tts_fork
.tts_flwpid
;
456 flwpid
= tts
.tts_lwpid
;
461 struct inferior
*inf
;
463 /* Copy user stepping state to the new inferior thread. */
464 step_resume_breakpoint
= last_tp
->step_resume_breakpoint
;
465 step_range_start
= last_tp
->step_range_start
;
466 step_range_end
= last_tp
->step_range_end
;
467 step_frame_id
= last_tp
->step_frame_id
;
469 /* Otherwise, deleting the parent would get rid of this
471 last_tp
->step_resume_breakpoint
= NULL
;
473 inferior_ptid
= ptid_build (fpid
, flwpid
, 0);
474 inf
= add_inferior (fpid
);
475 inf
->attach_flag
= find_inferior_pid (pid
)->attach_flag
;
476 detach_breakpoints (pid
);
478 target_terminal_ours ();
479 fprintf_unfiltered (gdb_stdlog
, _("\
480 Attaching after fork to child process %ld.\n"), (long)fpid
);
484 inferior_ptid
= ptid_build (pid
, lwpid
, 0);
485 detach_breakpoints (fpid
);
487 target_terminal_ours ();
488 fprintf_unfiltered (gdb_stdlog
, _("\
489 Detaching after fork from child process %ld.\n"), (long)fpid
);
492 if (tts
.tts_event
== TTEVT_VFORK
)
494 gdb_assert (!tts
.tts_u
.tts_fork
.tts_isparent
);
498 /* We can't detach from the parent yet. */
499 inf_ttrace_vfork_ppid
= pid
;
501 reattach_breakpoints (fpid
);
505 if (ttrace (TT_PROC_DETACH
, fpid
, 0, 0, 0, 0) == -1)
506 perror_with_name (("ttrace"));
508 /* Wait till we get the TTEVT_VFORK event in the parent.
509 This indicates that the child has called exec(3) or has
510 exited and that the parent is ready to be traced again. */
511 if (ttrace_wait (pid
, lwpid
, TTRACE_WAITOK
, &tts
, sizeof tts
) == -1)
512 perror_with_name (("ttrace_wait"));
513 gdb_assert (tts
.tts_event
== TTEVT_VFORK
);
514 gdb_assert (tts
.tts_u
.tts_fork
.tts_isparent
);
516 reattach_breakpoints (pid
);
521 gdb_assert (tts
.tts_u
.tts_fork
.tts_isparent
);
525 if (ttrace (TT_PROC_DETACH
, pid
, 0, 0, 0, 0) == -1)
526 perror_with_name (("ttrace"));
530 if (ttrace (TT_PROC_DETACH
, fpid
, 0, 0, 0, 0) == -1)
531 perror_with_name (("ttrace"));
537 struct thread_info
*ti
;
539 /* The child will start out single-threaded. */
540 inf_ttrace_num_lwps
= 1;
541 inf_ttrace_num_lwps_in_syscall
= 0;
544 delete_thread_silent (ptid_build (pid
, lwpid
, 0));
545 detach_inferior (pid
);
547 /* Add child thread. inferior_ptid was already set above. */
548 ti
= add_thread_silent (inferior_ptid
);
550 xmalloc (sizeof (struct inf_ttrace_private_thread_info
));
551 memset (ti
->private, 0,
552 sizeof (struct inf_ttrace_private_thread_info
));
554 ti
->step_resume_breakpoint
= step_resume_breakpoint
;
555 ti
->step_range_start
= step_range_start
;
556 ti
->step_range_end
= step_range_end
;
557 ti
->step_frame_id
= step_frame_id
;
559 /* Reset breakpoints in the child as appropriate. */
560 follow_inferior_reset_breakpoints ();
567 /* File descriptors for pipes used as semaphores during initial
568 startup of an inferior. */
569 static int inf_ttrace_pfd1
[2];
570 static int inf_ttrace_pfd2
[2];
573 do_cleanup_pfds (void *dummy
)
575 close (inf_ttrace_pfd1
[0]);
576 close (inf_ttrace_pfd1
[1]);
577 close (inf_ttrace_pfd2
[0]);
578 close (inf_ttrace_pfd2
[1]);
582 inf_ttrace_prepare (void)
584 if (pipe (inf_ttrace_pfd1
) == -1)
585 perror_with_name (("pipe"));
587 if (pipe (inf_ttrace_pfd2
) == -1)
589 close (inf_ttrace_pfd1
[0]);
590 close (inf_ttrace_pfd2
[0]);
591 perror_with_name (("pipe"));
595 /* Prepare to be traced. */
600 struct cleanup
*old_chain
= make_cleanup (do_cleanup_pfds
, 0);
603 /* "Trace me, Dr. Memory!" */
604 if (ttrace (TT_PROC_SETTRC
, 0, 0, 0, TT_VERSION
, 0) == -1)
605 perror_with_name (("ttrace"));
607 /* Tell our parent that we are ready to be traced. */
608 if (write (inf_ttrace_pfd1
[1], &c
, sizeof c
) != sizeof c
)
609 perror_with_name (("write"));
611 /* Wait until our parent has set the initial event mask. */
612 if (read (inf_ttrace_pfd2
[0], &c
, sizeof c
) != sizeof c
)
613 perror_with_name (("read"));
615 do_cleanups (old_chain
);
618 /* Start tracing PID. */
621 inf_ttrace_him (int pid
)
623 struct cleanup
*old_chain
= make_cleanup (do_cleanup_pfds
, 0);
627 /* Wait until our child is ready to be traced. */
628 if (read (inf_ttrace_pfd1
[0], &c
, sizeof c
) != sizeof c
)
629 perror_with_name (("read"));
631 /* Set the initial event mask. */
632 memset (&tte
, 0, sizeof (tte
));
633 tte
.tte_events
|= TTEVT_EXEC
| TTEVT_EXIT
| TTEVT_FORK
| TTEVT_VFORK
;
634 tte
.tte_events
|= TTEVT_LWP_CREATE
| TTEVT_LWP_EXIT
| TTEVT_LWP_TERMINATE
;
635 #ifdef TTEVT_BPT_SSTEP
636 tte
.tte_events
|= TTEVT_BPT_SSTEP
;
638 tte
.tte_opts
|= TTEO_PROC_INHERIT
;
639 if (ttrace (TT_PROC_SET_EVENT_MASK
, pid
, 0,
640 (uintptr_t)&tte
, sizeof tte
, 0) == -1)
641 perror_with_name (("ttrace"));
643 /* Tell our child that we have set the initial event mask. */
644 if (write (inf_ttrace_pfd2
[1], &c
, sizeof c
) != sizeof c
)
645 perror_with_name (("write"));
647 do_cleanups (old_chain
);
649 push_target (ttrace_ops_hack
);
651 /* On some targets, there must be some explicit synchronization
652 between the parent and child processes after the debugger forks,
653 and before the child execs the debuggee program. This call
654 basically gives permission for the child to exec. */
656 target_acknowledge_created_inferior (pid
);
658 /* START_INFERIOR_TRAPS_EXPECTED is defined in inferior.h, and will
659 be 1 or 2 depending on whether we're starting without or with a
661 startup_inferior (START_INFERIOR_TRAPS_EXPECTED
);
663 /* On some targets, there must be some explicit actions taken after
664 the inferior has been started up. */
665 target_post_startup_inferior (pid_to_ptid (pid
));
669 inf_ttrace_create_inferior (struct target_ops
*ops
, char *exec_file
,
670 char *allargs
, char **env
, int from_tty
)
672 gdb_assert (inf_ttrace_num_lwps
== 0);
673 gdb_assert (inf_ttrace_num_lwps_in_syscall
== 0);
674 gdb_assert (inf_ttrace_page_dict
.count
== 0);
675 gdb_assert (inf_ttrace_reenable_page_protections
== 0);
676 gdb_assert (inf_ttrace_vfork_ppid
== -1);
678 fork_inferior (exec_file
, allargs
, env
, inf_ttrace_me
, inf_ttrace_him
,
679 inf_ttrace_prepare
, NULL
);
683 inf_ttrace_mourn_inferior (struct target_ops
*ops
)
685 const int num_buckets
= ARRAY_SIZE (inf_ttrace_page_dict
.buckets
);
688 inf_ttrace_num_lwps
= 0;
689 inf_ttrace_num_lwps_in_syscall
= 0;
691 for (bucket
= 0; bucket
< num_buckets
; bucket
++)
693 struct inf_ttrace_page
*page
;
694 struct inf_ttrace_page
*next
;
696 page
= inf_ttrace_page_dict
.buckets
[bucket
].next
;
704 inf_ttrace_page_dict
.count
= 0;
706 unpush_target (ttrace_ops_hack
);
707 generic_mourn_inferior ();
711 inf_ttrace_attach (struct target_ops
*ops
, char *args
, int from_tty
)
717 struct inferior
*inf
;
720 error_no_arg (_("process-id to attach"));
723 pid
= strtol (args
, &dummy
, 0);
724 if (pid
== 0 && args
== dummy
)
725 error (_("Illegal process-id: %s."), args
);
727 if (pid
== getpid ()) /* Trying to masturbate? */
728 error (_("I refuse to debug myself!"));
732 exec_file
= get_exec_file (0);
735 printf_unfiltered (_("Attaching to program: %s, %s\n"), exec_file
,
736 target_pid_to_str (pid_to_ptid (pid
)));
738 printf_unfiltered (_("Attaching to %s\n"),
739 target_pid_to_str (pid_to_ptid (pid
)));
741 gdb_flush (gdb_stdout
);
744 gdb_assert (inf_ttrace_num_lwps
== 0);
745 gdb_assert (inf_ttrace_num_lwps_in_syscall
== 0);
746 gdb_assert (inf_ttrace_vfork_ppid
== -1);
748 if (ttrace (TT_PROC_ATTACH
, pid
, 0, TT_KILL_ON_EXIT
, TT_VERSION
, 0) == -1)
749 perror_with_name (("ttrace"));
751 inf
= add_inferior (pid
);
752 inf
->attach_flag
= 1;
754 /* Set the initial event mask. */
755 memset (&tte
, 0, sizeof (tte
));
756 tte
.tte_events
|= TTEVT_EXEC
| TTEVT_EXIT
| TTEVT_FORK
| TTEVT_VFORK
;
757 tte
.tte_events
|= TTEVT_LWP_CREATE
| TTEVT_LWP_EXIT
| TTEVT_LWP_TERMINATE
;
758 #ifdef TTEVT_BPT_SSTEP
759 tte
.tte_events
|= TTEVT_BPT_SSTEP
;
761 tte
.tte_opts
|= TTEO_PROC_INHERIT
;
762 if (ttrace (TT_PROC_SET_EVENT_MASK
, pid
, 0,
763 (uintptr_t)&tte
, sizeof tte
, 0) == -1)
764 perror_with_name (("ttrace"));
766 push_target (ttrace_ops_hack
);
768 /* We'll bump inf_ttrace_num_lwps up and add the private data to the
769 thread as soon as we get to inf_ttrace_wait. At this point, we
770 don't have lwpid info yet. */
771 inferior_ptid
= pid_to_ptid (pid
);
772 add_thread_silent (inferior_ptid
);
776 inf_ttrace_detach (struct target_ops
*ops
, char *args
, int from_tty
)
778 pid_t pid
= ptid_get_pid (inferior_ptid
);
783 char *exec_file
= get_exec_file (0);
786 printf_unfiltered (_("Detaching from program: %s, %s\n"), exec_file
,
787 target_pid_to_str (pid_to_ptid (pid
)));
788 gdb_flush (gdb_stdout
);
793 /* ??? The HP-UX 11.0 ttrace(2) manual page doesn't mention that we
794 can pass a signal number here. Does this really work? */
795 if (ttrace (TT_PROC_DETACH
, pid
, 0, 0, sig
, 0) == -1)
796 perror_with_name (("ttrace"));
798 if (inf_ttrace_vfork_ppid
!= -1)
800 if (ttrace (TT_PROC_DETACH
, inf_ttrace_vfork_ppid
, 0, 0, 0, 0) == -1)
801 perror_with_name (("ttrace"));
802 inf_ttrace_vfork_ppid
= -1;
805 inf_ttrace_num_lwps
= 0;
806 inf_ttrace_num_lwps_in_syscall
= 0;
808 inferior_ptid
= null_ptid
;
809 detach_inferior (pid
);
811 unpush_target (ttrace_ops_hack
);
815 inf_ttrace_kill (void)
817 pid_t pid
= ptid_get_pid (inferior_ptid
);
822 if (ttrace (TT_PROC_EXIT
, pid
, 0, 0, 0, 0) == -1)
823 perror_with_name (("ttrace"));
824 /* ??? Is it necessary to call ttrace_wait() here? */
826 if (inf_ttrace_vfork_ppid
!= -1)
828 if (ttrace (TT_PROC_DETACH
, inf_ttrace_vfork_ppid
, 0, 0, 0, 0) == -1)
829 perror_with_name (("ttrace"));
830 inf_ttrace_vfork_ppid
= -1;
833 target_mourn_inferior ();
836 /* Check is a dying thread is dead by now, and delete it from GDBs
837 thread list if so. */
839 inf_ttrace_delete_dead_threads_callback (struct thread_info
*info
, void *arg
)
842 struct inf_ttrace_private_thread_info
*p
;
844 if (is_exited (info
->ptid
))
847 lwpid
= ptid_get_lwp (info
->ptid
);
848 p
= (struct inf_ttrace_private_thread_info
*) info
->private;
850 /* Check if an lwp that was dying is still there or not. */
851 if (p
->dying
&& (kill (lwpid
, 0) == -1))
853 delete_thread (info
->ptid
);
858 /* Resume the lwp pointed to by INFO, with REQUEST, and pass it signal
862 inf_ttrace_resume_lwp (struct thread_info
*info
, ttreq_t request
, int sig
)
864 pid_t pid
= ptid_get_pid (info
->ptid
);
865 lwpid_t lwpid
= ptid_get_lwp (info
->ptid
);
867 if (ttrace (request
, pid
, lwpid
, TT_NOPC
, sig
, 0) == -1)
869 struct inf_ttrace_private_thread_info
*p
870 = (struct inf_ttrace_private_thread_info
*) info
->private;
871 if (p
->dying
&& errno
== EPROTO
)
872 /* This is expected, it means the dying lwp is really gone
873 by now. If ttrace had an event to inform the debugger
874 the lwp is really gone, this wouldn't be needed. */
875 delete_thread (info
->ptid
);
877 /* This was really unexpected. */
878 perror_with_name (("ttrace"));
882 /* Callback for iterate_over_threads. */
885 inf_ttrace_resume_callback (struct thread_info
*info
, void *arg
)
887 if (!ptid_equal (info
->ptid
, inferior_ptid
) && !is_exited (info
->ptid
))
888 inf_ttrace_resume_lwp (info
, TT_LWP_CONTINUE
, 0);
894 inf_ttrace_resume (ptid_t ptid
, int step
, enum target_signal signal
)
897 ttreq_t request
= step
? TT_LWP_SINGLE
: TT_LWP_CONTINUE
;
898 int sig
= target_signal_to_host (signal
);
899 struct thread_info
*info
;
901 /* A specific PTID means `step only this process id'. */
902 resume_all
= (ptid_equal (ptid
, minus_one_ptid
));
904 /* If resuming all threads, it's the current thread that should be
905 handled specially. */
907 ptid
= inferior_ptid
;
909 info
= find_thread_pid (ptid
);
910 inf_ttrace_resume_lwp (info
, request
, sig
);
913 /* Let all the other threads run too. */
914 iterate_over_threads (inf_ttrace_resume_callback
, NULL
);
918 inf_ttrace_wait (ptid_t ptid
, struct target_waitstatus
*ourstatus
)
920 pid_t pid
= ptid_get_pid (ptid
);
921 lwpid_t lwpid
= ptid_get_lwp (ptid
);
923 struct thread_info
*ti
;
926 /* Until proven otherwise. */
927 ourstatus
->kind
= TARGET_WAITKIND_SPURIOUS
;
932 gdb_assert (pid
!= 0 || lwpid
== 0);
938 if (ttrace_wait (pid
, lwpid
, TTRACE_WAITOK
, &tts
, sizeof tts
) == -1)
939 perror_with_name (("ttrace_wait"));
941 if (tts
.tts_event
== TTEVT_VFORK
&& tts
.tts_u
.tts_fork
.tts_isparent
)
943 if (inf_ttrace_vfork_ppid
!= -1)
945 gdb_assert (inf_ttrace_vfork_ppid
== tts
.tts_pid
);
947 if (ttrace (TT_PROC_DETACH
, tts
.tts_pid
, 0, 0, 0, 0) == -1)
948 perror_with_name (("ttrace"));
949 inf_ttrace_vfork_ppid
= -1;
952 tts
.tts_event
= TTEVT_NONE
;
955 clear_sigint_trap ();
957 while (tts
.tts_event
== TTEVT_NONE
);
959 /* Now that we've waited, we can re-enable the page protections. */
960 if (inf_ttrace_reenable_page_protections
)
962 gdb_assert (inf_ttrace_num_lwps_in_syscall
== 0);
963 inf_ttrace_enable_page_protections (tts
.tts_pid
);
964 inf_ttrace_reenable_page_protections
= 0;
967 ptid
= ptid_build (tts
.tts_pid
, tts
.tts_lwpid
, 0);
969 if (inf_ttrace_num_lwps
== 0)
971 struct thread_info
*ti
;
973 inf_ttrace_num_lwps
= 1;
975 /* This is the earliest we hear about the lwp member of
976 INFERIOR_PTID, after an attach or fork_inferior. */
977 gdb_assert (ptid_get_lwp (inferior_ptid
) == 0);
979 /* We haven't set the private member on the main thread yet. Do
981 ti
= find_thread_pid (inferior_ptid
);
982 gdb_assert (ti
!= NULL
&& ti
->private == NULL
);
984 xmalloc (sizeof (struct inf_ttrace_private_thread_info
));
985 memset (ti
->private, 0,
986 sizeof (struct inf_ttrace_private_thread_info
));
988 /* Notify the core that this ptid changed. This changes
989 inferior_ptid as well. */
990 thread_change_ptid (inferior_ptid
, ptid
);
993 switch (tts
.tts_event
)
995 #ifdef TTEVT_BPT_SSTEP
996 case TTEVT_BPT_SSTEP
:
997 /* Make it look like a breakpoint. */
998 ourstatus
->kind
= TARGET_WAITKIND_STOPPED
;
999 ourstatus
->value
.sig
= TARGET_SIGNAL_TRAP
;
1004 ourstatus
->kind
= TARGET_WAITKIND_EXECD
;
1005 ourstatus
->value
.execd_pathname
=
1006 xmalloc (tts
.tts_u
.tts_exec
.tts_pathlen
+ 1);
1007 if (ttrace (TT_PROC_GET_PATHNAME
, tts
.tts_pid
, 0,
1008 (uintptr_t)ourstatus
->value
.execd_pathname
,
1009 tts
.tts_u
.tts_exec
.tts_pathlen
, 0) == -1)
1010 perror_with_name (("ttrace"));
1011 ourstatus
->value
.execd_pathname
[tts
.tts_u
.tts_exec
.tts_pathlen
] = 0;
1013 /* At this point, all inserted breakpoints are gone. Doing this
1014 as soon as we detect an exec prevents the badness of deleting
1015 a breakpoint writing the current "shadow contents" to lift
1016 the bp. That shadow is NOT valid after an exec. */
1017 mark_breakpoints_out ();
1021 store_waitstatus (ourstatus
, tts
.tts_u
.tts_exit
.tts_exitcode
);
1022 inf_ttrace_num_lwps
= 0;
1026 related_ptid
= ptid_build (tts
.tts_u
.tts_fork
.tts_fpid
,
1027 tts
.tts_u
.tts_fork
.tts_flwpid
, 0);
1029 ourstatus
->kind
= TARGET_WAITKIND_FORKED
;
1030 ourstatus
->value
.related_pid
= related_ptid
;
1032 /* Make sure the other end of the fork is stopped too. */
1033 if (ttrace_wait (tts
.tts_u
.tts_fork
.tts_fpid
,
1034 tts
.tts_u
.tts_fork
.tts_flwpid
,
1035 TTRACE_WAITOK
, &tts
, sizeof tts
) == -1)
1036 perror_with_name (("ttrace_wait"));
1038 gdb_assert (tts
.tts_event
== TTEVT_FORK
);
1039 if (tts
.tts_u
.tts_fork
.tts_isparent
)
1041 related_ptid
= ptid_build (tts
.tts_u
.tts_fork
.tts_fpid
,
1042 tts
.tts_u
.tts_fork
.tts_flwpid
, 0);
1043 ptid
= ptid_build (tts
.tts_pid
, tts
.tts_lwpid
, 0);
1044 ourstatus
->value
.related_pid
= related_ptid
;
1049 gdb_assert (!tts
.tts_u
.tts_fork
.tts_isparent
);
1051 related_ptid
= ptid_build (tts
.tts_u
.tts_fork
.tts_fpid
,
1052 tts
.tts_u
.tts_fork
.tts_flwpid
, 0);
1054 ourstatus
->kind
= TARGET_WAITKIND_VFORKED
;
1055 ourstatus
->value
.related_pid
= related_ptid
;
1057 /* HACK: To avoid touching the parent during the vfork, switch
1059 inferior_ptid
= ptid
;
1062 case TTEVT_LWP_CREATE
:
1063 lwpid
= tts
.tts_u
.tts_thread
.tts_target_lwpid
;
1064 ptid
= ptid_build (tts
.tts_pid
, lwpid
, 0);
1065 ti
= add_thread (ptid
);
1067 xmalloc (sizeof (struct inf_ttrace_private_thread_info
));
1068 memset (ti
->private, 0,
1069 sizeof (struct inf_ttrace_private_thread_info
));
1070 inf_ttrace_num_lwps
++;
1071 ptid
= ptid_build (tts
.tts_pid
, tts
.tts_lwpid
, 0);
1072 /* Let the lwp_create-caller thread continue. */
1073 ttrace (TT_LWP_CONTINUE
, ptid_get_pid (ptid
),
1074 ptid_get_lwp (ptid
), TT_NOPC
, 0, 0);
1075 /* Return without stopping the whole process. */
1076 ourstatus
->kind
= TARGET_WAITKIND_IGNORE
;
1079 case TTEVT_LWP_EXIT
:
1080 if (print_thread_events
)
1081 printf_unfiltered (_("[%s exited]\n"), target_pid_to_str (ptid
));
1082 ti
= find_thread_pid (ptid
);
1083 gdb_assert (ti
!= NULL
);
1084 ((struct inf_ttrace_private_thread_info
*)ti
->private)->dying
= 1;
1085 inf_ttrace_num_lwps
--;
1086 /* Let the thread really exit. */
1087 ttrace (TT_LWP_CONTINUE
, ptid_get_pid (ptid
),
1088 ptid_get_lwp (ptid
), TT_NOPC
, 0, 0);
1089 /* Return without stopping the whole process. */
1090 ourstatus
->kind
= TARGET_WAITKIND_IGNORE
;
1093 case TTEVT_LWP_TERMINATE
:
1094 lwpid
= tts
.tts_u
.tts_thread
.tts_target_lwpid
;
1095 ptid
= ptid_build (tts
.tts_pid
, lwpid
, 0);
1096 if (print_thread_events
)
1097 printf_unfiltered(_("[%s has been terminated]\n"),
1098 target_pid_to_str (ptid
));
1099 ti
= find_thread_pid (ptid
);
1100 gdb_assert (ti
!= NULL
);
1101 ((struct inf_ttrace_private_thread_info
*)ti
->private)->dying
= 1;
1102 inf_ttrace_num_lwps
--;
1104 /* Resume the lwp_terminate-caller thread. */
1105 ptid
= ptid_build (tts
.tts_pid
, tts
.tts_lwpid
, 0);
1106 ttrace (TT_LWP_CONTINUE
, ptid_get_pid (ptid
),
1107 ptid_get_lwp (ptid
), TT_NOPC
, 0, 0);
1108 /* Return without stopping the whole process. */
1109 ourstatus
->kind
= TARGET_WAITKIND_IGNORE
;
1113 ourstatus
->kind
= TARGET_WAITKIND_STOPPED
;
1114 ourstatus
->value
.sig
=
1115 target_signal_from_host (tts
.tts_u
.tts_signal
.tts_signo
);
1118 case TTEVT_SYSCALL_ENTRY
:
1119 gdb_assert (inf_ttrace_reenable_page_protections
== 0);
1120 inf_ttrace_num_lwps_in_syscall
++;
1121 if (inf_ttrace_num_lwps_in_syscall
== 1)
1123 /* A thread has just entered a system call. Disable any
1124 page protections as the kernel can't deal with them. */
1125 inf_ttrace_disable_page_protections (tts
.tts_pid
);
1127 ourstatus
->kind
= TARGET_WAITKIND_SYSCALL_ENTRY
;
1128 ourstatus
->value
.syscall_id
= tts
.tts_scno
;
1131 case TTEVT_SYSCALL_RETURN
:
1132 if (inf_ttrace_num_lwps_in_syscall
> 0)
1134 /* If the last thread has just left the system call, this
1135 would be a logical place to re-enable the page
1136 protections, but that doesn't work. We can't re-enable
1137 them until we've done another wait. */
1138 inf_ttrace_reenable_page_protections
=
1139 (inf_ttrace_num_lwps_in_syscall
== 1);
1140 inf_ttrace_num_lwps_in_syscall
--;
1142 ourstatus
->kind
= TARGET_WAITKIND_SYSCALL_RETURN
;
1143 ourstatus
->value
.syscall_id
= tts
.tts_scno
;
1147 gdb_assert (!"Unexpected ttrace event");
1151 /* Make sure all threads within the process are stopped. */
1152 if (ttrace (TT_PROC_STOP
, tts
.tts_pid
, 0, 0, 0, 0) == -1)
1153 perror_with_name (("ttrace"));
1155 /* Now that the whole process is stopped, check if any dying thread
1156 is really dead by now. If a dying thread is still alive, it will
1157 be stopped too, and will still show up in `info threads', tagged
1158 with "(Exiting)". We could make `info threads' prune dead
1159 threads instead via inf_ttrace_thread_alive, but doing this here
1160 has the advantage that a frontend is notificed sooner of thread
1161 exits. Note that a dying lwp is still alive, it still has to be
1162 resumed, like any other lwp. */
1163 iterate_over_threads (inf_ttrace_delete_dead_threads_callback
, NULL
);
1168 /* Transfer LEN bytes from ADDR in the inferior's memory into READBUF,
1169 and transfer LEN bytes from WRITEBUF into the inferior's memory at
1170 ADDR. Either READBUF or WRITEBUF may be null, in which case the
1171 corresponding transfer doesn't happen. Return the number of bytes
1172 actually transferred (which may be zero if an error occurs). */
1175 inf_ttrace_xfer_memory (CORE_ADDR addr
, ULONGEST len
,
1176 void *readbuf
, const void *writebuf
)
1178 pid_t pid
= ptid_get_pid (inferior_ptid
);
1180 /* HP-UX treats text space and data space differently. GDB however,
1181 doesn't really know the difference. Therefore we try both. Try
1182 text space before data space though because when we're writing
1183 into text space the instruction cache might need to be flushed. */
1186 && ttrace (TT_PROC_RDTEXT
, pid
, 0, addr
, len
, (uintptr_t)readbuf
) == -1
1187 && ttrace (TT_PROC_RDDATA
, pid
, 0, addr
, len
, (uintptr_t)readbuf
) == -1)
1191 && ttrace (TT_PROC_WRTEXT
, pid
, 0, addr
, len
, (uintptr_t)writebuf
) == -1
1192 && ttrace (TT_PROC_WRDATA
, pid
, 0, addr
, len
, (uintptr_t)writebuf
) == -1)
1199 inf_ttrace_xfer_partial (struct target_ops
*ops
, enum target_object object
,
1200 const char *annex
, gdb_byte
*readbuf
,
1201 const gdb_byte
*writebuf
, ULONGEST offset
, LONGEST len
)
1205 case TARGET_OBJECT_MEMORY
:
1206 return inf_ttrace_xfer_memory (offset
, len
, readbuf
, writebuf
);
1208 case TARGET_OBJECT_UNWIND_TABLE
:
1211 case TARGET_OBJECT_AUXV
:
1214 case TARGET_OBJECT_WCOOKIE
:
1222 /* Print status information about what we're accessing. */
1225 inf_ttrace_files_info (struct target_ops
*ignore
)
1227 struct inferior
*inf
= current_inferior ();
1228 printf_filtered (_("\tUsing the running image of %s %s.\n"),
1229 inf
->attach_flag
? "attached" : "child",
1230 target_pid_to_str (inferior_ptid
));
1234 inf_ttrace_thread_alive (ptid_t ptid
)
1239 /* Return a string describing the state of the thread specified by
1243 inf_ttrace_extra_thread_info (struct thread_info
*info
)
1245 struct inf_ttrace_private_thread_info
* private =
1246 (struct inf_ttrace_private_thread_info
*) info
->private;
1248 if (private != NULL
&& private->dying
)
1255 inf_ttrace_pid_to_str (ptid_t ptid
)
1257 pid_t pid
= ptid_get_pid (ptid
);
1258 lwpid_t lwpid
= ptid_get_lwp (ptid
);
1259 static char buf
[128];
1262 xsnprintf (buf
, sizeof buf
, "process %ld",
1265 xsnprintf (buf
, sizeof buf
, "process %ld, lwp %ld",
1266 (long) pid
, (long) lwpid
);
1272 inf_ttrace_target (void)
1274 struct target_ops
*t
= inf_child_target ();
1276 t
->to_attach
= inf_ttrace_attach
;
1277 t
->to_detach
= inf_ttrace_detach
;
1278 t
->to_resume
= inf_ttrace_resume
;
1279 t
->to_wait
= inf_ttrace_wait
;
1280 t
->to_files_info
= inf_ttrace_files_info
;
1281 t
->to_can_use_hw_breakpoint
= inf_ttrace_can_use_hw_breakpoint
;
1282 t
->to_insert_watchpoint
= inf_ttrace_insert_watchpoint
;
1283 t
->to_remove_watchpoint
= inf_ttrace_remove_watchpoint
;
1284 t
->to_stopped_by_watchpoint
= inf_ttrace_stopped_by_watchpoint
;
1285 t
->to_region_ok_for_hw_watchpoint
=
1286 inf_ttrace_region_ok_for_hw_watchpoint
;
1287 t
->to_kill
= inf_ttrace_kill
;
1288 t
->to_create_inferior
= inf_ttrace_create_inferior
;
1289 t
->to_follow_fork
= inf_ttrace_follow_fork
;
1290 t
->to_mourn_inferior
= inf_ttrace_mourn_inferior
;
1291 t
->to_thread_alive
= inf_ttrace_thread_alive
;
1292 t
->to_extra_thread_info
= inf_ttrace_extra_thread_info
;
1293 t
->to_pid_to_str
= inf_ttrace_pid_to_str
;
1294 t
->to_xfer_partial
= inf_ttrace_xfer_partial
;
1296 ttrace_ops_hack
= t
;
1302 /* Prevent warning from -Wmissing-prototypes. */
1303 void _initialize_hppa_hpux_nat (void);
1306 _initialize_inf_ttrace (void)
1309 inf_ttrace_page_dict
.pagesize
= getpagesize();