This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
Other format: | [Raw text] |
This patch implements support for exec events in gdbserver on linux, in multiprocess mode (target extended-remote). Follow-exec-mode and rerun behave as expected. Catchpoints for exec are not yet implemented since it will be easier to implement catchpoints for fork, vfork, and exec all at the same time. TESTING --------- The patch was tested on GNU/Linux x86_64 with --target_board set to native-gdbserver and native-extended-gdbserver, as well as testing native GDB. The test results for native-gdbserver were unchanged. Thirteen tests that used to fail for native-extended-gdbserver on Linux pass with this patch, and the non-ldr-exc-*.exp tests all pass in non-stop mode and extended-remote. There are several failures in the new non-ldr-exc-*.exp tests in non-stop mode with native GDB. One caveat: when an exec is detected, gdbserver emits a couple of warnings: gdbserver: unexpected r_debug version 0 gdbserver: unexpected r_debug version 0 However, debugging of shared libraries that are loaded by the exec'd program works just fine. These messages may be caused by gdbserver making an attempt to initialize the solib hook before the r_debug structure has been initialized. I intend to follow up in a subsequent patch. IMPLEMENTATION ---------------- Support for exec events in single-threaded programs was a fairly straightforward replication of the implementation in native GDB: 1) Enable exec events via ptrace options. 2) Add support for handling the exec events to the handle_extended_wait and linux_wait_for_event_filtered. Detect the exec event, then find and save the pathname of the executable file being exec'd. 3) Implement an additional "stop reason", "exec", in the RSP stop reply packet "T". Existing GDB code takes care of handling the exec event on the host side without modification. Support for exec events in multi-threaded programs required some additional work that required a couple of significant changes to existing code. In a nutshell, the changes are to: 4) Use the PTRACE_EVENT_EXIT extended event to handle thread exit, while not exposing any change in exit handling to the user. The rationale for this is discussed in the "patch 0" email of this series. 5) Recognize when the exec'ing thread has vanished (become the thread group leader) in send_sigstop. Native GDB does this differently. Regarding items 4 & 5: Recall that when a non-leader thread exec's, all the other threads are terminated and the exec'ing thread changes its thread id to that of the old leader (the process id) as part of the exec. There is no event reported for the "exit" of the exec'ing thread; it appears to have vanished. The original thread group leader can't be reaped until all the other threads have been reaped, and some way of determining that it has exited is required in order to update the lwp list (#4 above). Also, some mechanism for deleting the lwp entry corresponding to the exec'ing thread is needed (#5 above). The rationale for #4 is that in my testing I ran into a race condition in the mechanism that's intended to detect when a thread group leader has exited, check_zombie_leaders. The race occurred when there were only two threads in the program. In this case the leader thread passes through a very brief zombie state before being replaced by the exec'ing thread as the thread group leader. This state transition is asynchronous, with no dependency on anything gdbserver does. Using PTRACE_EVENT_EXIT ensures that the leader exit will be detected. I can provide a more detailed explanation or the race, but I didn't want to be too long-winded here. Regarding item #5, determining that the exec'ing thread has "vanished", In native GDB this is done by calling waitpid(PID), and if it returns ECHILD it means that the thread is gone. We don't want to use waitpid(PID) in gdbserver, based on the discussion in https://www.sourceware.org/ml/gdb-patches/2014-02/msg00828.html. An alternative is to send a signal to each thread and look for an ESRCH (No such process) error. In all-stop mode this can be done in the normal course of events, since when gdbserver reports an exec event it stops all the other threads with a SIGSTOP. In non-stop mode, when an exec event has been detected, we can call stop_all_lwps/unstop_all_lwps to accomplish the same thing. gdb/ 2014-04-02 Don Breazeal <donb@codesourcery.com> * common/linux-ptrace.c (linux_test_for_tracefork) [GDBSERVER]: Add exec tracing to ptrace options if OS supports it. * remote.c (remote_parse_stop_reply): Support new RSP stop reply reason 'exec'. gdbserver/ 2014-04-02 Don Breazeal <donb@codesourcery.com> * gdb/gdbserver/linux-low.c (linux_child_pid_to_exec_file): New function. (handle_extended_wait): Add support for PTRACE_EVENT_EXEC. (check_zombie_leaders): Update comment. (linux_low_filter_event): Add support for PTRACE_EVENT_EXEC. (linux_wait_for_event_filtered): Update comment. (extended_event_reported): New function. (send_sigstop): Delete lwp on 'No such process' error and reset current_inferior. * gdb/gdbserver/linux-low.h (struct lwp_info): New member 'waitstatus'. * gdb/gdbserver/remote-utils.c (prepare_resume_reply): Support new RSP stop reply reason 'exec'.
Attachment:
0002-remote-exec.patch
Description: 0002-remote-exec.patch
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |