Index: gdb/linux-nat.c |
diff --git a/gdb/linux-nat.c b/gdb/linux-nat.c |
index d2a529ae6d40216237e6390fffff05ad05f7738c..d2091caf91a55344c3cb00252723db0c6df64286 100644 |
--- a/gdb/linux-nat.c |
+++ b/gdb/linux-nat.c |
@@ -1,6 +1,6 @@ |
/* GNU/Linux native-dependent code common to multiple platforms. |
- Copyright (C) 2001-2012 Free Software Foundation, Inc. |
+ Copyright (C) 2001-2013 Free Software Foundation, Inc. |
This file is part of GDB. |
@@ -20,7 +20,9 @@ |
#include "defs.h" |
#include "inferior.h" |
#include "target.h" |
-#include "gdb_string.h" |
+#include "nat/linux-nat.h" |
+#include "nat/linux-waitpid.h" |
+#include <string.h> |
#include "gdb_wait.h" |
#include "gdb_assert.h" |
#ifdef HAVE_TKILL_SYSCALL |
@@ -39,21 +41,20 @@ |
#include "inf-child.h" |
#include "inf-ptrace.h" |
#include "auxv.h" |
-#include <sys/param.h> /* for MAXPATHLEN */ |
#include <sys/procfs.h> /* for elf_gregset etc. */ |
#include "elf-bfd.h" /* for elfcore_write_* */ |
#include "gregset.h" /* for gregset */ |
#include "gdbcore.h" /* for get_exec_file */ |
#include <ctype.h> /* for isdigit */ |
#include "gdbthread.h" /* for struct thread_info etc. */ |
-#include "gdb_stat.h" /* for struct stat */ |
+#include <sys/stat.h> /* for struct stat */ |
#include <fcntl.h> /* for O_RDONLY */ |
#include "inf-loop.h" |
#include "event-loop.h" |
#include "event-top.h" |
#include <pwd.h> |
#include <sys/types.h> |
-#include "gdb_dirent.h" |
+#include <dirent.h> |
#include "xml-support.h" |
#include "terminal.h" |
#include <sys/vfs.h> |
@@ -66,6 +67,8 @@ |
#include "exceptions.h" |
#include "linux-ptrace.h" |
#include "buffer.h" |
+#include "target-descriptions.h" |
+#include "filestuff.h" |
#ifndef SPUFS_MAGIC |
#define SPUFS_MAGIC 0x23c9b64e |
@@ -170,11 +173,6 @@ blocked. */ |
#define O_LARGEFILE 0 |
#endif |
-/* Unlike other extended result codes, WSTOPSIG (status) on |
- PTRACE_O_TRACESYSGOOD syscall events doesn't return SIGTRAP, but |
- instead SIGTRAP with bit 7 set. */ |
-#define SYSCALL_SIGTRAP (SIGTRAP | 0x80) |
- |
/* The single-threaded native GNU/Linux target_ops. We save a pointer for |
the use of the multi-threaded target. */ |
static struct target_ops *linux_ops; |
@@ -183,6 +181,13 @@ static struct target_ops linux_ops_saved; |
/* The method to call, if any, when a new thread is attached. */ |
static void (*linux_nat_new_thread) (struct lwp_info *); |
+/* The method to call, if any, when a new fork is attached. */ |
+static linux_nat_new_fork_ftype *linux_nat_new_fork; |
+ |
+/* The method to call, if any, when a process is no longer |
+ attached. */ |
+static linux_nat_forget_process_ftype *linux_nat_forget_process_hook; |
+ |
/* Hook to call prior to resuming a thread. */ |
static void (*linux_nat_prepare_to_resume) (struct lwp_info *); |
@@ -201,7 +206,7 @@ static LONGEST (*super_xfer_partial) (struct target_ops *, |
const gdb_byte *, |
ULONGEST, LONGEST); |
-static int debug_linux_nat; |
+static unsigned int debug_linux_nat; |
static void |
show_debug_linux_nat (struct ui_file *file, int from_tty, |
struct cmd_list_element *c, const char *value) |
@@ -218,24 +223,6 @@ struct simple_pid_list |
}; |
struct simple_pid_list *stopped_pids; |
-/* This variable is a tri-state flag: -1 for unknown, 0 if PTRACE_O_TRACEFORK |
- can not be used, 1 if it can. */ |
- |
-static int linux_supports_tracefork_flag = -1; |
- |
-/* This variable is a tri-state flag: -1 for unknown, 0 if |
- PTRACE_O_TRACESYSGOOD can not be used, 1 if it can. */ |
- |
-static int linux_supports_tracesysgood_flag = -1; |
- |
-/* If we have PTRACE_O_TRACEFORK, this flag indicates whether we also have |
- PTRACE_O_TRACEVFORKDONE. */ |
- |
-static int linux_supports_tracevforkdone_flag = -1; |
- |
-/* Stores the current used ptrace() options. */ |
-static int current_ptrace_options = 0; |
- |
/* Async mode support. */ |
/* The read/write ends of the pipe registered as waitable file in the |
@@ -341,257 +328,26 @@ pull_pid_from_list (struct simple_pid_list **listp, int pid, int *statusp) |
return 0; |
} |
- |
-/* A helper function for linux_test_for_tracefork, called after fork (). */ |
- |
-static void |
-linux_tracefork_child (void) |
-{ |
- ptrace (PTRACE_TRACEME, 0, 0, 0); |
- kill (getpid (), SIGSTOP); |
- fork (); |
- _exit (0); |
-} |
- |
-/* Wrapper function for waitpid which handles EINTR. */ |
- |
-static int |
-my_waitpid (int pid, int *statusp, int flags) |
-{ |
- int ret; |
- |
- do |
- { |
- ret = waitpid (pid, statusp, flags); |
- } |
- while (ret == -1 && errno == EINTR); |
- |
- return ret; |
-} |
- |
-/* Determine if PTRACE_O_TRACEFORK can be used to follow fork events. |
- |
- First, we try to enable fork tracing on ORIGINAL_PID. If this fails, |
- we know that the feature is not available. This may change the tracing |
- options for ORIGINAL_PID, but we'll be setting them shortly anyway. |
- |
- However, if it succeeds, we don't know for sure that the feature is |
- available; old versions of PTRACE_SETOPTIONS ignored unknown options. We |
- create a child process, attach to it, use PTRACE_SETOPTIONS to enable |
- fork tracing, and let it fork. If the process exits, we assume that we |
- can't use TRACEFORK; if we get the fork notification, and we can extract |
- the new child's PID, then we assume that we can. */ |
+/* Initialize ptrace warnings and check for supported ptrace |
+ features given PID. */ |
static void |
-linux_test_for_tracefork (int original_pid) |
-{ |
- int child_pid, ret, status; |
- long second_pid; |
- sigset_t prev_mask; |
- |
- /* We don't want those ptrace calls to be interrupted. */ |
- block_child_signals (&prev_mask); |
- |
- linux_supports_tracefork_flag = 0; |
- linux_supports_tracevforkdone_flag = 0; |
- |
- ret = ptrace (PTRACE_SETOPTIONS, original_pid, 0, PTRACE_O_TRACEFORK); |
- if (ret != 0) |
- { |
- restore_child_signals_mask (&prev_mask); |
- return; |
- } |
- |
- child_pid = fork (); |
- if (child_pid == -1) |
- perror_with_name (("fork")); |
- |
- if (child_pid == 0) |
- linux_tracefork_child (); |
- |
- ret = my_waitpid (child_pid, &status, 0); |
- if (ret == -1) |
- perror_with_name (("waitpid")); |
- else if (ret != child_pid) |
- error (_("linux_test_for_tracefork: waitpid: unexpected result %d."), ret); |
- if (! WIFSTOPPED (status)) |
- error (_("linux_test_for_tracefork: waitpid: unexpected status %d."), |
- status); |
- |
- ret = ptrace (PTRACE_SETOPTIONS, child_pid, 0, PTRACE_O_TRACEFORK); |
- if (ret != 0) |
- { |
- ret = ptrace (PTRACE_KILL, child_pid, 0, 0); |
- if (ret != 0) |
- { |
- warning (_("linux_test_for_tracefork: failed to kill child")); |
- restore_child_signals_mask (&prev_mask); |
- return; |
- } |
- |
- ret = my_waitpid (child_pid, &status, 0); |
- if (ret != child_pid) |
- warning (_("linux_test_for_tracefork: failed " |
- "to wait for killed child")); |
- else if (!WIFSIGNALED (status)) |
- warning (_("linux_test_for_tracefork: unexpected " |
- "wait status 0x%x from killed child"), status); |
- |
- restore_child_signals_mask (&prev_mask); |
- return; |
- } |
- |
- /* Check whether PTRACE_O_TRACEVFORKDONE is available. */ |
- ret = ptrace (PTRACE_SETOPTIONS, child_pid, 0, |
- PTRACE_O_TRACEFORK | PTRACE_O_TRACEVFORKDONE); |
- linux_supports_tracevforkdone_flag = (ret == 0); |
- |
- ret = ptrace (PTRACE_CONT, child_pid, 0, 0); |
- if (ret != 0) |
- warning (_("linux_test_for_tracefork: failed to resume child")); |
- |
- ret = my_waitpid (child_pid, &status, 0); |
- |
- if (ret == child_pid && WIFSTOPPED (status) |
- && status >> 16 == PTRACE_EVENT_FORK) |
- { |
- second_pid = 0; |
- ret = ptrace (PTRACE_GETEVENTMSG, child_pid, 0, &second_pid); |
- if (ret == 0 && second_pid != 0) |
- { |
- int second_status; |
- |
- linux_supports_tracefork_flag = 1; |
- my_waitpid (second_pid, &second_status, 0); |
- ret = ptrace (PTRACE_KILL, second_pid, 0, 0); |
- if (ret != 0) |
- warning (_("linux_test_for_tracefork: " |
- "failed to kill second child")); |
- my_waitpid (second_pid, &status, 0); |
- } |
- } |
- else |
- warning (_("linux_test_for_tracefork: unexpected result from waitpid " |
- "(%d, status 0x%x)"), ret, status); |
- |
- ret = ptrace (PTRACE_KILL, child_pid, 0, 0); |
- if (ret != 0) |
- warning (_("linux_test_for_tracefork: failed to kill child")); |
- my_waitpid (child_pid, &status, 0); |
- |
- restore_child_signals_mask (&prev_mask); |
-} |
- |
-/* Determine if PTRACE_O_TRACESYSGOOD can be used to follow syscalls. |
- |
- We try to enable syscall tracing on ORIGINAL_PID. If this fails, |
- we know that the feature is not available. This may change the tracing |
- options for ORIGINAL_PID, but we'll be setting them shortly anyway. */ |
- |
-static void |
-linux_test_for_tracesysgood (int original_pid) |
-{ |
- int ret; |
- sigset_t prev_mask; |
- |
- /* We don't want those ptrace calls to be interrupted. */ |
- block_child_signals (&prev_mask); |
- |
- linux_supports_tracesysgood_flag = 0; |
- |
- ret = ptrace (PTRACE_SETOPTIONS, original_pid, 0, PTRACE_O_TRACESYSGOOD); |
- if (ret != 0) |
- goto out; |
- |
- linux_supports_tracesysgood_flag = 1; |
-out: |
- restore_child_signals_mask (&prev_mask); |
-} |
- |
-/* Determine wether we support PTRACE_O_TRACESYSGOOD option available. |
- This function also sets linux_supports_tracesysgood_flag. */ |
- |
-static int |
-linux_supports_tracesysgood (int pid) |
-{ |
- if (linux_supports_tracesysgood_flag == -1) |
- linux_test_for_tracesysgood (pid); |
- return linux_supports_tracesysgood_flag; |
-} |
- |
-/* Return non-zero iff we have tracefork functionality available. |
- This function also sets linux_supports_tracefork_flag. */ |
- |
-static int |
-linux_supports_tracefork (int pid) |
-{ |
- if (linux_supports_tracefork_flag == -1) |
- linux_test_for_tracefork (pid); |
- return linux_supports_tracefork_flag; |
-} |
- |
-static int |
-linux_supports_tracevforkdone (int pid) |
-{ |
- if (linux_supports_tracefork_flag == -1) |
- linux_test_for_tracefork (pid); |
- return linux_supports_tracevforkdone_flag; |
-} |
- |
-static void |
-linux_enable_tracesysgood (ptid_t ptid) |
-{ |
- int pid = ptid_get_lwp (ptid); |
- |
- if (pid == 0) |
- pid = ptid_get_pid (ptid); |
- |
- if (linux_supports_tracesysgood (pid) == 0) |
- return; |
- |
- current_ptrace_options |= PTRACE_O_TRACESYSGOOD; |
- |
- ptrace (PTRACE_SETOPTIONS, pid, 0, current_ptrace_options); |
-} |
- |
- |
-void |
-linux_enable_event_reporting (ptid_t ptid) |
+linux_init_ptrace (pid_t pid) |
{ |
- int pid = ptid_get_lwp (ptid); |
- |
- if (pid == 0) |
- pid = ptid_get_pid (ptid); |
- |
- if (! linux_supports_tracefork (pid)) |
- return; |
- |
- current_ptrace_options |= PTRACE_O_TRACEFORK | PTRACE_O_TRACEVFORK |
- | PTRACE_O_TRACEEXEC | PTRACE_O_TRACECLONE; |
- |
- if (linux_supports_tracevforkdone (pid)) |
- current_ptrace_options |= PTRACE_O_TRACEVFORKDONE; |
- |
- /* Do not enable PTRACE_O_TRACEEXIT until GDB is more prepared to support |
- read-only process state. */ |
- |
- ptrace (PTRACE_SETOPTIONS, pid, 0, current_ptrace_options); |
+ linux_enable_event_reporting (pid); |
+ linux_ptrace_init_warnings (); |
} |
static void |
linux_child_post_attach (int pid) |
{ |
- linux_enable_event_reporting (pid_to_ptid (pid)); |
- linux_enable_tracesysgood (pid_to_ptid (pid)); |
- linux_ptrace_init_warnings (); |
+ linux_init_ptrace (pid); |
} |
static void |
linux_child_post_startup_inferior (ptid_t ptid) |
{ |
- linux_enable_event_reporting (ptid); |
- linux_enable_tracesysgood (ptid); |
- linux_ptrace_init_warnings (); |
+ linux_init_ptrace (ptid_get_pid (ptid)); |
} |
/* Return the number of known LWPs in the tgid given by PID. */ |
@@ -620,23 +376,19 @@ delete_lwp_cleanup (void *lp_voidp) |
} |
static int |
-linux_child_follow_fork (struct target_ops *ops, int follow_child) |
+linux_child_follow_fork (struct target_ops *ops, int follow_child, |
+ int detach_fork) |
{ |
- sigset_t prev_mask; |
int has_vforked; |
int parent_pid, child_pid; |
- block_child_signals (&prev_mask); |
- |
has_vforked = (inferior_thread ()->pending_follow.kind |
== TARGET_WAITKIND_VFORKED); |
parent_pid = ptid_get_lwp (inferior_ptid); |
if (parent_pid == 0) |
parent_pid = ptid_get_pid (inferior_ptid); |
- child_pid = PIDGET (inferior_thread ()->pending_follow.value.related_pid); |
- |
- if (!detach_fork) |
- linux_enable_event_reporting (pid_to_ptid (child_pid)); |
+ child_pid |
+ = ptid_get_pid (inferior_thread ()->pending_follow.value.related_pid); |
if (has_vforked |
&& !non_stop /* Non-stop always resumes both branches. */ |
@@ -677,7 +429,7 @@ holding the child stopped. Try \"set detach-on-fork\" or \ |
if (has_vforked) |
{ |
/* keep breakpoints list in sync. */ |
- remove_breakpoints_pid (GET_PID (inferior_ptid)); |
+ remove_breakpoints_pid (ptid_get_pid (inferior_ptid)); |
} |
if (info_verbose || debug_linux_nat) |
@@ -697,15 +449,6 @@ holding the child stopped. Try \"set detach-on-fork\" or \ |
child_lp->last_resume_kind = resume_stop; |
make_cleanup (delete_lwp_cleanup, child_lp); |
- /* CHILD_LP has new PID, therefore linux_nat_new_thread is not called for it. |
- See i386_inferior_data_get for the Linux kernel specifics. |
- Ensure linux_nat_prepare_to_resume will reset the hardware debug |
- registers. It is done by the linux_nat_new_thread call, which is |
- being skipped in add_lwp above for the first lwp of a pid. */ |
- gdb_assert (num_lwps (GET_PID (child_lp->ptid)) == 1); |
- if (linux_nat_new_thread != NULL) |
- linux_nat_new_thread (child_lp); |
- |
if (linux_nat_prepare_to_resume != NULL) |
linux_nat_prepare_to_resume (child_lp); |
ptrace (PTRACE_DETACH, child_pid, 0, 0); |
@@ -723,6 +466,8 @@ holding the child stopped. Try \"set detach-on-fork\" or \ |
parent_inf = current_inferior (); |
child_inf->attach_flag = parent_inf->attach_flag; |
copy_terminal_info (child_inf, parent_inf); |
+ child_inf->gdbarch = parent_inf->gdbarch; |
+ copy_inferior_target_desc_info (child_inf, parent_inf); |
old_chain = save_inferior_ptid (); |
save_current_program_space (); |
@@ -790,9 +535,9 @@ holding the child stopped. Try \"set detach-on-fork\" or \ |
parent_inf->pspace->breakpoints_not_allowed = detach_fork; |
parent_lp = find_lwp_pid (pid_to_ptid (parent_pid)); |
- gdb_assert (linux_supports_tracefork_flag >= 0); |
+ gdb_assert (linux_supports_tracefork () >= 0); |
- if (linux_supports_tracevforkdone (0)) |
+ if (linux_supports_tracevforkdone ()) |
{ |
if (debug_linux_nat) |
fprintf_unfiltered (gdb_stdlog, |
@@ -887,6 +632,8 @@ holding the child stopped. Try \"set detach-on-fork\" or \ |
parent_inf = current_inferior (); |
child_inf->attach_flag = parent_inf->attach_flag; |
copy_terminal_info (child_inf, parent_inf); |
+ child_inf->gdbarch = parent_inf->gdbarch; |
+ copy_inferior_target_desc_info (child_inf, parent_inf); |
parent_pspace = parent_inf->pspace; |
@@ -954,7 +701,6 @@ holding the child stopped. Try \"set detach-on-fork\" or \ |
check_for_thread_db (); |
} |
- restore_child_signals_mask (&prev_mask); |
return 0; |
} |
@@ -962,7 +708,7 @@ holding the child stopped. Try \"set detach-on-fork\" or \ |
static int |
linux_child_insert_fork_catchpoint (int pid) |
{ |
- return !linux_supports_tracefork (pid); |
+ return !linux_supports_tracefork (); |
} |
static int |
@@ -974,7 +720,7 @@ linux_child_remove_fork_catchpoint (int pid) |
static int |
linux_child_insert_vfork_catchpoint (int pid) |
{ |
- return !linux_supports_tracefork (pid); |
+ return !linux_supports_tracefork (); |
} |
static int |
@@ -986,7 +732,7 @@ linux_child_remove_vfork_catchpoint (int pid) |
static int |
linux_child_insert_exec_catchpoint (int pid) |
{ |
- return !linux_supports_tracefork (pid); |
+ return !linux_supports_tracefork (); |
} |
static int |
@@ -999,7 +745,7 @@ static int |
linux_child_set_syscall_catchpoint (int pid, int needed, int any_count, |
int table_size, int *table) |
{ |
- if (!linux_supports_tracesysgood (pid)) |
+ if (!linux_supports_tracesysgood ()) |
return 1; |
/* On GNU/Linux, we ignore the arguments. It means that we only |
@@ -1171,16 +917,26 @@ purge_lwp_list (int pid) |
} |
} |
-/* Add the LWP specified by PID to the list. Return a pointer to the |
- structure describing the new LWP. The LWP should already be stopped |
- (with an exception for the very first LWP). */ |
+/* Add the LWP specified by PTID to the list. PTID is the first LWP |
+ in the process. Return a pointer to the structure describing the |
+ new LWP. |
+ |
+ This differs from add_lwp in that we don't let the arch specific |
+ bits know about this new thread. Current clients of this callback |
+ take the opportunity to install watchpoints in the new thread, and |
+ we shouldn't do that for the first thread. If we're spawning a |
+ child ("run"), the thread executes the shell wrapper first, and we |
+ shouldn't touch it until it execs the program we want to debug. |
+ For "attach", it'd be okay to call the callback, but it's not |
+ necessary, because watchpoints can't yet have been inserted into |
+ the inferior. */ |
static struct lwp_info * |
-add_lwp (ptid_t ptid) |
+add_initial_lwp (ptid_t ptid) |
{ |
struct lwp_info *lp; |
- gdb_assert (is_lwp (ptid)); |
+ gdb_assert (ptid_lwp_p (ptid)); |
lp = (struct lwp_info *) xmalloc (sizeof (struct lwp_info)); |
@@ -1195,15 +951,25 @@ add_lwp (ptid_t ptid) |
lp->next = lwp_list; |
lwp_list = lp; |
+ return lp; |
+} |
+ |
+/* Add the LWP specified by PID to the list. Return a pointer to the |
+ structure describing the new LWP. The LWP should already be |
+ stopped. */ |
+ |
+static struct lwp_info * |
+add_lwp (ptid_t ptid) |
+{ |
+ struct lwp_info *lp; |
+ |
+ lp = add_initial_lwp (ptid); |
+ |
/* Let the arch specific bits know about this new thread. Current |
clients of this callback take the opportunity to install |
- watchpoints in the new thread. Don't do this for the first |
- thread though. If we're spawning a child ("run"), the thread |
- executes the shell wrapper first, and we shouldn't touch it until |
- it execs the program we want to debug. For "attach", it'd be |
- okay to call the callback, but it's not necessary, because |
- watchpoints can't yet have been inserted into the inferior. */ |
- if (num_lwps (GET_PID (ptid)) > 1 && linux_nat_new_thread != NULL) |
+ watchpoints in the new thread. We don't do this for the first |
+ thread though. See add_initial_lwp. */ |
+ if (linux_nat_new_thread != NULL) |
linux_nat_new_thread (lp); |
return lp; |
@@ -1242,13 +1008,13 @@ find_lwp_pid (ptid_t ptid) |
struct lwp_info *lp; |
int lwp; |
- if (is_lwp (ptid)) |
- lwp = GET_LWP (ptid); |
+ if (ptid_lwp_p (ptid)) |
+ lwp = ptid_get_lwp (ptid); |
else |
- lwp = GET_PID (ptid); |
+ lwp = ptid_get_pid (ptid); |
for (lp = lwp_list; lp; lp = lp->next) |
- if (lwp == GET_LWP (lp->ptid)) |
+ if (lwp == ptid_get_lwp (lp->ptid)) |
return lp; |
return NULL; |
@@ -1280,46 +1046,6 @@ iterate_over_lwps (ptid_t filter, |
return NULL; |
} |
-/* Iterate like iterate_over_lwps does except when forking-off a child call |
- CALLBACK with CALLBACK_DATA specifically only for that new child PID. */ |
- |
-void |
-linux_nat_iterate_watchpoint_lwps |
- (linux_nat_iterate_watchpoint_lwps_ftype callback, void *callback_data) |
-{ |
- int inferior_pid = ptid_get_pid (inferior_ptid); |
- struct inferior *inf = current_inferior (); |
- |
- if (inf->pid == inferior_pid) |
- { |
- /* Iterate all the threads of the current inferior. Without specifying |
- INFERIOR_PID it would iterate all threads of all inferiors, which is |
- inappropriate for watchpoints. */ |
- |
- iterate_over_lwps (pid_to_ptid (inferior_pid), callback, callback_data); |
- } |
- else |
- { |
- /* Detaching a new child PID temporarily present in INFERIOR_PID. */ |
- |
- struct lwp_info *child_lp; |
- struct cleanup *old_chain; |
- pid_t child_pid = GET_PID (inferior_ptid); |
- ptid_t child_ptid = ptid_build (child_pid, child_pid, 0); |
- |
- gdb_assert (!is_lwp (inferior_ptid)); |
- gdb_assert (find_lwp_pid (child_ptid) == NULL); |
- child_lp = add_lwp (child_ptid); |
- child_lp->stopped = 1; |
- child_lp->last_resume_kind = resume_stop; |
- old_chain = make_cleanup (delete_lwp_cleanup, child_lp); |
- |
- callback (child_lp, callback_data); |
- |
- do_cleanups (old_chain); |
- } |
-} |
- |
/* Update our internal state when changing from one checkpoint to |
another indicated by NEW_PTID. We can only switch single-threaded |
applications, so we only create one new LWP, and the previous list |
@@ -1330,7 +1056,7 @@ linux_nat_switch_fork (ptid_t new_ptid) |
{ |
struct lwp_info *lp; |
- purge_lwp_list (GET_PID (inferior_ptid)); |
+ purge_lwp_list (ptid_get_pid (inferior_ptid)); |
lp = add_lwp (new_ptid); |
lp->stopped = 1; |
@@ -1371,7 +1097,7 @@ static int |
linux_nat_post_attach_wait (ptid_t ptid, int first, int *cloned, |
int *signalled) |
{ |
- pid_t new_pid, pid = GET_LWP (ptid); |
+ pid_t new_pid, pid = ptid_get_lwp (ptid); |
int status; |
if (linux_proc_pid_is_stopped (pid)) |
@@ -1447,15 +1173,12 @@ int |
lin_lwp_attach_lwp (ptid_t ptid) |
{ |
struct lwp_info *lp; |
- sigset_t prev_mask; |
int lwpid; |
- gdb_assert (is_lwp (ptid)); |
- |
- block_child_signals (&prev_mask); |
+ gdb_assert (ptid_lwp_p (ptid)); |
lp = find_lwp_pid (ptid); |
- lwpid = GET_LWP (ptid); |
+ lwpid = ptid_get_lwp (ptid); |
/* We assume that we're already attached to any LWP that has an id |
equal to the overall process id, and to any LWP that is already |
@@ -1463,13 +1186,13 @@ lin_lwp_attach_lwp (ptid_t ptid) |
and we've had PID wraparound since we last tried to stop all threads, |
this assumption might be wrong; fortunately, this is very unlikely |
to happen. */ |
- if (lwpid != GET_PID (ptid) && lp == NULL) |
+ if (lwpid != ptid_get_pid (ptid) && lp == NULL) |
{ |
int status, cloned = 0, signalled = 0; |
if (ptrace (PTRACE_ATTACH, lwpid, 0, 0) < 0) |
{ |
- if (linux_supports_tracefork_flag) |
+ if (linux_supports_tracefork ()) |
{ |
/* If we haven't stopped all threads when we get here, |
we may have seen a thread listed in thread_db's list, |
@@ -1481,7 +1204,6 @@ lin_lwp_attach_lwp (ptid_t ptid) |
/* We've already seen this thread stop, but we |
haven't seen the PTRACE_EVENT_CLONE extended |
event yet. */ |
- restore_child_signals_mask (&prev_mask); |
return 0; |
} |
else |
@@ -1498,8 +1220,6 @@ lin_lwp_attach_lwp (ptid_t ptid) |
{ |
if (WIFSTOPPED (status)) |
add_to_pid_list (&stopped_pids, lwpid, status); |
- |
- restore_child_signals_mask (&prev_mask); |
return 1; |
} |
} |
@@ -1512,7 +1232,6 @@ lin_lwp_attach_lwp (ptid_t ptid) |
to create them. */ |
warning (_("Can't attach %s: %s"), target_pid_to_str (ptid), |
safe_strerror (errno)); |
- restore_child_signals_mask (&prev_mask); |
return -1; |
} |
@@ -1523,10 +1242,7 @@ lin_lwp_attach_lwp (ptid_t ptid) |
status = linux_nat_post_attach_wait (ptid, 0, &cloned, &signalled); |
if (!WIFSTOPPED (status)) |
- { |
- restore_child_signals_mask (&prev_mask); |
- return 1; |
- } |
+ return 1; |
lp = add_lwp (ptid); |
lp->stopped = 1; |
@@ -1538,7 +1254,7 @@ lin_lwp_attach_lwp (ptid_t ptid) |
lp->status = status; |
} |
- target_post_attach (GET_LWP (lp->ptid)); |
+ target_post_attach (ptid_get_lwp (lp->ptid)); |
if (debug_linux_nat) |
{ |
@@ -1562,7 +1278,6 @@ lin_lwp_attach_lwp (ptid_t ptid) |
} |
lp->last_resume_kind = resume_stop; |
- restore_child_signals_mask (&prev_mask); |
return 0; |
} |
@@ -1648,11 +1363,13 @@ linux_nat_attach (struct target_ops *ops, char *args, int from_tty) |
/* The ptrace base target adds the main thread with (pid,0,0) |
format. Decorate it with lwp info. */ |
- ptid = BUILD_LWP (GET_PID (inferior_ptid), GET_PID (inferior_ptid)); |
+ ptid = ptid_build (ptid_get_pid (inferior_ptid), |
+ ptid_get_pid (inferior_ptid), |
+ 0); |
thread_change_ptid (inferior_ptid, ptid); |
/* Add the initial process as the first LWP to the list. */ |
- lp = add_lwp (ptid); |
+ lp = add_initial_lwp (ptid); |
status = linux_nat_post_attach_wait (lp->ptid, 1, &lp->cloned, |
&lp->signalled); |
@@ -1686,7 +1403,7 @@ linux_nat_attach (struct target_ops *ops, char *args, int from_tty) |
internal_error (__FILE__, __LINE__, |
_("unexpected status %d for PID %ld"), |
- status, (long) GET_LWP (ptid)); |
+ status, (long) ptid_get_lwp (ptid)); |
} |
lp->stopped = 1; |
@@ -1696,7 +1413,7 @@ linux_nat_attach (struct target_ops *ops, char *args, int from_tty) |
if (debug_linux_nat) |
fprintf_unfiltered (gdb_stdlog, |
"LNA: waitpid %ld, saving status %s\n", |
- (long) GET_PID (lp->ptid), status_to_str (status)); |
+ (long) ptid_get_pid (lp->ptid), status_to_str (status)); |
lp->status = status; |
@@ -1748,7 +1465,7 @@ get_pending_status (struct lwp_info *lp, int *status) |
get_last_target_status (&last_ptid, &last); |
- if (GET_LWP (lp->ptid) == GET_LWP (last_ptid)) |
+ if (ptid_get_lwp (lp->ptid) == ptid_get_lwp (last_ptid)) |
{ |
struct thread_info *tp = find_thread_ptid (lp->ptid); |
@@ -1806,13 +1523,13 @@ detach_callback (struct lwp_info *lp, void *data) |
"DC: Sending SIGCONT to %s\n", |
target_pid_to_str (lp->ptid)); |
- kill_lwp (GET_LWP (lp->ptid), SIGCONT); |
+ kill_lwp (ptid_get_lwp (lp->ptid), SIGCONT); |
lp->signalled = 0; |
} |
/* We don't actually detach from the LWP that has an id equal to the |
overall process id just yet. */ |
- if (GET_LWP (lp->ptid) != GET_PID (lp->ptid)) |
+ if (ptid_get_lwp (lp->ptid) != ptid_get_pid (lp->ptid)) |
{ |
int status = 0; |
@@ -1822,7 +1539,7 @@ detach_callback (struct lwp_info *lp, void *data) |
if (linux_nat_prepare_to_resume != NULL) |
linux_nat_prepare_to_resume (lp); |
errno = 0; |
- if (ptrace (PTRACE_DETACH, GET_LWP (lp->ptid), 0, |
+ if (ptrace (PTRACE_DETACH, ptid_get_lwp (lp->ptid), 0, |
WSTOPSIG (status)) < 0) |
error (_("Can't detach %s: %s"), target_pid_to_str (lp->ptid), |
safe_strerror (errno)); |
@@ -1840,13 +1557,13 @@ detach_callback (struct lwp_info *lp, void *data) |
} |
static void |
-linux_nat_detach (struct target_ops *ops, char *args, int from_tty) |
+linux_nat_detach (struct target_ops *ops, const char *args, int from_tty) |
{ |
int pid; |
int status; |
struct lwp_info *main_lwp; |
- pid = GET_PID (inferior_ptid); |
+ pid = ptid_get_pid (inferior_ptid); |
/* Don't unregister from the event loop, as there may be other |
inferiors running. */ |
@@ -1861,7 +1578,7 @@ linux_nat_detach (struct target_ops *ops, char *args, int from_tty) |
iterate_over_lwps (pid_to_ptid (pid), detach_callback, NULL); |
/* Only the initial process should be left right now. */ |
- gdb_assert (num_lwps (GET_PID (inferior_ptid)) == 1); |
+ gdb_assert (num_lwps (ptid_get_pid (inferior_ptid)) == 1); |
main_lwp = find_lwp_pid (pid_to_ptid (pid)); |
@@ -1870,10 +1587,13 @@ linux_nat_detach (struct target_ops *ops, char *args, int from_tty) |
&& get_pending_status (main_lwp, &status) != -1 |
&& WIFSTOPPED (status)) |
{ |
+ char *tem; |
+ |
/* Put the signal number in ARGS so that inf_ptrace_detach will |
pass it along with PTRACE_DETACH. */ |
- args = alloca (8); |
- sprintf (args, "%d", (int) WSTOPSIG (status)); |
+ tem = alloca (8); |
+ sprintf (tem, "%d", (int) WSTOPSIG (status)); |
+ args = tem; |
if (debug_linux_nat) |
fprintf_unfiltered (gdb_stdlog, |
"LND: Sending signal %s to %s\n", |
@@ -1904,7 +1624,7 @@ resume_lwp (struct lwp_info *lp, int step, enum gdb_signal signo) |
{ |
if (lp->stopped) |
{ |
- struct inferior *inf = find_inferior_pid (GET_PID (lp->ptid)); |
+ struct inferior *inf = find_inferior_pid (ptid_get_pid (lp->ptid)); |
if (inf->vfork_child != NULL) |
{ |
@@ -1928,7 +1648,7 @@ resume_lwp (struct lwp_info *lp, int step, enum gdb_signal signo) |
if (linux_nat_prepare_to_resume != NULL) |
linux_nat_prepare_to_resume (lp); |
linux_ops->to_resume (linux_ops, |
- pid_to_ptid (GET_LWP (lp->ptid)), |
+ pid_to_ptid (ptid_get_lwp (lp->ptid)), |
step, signo); |
lp->stopped = 0; |
lp->step = step; |
@@ -1995,7 +1715,6 @@ static void |
linux_nat_resume (struct target_ops *ops, |
ptid_t ptid, int step, enum gdb_signal signo) |
{ |
- sigset_t prev_mask; |
struct lwp_info *lp; |
int resume_many; |
@@ -2008,8 +1727,6 @@ linux_nat_resume (struct target_ops *ops, |
? strsignal (gdb_signal_to_host (signo)) : "0"), |
target_pid_to_str (inferior_ptid)); |
- block_child_signals (&prev_mask); |
- |
/* A specific PTID means `step only this process id'. */ |
resume_many = (ptid_equal (minus_one_ptid, ptid) |
|| ptid_is_pid (ptid)); |
@@ -2067,7 +1784,6 @@ linux_nat_resume (struct target_ops *ops, |
"LLR: Short circuiting for status 0x%x\n", |
lp->status); |
- restore_child_signals_mask (&prev_mask); |
if (target_can_async_p ()) |
{ |
target_async (inferior_event_handler, 0); |
@@ -2085,7 +1801,7 @@ linux_nat_resume (struct target_ops *ops, |
iterate_over_lwps (ptid, linux_nat_resume_callback, NULL); |
/* Convert to something the lower layer understands. */ |
- ptid = pid_to_ptid (GET_LWP (lp->ptid)); |
+ ptid = pid_to_ptid (ptid_get_lwp (lp->ptid)); |
if (linux_nat_prepare_to_resume != NULL) |
linux_nat_prepare_to_resume (lp); |
@@ -2100,7 +1816,6 @@ linux_nat_resume (struct target_ops *ops, |
(signo != GDB_SIGNAL_0 |
? strsignal (gdb_signal_to_host (signo)) : "0")); |
- restore_child_signals_mask (&prev_mask); |
if (target_can_async_p ()) |
target_async (inferior_event_handler, 0); |
} |
@@ -2174,10 +1889,10 @@ linux_handle_syscall_trap (struct lwp_info *lp, int stopping) |
"for LWP %ld (stopping threads), " |
"resuming with PTRACE_CONT for SIGSTOP\n", |
syscall_number, |
- GET_LWP (lp->ptid)); |
+ ptid_get_lwp (lp->ptid)); |
lp->syscall_state = TARGET_WAITKIND_IGNORE; |
- ptrace (PTRACE_CONT, GET_LWP (lp->ptid), 0, 0); |
+ ptrace (PTRACE_CONT, ptid_get_lwp (lp->ptid), 0, 0); |
return 1; |
} |
@@ -2206,7 +1921,7 @@ linux_handle_syscall_trap (struct lwp_info *lp, int stopping) |
== TARGET_WAITKIND_SYSCALL_ENTRY |
? "entry" : "return", |
syscall_number, |
- GET_LWP (lp->ptid)); |
+ ptid_get_lwp (lp->ptid)); |
return 0; |
} |
@@ -2217,7 +1932,7 @@ linux_handle_syscall_trap (struct lwp_info *lp, int stopping) |
lp->syscall_state == TARGET_WAITKIND_SYSCALL_ENTRY |
? "entry" : "return", |
syscall_number, |
- GET_LWP (lp->ptid)); |
+ ptid_get_lwp (lp->ptid)); |
} |
else |
{ |
@@ -2243,7 +1958,7 @@ linux_handle_syscall_trap (struct lwp_info *lp, int stopping) |
"with no syscall catchpoints." |
" %d for LWP %ld, ignoring\n", |
syscall_number, |
- GET_LWP (lp->ptid)); |
+ ptid_get_lwp (lp->ptid)); |
lp->syscall_state = TARGET_WAITKIND_IGNORE; |
} |
@@ -2259,7 +1974,7 @@ linux_handle_syscall_trap (struct lwp_info *lp, int stopping) |
registers_changed (); |
if (linux_nat_prepare_to_resume != NULL) |
linux_nat_prepare_to_resume (lp); |
- linux_ops->to_resume (linux_ops, pid_to_ptid (GET_LWP (lp->ptid)), |
+ linux_ops->to_resume (linux_ops, pid_to_ptid (ptid_get_lwp (lp->ptid)), |
lp->step, GDB_SIGNAL_0); |
return 1; |
} |
@@ -2274,7 +1989,7 @@ static int |
linux_handle_extended_wait (struct lwp_info *lp, int status, |
int stopping) |
{ |
- int pid = GET_LWP (lp->ptid); |
+ int pid = ptid_get_lwp (lp->ptid); |
struct target_waitstatus *ourstatus = &lp->waitstatus; |
int event = status >> 16; |
@@ -2305,8 +2020,17 @@ linux_handle_extended_wait (struct lwp_info *lp, int status, |
ourstatus->value.related_pid = ptid_build (new_pid, new_pid, 0); |
+ if (event == PTRACE_EVENT_FORK || event == PTRACE_EVENT_VFORK) |
+ { |
+ /* The arch-specific native code may need to know about new |
+ forks even if those end up never mapped to an |
+ inferior. */ |
+ if (linux_nat_new_fork != NULL) |
+ linux_nat_new_fork (lp, new_pid); |
+ } |
+ |
if (event == PTRACE_EVENT_FORK |
- && linux_fork_checkpointing_p (GET_PID (lp->ptid))) |
+ && linux_fork_checkpointing_p (ptid_get_pid (lp->ptid))) |
{ |
/* Handle checkpointing by linux-fork.c here as a special |
case. We don't want the follow-fork-mode or 'catch fork' |
@@ -2314,7 +2038,7 @@ linux_handle_extended_wait (struct lwp_info *lp, int status, |
/* This won't actually modify the breakpoint list, but will |
physically remove the breakpoints from the child. */ |
- detach_breakpoints (new_pid); |
+ detach_breakpoints (ptid_build (new_pid, new_pid, 0)); |
/* Retain child fork in ptrace (stopped) state. */ |
if (!find_fork_pid (new_pid)) |
@@ -2324,7 +2048,6 @@ linux_handle_extended_wait (struct lwp_info *lp, int status, |
this fork. We're actually doing an infcall in |
linux-fork.c. */ |
ourstatus->kind = TARGET_WAITKIND_SPURIOUS; |
- linux_enable_event_reporting (pid_to_ptid (new_pid)); |
/* Report the stop to the core. */ |
return 0; |
@@ -2346,7 +2069,7 @@ linux_handle_extended_wait (struct lwp_info *lp, int status, |
"from LWP %d, new child is LWP %ld\n", |
pid, new_pid); |
- new_lp = add_lwp (BUILD_LWP (new_pid, GET_PID (lp->ptid))); |
+ new_lp = add_lwp (ptid_build (ptid_get_pid (lp->ptid), new_pid, 0)); |
new_lp->cloned = 1; |
new_lp->stopped = 1; |
@@ -2403,7 +2126,7 @@ linux_handle_extended_wait (struct lwp_info *lp, int status, |
{ |
/* We're not using thread_db. Add it to GDB's |
list. */ |
- target_post_attach (GET_LWP (new_lp->ptid)); |
+ target_post_attach (ptid_get_lwp (new_lp->ptid)); |
add_thread (new_lp->ptid); |
} |
@@ -2427,7 +2150,7 @@ linux_handle_extended_wait (struct lwp_info *lp, int status, |
fprintf_unfiltered (gdb_stdlog, |
"LHEW: waitpid of new LWP %ld, " |
"saving status %s\n", |
- (long) GET_LWP (new_lp->ptid), |
+ (long) ptid_get_lwp (new_lp->ptid), |
status_to_str (status)); |
new_lp->status = status; |
} |
@@ -2445,7 +2168,7 @@ linux_handle_extended_wait (struct lwp_info *lp, int status, |
if (debug_linux_nat) |
fprintf_unfiltered (gdb_stdlog, |
"LHEW: resuming new LWP %ld\n", |
- GET_LWP (new_lp->ptid)); |
+ ptid_get_lwp (new_lp->ptid)); |
if (linux_nat_prepare_to_resume != NULL) |
linux_nat_prepare_to_resume (new_lp); |
linux_ops->to_resume (linux_ops, pid_to_ptid (new_pid), |
@@ -2459,7 +2182,8 @@ linux_handle_extended_wait (struct lwp_info *lp, int status, |
"LHEW: resuming parent LWP %d\n", pid); |
if (linux_nat_prepare_to_resume != NULL) |
linux_nat_prepare_to_resume (lp); |
- linux_ops->to_resume (linux_ops, pid_to_ptid (GET_LWP (lp->ptid)), |
+ linux_ops->to_resume (linux_ops, |
+ pid_to_ptid (ptid_get_lwp (lp->ptid)), |
0, GDB_SIGNAL_0); |
return 1; |
@@ -2473,7 +2197,7 @@ linux_handle_extended_wait (struct lwp_info *lp, int status, |
if (debug_linux_nat) |
fprintf_unfiltered (gdb_stdlog, |
"LHEW: Got exec event from LWP %ld\n", |
- GET_LWP (lp->ptid)); |
+ ptid_get_lwp (lp->ptid)); |
ourstatus->kind = TARGET_WAITKIND_EXECD; |
ourstatus->value.execd_pathname |
@@ -2490,7 +2214,7 @@ linux_handle_extended_wait (struct lwp_info *lp, int status, |
fprintf_unfiltered (gdb_stdlog, |
"LHEW: Got expected PTRACE_EVENT_" |
"VFORK_DONE from LWP %ld: stopping\n", |
- GET_LWP (lp->ptid)); |
+ ptid_get_lwp (lp->ptid)); |
ourstatus->kind = TARGET_WAITKIND_VFORK_DONE; |
return 0; |
@@ -2500,8 +2224,8 @@ linux_handle_extended_wait (struct lwp_info *lp, int status, |
fprintf_unfiltered (gdb_stdlog, |
"LHEW: Got PTRACE_EVENT_VFORK_DONE " |
"from LWP %ld: resuming\n", |
- GET_LWP (lp->ptid)); |
- ptrace (PTRACE_CONT, GET_LWP (lp->ptid), 0, 0); |
+ ptid_get_lwp (lp->ptid)); |
+ ptrace (PTRACE_CONT, ptid_get_lwp (lp->ptid), 0, 0); |
return 1; |
} |
@@ -2531,9 +2255,9 @@ wait_lwp (struct lwp_info *lp) |
/* If my_waitpid returns 0 it means the __WCLONE vs. non-__WCLONE kind |
was right and we should just call sigsuspend. */ |
- pid = my_waitpid (GET_LWP (lp->ptid), &status, WNOHANG); |
+ pid = my_waitpid (ptid_get_lwp (lp->ptid), &status, WNOHANG); |
if (pid == -1 && errno == ECHILD) |
- pid = my_waitpid (GET_LWP (lp->ptid), &status, __WCLONE | WNOHANG); |
+ pid = my_waitpid (ptid_get_lwp (lp->ptid), &status, __WCLONE | WNOHANG); |
if (pid == -1 && errno == ECHILD) |
{ |
/* The thread has previously exited. We need to delete it |
@@ -2564,8 +2288,8 @@ wait_lwp (struct lwp_info *lp) |
Therefore always use WNOHANG with sigsuspend - it is equivalent to |
waiting waitpid but linux_proc_pid_is_zombie is safe this way. */ |
- if (GET_PID (lp->ptid) == GET_LWP (lp->ptid) |
- && linux_proc_pid_is_zombie (GET_LWP (lp->ptid))) |
+ if (ptid_get_pid (lp->ptid) == ptid_get_lwp (lp->ptid) |
+ && linux_proc_pid_is_zombie (ptid_get_lwp (lp->ptid))) |
{ |
thread_dead = 1; |
if (debug_linux_nat) |
@@ -2589,7 +2313,7 @@ wait_lwp (struct lwp_info *lp) |
if (!thread_dead) |
{ |
- gdb_assert (pid == GET_LWP (lp->ptid)); |
+ gdb_assert (pid == ptid_get_lwp (lp->ptid)); |
if (debug_linux_nat) |
{ |
@@ -2659,7 +2383,7 @@ stop_callback (struct lwp_info *lp, void *data) |
target_pid_to_str (lp->ptid)); |
} |
errno = 0; |
- ret = kill_lwp (GET_LWP (lp->ptid), SIGSTOP); |
+ ret = kill_lwp (ptid_get_lwp (lp->ptid), SIGSTOP); |
if (debug_linux_nat) |
{ |
fprintf_unfiltered (gdb_stdlog, |
@@ -2727,7 +2451,7 @@ maybe_clear_ignore_sigint (struct lwp_info *lp) |
if (!lp->ignore_sigint) |
return; |
- if (!linux_nat_has_pending_sigint (GET_LWP (lp->ptid))) |
+ if (!linux_nat_has_pending_sigint (ptid_get_lwp (lp->ptid))) |
{ |
if (debug_linux_nat) |
fprintf_unfiltered (gdb_stdlog, |
@@ -2847,7 +2571,7 @@ linux_nat_set_status_is_event (struct target_ops *t, |
static int |
stop_wait_callback (struct lwp_info *lp, void *data) |
{ |
- struct inferior *inf = find_inferior_pid (GET_PID (lp->ptid)); |
+ struct inferior *inf = find_inferior_pid (ptid_get_pid (lp->ptid)); |
/* If this is a vfork parent, bail out, it is not going to report |
any SIGSTOP until the vfork is done with. */ |
@@ -2868,7 +2592,7 @@ stop_wait_callback (struct lwp_info *lp, void *data) |
lp->ignore_sigint = 0; |
errno = 0; |
- ptrace (PTRACE_CONT, GET_LWP (lp->ptid), 0, 0); |
+ ptrace (PTRACE_CONT, ptid_get_lwp (lp->ptid), 0, 0); |
if (debug_linux_nat) |
fprintf_unfiltered (gdb_stdlog, |
"PTRACE_CONT %s, 0, 0 (%s) " |
@@ -3156,7 +2880,7 @@ stop_and_resume_callback (struct lwp_info *lp, void *data) |
fprintf_unfiltered (gdb_stdlog, |
"SARC: core wanted LWP %ld stopped " |
"(leaving SIGSTOP pending)\n", |
- GET_LWP (lp->ptid)); |
+ ptid_get_lwp (lp->ptid)); |
lp->status = W_STOPCODE (SIGSTOP); |
} |
@@ -3165,7 +2889,7 @@ stop_and_resume_callback (struct lwp_info *lp, void *data) |
if (debug_linux_nat) |
fprintf_unfiltered (gdb_stdlog, |
"SARC: re-resuming LWP %ld\n", |
- GET_LWP (lp->ptid)); |
+ ptid_get_lwp (lp->ptid)); |
resume_lwp (lp, lp->step, GDB_SIGNAL_0); |
} |
else |
@@ -3174,7 +2898,7 @@ stop_and_resume_callback (struct lwp_info *lp, void *data) |
fprintf_unfiltered (gdb_stdlog, |
"SARC: not re-resuming LWP %ld " |
"(has pending)\n", |
- GET_LWP (lp->ptid)); |
+ ptid_get_lwp (lp->ptid)); |
if (new_pending_p) |
*new_pending_p = 1; |
} |
@@ -3219,7 +2943,7 @@ linux_nat_filter_event (int lwpid, int status, int *new_pending_p) |
"LLW: Re-adding thread group leader LWP %d.\n", |
lwpid); |
- lp = add_lwp (BUILD_LWP (lwpid, lwpid)); |
+ lp = add_lwp (ptid_build (lwpid, lwpid, 0)); |
lp->stopped = 1; |
lp->resumed = 1; |
add_thread (lp->ptid); |
@@ -3266,7 +2990,7 @@ linux_nat_filter_event (int lwpid, int status, int *new_pending_p) |
/* Check if the thread has exited. */ |
if ((WIFEXITED (status) || WIFSIGNALED (status)) |
- && num_lwps (GET_PID (lp->ptid)) > 1) |
+ && num_lwps (ptid_get_pid (lp->ptid)) > 1) |
{ |
/* If this is the main thread, we must stop all threads and verify |
if they are still alive. This is because in the nptl thread model |
@@ -3278,10 +3002,10 @@ linux_nat_filter_event (int lwpid, int status, int *new_pending_p) |
should be ignored or whether it means the end of the debugged |
application, regardless of which threading model is being |
used. */ |
- if (GET_PID (lp->ptid) == GET_LWP (lp->ptid)) |
+ if (ptid_get_pid (lp->ptid) == ptid_get_lwp (lp->ptid)) |
{ |
lp->stopped = 1; |
- iterate_over_lwps (pid_to_ptid (GET_PID (lp->ptid)), |
+ iterate_over_lwps (pid_to_ptid (ptid_get_pid (lp->ptid)), |
stop_and_resume_callback, new_pending_p); |
} |
@@ -3290,7 +3014,7 @@ linux_nat_filter_event (int lwpid, int status, int *new_pending_p) |
"LLW: %s exited.\n", |
target_pid_to_str (lp->ptid)); |
- if (num_lwps (GET_PID (lp->ptid)) > 1) |
+ if (num_lwps (ptid_get_pid (lp->ptid)) > 1) |
{ |
/* If there is at least one more LWP, then the exit signal |
was not the end of the debugged application and should be |
@@ -3304,9 +3028,9 @@ linux_nat_filter_event (int lwpid, int status, int *new_pending_p) |
thread model, LWPs other than the main thread do not issue |
signals when they exit so we must check whenever the thread has |
stopped. A similar check is made in stop_wait_callback(). */ |
- if (num_lwps (GET_PID (lp->ptid)) > 1 && !linux_thread_alive (lp->ptid)) |
+ if (num_lwps (ptid_get_pid (lp->ptid)) > 1 && !linux_thread_alive (lp->ptid)) |
{ |
- ptid_t ptid = pid_to_ptid (GET_PID (lp->ptid)); |
+ ptid_t ptid = pid_to_ptid (ptid_get_pid (lp->ptid)); |
if (debug_linux_nat) |
fprintf_unfiltered (gdb_stdlog, |
@@ -3342,8 +3066,9 @@ linux_nat_filter_event (int lwpid, int status, int *new_pending_p) |
if (linux_nat_prepare_to_resume != NULL) |
linux_nat_prepare_to_resume (lp); |
- linux_ops->to_resume (linux_ops, pid_to_ptid (GET_LWP (lp->ptid)), |
- lp->step, GDB_SIGNAL_0); |
+ linux_ops->to_resume (linux_ops, |
+ pid_to_ptid (ptid_get_lwp (lp->ptid)), |
+ lp->step, GDB_SIGNAL_0); |
if (debug_linux_nat) |
fprintf_unfiltered (gdb_stdlog, |
"LLW: %s %s, 0, 0 (discard SIGSTOP)\n", |
@@ -3375,7 +3100,7 @@ linux_nat_filter_event (int lwpid, int status, int *new_pending_p) |
registers_changed (); |
if (linux_nat_prepare_to_resume != NULL) |
linux_nat_prepare_to_resume (lp); |
- linux_ops->to_resume (linux_ops, pid_to_ptid (GET_LWP (lp->ptid)), |
+ linux_ops->to_resume (linux_ops, pid_to_ptid (ptid_get_lwp (lp->ptid)), |
lp->step, GDB_SIGNAL_0); |
if (debug_linux_nat) |
fprintf_unfiltered (gdb_stdlog, |
@@ -3482,14 +3207,14 @@ linux_nat_wait_1 (struct target_ops *ops, |
{ |
/* Upgrade the main thread's ptid. */ |
thread_change_ptid (inferior_ptid, |
- BUILD_LWP (GET_PID (inferior_ptid), |
- GET_PID (inferior_ptid))); |
+ ptid_build (ptid_get_pid (inferior_ptid), |
+ ptid_get_pid (inferior_ptid), 0)); |
- lp = add_lwp (inferior_ptid); |
+ lp = add_initial_lwp (inferior_ptid); |
lp->resumed = 1; |
} |
- /* Make sure SIGCHLD is blocked. */ |
+ /* Make sure SIGCHLD is blocked until the sigsuspend below. */ |
block_child_signals (&prev_mask); |
retry: |
@@ -3510,7 +3235,7 @@ retry: |
target_pid_to_str (lp->ptid)); |
} |
} |
- else if (is_lwp (ptid)) |
+ else if (ptid_lwp_p (ptid)) |
{ |
if (debug_linux_nat) |
fprintf_unfiltered (gdb_stdlog, |
@@ -3754,7 +3479,8 @@ retry: |
registers_changed (); |
if (linux_nat_prepare_to_resume != NULL) |
linux_nat_prepare_to_resume (lp); |
- linux_ops->to_resume (linux_ops, pid_to_ptid (GET_LWP (lp->ptid)), |
+ linux_ops->to_resume (linux_ops, |
+ pid_to_ptid (ptid_get_lwp (lp->ptid)), |
lp->step, signo); |
if (debug_linux_nat) |
fprintf_unfiltered (gdb_stdlog, |
@@ -3912,7 +3638,7 @@ resume_stopped_resumed_lwps (struct lwp_info *lp, void *data) |
registers_changed (); |
if (linux_nat_prepare_to_resume != NULL) |
linux_nat_prepare_to_resume (lp); |
- linux_ops->to_resume (linux_ops, pid_to_ptid (GET_LWP (lp->ptid)), |
+ linux_ops->to_resume (linux_ops, pid_to_ptid (ptid_get_lwp (lp->ptid)), |
lp->step, GDB_SIGNAL_0); |
lp->stopped = 0; |
lp->stopped_by_watchpoint = 0; |
@@ -3929,8 +3655,16 @@ linux_nat_wait (struct target_ops *ops, |
ptid_t event_ptid; |
if (debug_linux_nat) |
- fprintf_unfiltered (gdb_stdlog, |
- "linux_nat_wait: [%s]\n", target_pid_to_str (ptid)); |
+ { |
+ char *options_string; |
+ |
+ options_string = target_options_to_string (target_options); |
+ fprintf_unfiltered (gdb_stdlog, |
+ "linux_nat_wait: [%s], [%s]\n", |
+ target_pid_to_str (ptid), |
+ options_string); |
+ xfree (options_string); |
+ } |
/* Flush the async file first. */ |
if (target_can_async_p ()) |
@@ -3970,7 +3704,7 @@ kill_callback (struct lwp_info *lp, void *data) |
/* PTRACE_KILL may resume the inferior. Send SIGKILL first. */ |
errno = 0; |
- kill (GET_LWP (lp->ptid), SIGKILL); |
+ kill (ptid_get_lwp (lp->ptid), SIGKILL); |
if (debug_linux_nat) |
fprintf_unfiltered (gdb_stdlog, |
"KC: kill (SIGKILL) %s, 0, 0 (%s)\n", |
@@ -3980,7 +3714,7 @@ kill_callback (struct lwp_info *lp, void *data) |
/* Some kernels ignore even SIGKILL for processes under ptrace. */ |
errno = 0; |
- ptrace (PTRACE_KILL, GET_LWP (lp->ptid), 0, 0); |
+ ptrace (PTRACE_KILL, ptid_get_lwp (lp->ptid), 0, 0); |
if (debug_linux_nat) |
fprintf_unfiltered (gdb_stdlog, |
"KC: PTRACE_KILL %s, 0, 0 (%s)\n", |
@@ -4006,7 +3740,7 @@ kill_wait_callback (struct lwp_info *lp, void *data) |
{ |
do |
{ |
- pid = my_waitpid (GET_LWP (lp->ptid), NULL, __WCLONE); |
+ pid = my_waitpid (ptid_get_lwp (lp->ptid), NULL, __WCLONE); |
if (pid != (pid_t) -1) |
{ |
if (debug_linux_nat) |
@@ -4021,14 +3755,14 @@ kill_wait_callback (struct lwp_info *lp, void *data) |
kill_callback (lp, NULL); |
} |
} |
- while (pid == GET_LWP (lp->ptid)); |
+ while (pid == ptid_get_lwp (lp->ptid)); |
gdb_assert (pid == -1 && errno == ECHILD); |
} |
do |
{ |
- pid = my_waitpid (GET_LWP (lp->ptid), NULL, 0); |
+ pid = my_waitpid (ptid_get_lwp (lp->ptid), NULL, 0); |
if (pid != (pid_t) -1) |
{ |
if (debug_linux_nat) |
@@ -4039,7 +3773,7 @@ kill_wait_callback (struct lwp_info *lp, void *data) |
kill_callback (lp, NULL); |
} |
} |
- while (pid == GET_LWP (lp->ptid)); |
+ while (pid == ptid_get_lwp (lp->ptid)); |
gdb_assert (pid == -1 && errno == ECHILD); |
return 0; |
@@ -4061,8 +3795,12 @@ linux_nat_kill (struct target_ops *ops) |
if (last.kind == TARGET_WAITKIND_FORKED |
|| last.kind == TARGET_WAITKIND_VFORKED) |
{ |
- ptrace (PT_KILL, PIDGET (last.value.related_pid), 0, 0); |
+ ptrace (PT_KILL, ptid_get_pid (last.value.related_pid), 0, 0); |
wait (&status); |
+ |
+ /* Let the arch-specific native code know this process is |
+ gone. */ |
+ linux_nat_forget_process (ptid_get_pid (last.value.related_pid)); |
} |
if (forks_exist_p ()) |
@@ -4091,7 +3829,9 @@ linux_nat_kill (struct target_ops *ops) |
static void |
linux_nat_mourn_inferior (struct target_ops *ops) |
{ |
- purge_lwp_list (ptid_get_pid (inferior_ptid)); |
+ int pid = ptid_get_pid (inferior_ptid); |
+ |
+ purge_lwp_list (pid); |
if (! forks_exist_p ()) |
/* Normal case, no other forks available. */ |
@@ -4101,6 +3841,9 @@ linux_nat_mourn_inferior (struct target_ops *ops) |
there are other viable forks to debug. Delete the exiting |
one and context-switch to the first available. */ |
linux_fork_mourn_inferior (); |
+ |
+ /* Let the arch-specific native code know this process is gone. */ |
+ linux_nat_forget_process (pid); |
} |
/* Convert a native/host siginfo object, into/from the siginfo in the |
@@ -4137,9 +3880,9 @@ linux_xfer_siginfo (struct target_ops *ops, enum target_object object, |
gdb_assert (object == TARGET_OBJECT_SIGNAL_INFO); |
gdb_assert (readbuf || writebuf); |
- pid = GET_LWP (inferior_ptid); |
+ pid = ptid_get_lwp (inferior_ptid); |
if (pid == 0) |
- pid = GET_PID (inferior_ptid); |
+ pid = ptid_get_pid (inferior_ptid); |
if (offset > sizeof (siginfo)) |
return -1; |
@@ -4199,8 +3942,8 @@ linux_nat_xfer_partial (struct target_ops *ops, enum target_object object, |
old_chain = save_inferior_ptid (); |
- if (is_lwp (inferior_ptid)) |
- inferior_ptid = pid_to_ptid (GET_LWP (inferior_ptid)); |
+ if (ptid_lwp_p (inferior_ptid)) |
+ inferior_ptid = pid_to_ptid (ptid_get_lwp (inferior_ptid)); |
xfer = linux_ops->to_xfer_partial (ops, object, annex, readbuf, writebuf, |
offset, len); |
@@ -4214,12 +3957,12 @@ linux_thread_alive (ptid_t ptid) |
{ |
int err, tmp_errno; |
- gdb_assert (is_lwp (ptid)); |
+ gdb_assert (ptid_lwp_p (ptid)); |
/* Send signal 0 instead of anything ptrace, because ptracing a |
running thread errors out claiming that the thread doesn't |
exist. */ |
- err = kill_lwp (GET_LWP (ptid), 0); |
+ err = kill_lwp (ptid_get_lwp (ptid), 0); |
tmp_errno = errno; |
if (debug_linux_nat) |
fprintf_unfiltered (gdb_stdlog, |
@@ -4244,11 +3987,11 @@ linux_nat_pid_to_str (struct target_ops *ops, ptid_t ptid) |
{ |
static char buf[64]; |
- if (is_lwp (ptid) |
- && (GET_PID (ptid) != GET_LWP (ptid) |
- || num_lwps (GET_PID (ptid)) > 1)) |
+ if (ptid_lwp_p (ptid) |
+ && (ptid_get_pid (ptid) != ptid_get_lwp (ptid) |
+ || num_lwps (ptid_get_pid (ptid)) > 1)) |
{ |
- snprintf (buf, sizeof (buf), "LWP %ld", GET_LWP (ptid)); |
+ snprintf (buf, sizeof (buf), "LWP %ld", ptid_get_lwp (ptid)); |
return buf; |
} |
@@ -4266,7 +4009,7 @@ linux_nat_thread_name (struct thread_info *thr) |
char *result = NULL; |
snprintf (buf, sizeof (buf), FORMAT, pid, lwp); |
- comm_file = fopen (buf, "r"); |
+ comm_file = gdb_fopen_cloexec (buf, "r"); |
if (comm_file) |
{ |
/* Not exported by the kernel, so we define it here. */ |
@@ -4300,14 +4043,14 @@ linux_child_pid_to_exec_file (int pid) |
{ |
char *name1, *name2; |
- name1 = xmalloc (MAXPATHLEN); |
- name2 = xmalloc (MAXPATHLEN); |
+ name1 = xmalloc (PATH_MAX); |
+ name2 = xmalloc (PATH_MAX); |
make_cleanup (xfree, name1); |
make_cleanup (xfree, name2); |
- memset (name2, 0, MAXPATHLEN); |
+ memset (name2, 0, PATH_MAX); |
sprintf (name1, "/proc/%d/exe", pid); |
- if (readlink (name1, name2, MAXPATHLEN) > 0) |
+ if (readlink (name1, name2, PATH_MAX - 1) > 0) |
return name2; |
else |
return name1; |
@@ -4364,7 +4107,7 @@ linux_nat_make_corefile_notes (bfd *obfd, int *note_size) |
{ |
/* FIXME: uweigand/2011-10-06: Once all GNU/Linux architectures have been |
converted to gdbarch_core_regset_sections, this function can go away. */ |
- return linux_make_corefile_notes (target_gdbarch, obfd, note_size, |
+ return linux_make_corefile_notes (target_gdbarch (), obfd, note_size, |
linux_nat_collect_thread_registers); |
} |
@@ -4392,8 +4135,8 @@ linux_proc_xfer_partial (struct target_ops *ops, enum target_object object, |
/* We could keep this file open and cache it - possibly one per |
thread. That requires some juggling, but is even faster. */ |
- sprintf (filename, "/proc/%d/mem", PIDGET (inferior_ptid)); |
- fd = open (filename, O_RDONLY | O_LARGEFILE); |
+ sprintf (filename, "/proc/%d/mem", ptid_get_pid (inferior_ptid)); |
+ fd = gdb_open_cloexec (filename, O_RDONLY | O_LARGEFILE, 0); |
if (fd == -1) |
return 0; |
@@ -4419,7 +4162,7 @@ linux_proc_xfer_partial (struct target_ops *ops, enum target_object object, |
static LONGEST |
spu_enumerate_spu_ids (int pid, gdb_byte *buf, ULONGEST offset, LONGEST len) |
{ |
- enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch); |
+ enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ()); |
LONGEST pos = 0; |
LONGEST written = 0; |
char path[128]; |
@@ -4476,7 +4219,7 @@ linux_proc_xfer_spu (struct target_ops *ops, enum target_object object, |
char buf[128]; |
int fd = 0; |
int ret = -1; |
- int pid = PIDGET (inferior_ptid); |
+ int pid = ptid_get_pid (inferior_ptid); |
if (!annex) |
{ |
@@ -4487,7 +4230,7 @@ linux_proc_xfer_spu (struct target_ops *ops, enum target_object object, |
} |
xsnprintf (buf, sizeof buf, "/proc/%d/fd/%s", pid, annex); |
- fd = open (buf, writebuf? O_WRONLY : O_RDONLY); |
+ fd = gdb_open_cloexec (buf, writebuf? O_WRONLY : O_RDONLY, 0); |
if (fd <= 0) |
return -1; |
@@ -4556,19 +4299,19 @@ linux_proc_pending_signals (int pid, sigset_t *pending, |
sigset_t *blocked, sigset_t *ignored) |
{ |
FILE *procfile; |
- char buffer[MAXPATHLEN], fname[MAXPATHLEN]; |
+ char buffer[PATH_MAX], fname[PATH_MAX]; |
struct cleanup *cleanup; |
sigemptyset (pending); |
sigemptyset (blocked); |
sigemptyset (ignored); |
sprintf (fname, "/proc/%d/status", pid); |
- procfile = fopen (fname, "r"); |
+ procfile = gdb_fopen_cloexec (fname, "r"); |
if (procfile == NULL) |
error (_("Could not open %s"), fname); |
cleanup = make_cleanup_fclose (procfile); |
- while (fgets (buffer, MAXPATHLEN, procfile) != NULL) |
+ while (fgets (buffer, PATH_MAX, procfile) != NULL) |
{ |
/* Normal queued signals are on the SigPnd line in the status |
file. However, 2.6 kernels also have a "shared" pending |
@@ -4628,7 +4371,7 @@ linux_xfer_partial (struct target_ops *ops, enum target_object object, |
if (object == TARGET_OBJECT_MEMORY) |
{ |
- int addr_bit = gdbarch_addr_bit (target_gdbarch); |
+ int addr_bit = gdbarch_addr_bit (target_gdbarch ()); |
if (addr_bit < (sizeof (ULONGEST) * HOST_CHAR_BIT)) |
offset &= ((ULONGEST) 1 << addr_bit) - 1; |
@@ -4902,11 +4645,13 @@ linux_async_pipe (int enable) |
{ |
sigset_t prev_mask; |
+ /* Block child signals while we create/destroy the pipe, as |
+ their handler writes to it. */ |
block_child_signals (&prev_mask); |
if (enable) |
{ |
- if (pipe (linux_nat_event_pipe) == -1) |
+ if (gdb_pipe_cloexec (linux_nat_event_pipe) == -1) |
internal_error (__FILE__, __LINE__, |
"creating event pipe failed."); |
@@ -4964,8 +4709,6 @@ linux_nat_stop_lwp (struct lwp_info *lwp, void *data) |
{ |
if (!lwp->stopped) |
{ |
- ptid_t ptid = lwp->ptid; |
- |
if (debug_linux_nat) |
fprintf_unfiltered (gdb_stdlog, |
"LNSL: running -> suspending %s\n", |
@@ -5015,14 +4758,14 @@ linux_nat_stop (ptid_t ptid) |
} |
static void |
-linux_nat_close (int quitting) |
+linux_nat_close (void) |
{ |
/* Unregister from the event loop. */ |
if (linux_nat_is_async_p ()) |
linux_nat_async (NULL, 0); |
if (linux_ops->to_close) |
- linux_ops->to_close (quitting); |
+ linux_ops->to_close (); |
} |
/* When requests are passed down from the linux-nat layer to the |
@@ -5039,18 +4782,18 @@ linux_nat_thread_address_space (struct target_ops *t, ptid_t ptid) |
struct inferior *inf; |
int pid; |
- pid = GET_LWP (ptid); |
- if (GET_LWP (ptid) == 0) |
+ pid = ptid_get_lwp (ptid); |
+ if (ptid_get_lwp (ptid) == 0) |
{ |
/* An (lwpid,0,0) ptid. Look up the lwp object to get at the |
tgid. */ |
lwp = find_lwp_pid (ptid); |
- pid = GET_PID (lwp->ptid); |
+ pid = ptid_get_pid (lwp->ptid); |
} |
else |
{ |
/* A (pid,lwpid,0) ptid. */ |
- pid = GET_PID (ptid); |
+ pid = ptid_get_pid (ptid); |
} |
inf = find_inferior_pid (pid); |
@@ -5136,6 +4879,35 @@ linux_nat_set_new_thread (struct target_ops *t, |
linux_nat_new_thread = new_thread; |
} |
+/* See declaration in linux-nat.h. */ |
+ |
+void |
+linux_nat_set_new_fork (struct target_ops *t, |
+ linux_nat_new_fork_ftype *new_fork) |
+{ |
+ /* Save the pointer. */ |
+ linux_nat_new_fork = new_fork; |
+} |
+ |
+/* See declaration in linux-nat.h. */ |
+ |
+void |
+linux_nat_set_forget_process (struct target_ops *t, |
+ linux_nat_forget_process_ftype *fn) |
+{ |
+ /* Save the pointer. */ |
+ linux_nat_forget_process_hook = fn; |
+} |
+ |
+/* See declaration in linux-nat.h. */ |
+ |
+void |
+linux_nat_forget_process (pid_t pid) |
+{ |
+ if (linux_nat_forget_process_hook != NULL) |
+ linux_nat_forget_process_hook (pid); |
+} |
+ |
/* Register a method that converts a siginfo object between the layout |
that ptrace returns, and the layout in the architecture of the |
inferior. */ |
@@ -5166,9 +4938,9 @@ linux_nat_get_siginfo (ptid_t ptid, siginfo_t *siginfo) |
{ |
int pid; |
- pid = GET_LWP (ptid); |
+ pid = ptid_get_lwp (ptid); |
if (pid == 0) |
- pid = GET_PID (ptid); |
+ pid = ptid_get_pid (ptid); |
errno = 0; |
ptrace (PTRACE_GETSIGINFO, pid, (PTRACE_TYPE_ARG3) 0, siginfo); |
@@ -5186,14 +4958,14 @@ extern initialize_file_ftype _initialize_linux_nat; |
void |
_initialize_linux_nat (void) |
{ |
- add_setshow_zinteger_cmd ("lin-lwp", class_maintenance, |
- &debug_linux_nat, _("\ |
+ add_setshow_zuinteger_cmd ("lin-lwp", class_maintenance, |
+ &debug_linux_nat, _("\ |
Set debugging of GNU/Linux lwp module."), _("\ |
Show debugging of GNU/Linux lwp module."), _("\ |
Enables printf debugging output."), |
- NULL, |
- show_debug_linux_nat, |
- &setdebuglist, &showdebuglist); |
+ NULL, |
+ show_debug_linux_nat, |
+ &setdebuglist, &showdebuglist); |
/* Save this mask as the default. */ |
sigprocmask (SIG_SETMASK, NULL, &normal_mask); |