From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from kwanyin.sergiodj.net (kwanyin.sergiodj.net [158.69.185.54]) by sourceware.org (Postfix) with ESMTPS id 6D5183858D33 for ; Wed, 22 Apr 2020 16:13:30 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 6D5183858D33 Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [binutils-gdb] Implement basic threading support in the NetBSD target From: gdb-buildbot@sergiodj.net To: gdb-testers@sourceware.org Message-Id: <05f00e223d56927bfb03e3272a4827276ed67372@gdb-build> Date: Wed, 22 Apr 2020 12:13:28 -0400 X-Spam-Status: No, score=-15.5 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: gdb-testers@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb-testers mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 22 Apr 2020 16:13:31 -0000 *** TEST RESULTS FOR COMMIT 05f00e223d56927bfb03e3272a4827276ed67372 *** commit 05f00e223d56927bfb03e3272a4827276ed67372 Author: Kamil Rytarowski AuthorDate: Wed Mar 25 20:29:44 2020 +0100 Commit: Kamil Rytarowski CommitDate: Mon Apr 6 23:04:36 2020 +0200 Implement basic threading support in the NetBSD target Use sysctl(3) as the portable interface to prompt NetBSD threads on all supported NetBSD versions. In future newer versions could switch to PT_LWPSTATUS ptrace(2) API that will be supported on NetBSD 10.0 and newer. Implement as part of nbsd_nat_target: - thread_name() - read descriptive thread name - thread_alive() - check whether a thread is alive - post_attach() - updates the list of threads after attach - update_thread_list() - updates the list of threads - pid_to_str() - translates ptid to a descriptive string There are two local static functions: - nbsd_thread_lister() - generic LWP lister for a specified pid - nbsd_add_threads() - utility to update the list of threads Now, GDB on NetBSD can attach to a multithreaded process, spawn a multithreaded process, list threads, print their LWP+PID numbers and descriptive thread names. gdb/ChangeLog: * nbsd-nat.h (struct thread_info): Add forward declaration. (nbsd_nat_target::thread_alive): Add. (nbsd_nat_target::thread_name): Likewise. (nbsd_nat_target::update_thread_list): Likewise. (update_thread_list::post_attach): Likewise. (post_attach::pid_to_str): Likewise. * nbsd-nat.c: Include "gdbthread.h" and "inferior.h". (nbsd_thread_lister): Add. (nbsd_nat_target::thread_alive): Likewise. (nbsd_nat_target::thread_name): Likewise. (nbsd_add_threads): Likewise. (update_thread_list::post_attach): Likewise. (nbsd_nat_target::update_thread_list): Likewise. (post_attach::pid_to_str): Likewise. diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 94fbdbde2f..bd1a0f4df1 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,20 @@ +2020-04-06 Kamil Rytarowski + + * nbsd-nat.h (struct thread_info): Add forward declaration. + (nbsd_nat_target::thread_alive): Add. + (nbsd_nat_target::thread_name): Likewise. + (nbsd_nat_target::update_thread_list): Likewise. + (update_thread_list::post_attach): Likewise. + (post_attach::pid_to_str): Likewise. + * nbsd-nat.c: Include "gdbthread.h" and "inferior.h". + (nbsd_thread_lister): Add. + (nbsd_nat_target::thread_alive): Likewise. + (nbsd_nat_target::thread_name): Likewise. + (nbsd_add_threads): Likewise. + (update_thread_list::post_attach): Likewise. + (nbsd_nat_target::update_thread_list): Likewise. + (post_attach::pid_to_str): Likewise. + 2020-04-06 Tom Tromey * ada-valprint.c (print_variant_part): Extract the variant field. diff --git a/gdb/nbsd-nat.c b/gdb/nbsd-nat.c index 326bbe3aec..4423e19428 100644 --- a/gdb/nbsd-nat.c +++ b/gdb/nbsd-nat.c @@ -20,6 +20,8 @@ #include "defs.h" #include "nbsd-nat.h" +#include "gdbthread.h" +#include "inferior.h" #include #include @@ -39,3 +41,161 @@ nbsd_nat_target::pid_to_exec_file (int pid) return NULL; return buf; } + +/* Generic thread (LWP) lister within a specified process. The callback + parameters is a C++ function that is called for each detected thread. */ + +static bool +nbsd_thread_lister (const pid_t pid, + gdb::function_view + callback) +{ + int mib[5] = {CTL_KERN, KERN_LWP, pid, sizeof (struct kinfo_lwp), 0}; + size_t size; + + if (sysctl (mib, ARRAY_SIZE (mib), NULL, &size, NULL, 0) == -1 || size == 0) + perror_with_name (("sysctl")); + + mib[4] = size / sizeof (size_t); + + gdb::unique_xmalloc_ptr kl + ((struct kinfo_lwp *) xcalloc (size, 1)); + + if (sysctl (mib, ARRAY_SIZE (mib), kl.get (), &size, NULL, 0) == -1 + || size == 0) + perror_with_name (("sysctl")); + + for (size_t i = 0; i < size / sizeof (struct kinfo_lwp); i++) + { + struct kinfo_lwp *l = &kl[i]; + + /* Return true if the specified thread is alive. */ + auto lwp_alive + = [] (struct kinfo_lwp *lwp) + { + switch (lwp->l_stat) + { + case LSSLEEP: + case LSRUN: + case LSONPROC: + case LSSTOP: + case LSSUSPENDED: + return true; + default: + return false; + } + }; + + /* Ignore embryonic or demised threads. */ + if (!lwp_alive (l)) + continue; + + if (callback (l)) + return true; + } + + return false; +} + +/* Return true if PTID is still active in the inferior. */ + +bool +nbsd_nat_target::thread_alive (ptid_t ptid) +{ + pid_t pid = ptid.pid (); + int lwp = ptid.lwp (); + + auto fn + = [&lwp] (const struct kinfo_lwp *kl) + { + return kl->l_lid == lwp; + }; + + return nbsd_thread_lister (pid, fn); +} + +/* Return the name assigned to a thread by an application. Returns + the string in a static buffer. */ + +const char * +nbsd_nat_target::thread_name (struct thread_info *thr) +{ + ptid_t ptid = thr->ptid; + pid_t pid = ptid.pid (); + int lwp = ptid.lwp (); + + static char buf[KI_LNAMELEN] = {}; + + auto fn + = [&lwp] (const struct kinfo_lwp *kl) + { + if (kl->l_lid == lwp) + { + xsnprintf (buf, sizeof buf, "%s", kl->l_name); + return true; + } + return false; + }; + + if (nbsd_thread_lister (pid, fn)) + return buf; + else + return NULL; +} + +/* Implement the "post_attach" target_ops method. */ + +static void +nbsd_add_threads (nbsd_nat_target *target, pid_t pid) +{ + auto fn + = [&target, &pid] (const struct kinfo_lwp *kl) + { + ptid_t ptid = ptid_t (pid, kl->l_lid, 0); + if (!in_thread_list (target, ptid)) + { + if (inferior_ptid.lwp () == 0) + thread_change_ptid (target, inferior_ptid, ptid); + else + add_thread (target, ptid); + } + return false; + }; + + nbsd_thread_lister (pid, fn); +} + +/* Implement the "post_attach" target_ops method. */ + +void +nbsd_nat_target::post_attach (int pid) +{ + nbsd_add_threads (this, pid); +} + +/* Implement the "update_thread_list" target_ops method. */ + +void +nbsd_nat_target::update_thread_list () +{ + prune_threads (); + + nbsd_add_threads (this, inferior_ptid.pid ()); +} + +/* Convert PTID to a string. */ + +std::string +nbsd_nat_target::pid_to_str (ptid_t ptid) +{ + int lwp = ptid.lwp (); + + if (lwp != 0) + { + pid_t pid = ptid.pid (); + + return string_printf ("LWP %d of process %d", lwp, pid); + } + + return normal_pid_to_str (ptid); +} diff --git a/gdb/nbsd-nat.h b/gdb/nbsd-nat.h index a752fbe572..3606048cd0 100644 --- a/gdb/nbsd-nat.h +++ b/gdb/nbsd-nat.h @@ -22,11 +22,19 @@ #include "inf-ptrace.h" +struct thread_info; + /* A prototype NetBSD target. */ struct nbsd_nat_target : public inf_ptrace_target { char *pid_to_exec_file (int pid) override; + + bool thread_alive (ptid_t ptid) override; + const char *thread_name (struct thread_info *thr) override; + void post_attach (int pid) override; + void update_thread_list () override; + std::string pid_to_str (ptid_t ptid) override; }; #endif /* nbsd-nat.h */