From: Kamil Rytarowski <n54@gmx.com>
To: gdb-patches <gdb-patches@sourceware.org>
Subject: Re: [PATCH] Add basic event handling in the NetBSD target
Date: Mon, 20 Apr 2020 12:28:11 +0200 [thread overview]
Message-ID: <aad65895-a4fd-fd0a-7f81-3cc5361e242c@gmx.com> (raw)
In-Reply-To: <20200417144508.6366-1-n54@gmx.com>
[-- Attachment #1.1: Type: text/plain, Size: 11718 bytes --]
Ping?
On 17.04.2020 16:45, Kamil Rytarowski wrote:
> Implement the following events:
> - single step (TRAP_TRACE)
> - software breakpoint (TRAP_DBREG)
> - exec() (TRAP_EXEC)
> - syscall entry/exit (TRAP_SCE / TRAP_SCX)
>
> Add support for NetBSD specific ::wait () and ::resume ().
>
> Instruct the generic code that exec and syscall events are supported.
>
> Define an empty nbsd_get_syscall_number as it is prerequisite for
> catching syscall entry and exit events, even if it is unused.
> This function is used to detect whether the gdbarch supports the
> 'catch syscall' feature.
>
> gdb/ChangeLog:
>
> * nbsd-nat.c: Include "sys/wait.h".
> * (nbsd_nat_target::resume, nbsd_wait, nbsd_nat_target::wait)
> (nbsd_nat_target::insert_exec_catchpoint)
> (nbsd_nat_target::remove_exec_catchpoint)
> (nbsd_nat_target::set_syscall_catchpoint): Add.
> * nbsd-nat.h (nbsd_nat_target::resume, nbsd_nat_target::wait)
> (nbsd_nat_target::insert_exec_catchpoint)
> (nbsd_nat_target::remove_exec_catchpoint)
> (nbsd_nat_target::set_syscall_catchpoint): Add.
> * nbsd-tdep.c (nbsd_get_syscall_number): Add.
> (nbsd_init_abi): Call `set_gdbarch_get_syscall_number' and pass
> `nbsd_get_syscall_number'.
> ---
> gdb/ChangeLog | 15 ++++
> gdb/nbsd-nat.c | 211 ++++++++++++++++++++++++++++++++++++++++++++++++
> gdb/nbsd-nat.h | 9 +++
> gdb/nbsd-tdep.c | 18 +++++
> 4 files changed, 253 insertions(+)
>
> diff --git a/gdb/ChangeLog b/gdb/ChangeLog
> index 0caeca04e79..9652daabbbd 100644
> --- a/gdb/ChangeLog
> +++ b/gdb/ChangeLog
> @@ -1,3 +1,18 @@
> +2020-04-16 Kamil Rytarowski <n54@gmx.com>
> +
> + * nbsd-nat.c: Include "sys/wait.h".
> + * (nbsd_nat_target::resume, nbsd_wait, nbsd_nat_target::wait)
> + (nbsd_nat_target::insert_exec_catchpoint)
> + (nbsd_nat_target::remove_exec_catchpoint)
> + (nbsd_nat_target::set_syscall_catchpoint): Add.
> + * nbsd-nat.h (nbsd_nat_target::resume, nbsd_nat_target::wait)
> + (nbsd_nat_target::insert_exec_catchpoint)
> + (nbsd_nat_target::remove_exec_catchpoint)
> + (nbsd_nat_target::set_syscall_catchpoint): Add.
> + * nbsd-tdep.c (nbsd_get_syscall_number): Add.
> + (nbsd_init_abi): Call `set_gdbarch_get_syscall_number' and pass
> + `nbsd_get_syscall_number'.
> +
> 2020-04-16 Kamil Rytarowski <n54@gmx.com>
>
> * inf-ptrace.h (follow_fork, insert_fork_catchpoint)
> diff --git a/gdb/nbsd-nat.c b/gdb/nbsd-nat.c
> index d41cfc815d3..f9e85e10b16 100644
> --- a/gdb/nbsd-nat.c
> +++ b/gdb/nbsd-nat.c
> @@ -28,6 +28,7 @@
> #include <sys/types.h>
> #include <sys/ptrace.h>
> #include <sys/sysctl.h>
> +#include <sys/wait.h>
>
> /* Return the name of a file that can be opened to get the symbols for
> the child process identified by PID. */
> @@ -539,3 +540,213 @@ nbsd_nat_target::info_proc (const char *args, enum info_proc_what what)
>
> return true;
> }
> +
> +/* Resume execution of thread PTID, or all threads if PTID is -1. If
> + STEP is nonzero, single-step it. If SIGNAL is nonzero, give it
> + that signal. */
> +
> +void
> +nbsd_nat_target::resume (ptid_t ptid, int step, enum gdb_signal signal)
> +{
> + int request;
> +
> + if (ptid.lwp_p ())
> + {
> + /* If ptid is a specific LWP, suspend all other LWPs in the process. */
> + inferior *inf = find_inferior_ptid (this, ptid);
> +
> + for (thread_info *tp : inf->non_exited_threads ())
> + {
> + if (tp->ptid.lwp () == ptid.lwp ())
> + request = PT_RESUME;
> + else
> + request = PT_SUSPEND;
> +
> + if (ptrace (request, tp->ptid.pid (), NULL, tp->ptid.lwp ()) == -1)
> + perror_with_name (("ptrace"));
> + }
> + }
> + else
> + {
> + /* If ptid is a wildcard, resume all matching threads (they won't run
> + until the process is continued however). */
> + for (thread_info *tp : all_non_exited_threads (this, ptid))
> + if (ptrace (PT_RESUME, tp->ptid.pid (), NULL, tp->ptid.lwp ()) == -1)
> + perror_with_name (("ptrace"));
> + ptid = inferior_ptid;
> + }
> +
> + if (step)
> + {
> + for (thread_info *tp : all_non_exited_threads (this, ptid))
> + if (ptrace (PT_SETSTEP, tp->ptid.pid (), NULL, tp->ptid.lwp ()) == -1)
> + perror_with_name (("ptrace"));
> + }
> + else
> + {
> + for (thread_info *tp : all_non_exited_threads (this, ptid))
> + if (ptrace (PT_CLEARSTEP, tp->ptid.pid (), NULL, tp->ptid.lwp ()) == -1)
> + perror_with_name (("ptrace"));
> + }
> +
> + if (minus_one_ptid == ptid)
> + /* Resume all threads. Traditionally ptrace() only supports
> + single-threaded processes, so simply resume the inferior. */
> + ptid = ptid_t (inferior_ptid.pid ());
> +
> + if (catch_syscall_enabled () > 0)
> + request = PT_SYSCALL;
> + else
> + request = PT_CONTINUE;
> +
> + /* An address of (void *)1 tells ptrace to continue from
> + where it was. If GDB wanted it to start some other way, we have
> + already written a new program counter value to the child. */
> + if (ptrace (request, ptid.pid (), (void *)1, gdb_signal_to_host (signal)) == -1)
> + perror_with_name (("ptrace"));
> +}
> +
> +/* Implement the "update_thread_list" target_ops method. */
> +
> +static ptid_t
> +nbsd_wait (ptid_t ptid, struct target_waitstatus *ourstatus, int options)
> +{
> + pid_t pid;
> + int status;
> +
> + set_sigint_trap ();
> +
> + do
> + {
> + /* The common code passes WNOHANG that leads to crashes, overwrite it. */
> + pid = waitpid (ptid.pid (), &status, 0);
> + }
> + while (pid == -1 && errno == EINTR);
> +
> + clear_sigint_trap ();
> +
> + if (pid == -1)
> + perror_with_name (_("Child process unexpectedly missing"));
> +
> + store_waitstatus (ourstatus, status);
> + return ptid_t (pid);
> +}
> +
> +/* Wait for the child specified by PTID to do something. Return the
> + process ID of the child, or MINUS_ONE_PTID in case of error; store
> + the status in *OURSTATUS. */
> +
> +ptid_t
> +nbsd_nat_target::wait (ptid_t ptid, struct target_waitstatus *ourstatus,
> + int target_options)
> +{
> + ptid_t wptid = nbsd_wait(ptid, ourstatus, target_options);
> +
> + /* If the child stopped, keep investigating its status. */
> + if (ourstatus->kind != TARGET_WAITKIND_STOPPED)
> + return wptid;
> +
> + pid_t pid = wptid.pid ();
> +
> + /* Extract the event and thread that received a signal. */
> + ptrace_siginfo_t psi;
> + if (ptrace (PT_GET_SIGINFO, pid, &psi, sizeof (psi)) == -1)
> + perror_with_name (("ptrace"));
> +
> + /* Pick child's siginfo_t. */
> + siginfo_t *si = &psi.psi_siginfo;
> +
> + int lwp = psi.psi_lwpid;
> +
> + int signo = si->si_signo;
> + const int code = si->si_code;
> +
> + /* Construct PTID with a specified thread that received the event.
> + If a signal was targeted to the whole process, lwp is 0. */
> + wptid = ptid_t (pid, lwp, 0);
> +
> + /* Bail out on non-debugger oriented signals.. */
> + if (signo != SIGTRAP)
> + return wptid;
> +
> + /* Stop examining non-debugger oriented SIGTRAP codes. */
> + if (code <= SI_USER || code == SI_NOINFO)
> + return wptid;
> +
> + if (in_thread_list (this, ptid_t (pid)))
> + {
> + thread_change_ptid (this, ptid_t (pid), wptid);
> + }
> +
> + if (code == TRAP_EXEC)
> + {
> + ourstatus->kind = TARGET_WAITKIND_EXECD;
> + ourstatus->value.execd_pathname = xstrdup (pid_to_exec_file (pid));
> + return wptid;
> + }
> +
> + if (code == TRAP_TRACE)
> + {
> + /* Unhandled at this level. */
> + return wptid;
> + }
> +
> + if (code == TRAP_SCE || code == TRAP_SCX)
> + {
> + int sysnum = si->si_sysnum;
> +
> + if (!catch_syscall_enabled () || !catching_syscall_number (sysnum))
> + {
> + /* If the core isn't interested in this event, ignore it. */
> + ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
> + return wptid;
> + }
> +
> + ourstatus->kind =
> + (code == TRAP_SCE) ? TARGET_WAITKIND_SYSCALL_ENTRY :
> + TARGET_WAITKIND_SYSCALL_RETURN;
> + ourstatus->value.syscall_number = sysnum;
> + return wptid;
> + }
> +
> + if (code == TRAP_BRKPT)
> + {
> + /* Unhandled at this level. */
> + return wptid;
> + }
> +
> + /* Unclassified SIGTRAP event. */
> + ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
> + return wptid;
> +}
> +
> +/* Implement the "insert_exec_catchpoint" target_ops method. */
> +
> +int
> +nbsd_nat_target::insert_exec_catchpoint (int pid)
> +{
> + /* Nothing to do. */
> + return 0;
> +}
> +
> +/* Implement the "remove_exec_catchpoint" target_ops method. */
> +
> +int
> +nbsd_nat_target::remove_exec_catchpoint (int pid)
> +{
> + /* Nothing to do. */
> + return 0;
> +}
> +
> +/* Implement the "set_syscall_catchpoint" target_ops method. */
> +
> +int
> +nbsd_nat_target::set_syscall_catchpoint (int pid, bool needed,
> + int any_count,
> + gdb::array_view<const int> syscall_counts)
> +{
> + /* Ignore the arguments. inf-ptrace.c will use PT_SYSCALL which
> + will catch all system call entries and exits. The system calls
> + are filtered by GDB rather than the kernel. */
> + return 0;
> +}
> diff --git a/gdb/nbsd-nat.h b/gdb/nbsd-nat.h
> index 256db4b9017..6e14cbb889d 100644
> --- a/gdb/nbsd-nat.h
> +++ b/gdb/nbsd-nat.h
> @@ -38,6 +38,15 @@ struct nbsd_nat_target : public inf_ptrace_target
>
> int find_memory_regions (find_memory_region_ftype func, void *data) override;
> bool info_proc (const char *, enum info_proc_what) override;
> +
> + void resume (ptid_t, int, enum gdb_signal) override;
> + ptid_t wait (ptid_t, struct target_waitstatus *, int) override;
> + int insert_exec_catchpoint (int pid) override;
> + int remove_exec_catchpoint (int pid) override;
> + int set_syscall_catchpoint (int pid, bool needed, int any_count,
> + gdb::array_view<const int> syscall_counts)
> + override;
> +
> };
>
> #endif /* nbsd-nat.h */
> diff --git a/gdb/nbsd-tdep.c b/gdb/nbsd-tdep.c
> index 52e0640e35c..d5d1b7211c1 100644
> --- a/gdb/nbsd-tdep.c
> +++ b/gdb/nbsd-tdep.c
> @@ -444,6 +444,21 @@ nbsd_info_proc_mappings_entry (int addr_bit, ULONGEST kve_start,
> }
> }
>
> +/* Implement the "get_syscall_number" gdbarch method. */
> +
> +static LONGEST
> +nbsd_get_syscall_number (struct gdbarch *gdbarch, thread_info *thread)
> +{
> +
> + /* FreeBSD doesn't use gdbarch_get_syscall_number since NetBSD
> + native targets fetch the system call number from the
> + 'si_sysnum' member of siginfo_t in nbsd_nat_target::wait.
> + However, system call catching requires this function to be
> + set. */
> +
> + internal_error (__FILE__, __LINE__, _("nbsd_get_sycall_number called"));
> +}
> +
> /* See nbsd-tdep.h. */
>
> void
> @@ -453,4 +468,7 @@ nbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
> set_gdbarch_gdb_signal_to_target (gdbarch, nbsd_gdb_signal_to_target);
> set_gdbarch_skip_solib_resolver (gdbarch, nbsd_skip_solib_resolver);
> set_gdbarch_auxv_parse (gdbarch, svr4_auxv_parse);
> +
> + /* `catch syscall' */
> + set_gdbarch_get_syscall_number (gdbarch, nbsd_get_syscall_number);
> }
> --
> 2.25.0
>
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
next prev parent reply other threads:[~2020-04-20 10:29 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-04-17 14:45 Kamil Rytarowski
2020-04-20 10:28 ` Kamil Rytarowski [this message]
2020-04-24 1:33 ` Simon Marchi
2020-04-24 10:09 ` Kamil Rytarowski
2020-04-26 21:14 ` Simon Marchi
2020-04-29 9:12 ` Kamil Rytarowski
2020-04-29 11:08 ` [PATCH v2] " Kamil Rytarowski
2020-04-29 15:44 ` Simon Marchi
2020-04-29 11:47 ` [PATCH v2] Implement the following events: - single step (TRAP_TRACE) - software breakpoint (TRAP_DBREG) - exec() (TRAP_EXEC) - syscall entry/exit (TRAP_SCE / TRAP_SCX) Kamil Rytarowski
2020-04-29 12:07 ` [PATCH v2] Add basic event handling in the NetBSD target Kamil Rytarowski
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=aad65895-a4fd-fd0a-7f81-3cc5361e242c@gmx.com \
--to=n54@gmx.com \
--cc=gdb-patches@sourceware.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox