From patchwork Thu Jan 23 16:59:38 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Marchi X-Patchwork-Id: 37514 Received: (qmail 23934 invoked by alias); 23 Jan 2020 16:59:50 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 23922 invoked by uid 89); 23 Jan 2020 16:59:50 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-23.3 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, SPF_PASS autolearn=ham version=3.3.1 spammy=inferior_ptid, darwin-nat.c, darwinnatc, UD:darwin-nat.c X-HELO: mail.efficios.com Received: from mail.efficios.com (HELO mail.efficios.com) (167.114.26.124) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 23 Jan 2020 16:59:46 +0000 Received: from localhost (localhost [127.0.0.1]) by mail.efficios.com (Postfix) with ESMTP id DF266242495 for ; Thu, 23 Jan 2020 11:59:44 -0500 (EST) Received: from mail.efficios.com ([127.0.0.1]) by localhost (mail03.efficios.com [127.0.0.1]) (amavisd-new, port 10032) with ESMTP id WIhQLiiWZtB0; Thu, 23 Jan 2020 11:59:44 -0500 (EST) Received: from localhost (localhost [127.0.0.1]) by mail.efficios.com (Postfix) with ESMTP id 1BC9024203B; Thu, 23 Jan 2020 11:59:44 -0500 (EST) DKIM-Filter: OpenDKIM Filter v2.10.3 mail.efficios.com 1BC9024203B DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=efficios.com; s=default; t=1579798784; bh=T/v7/Gpb5L2q2oCBOWwMDgOTJSo7Yy0UVmjaXEHnAps=; h=From:To:Date:Message-Id:MIME-Version; b=gruAZbv0wtxgnwjdHjKriHgguqrRbFJBZ5Dy+O+PqCCJAB5vxdo+HeGkk33aV8HKP OAjyM/31uB3ncandmJ2PQewW3PDmLYN9EWV/NmwXKMK14cyqzz4HBx9tbeCW0eR9yU lRJ3VxrN671dIJ4N7hVf7qLZVN5cKTx0OfycfPWBCU2j33pkP1hRaXxTm3xbNLaHcb det6+9sh+ZWLsXFDK5AtPXmdeekE0qUMqU1hIvSxSnGnOba6dJ81nQxFtmjymPn13c yAoH0iWT2bFnb6paetPhZfdSzSP7aaf/eXPPsdqHS55SSRoj6aqJy/YVOomCPQnkvq zSHCvap7RhSMg== Received: from mail.efficios.com ([127.0.0.1]) by localhost (mail03.efficios.com [127.0.0.1]) (amavisd-new, port 10026) with ESMTP id o239-pInOobM; Thu, 23 Jan 2020 11:59:44 -0500 (EST) Received: from smarchi-efficios.internal.efficios.com (192-222-181-218.qc.cable.ebox.net [192.222.181.218]) by mail.efficios.com (Postfix) with ESMTPSA id F05C924203A; Thu, 23 Jan 2020 11:59:43 -0500 (EST) From: Simon Marchi To: gdb-patches@sourceware.org Cc: Simon Marchi Subject: [PATCH] gdb: fix darwin-nat.c build / adapt to multi-target Date: Thu, 23 Jan 2020 11:59:38 -0500 Message-Id: <20200123165938.32116-1-simon.marchi@efficios.com> MIME-Version: 1.0 From: Simon Marchi The darwin-nat.c file doesn't build since the multi-target changes (5b6d1e4f, "Multi-target support"). This patch makes it build. I have access to a macOS vm, so I am able to build it, but I wasn't able to successfully codesign it and try to actually debug something, so I don't know if it works. I don't have much more time to put on this to figure it out, so I thought I'd sent the patch anyway, as it's at least a step in the right direction. The bulk of the patch is to change a bunch of functions to be methods of the darwin_nat_target object, so that this can pass `this` to find_inferior_ptid and other functions that now require a process_stratum_target pointer. The darwin_ptrace_him function (renamed to darwin_nat_target::ptrace_him in this patch) is passed to fork_inferior as the `init_trace_fun` parameter. Since the method can't be passed as a plain function pointer (we need the `this` pointer), I changed the `init_trace_fun` parameter of fork_inferior to be a gdb::function_view, so we can pass a lambda and capture `this`. The changes in darwin-nat.h are only to move definition higher in the file, so that forward declarations are not needed. gdb/ChangeLog: * darwin-nat.h (struct darwin_exception_msg, enum darwin_msg_state, struct darwin_thread_info, darwin_thread_t): Move up. (class darwin_nat_target) : Declare. * darwin-nat.c (darwin_check_new_threads): Rename to... (darwin_nat_target::check_new_threads): ... this. (darwin_suspend_inferior_it): Remove. (darwin_decode_exception_message): Rename to... (darwin_nat_target::decode_exception_message): ... this. (darwin_nat_target::resume): Pass target to find_inferior_ptid. (darwin_decode_message): Rename to... (darwin_nat_target::decode_message): ... this. (cancel_breakpoint): Rename to... (darwin_nat_target::cancel_breakpoint): ... this. (darwin_wait): Rename to... (darwin_nat_target::wait_1): ... this. Use range-based for loop instead of iterate_over_inferiors. (darwin_nat_target::wait): Call wait_1 instead of darwin_wait. (darwin_stop_inferior): Rename to... (darwin_nat_target::stop_inferior): ... this. (darwin_nat_target::kill): Call wait_1 instead of darwin_wait. (darwin_init_thread_list): Rename to... (darwin_nat_target::init_thread_list): ... this. (darwin_ptrace_him): Rename to... (darwin_nat_target::ptrace_him): ... this. (darwin_nat_target::create_inferior): Pass lambda function to fork_inferior. (darwin_nat_target::detach): Call stop_inferior instead of darwin_stop_inferior. * fork-inferior.h (fork_inferior): Change init_trace_fun parameter to gdb::function_view. * fork-inferior.c (fork_inferior): Likewise. --- gdb/darwin-nat.c | 103 +++++++++++++++++----------------- gdb/darwin-nat.h | 121 ++++++++++++++++++++++------------------ gdb/nat/fork-inferior.c | 5 +- gdb/nat/fork-inferior.h | 3 +- 4 files changed, 123 insertions(+), 109 deletions(-) diff --git a/gdb/darwin-nat.c b/gdb/darwin-nat.c index 9baa1e91d539..27677d16eae1 100644 --- a/gdb/darwin-nat.c +++ b/gdb/darwin-nat.c @@ -89,12 +89,8 @@ #define PTRACE(CMD, PID, ADDR, SIG) \ darwin_ptrace(#CMD, CMD, (PID), (ADDR), (SIG)) -static ptid_t darwin_wait (ptid_t ptid, struct target_waitstatus *status); - static void darwin_ptrace_me (void); -static void darwin_ptrace_him (int pid); - static void darwin_encode_reply (mig_reply_error_t *reply, mach_msg_header_t *hdr, integer_t code); @@ -258,8 +254,8 @@ cmp_thread_t (const void *l, const void *r) return (int)(tl - tr); } -static void -darwin_check_new_threads (struct inferior *inf) +void +darwin_nat_target::check_new_threads (inferior *inf) { kern_return_t kret; thread_array_t thread_list; @@ -355,7 +351,7 @@ darwin_check_new_threads (struct inferior *inf) pti->msg_state = DARWIN_RUNNING; /* Add the new thread. */ - add_thread_with_info (ptid_t (inf->pid, 0, new_id), pti); + add_thread_with_info (this, ptid_t (inf->pid, 0, new_id), pti); new_thread_vec.push_back (pti); new_ix++; continue; @@ -364,7 +360,7 @@ darwin_check_new_threads (struct inferior *inf) { /* A thread was removed. */ struct thread_info *thr - = find_thread_ptid (ptid_t (inf->pid, 0, old_id)); + = find_thread_ptid (this, ptid_t (inf->pid, 0, old_id)); delete_thread (thr); kret = mach_port_deallocate (gdb_task, old_id); MACH_CHECK_ERROR (kret); @@ -464,14 +460,6 @@ darwin_resume_inferior (struct inferior *inf) /* Iterator functions. */ -static int -darwin_suspend_inferior_it (struct inferior *inf, void *arg) -{ - darwin_suspend_inferior (inf); - darwin_check_new_threads (inf); - return 0; -} - static int darwin_resume_inferior_it (struct inferior *inf, void *arg) { @@ -611,10 +599,10 @@ darwin_check_message_ndr (NDR_record_t *ndr) /* Decode an exception message. */ -static int -darwin_decode_exception_message (mach_msg_header_t *hdr, - struct inferior **pinf, - darwin_thread_t **pthread) +int +darwin_nat_target::decode_exception_message (mach_msg_header_t *hdr, + inferior **pinf, + darwin_thread_t **pthread) { mach_msg_body_t *bod = (mach_msg_body_t*)(hdr + 1); mach_msg_port_descriptor_t *desc = (mach_msg_port_descriptor_t *)(bod + 1); @@ -712,7 +700,7 @@ darwin_decode_exception_message (mach_msg_header_t *hdr, /* Find thread by port. */ /* Check for new threads. Do it early so that the port in the exception message can be deallocated. */ - darwin_check_new_threads (inf); + check_new_threads (inf); /* Free the thread port (as gdb knows the thread, it has already has a right for it, so this just decrement a reference counter). */ @@ -975,7 +963,7 @@ darwin_nat_target::resume (ptid_t ptid, int step, enum gdb_signal signal) } else { - struct inferior *inf = find_inferior_ptid (ptid); + inferior *inf = find_inferior_ptid (this, ptid); long tid = ptid.tid (); /* Stop the inferior (should be useless). */ @@ -1001,11 +989,11 @@ darwin_nat_target::resume (ptid_t ptid, int step, enum gdb_signal signal) } } -static ptid_t -darwin_decode_message (mach_msg_header_t *hdr, - darwin_thread_t **pthread, - struct inferior **pinf, - struct target_waitstatus *status) +ptid_t +darwin_nat_target::decode_message (mach_msg_header_t *hdr, + darwin_thread_t **pthread, + inferior **pinf, + target_waitstatus *status) { darwin_thread_t *thread; struct inferior *inf; @@ -1016,7 +1004,7 @@ darwin_decode_message (mach_msg_header_t *hdr, int res; /* Decode message. */ - res = darwin_decode_exception_message (hdr, &inf, &thread); + res = decode_exception_message (hdr, &inf, &thread); if (res < 0) { @@ -1172,8 +1160,8 @@ darwin_decode_message (mach_msg_header_t *hdr, return minus_one_ptid; } -static int -cancel_breakpoint (ptid_t ptid) +int +darwin_nat_target::cancel_breakpoint (ptid_t ptid) { /* Arrange for a breakpoint to be hit again later. We will handle the current event, eventually we will resume this thread, and this @@ -1183,7 +1171,7 @@ cancel_breakpoint (ptid_t ptid) delete or disable the breakpoint, but the thread will have already tripped on it. */ - struct regcache *regcache = get_thread_regcache (ptid); + struct regcache *regcache = get_thread_regcache (this, ptid); struct gdbarch *gdbarch = regcache->arch (); CORE_ADDR pc; @@ -1202,8 +1190,8 @@ cancel_breakpoint (ptid_t ptid) return 0; } -static ptid_t -darwin_wait (ptid_t ptid, struct target_waitstatus *status) +ptid_t +darwin_nat_target::wait_1 (ptid_t ptid, struct target_waitstatus *status) { kern_return_t kret; union @@ -1262,7 +1250,7 @@ darwin_wait (ptid_t ptid, struct target_waitstatus *status) if (darwin_debug_flag > 10) darwin_dump_message (hdr, darwin_debug_flag > 11); - res = darwin_decode_message (hdr, &thread, &inf, status); + res = decode_message (hdr, &thread, &inf, status); if (res == minus_one_ptid) continue; @@ -1273,7 +1261,11 @@ darwin_wait (ptid_t ptid, struct target_waitstatus *status) while (status->kind == TARGET_WAITKIND_IGNORE); /* Stop all tasks. */ - iterate_over_inferiors (darwin_suspend_inferior_it, NULL); + for (inferior *inf : all_inferiors (this)) + { + darwin_suspend_inferior (inf); + check_new_threads (inf); + } /* Read pending messages. */ while (1) @@ -1298,7 +1290,7 @@ darwin_wait (ptid_t ptid, struct target_waitstatus *status) if (darwin_debug_flag > 10) darwin_dump_message (hdr, darwin_debug_flag > 11); - ptid2 = darwin_decode_message (hdr, &thread, &inf, &status2); + ptid2 = decode_message (hdr, &thread, &inf, &status2); if (inf != NULL && thread != NULL && thread->event.ex_type == EXC_BREAKPOINT) @@ -1325,7 +1317,7 @@ ptid_t darwin_nat_target::wait (ptid_t ptid, struct target_waitstatus *status, int options) { - return darwin_wait (ptid, status); + return wait_1 (ptid, status); } void @@ -1415,8 +1407,8 @@ darwin_reply_to_all_pending_messages (struct inferior *inf) } } -static void -darwin_stop_inferior (struct inferior *inf) +void +darwin_nat_target::stop_inferior (inferior *inf) { struct target_waitstatus wstatus; ptid_t ptid; @@ -1432,14 +1424,14 @@ darwin_stop_inferior (struct inferior *inf) if (priv->no_ptrace) return; - res = kill (inf->pid, SIGSTOP); + res = ::kill (inf->pid, SIGSTOP); if (res != 0) warning (_("cannot kill: %s"), safe_strerror (errno)); /* Wait until the process is really stopped. */ while (1) { - ptid = darwin_wait (inferior_ptid, &wstatus); + ptid = wait_1 (inferior_ptid, &wstatus); if (wstatus.kind == TARGET_WAITKIND_STOPPED && wstatus.value.sig == GDB_SIGNAL_STOP) break; @@ -1564,7 +1556,7 @@ darwin_nat_target::kill () darwin_resume_inferior (inf); - ptid = darwin_wait (inferior_ptid, &wstatus); + ptid = wait_1 (inferior_ptid, &wstatus); } else if (errno != ESRCH) warning (_("Failed to kill inferior: kill (%d, 9) returned [%s]"), @@ -1716,10 +1708,10 @@ thread_info_from_private_thread_info (darwin_thread_info *pti) gdb_assert_not_reached ("did not find gdb thread for darwin thread"); } -static void -darwin_init_thread_list (struct inferior *inf) +void +darwin_nat_target::init_thread_list (inferior *inf) { - darwin_check_new_threads (inf); + check_new_threads (inf); darwin_inferior *priv = get_darwin_inferior (inf); @@ -1783,21 +1775,21 @@ darwin_pre_ptrace (void) mark_fd_no_cloexec (ptrace_fds[1]); } -static void -darwin_ptrace_him (int pid) +void +darwin_nat_target::ptrace_him (int pid) { struct inferior *inf = current_inferior (); darwin_attach_pid (inf); /* Let's the child run. */ - close (ptrace_fds[0]); - close (ptrace_fds[1]); + ::close (ptrace_fds[0]); + ::close (ptrace_fds[1]); unmark_fd_no_cloexec (ptrace_fds[0]); unmark_fd_no_cloexec (ptrace_fds[1]); - darwin_init_thread_list (inf); + init_thread_list (inf); gdb_startup_inferior (pid, START_INFERIOR_TRAPS_EXPECTED); } @@ -1986,6 +1978,7 @@ darwin_nat_target::create_inferior (const char *exec_file, char **env, int from_tty) { gdb::optional> restore_startup_with_shell; + darwin_nat_target *the_target = this; if (startup_with_shell && may_have_sip ()) { @@ -1998,7 +1991,11 @@ darwin_nat_target::create_inferior (const char *exec_file, /* Do the hard work. */ fork_inferior (exec_file, allargs, env, darwin_ptrace_me, - darwin_ptrace_him, darwin_pre_ptrace, copied_shell, + [the_target] (int pid) + { + the_target->ptrace_him (pid); + }, + darwin_pre_ptrace, copied_shell, darwin_execvp); } @@ -2068,7 +2065,7 @@ darwin_nat_target::attach (const char *args, int from_tty) darwin_suspend_inferior (inf); - darwin_init_thread_list (inf); + init_thread_list (inf); darwin_inferior *priv = get_darwin_inferior (inf); @@ -2099,7 +2096,7 @@ darwin_nat_target::detach (inferior *inf, int from_tty) /* If ptrace() is in use, stop the process. */ if (!priv->no_ptrace) - darwin_stop_inferior (inf); + stop_inferior (inf); kret = darwin_restore_exception_ports (priv); MACH_CHECK_ERROR (kret); diff --git a/gdb/darwin-nat.h b/gdb/darwin-nat.h index 5d2f30dae146..86bb33892122 100644 --- a/gdb/darwin-nat.h +++ b/gdb/darwin-nat.h @@ -21,6 +21,59 @@ #include #include "gdbthread.h" +struct darwin_exception_msg +{ + mach_msg_header_t header; + + /* Thread and task taking the exception. */ + mach_port_t thread_port; + mach_port_t task_port; + + /* Type of the exception. */ + exception_type_t ex_type; + + /* Machine dependent details. */ + mach_msg_type_number_t data_count; + integer_t ex_data[2]; +}; + +enum darwin_msg_state +{ + /* The thread is running. */ + DARWIN_RUNNING, + + /* The thread is stopped. */ + DARWIN_STOPPED, + + /* The thread has sent a message and waits for a reply. */ + DARWIN_MESSAGE +}; + +struct darwin_thread_info : public private_thread_info +{ + /* The thread port from a GDB point of view. */ + thread_t gdb_port = 0; + + /* The thread port from the inferior point of view. Not to be used inside + gdb except for get_ada_task_ptid. */ + thread_t inf_port = 0; + + /* Current message state. + If the kernel has sent a message it expects a reply and the inferior + can't be killed before. */ + enum darwin_msg_state msg_state = DARWIN_RUNNING; + + /* True if this thread is single-stepped. */ + bool single_step = false; + + /* True if a signal was manually sent to the thread. */ + bool signaled = false; + + /* The last exception received. */ + struct darwin_exception_msg event {}; +}; +typedef struct darwin_thread_info darwin_thread_t; + /* This needs to be overridden by the platform specific nat code. */ class darwin_nat_target : public inf_child_target @@ -59,6 +112,21 @@ class darwin_nat_target : public inf_child_target bool supports_multi_process () override; ptid_t get_ada_task_ptid (long lwp, long thread) override; + +private: + ptid_t wait_1 (ptid_t, struct target_waitstatus *); + void check_new_threads (inferior *inf); + int decode_exception_message (mach_msg_header_t *hdr, + inferior **pinf, + darwin_thread_t **pthread); + ptid_t decode_message (mach_msg_header_t *hdr, + darwin_thread_t **pthread, + inferior **pinf, + target_waitstatus *status); + void stop_inferior (inferior *inf); + void init_thread_list (inferior *inf); + void ptrace_him (int pid); + int cancel_breakpoint (ptid_t ptid); }; /* Describe the mach exception handling state for a task. This state is saved @@ -83,59 +151,6 @@ struct darwin_exception_info mach_msg_type_number_t count = 0; }; -struct darwin_exception_msg -{ - mach_msg_header_t header; - - /* Thread and task taking the exception. */ - mach_port_t thread_port; - mach_port_t task_port; - - /* Type of the exception. */ - exception_type_t ex_type; - - /* Machine dependent details. */ - mach_msg_type_number_t data_count; - integer_t ex_data[2]; -}; - -enum darwin_msg_state -{ - /* The thread is running. */ - DARWIN_RUNNING, - - /* The thread is stopped. */ - DARWIN_STOPPED, - - /* The thread has sent a message and waits for a reply. */ - DARWIN_MESSAGE -}; - -struct darwin_thread_info : public private_thread_info -{ - /* The thread port from a GDB point of view. */ - thread_t gdb_port = 0; - - /* The thread port from the inferior point of view. Not to be used inside - gdb except for get_ada_task_ptid. */ - thread_t inf_port = 0; - - /* Current message state. - If the kernel has sent a message it expects a reply and the inferior - can't be killed before. */ - enum darwin_msg_state msg_state = DARWIN_RUNNING; - - /* True if this thread is single-stepped. */ - bool single_step = false; - - /* True if a signal was manually sent to the thread. */ - bool signaled = false; - - /* The last exception received. */ - struct darwin_exception_msg event {}; -}; -typedef struct darwin_thread_info darwin_thread_t; - static inline darwin_thread_info * get_darwin_thread_info (class thread_info *thread) { diff --git a/gdb/nat/fork-inferior.c b/gdb/nat/fork-inferior.c index 78f972a7496d..ef5a75292fb1 100644 --- a/gdb/nat/fork-inferior.c +++ b/gdb/nat/fork-inferior.c @@ -267,7 +267,8 @@ execv_argv::init_for_shell (const char *exec_file, pid_t fork_inferior (const char *exec_file_arg, const std::string &allargs, char **env, void (*traceme_fun) (), - void (*init_trace_fun) (int), void (*pre_trace_fun) (), + gdb::function_view init_trace_fun, + void (*pre_trace_fun) (), const char *shell_file_arg, void (*exec_fun)(const char *file, char * const *argv, char * const *env)) @@ -439,7 +440,7 @@ fork_inferior (const char *exec_file_arg, const std::string &allargs, initialize anything target-vector-specific that needs initializing. */ if (init_trace_fun) - (*init_trace_fun) (pid); + init_trace_fun (pid); /* We are now in the child process of interest, having exec'd the correct program, and are poised at the first instruction of the diff --git a/gdb/nat/fork-inferior.h b/gdb/nat/fork-inferior.h index 9cbe9bd19d5a..d6f778da1ad2 100644 --- a/gdb/nat/fork-inferior.h +++ b/gdb/nat/fork-inferior.h @@ -21,6 +21,7 @@ #define NAT_FORK_INFERIOR_H #include +#include "gdbsupport/function-view.h" struct process_stratum_target; @@ -42,7 +43,7 @@ struct process_stratum_target; extern pid_t fork_inferior (const char *exec_file_arg, const std::string &allargs, char **env, void (*traceme_fun) (), - void (*init_trace_fun) (int), + gdb::function_view init_trace_fun, void (*pre_trace_fun) (), const char *shell_file_arg, void (*exec_fun) (const char *file,