X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Finf-ttrace.c;h=f3f9bbdd679870dd557e829b9fc74a6af621a568;hb=a493e3e2e429e4832b8620bd920ad07d0c2892d7;hp=0ad915761ab1779316b609374810aa5178244c71;hpb=62a93fa9cbc7a5db0db8919f1a0b76ff401f7af5;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/inf-ttrace.c b/gdb/inf-ttrace.c index 0ad915761a..f3f9bbdd67 100644 --- a/gdb/inf-ttrace.c +++ b/gdb/inf-ttrace.c @@ -1,6 +1,6 @@ /* Low-level child interface to ttrace. - Copyright (C) 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. + Copyright (C) 2004-2012 Free Software Foundation, Inc. This file is part of GDB. @@ -27,6 +27,7 @@ #include "gdbcore.h" #include "gdbthread.h" #include "inferior.h" +#include "terminal.h" #include "target.h" #include "gdb_assert.h" @@ -38,8 +39,6 @@ #include "inf-child.h" #include "inf-ttrace.h" -/* HACK: Save the ttrace ops returned by inf_ttrace_target. */ -static struct target_ops *ttrace_ops_hack; /* HP-UX uses a threading model where each user-space thread @@ -314,7 +313,8 @@ inf_ttrace_disable_page_protections (pid_t pid) type TYPE. */ static int -inf_ttrace_insert_watchpoint (CORE_ADDR addr, int len, int type) +inf_ttrace_insert_watchpoint (CORE_ADDR addr, int len, int type, + struct expression *cond) { const int pagesize = inf_ttrace_page_dict.pagesize; pid_t pid = ptid_get_pid (inferior_ptid); @@ -337,7 +337,8 @@ inf_ttrace_insert_watchpoint (CORE_ADDR addr, int len, int type) type TYPE. */ static int -inf_ttrace_remove_watchpoint (CORE_ADDR addr, int len, int type) +inf_ttrace_remove_watchpoint (CORE_ADDR addr, int len, int type, + struct expression *cond) { const int pagesize = inf_ttrace_page_dict.pagesize; pid_t pid = ptid_get_pid (inferior_ptid); @@ -412,20 +413,13 @@ inf_ttrace_follow_fork (struct target_ops *ops, int follow_child) pid_t pid, fpid; lwpid_t lwpid, flwpid; ttstate_t tts; + struct thread_info *tp = inferior_thread (); - /* FIXME: kettenis/20050720: This stuff should really be passed as - an argument by our caller. */ - { - ptid_t ptid; - struct target_waitstatus status; + gdb_assert (tp->pending_follow.kind == TARGET_WAITKIND_FORKED + || tp->pending_follow.kind == TARGET_WAITKIND_VFORKED); - get_last_target_status (&ptid, &status); - gdb_assert (status.kind == TARGET_WAITKIND_FORKED - || status.kind == TARGET_WAITKIND_VFORKED); - - pid = ptid_get_pid (ptid); - lwpid = ptid_get_lwp (ptid); - } + pid = ptid_get_pid (inferior_ptid); + lwpid = ptid_get_lwp (inferior_ptid); /* Get all important details that core GDB doesn't (and shouldn't) know about. */ @@ -452,12 +446,23 @@ inf_ttrace_follow_fork (struct target_ops *ops, int follow_child) if (follow_child) { + struct inferior *inf; + struct inferior *parent_inf; + + parent_inf = find_inferior_pid (pid); + inferior_ptid = ptid_build (fpid, flwpid, 0); + inf = add_inferior (fpid); + inf->attach_flag = parent_inf->attach_flag; + inf->pspace = parent_inf->pspace; + inf->aspace = parent_inf->aspace; + copy_terminal_info (inf, parent_inf); detach_breakpoints (pid); target_terminal_ours (); - fprintf_unfiltered (gdb_stdlog, _("\ -Attaching after fork to child process %ld.\n"), (long)fpid); + fprintf_unfiltered (gdb_stdlog, + _("Attaching after fork to child process %ld.\n"), + (long)fpid); } else { @@ -465,8 +470,9 @@ Attaching after fork to child process %ld.\n"), (long)fpid); detach_breakpoints (fpid); target_terminal_ours (); - fprintf_unfiltered (gdb_stdlog, _("\ -Detaching after fork from child process %ld.\n"), (long)fpid); + fprintf_unfiltered (gdb_stdlog, + _("Detaching after fork from child process %ld.\n"), + (long)fpid); } if (tts.tts_event == TTEVT_VFORK) @@ -522,16 +528,14 @@ Detaching after fork from child process %ld.\n"), (long)fpid); /* Delete parent. */ delete_thread_silent (ptid_build (pid, lwpid, 0)); + detach_inferior (pid); - /* Add child. inferior_ptid was already set above. */ + /* Add child thread. inferior_ptid was already set above. */ ti = add_thread_silent (inferior_ptid); ti->private = xmalloc (sizeof (struct inf_ttrace_private_thread_info)); memset (ti->private, 0, sizeof (struct inf_ttrace_private_thread_info)); - - /* Reset breakpoints in the child as appropriate. */ - follow_inferior_reset_breakpoints (); } return 0; @@ -592,7 +596,7 @@ inf_ttrace_me (void) /* Start tracing PID. */ static void -inf_ttrace_him (int pid) +inf_ttrace_him (struct target_ops *ops, int pid) { struct cleanup *old_chain = make_cleanup (do_cleanup_pfds, 0); ttevent_t tte; @@ -620,14 +624,7 @@ inf_ttrace_him (int pid) do_cleanups (old_chain); - push_target (ttrace_ops_hack); - - /* On some targets, there must be some explicit synchronization - between the parent and child processes after the debugger forks, - and before the child execs the debuggee program. This call - basically gives permission for the child to exec. */ - - target_acknowledge_created_inferior (pid); + push_target (ops); /* START_INFERIOR_TRAPS_EXPECTED is defined in inferior.h, and will be 1 or 2 depending on whether we're starting without or with a @@ -640,21 +637,25 @@ inf_ttrace_him (int pid) } static void -inf_ttrace_create_inferior (char *exec_file, char *allargs, char **env, - int from_tty) +inf_ttrace_create_inferior (struct target_ops *ops, char *exec_file, + char *allargs, char **env, int from_tty) { + int pid; + gdb_assert (inf_ttrace_num_lwps == 0); gdb_assert (inf_ttrace_num_lwps_in_syscall == 0); gdb_assert (inf_ttrace_page_dict.count == 0); gdb_assert (inf_ttrace_reenable_page_protections == 0); gdb_assert (inf_ttrace_vfork_ppid == -1); - fork_inferior (exec_file, allargs, env, inf_ttrace_me, inf_ttrace_him, - inf_ttrace_prepare, NULL); + pid = fork_inferior (exec_file, allargs, env, inf_ttrace_me, NULL, + inf_ttrace_prepare, NULL, NULL); + + inf_ttrace_him (ops, pid); } static void -inf_ttrace_mourn_inferior (void) +inf_ttrace_mourn_inferior (struct target_ops *ops) { const int num_buckets = ARRAY_SIZE (inf_ttrace_page_dict.buckets); int bucket; @@ -677,25 +678,66 @@ inf_ttrace_mourn_inferior (void) } inf_ttrace_page_dict.count = 0; - unpush_target (ttrace_ops_hack); + unpush_target (ops); generic_mourn_inferior (); } +/* Assuming we just attached the debugger to a new inferior, create + a new thread_info structure for each thread, and add it to our + list of threads. */ + +static void +inf_ttrace_create_threads_after_attach (int pid) +{ + int status; + ptid_t ptid; + ttstate_t tts; + struct thread_info *ti; + + status = ttrace (TT_PROC_GET_FIRST_LWP_STATE, pid, 0, + (uintptr_t) &tts, sizeof (ttstate_t), 0); + if (status < 0) + perror_with_name (_("TT_PROC_GET_FIRST_LWP_STATE ttrace call failed")); + gdb_assert (tts.tts_pid == pid); + + /* Add the stopped thread. */ + ptid = ptid_build (pid, tts.tts_lwpid, 0); + ti = add_thread (ptid); + ti->private = xzalloc (sizeof (struct inf_ttrace_private_thread_info)); + inf_ttrace_num_lwps++; + + /* We use the "first stopped thread" as the currently active thread. */ + inferior_ptid = ptid; + + /* Iterative over all the remaining threads. */ + + for (;;) + { + ptid_t ptid; + + status = ttrace (TT_PROC_GET_NEXT_LWP_STATE, pid, 0, + (uintptr_t) &tts, sizeof (ttstate_t), 0); + if (status < 0) + perror_with_name (_("TT_PROC_GET_NEXT_LWP_STATE ttrace call failed")); + if (status == 0) + break; /* End of list. */ + + ptid = ptid_build (tts.tts_pid, tts.tts_lwpid, 0); + ti = add_thread (ptid); + ti->private = xzalloc (sizeof (struct inf_ttrace_private_thread_info)); + inf_ttrace_num_lwps++; + } +} + static void -inf_ttrace_attach (char *args, int from_tty) +inf_ttrace_attach (struct target_ops *ops, char *args, int from_tty) { char *exec_file; pid_t pid; - char *dummy; ttevent_t tte; + struct inferior *inf; - if (!args) - error_no_arg (_("process-id to attach")); - - dummy = args; - pid = strtol (args, &dummy, 0); - if (pid == 0 && args == dummy) - error (_("Illegal process-id: %s."), args); + pid = parse_pid_to_attach (args); if (pid == getpid ()) /* Trying to masturbate? */ error (_("I refuse to debug myself!")); @@ -720,7 +762,10 @@ inf_ttrace_attach (char *args, int from_tty) if (ttrace (TT_PROC_ATTACH, pid, 0, TT_KILL_ON_EXIT, TT_VERSION, 0) == -1) perror_with_name (("ttrace")); - attach_flag = 1; + + inf = current_inferior (); + inferior_appeared (inf, pid); + inf->attach_flag = 1; /* Set the initial event mask. */ memset (&tte, 0, sizeof (tte)); @@ -734,17 +779,13 @@ inf_ttrace_attach (char *args, int from_tty) (uintptr_t)&tte, sizeof tte, 0) == -1) perror_with_name (("ttrace")); - push_target (ttrace_ops_hack); + push_target (ops); - /* We'll bump inf_ttrace_num_lwps up and add the private data to the - thread as soon as we get to inf_ttrace_wait. At this point, we - don't have lwpid info yet. */ - inferior_ptid = pid_to_ptid (pid); - add_thread_silent (inferior_ptid); + inf_ttrace_create_threads_after_attach (pid); } static void -inf_ttrace_detach (char *args, int from_tty) +inf_ttrace_detach (struct target_ops *ops, char *args, int from_tty) { pid_t pid = ptid_get_pid (inferior_ptid); int sig = 0; @@ -776,12 +817,14 @@ inf_ttrace_detach (char *args, int from_tty) inf_ttrace_num_lwps = 0; inf_ttrace_num_lwps_in_syscall = 0; - unpush_target (ttrace_ops_hack); inferior_ptid = null_ptid; + detach_inferior (pid); + + unpush_target (ops); } static void -inf_ttrace_kill (void) +inf_ttrace_kill (struct target_ops *ops) { pid_t pid = ptid_get_pid (inferior_ptid); @@ -860,11 +903,12 @@ inf_ttrace_resume_callback (struct thread_info *info, void *arg) } static void -inf_ttrace_resume (ptid_t ptid, int step, enum target_signal signal) +inf_ttrace_resume (struct target_ops *ops, + ptid_t ptid, int step, enum gdb_signal signal) { int resume_all; ttreq_t request = step ? TT_LWP_SINGLE : TT_LWP_CONTINUE; - int sig = target_signal_to_host (signal); + int sig = gdb_signal_to_host (signal); struct thread_info *info; /* A specific PTID means `step only this process id'. */ @@ -875,7 +919,7 @@ inf_ttrace_resume (ptid_t ptid, int step, enum target_signal signal) if (resume_all) ptid = inferior_ptid; - info = thread_find_pid (ptid); + info = find_thread_ptid (ptid); inf_ttrace_resume_lwp (info, request, sig); if (resume_all) @@ -884,7 +928,8 @@ inf_ttrace_resume (ptid_t ptid, int step, enum target_signal signal) } static ptid_t -inf_ttrace_wait (ptid_t ptid, struct target_waitstatus *ourstatus) +inf_ttrace_wait (struct target_ops *ops, + ptid_t ptid, struct target_waitstatus *ourstatus, int options) { pid_t pid = ptid_get_pid (ptid); lwpid_t lwpid = ptid_get_lwp (ptid); @@ -903,7 +948,6 @@ inf_ttrace_wait (ptid_t ptid, struct target_waitstatus *ourstatus) do { set_sigint_trap (); - set_sigio_trap (); if (ttrace_wait (pid, lwpid, TTRACE_WAITOK, &tts, sizeof tts) == -1) perror_with_name (("ttrace_wait")); @@ -922,7 +966,6 @@ inf_ttrace_wait (ptid_t ptid, struct target_waitstatus *ourstatus) tts.tts_event = TTEVT_NONE; } - clear_sigio_trap (); clear_sigint_trap (); } while (tts.tts_event == TTEVT_NONE); @@ -949,7 +992,7 @@ inf_ttrace_wait (ptid_t ptid, struct target_waitstatus *ourstatus) /* We haven't set the private member on the main thread yet. Do it now. */ - ti = find_thread_pid (inferior_ptid); + ti = find_thread_ptid (inferior_ptid); gdb_assert (ti != NULL && ti->private == NULL); ti->private = xmalloc (sizeof (struct inf_ttrace_private_thread_info)); @@ -967,7 +1010,7 @@ inf_ttrace_wait (ptid_t ptid, struct target_waitstatus *ourstatus) case TTEVT_BPT_SSTEP: /* Make it look like a breakpoint. */ ourstatus->kind = TARGET_WAITKIND_STOPPED; - ourstatus->value.sig = TARGET_SIGNAL_TRAP; + ourstatus->value.sig = GDB_SIGNAL_TRAP; break; #endif @@ -1050,7 +1093,7 @@ inf_ttrace_wait (ptid_t ptid, struct target_waitstatus *ourstatus) case TTEVT_LWP_EXIT: if (print_thread_events) printf_unfiltered (_("[%s exited]\n"), target_pid_to_str (ptid)); - ti = find_thread_pid (ptid); + ti = find_thread_ptid (ptid); gdb_assert (ti != NULL); ((struct inf_ttrace_private_thread_info *)ti->private)->dying = 1; inf_ttrace_num_lwps--; @@ -1065,9 +1108,9 @@ inf_ttrace_wait (ptid_t ptid, struct target_waitstatus *ourstatus) lwpid = tts.tts_u.tts_thread.tts_target_lwpid; ptid = ptid_build (tts.tts_pid, lwpid, 0); if (print_thread_events) - printf_unfiltered(_("[%s has been terminated]\n") + printf_unfiltered(_("[%s has been terminated]\n"), target_pid_to_str (ptid)); - ti = find_thread_pid (ptid); + ti = find_thread_ptid (ptid); gdb_assert (ti != NULL); ((struct inf_ttrace_private_thread_info *)ti->private)->dying = 1; inf_ttrace_num_lwps--; @@ -1083,7 +1126,7 @@ inf_ttrace_wait (ptid_t ptid, struct target_waitstatus *ourstatus) case TTEVT_SIGNAL: ourstatus->kind = TARGET_WAITKIND_STOPPED; ourstatus->value.sig = - target_signal_from_host (tts.tts_u.tts_signal.tts_signo); + gdb_signal_from_host (tts.tts_u.tts_signal.tts_signo); break; case TTEVT_SYSCALL_ENTRY: @@ -1096,7 +1139,7 @@ inf_ttrace_wait (ptid_t ptid, struct target_waitstatus *ourstatus) inf_ttrace_disable_page_protections (tts.tts_pid); } ourstatus->kind = TARGET_WAITKIND_SYSCALL_ENTRY; - ourstatus->value.syscall_id = tts.tts_scno; + ourstatus->value.syscall_number = tts.tts_scno; break; case TTEVT_SYSCALL_RETURN: @@ -1111,7 +1154,7 @@ inf_ttrace_wait (ptid_t ptid, struct target_waitstatus *ourstatus) inf_ttrace_num_lwps_in_syscall--; } ourstatus->kind = TARGET_WAITKIND_SYSCALL_RETURN; - ourstatus->value.syscall_id = tts.tts_scno; + ourstatus->value.syscall_number = tts.tts_scno; break; default: @@ -1169,7 +1212,8 @@ inf_ttrace_xfer_memory (CORE_ADDR addr, ULONGEST len, static LONGEST inf_ttrace_xfer_partial (struct target_ops *ops, enum target_object object, const char *annex, gdb_byte *readbuf, - const gdb_byte *writebuf, ULONGEST offset, LONGEST len) + const gdb_byte *writebuf, + ULONGEST offset, LONGEST len) { switch (object) { @@ -1195,13 +1239,14 @@ inf_ttrace_xfer_partial (struct target_ops *ops, enum target_object object, static void inf_ttrace_files_info (struct target_ops *ignore) { + struct inferior *inf = current_inferior (); printf_filtered (_("\tUsing the running image of %s %s.\n"), - attach_flag ? "attached" : "child", + inf->attach_flag ? "attached" : "child", target_pid_to_str (inferior_ptid)); } static int -inf_ttrace_thread_alive (ptid_t ptid) +inf_ttrace_thread_alive (struct target_ops *ops, ptid_t ptid) { return 1; } @@ -1222,7 +1267,7 @@ inf_ttrace_extra_thread_info (struct thread_info *info) } static char * -inf_ttrace_pid_to_str (ptid_t ptid) +inf_ttrace_pid_to_str (struct target_ops *ops, ptid_t ptid) { pid_t pid = ptid_get_pid (ptid); lwpid_t lwpid = ptid_get_lwp (ptid); @@ -1238,6 +1283,15 @@ inf_ttrace_pid_to_str (ptid_t ptid) } +/* Implement the get_ada_task_ptid target_ops method. */ + +static ptid_t +inf_ttrace_get_ada_task_ptid (long lwp, long thread) +{ + return ptid_build (ptid_get_pid (inferior_ptid), lwp, 0); +} + + struct target_ops * inf_ttrace_target (void) { @@ -1262,8 +1316,8 @@ inf_ttrace_target (void) t->to_extra_thread_info = inf_ttrace_extra_thread_info; t->to_pid_to_str = inf_ttrace_pid_to_str; t->to_xfer_partial = inf_ttrace_xfer_partial; + t->to_get_ada_task_ptid = inf_ttrace_get_ada_task_ptid; - ttrace_ops_hack = t; return t; } #endif