diff options
Diffstat (limited to 'gdb/nat')
-rw-r--r-- | gdb/nat/linux-ptrace.c | 186 | ||||
-rw-r--r-- | gdb/nat/linux-ptrace.h | 5 |
2 files changed, 9 insertions, 182 deletions
diff --git a/gdb/nat/linux-ptrace.c b/gdb/nat/linux-ptrace.c index 7258f4a..5b3086e 100644 --- a/gdb/nat/linux-ptrace.c +++ b/gdb/nat/linux-ptrace.c @@ -301,20 +301,6 @@ linux_fork_to_function (gdb_byte *child_stack, int (*function) (void *)) } /* A helper function for linux_check_ptrace_features, called after - the child forks a grandchild. */ - -static int -linux_grandchild_function (void *child_stack) -{ - /* Free any allocated stack. */ - xfree (child_stack); - - /* This code is only reacheable by the grandchild (child's child) - process. */ - _exit (0); -} - -/* A helper function for linux_check_ptrace_features, called after the parent process forks a child. The child allows itself to be traced by its parent. */ @@ -324,16 +310,11 @@ linux_child_function (void *child_stack) ptrace (PTRACE_TRACEME, 0, (PTRACE_TYPE_ARG3) 0, (PTRACE_TYPE_ARG4) 0); kill (getpid (), SIGSTOP); - /* Fork a grandchild. */ - linux_fork_to_function ((gdb_byte *) child_stack, linux_grandchild_function); - /* This code is only reacheable by the child (grandchild's parent) process. */ _exit (0); } -static void linux_test_for_tracesysgood (int child_pid); -static void linux_test_for_tracefork (int child_pid); static void linux_test_for_exitkill (int child_pid); /* Determine ptrace features available on this target. */ @@ -343,8 +324,15 @@ linux_check_ptrace_features (void) { int child_pid, ret, status; - /* Initialize the options. */ - supported_ptrace_options = 0; + /* Initialize the options. We consider that these options are always + supported. */ + supported_ptrace_options + = (PTRACE_O_TRACESYSGOOD + | PTRACE_O_TRACECLONE + | PTRACE_O_TRACEFORK + | PTRACE_O_TRACEVFORK + | PTRACE_O_TRACEVFORKDONE + | PTRACE_O_TRACEEXEC); /* Fork a child so we can do some testing. The child will call linux_child_function and will get traced. The child will @@ -362,104 +350,12 @@ linux_check_ptrace_features (void) error (_("linux_check_ptrace_features: waitpid: unexpected status %d."), status); - linux_test_for_tracesysgood (child_pid); - - linux_test_for_tracefork (child_pid); - linux_test_for_exitkill (child_pid); /* Kill child_pid. */ kill_child (child_pid, "linux_check_ptrace_features"); } -/* Determine if PTRACE_O_TRACESYSGOOD can be used to catch - syscalls. */ - -static void -linux_test_for_tracesysgood (int child_pid) -{ - int ret; - - ret = ptrace (PTRACE_SETOPTIONS, child_pid, (PTRACE_TYPE_ARG3) 0, - (PTRACE_TYPE_ARG4) PTRACE_O_TRACESYSGOOD); - - if (ret == 0) - supported_ptrace_options |= PTRACE_O_TRACESYSGOOD; -} - -/* Determine if PTRACE_O_TRACEFORK can be used to follow fork - events. */ - -static void -linux_test_for_tracefork (int child_pid) -{ - int ret, status; - long second_pid; - - /* First, set the PTRACE_O_TRACEFORK option. If this fails, we - know for sure that it is not supported. */ - ret = ptrace (PTRACE_SETOPTIONS, child_pid, (PTRACE_TYPE_ARG3) 0, - (PTRACE_TYPE_ARG4) PTRACE_O_TRACEFORK); - - if (ret != 0) - return; - - /* Check if the target supports PTRACE_O_TRACEVFORKDONE. */ - ret = ptrace (PTRACE_SETOPTIONS, child_pid, (PTRACE_TYPE_ARG3) 0, - (PTRACE_TYPE_ARG4) (PTRACE_O_TRACEFORK - | PTRACE_O_TRACEVFORKDONE)); - if (ret == 0) - supported_ptrace_options |= PTRACE_O_TRACEVFORKDONE; - - /* Setting PTRACE_O_TRACEFORK did not cause an error, however we - don't know for sure that the feature is available; old - versions of PTRACE_SETOPTIONS ignored unknown options. - Therefore, we attach to the child process, use PTRACE_SETOPTIONS - to enable fork tracing, and let it fork. If the process exits, - we assume that we can't use PTRACE_O_TRACEFORK; if we get the - fork notification, and we can extract the new child's PID, then - we assume that we can. - - We do not explicitly check for vfork tracing here. It is - assumed that vfork tracing is available whenever fork tracing - is available. */ - ret = ptrace (PTRACE_CONT, child_pid, (PTRACE_TYPE_ARG3) 0, - (PTRACE_TYPE_ARG4) 0); - if (ret != 0) - warning (_("linux_test_for_tracefork: failed to resume child")); - - ret = my_waitpid (child_pid, &status, 0); - - /* Check if we received a fork event notification. */ - if (ret == child_pid && WIFSTOPPED (status) - && linux_ptrace_get_extended_event (status) == PTRACE_EVENT_FORK) - { - /* We did receive a fork event notification. Make sure its PID - is reported. */ - second_pid = 0; - ret = ptrace (PTRACE_GETEVENTMSG, child_pid, (PTRACE_TYPE_ARG3) 0, - (PTRACE_TYPE_ARG4) &second_pid); - if (ret == 0 && second_pid != 0) - { - int second_status; - - /* We got the PID from the grandchild, which means fork - tracing is supported. */ - supported_ptrace_options |= PTRACE_O_TRACECLONE; - supported_ptrace_options |= (PTRACE_O_TRACEFORK - | PTRACE_O_TRACEVFORK - | PTRACE_O_TRACEEXEC); - - /* Do some cleanup and kill the grandchild. */ - my_waitpid (second_pid, &second_status, 0); - kill_child (second_pid, "linux_test_for_tracefork"); - } - } - else - warning (_("linux_test_for_tracefork: unexpected result from waitpid " - "(%d, status 0x%x)"), ret, status); -} - /* Determine if PTRACE_O_EXITKILL can be used. */ static void @@ -507,70 +403,6 @@ linux_disable_event_reporting (pid_t pid) ptrace (PTRACE_SETOPTIONS, pid, (PTRACE_TYPE_ARG3) 0, 0); } -/* Returns non-zero if PTRACE_OPTIONS is contained within - SUPPORTED_PTRACE_OPTIONS, therefore supported. Returns 0 - otherwise. */ - -static int -ptrace_supports_feature (int ptrace_options) -{ - if (supported_ptrace_options == -1) - linux_check_ptrace_features (); - - return ((supported_ptrace_options & ptrace_options) == ptrace_options); -} - -/* Returns non-zero if PTRACE_EVENT_FORK is supported by ptrace, - 0 otherwise. Note that if PTRACE_EVENT_FORK is supported so is - PTRACE_EVENT_CLONE, PTRACE_EVENT_EXEC and PTRACE_EVENT_VFORK, - since they were all added to the kernel at the same time. */ - -int -linux_supports_tracefork (void) -{ - return ptrace_supports_feature (PTRACE_O_TRACEFORK); -} - -/* Returns non-zero if PTRACE_EVENT_EXEC is supported by ptrace, - 0 otherwise. Note that if PTRACE_EVENT_FORK is supported so is - PTRACE_EVENT_CLONE, PTRACE_EVENT_FORK and PTRACE_EVENT_VFORK, - since they were all added to the kernel at the same time. */ - -int -linux_supports_traceexec (void) -{ - return ptrace_supports_feature (PTRACE_O_TRACEEXEC); -} - -/* Returns non-zero if PTRACE_EVENT_CLONE is supported by ptrace, - 0 otherwise. Note that if PTRACE_EVENT_CLONE is supported so is - PTRACE_EVENT_FORK, PTRACE_EVENT_EXEC and PTRACE_EVENT_VFORK, - since they were all added to the kernel at the same time. */ - -int -linux_supports_traceclone (void) -{ - return ptrace_supports_feature (PTRACE_O_TRACECLONE); -} - -/* Returns non-zero if PTRACE_O_TRACEVFORKDONE is supported by - ptrace, 0 otherwise. */ - -int -linux_supports_tracevforkdone (void) -{ - return ptrace_supports_feature (PTRACE_O_TRACEVFORKDONE); -} - -/* Returns non-zero if PTRACE_O_TRACESYSGOOD is supported by ptrace, - 0 otherwise. */ - -int -linux_supports_tracesysgood (void) -{ - return ptrace_supports_feature (PTRACE_O_TRACESYSGOOD); -} - /* Display possible problems on this system. Display them only once per GDB execution. */ diff --git a/gdb/nat/linux-ptrace.h b/gdb/nat/linux-ptrace.h index 2ac59a7..4694046 100644 --- a/gdb/nat/linux-ptrace.h +++ b/gdb/nat/linux-ptrace.h @@ -187,11 +187,6 @@ extern void linux_ptrace_init_warnings (void); extern void linux_check_ptrace_features (void); extern void linux_enable_event_reporting (pid_t pid, int attached); extern void linux_disable_event_reporting (pid_t pid); -extern int linux_supports_tracefork (void); -extern int linux_supports_traceexec (void); -extern int linux_supports_traceclone (void); -extern int linux_supports_tracevforkdone (void); -extern int linux_supports_tracesysgood (void); extern int linux_ptrace_get_extended_event (int wstat); extern int linux_is_extended_waitstatus (int wstat); extern int linux_wstatus_maybe_breakpoint (int wstat); |