From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from simark.ca by simark.ca with LMTP id zzXZHTAEI2DtbAAAWB0awg (envelope-from ) for ; Tue, 09 Feb 2021 16:52:48 -0500 Received: by simark.ca (Postfix, from userid 112) id 6F2D21EF4F; Tue, 9 Feb 2021 16:52:48 -0500 (EST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on simark.ca X-Spam-Level: X-Spam-Status: No, score=0.2 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,MAILING_LIST_MULTI,RDNS_NONE,URIBL_BLOCKED autolearn=no autolearn_force=no version=3.4.2 Received: from sourceware.org (unknown [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by simark.ca (Postfix) with ESMTPS id AB30E1E590 for ; Tue, 9 Feb 2021 16:52:47 -0500 (EST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 2DD89398B40C; Tue, 9 Feb 2021 21:52:47 +0000 (GMT) Received: from mail-wm1-x336.google.com (mail-wm1-x336.google.com [IPv6:2a00:1450:4864:20::336]) by sourceware.org (Postfix) with ESMTPS id 7CC96393D003 for ; Tue, 9 Feb 2021 21:52:43 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 7CC96393D003 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=embecosm.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=andrew.burgess@embecosm.com Received: by mail-wm1-x336.google.com with SMTP id 190so95746wmz.0 for ; Tue, 09 Feb 2021 13:52:43 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=embecosm.com; s=google; h=date:from:to:cc:subject:message-id:references:mime-version :content-disposition:in-reply-to; bh=5oVUsOQ7ZSG5dnMrqe0om38xosFqGBRoh8Zh5jTLZG0=; b=V0dNZkUG1BVqk9g9CRyQ+1uZoxkKvfHUazCIcqgg/tymLM9gEq9Kn3rF0ZWMRTxAMG d8wl36BFtshXw/fz768zasZE0SFi3uugXcT7hMuhlD9GMY1zxQCVnNF3QrRw33/RzjAm U/wZqQMLNkzNpcn7vVfcGs7iZt/7CVz6T18UPEKUJvBaSTH2G+SN4XFY2aO7s03WpBI0 vt74jmRM3HEe7IwrH9PqEzQy1PCsO1QT4EGxpAACER7BjwBDW2fGCJFoEDN9rkVJ2D4w jXgpWLAu24X/6nibyqWIIbW7ET+oE1R6XfGKcWDtvyhxbpECLLC8dIkaNzj8Xym+K4H7 x5UQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to; bh=5oVUsOQ7ZSG5dnMrqe0om38xosFqGBRoh8Zh5jTLZG0=; b=ej7b5RF4UUWZctFCM+pxltwZVLZgQiRcuShZ9PPv2wWrjzdh1p8RQA5hw27oES9rO1 jtupcbwmjsqEV4Ec/7D9Cn6aA9J+gDaz5NjebNc1FGyR3tbwKY15lVgi88x0Rcxj9oMq XMl+U8MYPIil+sIgBoa58h9wSJ1xd81jw9AVAG9id9TCmM7lrUb0w6aPzzi//ocMVVAk ksTroREDlcGK4mj1+i8px3pqUj7waWB77CBs0hnGH8scete0TBbIcPw7dcGBbUAM0eKp OTwAKdJqXC5oFzCsPGtzngX4uKY8a+NXPdjHSRfrlWggAMy4bV7fxOUHbmDtRJq02OaN ++4w== X-Gm-Message-State: AOAM531J6ove6Ee705AQzedEkeQ5vBkYxfS1RU3TrcgsGvPxTyOpSiwu wNun/pOCoK8SlUBuPQ3d/KDoKf05Epq44w== X-Google-Smtp-Source: ABdhPJyPTP8yjLK86RlvWci/O/TUYBPAjEeKf4IxQAeYqnAQc5OMdgQw9pDHwryIIYrRHmSuyjS9Kw== X-Received: by 2002:a1c:1fce:: with SMTP id f197mr139502wmf.110.1612907562044; Tue, 09 Feb 2021 13:52:42 -0800 (PST) Received: from localhost (host109-151-46-64.range109-151.btcentralplus.com. [109.151.46.64]) by smtp.gmail.com with ESMTPSA id c62sm70763wmd.43.2021.02.09.13.52.41 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 09 Feb 2021 13:52:41 -0800 (PST) Date: Tue, 9 Feb 2021 21:52:40 +0000 From: Andrew Burgess To: gdb-patches@sourceware.org, binutils@sourceware.org Subject: Re: [PATCHv2 1/9] gdb: unify parts of the Linux and FreeBSD core dumping code Message-ID: <20210209215240.GK265215@embecosm.com> References: <1d4520c35b2aa9c7eadf015ac6af4dd955253660.1611172468.git.andrew.burgess@embecosm.com> <20210201115600.GS265215@embecosm.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20210201115600.GS265215@embecosm.com> X-Operating-System: Linux/5.8.13-100.fc31.x86_64 (x86_64) X-Uptime: 21:50:08 up 63 days, 2:34, X-Editor: GNU Emacs [ http://www.gnu.org/software/emacs ] X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Fredrik Hederstierna Errors-To: gdb-patches-bounces@sourceware.org Sender: "Gdb-patches" * Andrew Burgess [2021-02-01 11:56:00 +0000]: > I have pushed this patch only so far as this is a nice clean up in its > own right. I have now reverted this patch due to the regressions it introduced, see here: https://sourceware.org/pipermail/gdb-patches/2021-February/175750.html I still plan to bring this patch back as soon as I have a good solution - I just don't have one immediately, hence the revert. Any suggestions for good solutions will be appreciated :) Thanks, Andrew --- commit 03642b7189bc0bfdf61354a6d9a3f3e46d82709c Author: Andrew Burgess Date: Tue Feb 9 21:41:30 2021 +0000 gdb: revert "gdb: unify parts of the Linux and FreeBSD core dumping code" This reverts commit 82a1fd3a4935fe665cf08bc6820942c4a091184c. It was pointed out: https://sourceware.org/pipermail/gdb-patches/2021-February/175750.html that commit 82a1fd3a4935 caused GDB to have an unconditional dependency on ELF specific parts of BFD. What this means is that if GDB and BFD are built for a non-elf target then there will be undefined symbol references within GDB. The right solution isn't immediately obvious. So rather than rush a fix in I'm reverting this commit for now, and will bring it back once I have a good solution. gdb/ChangeLog: * gcore.c (struct gcore_collect_regset_section_cb_data): Delete. (gcore_collect_regset_section_cb): Delete. (gcore_collect_thread_registers): Delete. (gcore_build_thread_register_notes): Delete. (gcore_find_signalled_thread): Delete. * gcore.h: Remove 'gdbsupport/gdb_signals.h' include and delete 'gdbarch' and 'thread_info' declarations. (gcore_build_thread_register_notes): Delete declaration. (gcore_find_signalled_thread): Likewise. * fbsd-tdep.c: Remove 'gcore.h' include. (struct fbsd_collect_regset_section_cb_data): New struct. (fbsd_collect_regset_section_cb): New function. (fbsd_collect_thread_registers): New function. (struct fbsd_corefile_thread_data): New struct. (fbsd_corefile_thread): New function. (fbsd_make_corefile_notes): Call FreeBSD specific code. * linux-tdep.c: Remove 'gcore.h' include. (struct linux_collect_regset_section_cb_data): New struct. (linux_collect_regset_section_cb): New function. (linux_collect_thread_registers): New function. (linux_corefile_thread): Call Linux specific code. (find_signalled_thread): New function. (linux_make_corefile_notes): Call find_signalled_thread. diff --git a/gdb/fbsd-tdep.c b/gdb/fbsd-tdep.c index edd3edc4220..cc51e921ae2 100644 --- a/gdb/fbsd-tdep.c +++ b/gdb/fbsd-tdep.c @@ -32,7 +32,6 @@ #include "elf-bfd.h" #include "fbsd-tdep.h" -#include "gcore.h" /* This enum is derived from FreeBSD's . */ @@ -584,6 +583,129 @@ find_signalled_thread (struct thread_info *info, void *data) return 0; } +/* Structure for passing information from + fbsd_collect_thread_registers via an iterator to + fbsd_collect_regset_section_cb. */ + +struct fbsd_collect_regset_section_cb_data +{ + fbsd_collect_regset_section_cb_data (const struct regcache *regcache, + bfd *obfd, + gdb::unique_xmalloc_ptr ¬e_data, + int *note_size, + unsigned long lwp, + gdb_signal stop_signal) + : regcache (regcache), + obfd (obfd), + note_data (note_data), + note_size (note_size), + lwp (lwp), + stop_signal (stop_signal) + {} + + const struct regcache *regcache; + bfd *obfd; + gdb::unique_xmalloc_ptr ¬e_data; + int *note_size; + unsigned long lwp; + enum gdb_signal stop_signal; + bool abort_iteration = false; +}; + +static void +fbsd_collect_regset_section_cb (const char *sect_name, int supply_size, + int collect_size, const struct regset *regset, + const char *human_name, void *cb_data) +{ + char *buf; + struct fbsd_collect_regset_section_cb_data *data + = (struct fbsd_collect_regset_section_cb_data *) cb_data; + + if (data->abort_iteration) + return; + + gdb_assert (regset->collect_regset); + + buf = (char *) xmalloc (collect_size); + regset->collect_regset (regset, data->regcache, -1, buf, collect_size); + + /* PRSTATUS still needs to be treated specially. */ + if (strcmp (sect_name, ".reg") == 0) + data->note_data.reset (elfcore_write_prstatus + (data->obfd, data->note_data.release (), + data->note_size, data->lwp, + gdb_signal_to_host (data->stop_signal), + buf)); + else + data->note_data.reset (elfcore_write_register_note + (data->obfd, data->note_data.release (), + data->note_size, sect_name, buf, + collect_size)); + xfree (buf); + + if (data->note_data == NULL) + data->abort_iteration = true; +} + +/* Records the thread's register state for the corefile note + section. */ + +static void +fbsd_collect_thread_registers (const struct regcache *regcache, + ptid_t ptid, bfd *obfd, + gdb::unique_xmalloc_ptr ¬e_data, + int *note_size, + enum gdb_signal stop_signal) +{ + fbsd_collect_regset_section_cb_data data (regcache, obfd, note_data, + note_size, ptid.lwp (), + stop_signal); + + gdbarch_iterate_over_regset_sections (regcache->arch (), + fbsd_collect_regset_section_cb, + &data, regcache); +} + +struct fbsd_corefile_thread_data +{ + fbsd_corefile_thread_data (struct gdbarch *gdbarch, + bfd *obfd, + gdb::unique_xmalloc_ptr ¬e_data, + int *note_size, + gdb_signal stop_signal) + : gdbarch (gdbarch), + obfd (obfd), + note_data (note_data), + note_size (note_size), + stop_signal (stop_signal) + {} + + struct gdbarch *gdbarch; + bfd *obfd; + gdb::unique_xmalloc_ptr ¬e_data; + int *note_size; + enum gdb_signal stop_signal; +}; + +/* Records the thread's register state for the corefile note + section. */ + +static void +fbsd_corefile_thread (struct thread_info *info, + struct fbsd_corefile_thread_data *args) +{ + struct regcache *regcache; + + regcache = get_thread_arch_regcache (info->inf->process_target (), + info->ptid, args->gdbarch); + + target_fetch_registers (regcache, -1); + + fbsd_collect_thread_registers (regcache, info->ptid, args->obfd, + args->note_data, args->note_size, + args->stop_signal); +} + /* Return a byte_vector containing the contents of a core dump note for the target object of type OBJECT. If STRUCTSIZE is non-zero, the data is prefixed with a 32-bit integer size to match the format @@ -660,17 +782,16 @@ fbsd_make_corefile_notes (struct gdbarch *gdbarch, bfd *obfd, int *note_size) signalled_thr = curr_thr; } - gcore_build_thread_register_notes (gdbarch, signalled_thr, - signalled_thr->suspend.stop_signal, - obfd, ¬e_data, note_size); + fbsd_corefile_thread_data thread_args (gdbarch, obfd, note_data, note_size, + signalled_thr->suspend.stop_signal); + + fbsd_corefile_thread (signalled_thr, &thread_args); for (thread_info *thr : current_inferior ()->non_exited_threads ()) { if (thr == signalled_thr) continue; - gcore_build_thread_register_notes (gdbarch, thr, - signalled_thr->suspend.stop_signal, - obfd, ¬e_data, note_size); + fbsd_corefile_thread (thr, &thread_args); } /* Auxiliary vector. */ diff --git a/gdb/gcore.c b/gdb/gcore.c index d62aa3a7109..73ac6b09c70 100644 --- a/gdb/gcore.c +++ b/gdb/gcore.c @@ -579,142 +579,6 @@ gcore_memory_sections (bfd *obfd) return 1; } -/* Structure for passing information from GCORE_COLLECT_THREAD_REGISTERS - via an iterator to GCORE_COLLECT_REGSET_SECTION_CB. */ - -struct gcore_collect_regset_section_cb_data -{ - gcore_collect_regset_section_cb_data (struct gdbarch *gdbarch, - const struct regcache *regcache, - bfd *obfd, ptid_t ptid, - gdb_signal stop_signal, - gdb::unique_xmalloc_ptr *note_data, - int *note_size) - - : gdbarch (gdbarch), regcache (regcache), obfd (obfd), - note_data (note_data), note_size (note_size), - stop_signal (stop_signal) - { - /* The LWP is often not available for bare metal target, in which case - use the tid instead. */ - if (ptid.lwp_p ()) - lwp = ptid.lwp (); - else - lwp = ptid.tid (); - } - - struct gdbarch *gdbarch; - const struct regcache *regcache; - bfd *obfd; - gdb::unique_xmalloc_ptr *note_data; - int *note_size; - unsigned long lwp; - enum gdb_signal stop_signal; - bool abort_iteration = false; -}; - -/* Callback for ITERATE_OVER_REGSET_SECTIONS that records a single - regset in the core file note section. */ - -static void -gcore_collect_regset_section_cb (const char *sect_name, int supply_size, - int collect_size, - const struct regset *regset, - const char *human_name, void *cb_data) -{ - struct gcore_collect_regset_section_cb_data *data - = (struct gcore_collect_regset_section_cb_data *) cb_data; - bool variable_size_section = (regset != NULL - && regset->flags & REGSET_VARIABLE_SIZE); - - gdb_assert (variable_size_section || supply_size == collect_size); - - if (data->abort_iteration) - return; - - gdb_assert (regset != nullptr && regset->collect_regset != nullptr); - - /* This is intentionally zero-initialized by using std::vector, so - that any padding bytes in the core file will show as 0. */ - std::vector buf (collect_size); - - regset->collect_regset (regset, data->regcache, -1, buf.data (), - collect_size); - - /* PRSTATUS still needs to be treated specially. */ - if (strcmp (sect_name, ".reg") == 0) - data->note_data->reset (elfcore_write_prstatus - (data->obfd, data->note_data->release (), - data->note_size, data->lwp, - gdb_signal_to_host (data->stop_signal), - buf.data ())); - else - data->note_data->reset (elfcore_write_register_note - (data->obfd, data->note_data->release (), - data->note_size, sect_name, buf.data (), - collect_size)); - - if (data->note_data == nullptr) - data->abort_iteration = true; -} - -/* Records the register state of thread PTID out of REGCACHE into the note - buffer represented by *NOTE_DATA and NOTE_SIZE. OBFD is the bfd into - which the core file is being created, and STOP_SIGNAL is the signal that - cause thread PTID to stop. */ - -static void -gcore_collect_thread_registers (const struct regcache *regcache, - ptid_t ptid, bfd *obfd, - gdb::unique_xmalloc_ptr *note_data, - int *note_size, - enum gdb_signal stop_signal) -{ - struct gdbarch *gdbarch = regcache->arch (); - gcore_collect_regset_section_cb_data data (gdbarch, regcache, obfd, ptid, - stop_signal, note_data, - note_size); - gdbarch_iterate_over_regset_sections (gdbarch, - gcore_collect_regset_section_cb, - &data, regcache); -} - -/* See gcore.h. */ - -void -gcore_build_thread_register_notes - (struct gdbarch *gdbarch, struct thread_info *info, gdb_signal stop_signal, - bfd *obfd, gdb::unique_xmalloc_ptr *note_data, int *note_size) -{ - struct regcache *regcache - = get_thread_arch_regcache (info->inf->process_target (), - info->ptid, gdbarch); - target_fetch_registers (regcache, -1); - gcore_collect_thread_registers (regcache, info->ptid, obfd, note_data, - note_size, stop_signal); -} - -/* See gcore.h. */ - -thread_info * -gcore_find_signalled_thread () -{ - thread_info *curr_thr = inferior_thread (); - if (curr_thr->state != THREAD_EXITED - && curr_thr->suspend.stop_signal != GDB_SIGNAL_0) - return curr_thr; - - for (thread_info *thr : current_inferior ()->non_exited_threads ()) - if (thr->suspend.stop_signal != GDB_SIGNAL_0) - return thr; - - /* Default to the current thread, unless it has exited. */ - if (curr_thr->state != THREAD_EXITED) - return curr_thr; - - return nullptr; -} - void _initialize_gcore (); void _initialize_gcore () diff --git a/gdb/gcore.h b/gdb/gcore.h index ce60841c1a5..af37ff39b41 100644 --- a/gdb/gcore.h +++ b/gdb/gcore.h @@ -21,10 +21,6 @@ #define GCORE_H 1 #include "gdb_bfd.h" -#include "gdbsupport/gdb_signals.h" - -struct gdbarch; -struct thread_info; extern gdb_bfd_ref_ptr create_gcore_bfd (const char *filename); extern void write_gcore_file (bfd *obfd); @@ -32,20 +28,4 @@ extern int objfile_find_memory_regions (struct target_ops *self, find_memory_region_ftype func, void *obfd); -/* Add content to *NOTE_DATA (and update *NOTE_SIZE) to describe the - registers of thread INFO. Report the thread as having stopped with - STOP_SIGNAL. The core file is being written to OFD, and GDBARCH is the - architecture for which the core file is being generated. */ - -extern void gcore_build_thread_register_notes - (struct gdbarch *gdbarch, struct thread_info *info, gdb_signal stop_signal, - bfd *obfd, gdb::unique_xmalloc_ptr *note_data, int *note_size); - -/* Find the signalled thread. In case there's more than one signalled - thread, prefer the current thread, if it is signalled. If no thread was - signalled, default to the current thread, unless it has exited, in which - case return NULL. */ - -extern thread_info *gcore_find_signalled_thread (); - #endif /* GCORE_H */ diff --git a/gdb/linux-tdep.c b/gdb/linux-tdep.c index 3db4d31de37..e9f8e1b6133 100644 --- a/gdb/linux-tdep.c +++ b/gdb/linux-tdep.c @@ -39,7 +39,6 @@ #include "gdb_regex.h" #include "gdbsupport/enum-flags.h" #include "gdbsupport/gdb_optional.h" -#include "gcore.h" #include @@ -1598,6 +1597,104 @@ linux_make_mappings_corefile_notes (struct gdbarch *gdbarch, bfd *obfd, } } +/* Structure for passing information from + linux_collect_thread_registers via an iterator to + linux_collect_regset_section_cb. */ + +struct linux_collect_regset_section_cb_data +{ + linux_collect_regset_section_cb_data (struct gdbarch *gdbarch, + const struct regcache *regcache, + bfd *obfd, + gdb::unique_xmalloc_ptr ¬e_data, + int *note_size, + unsigned long lwp, + gdb_signal stop_signal) + : gdbarch (gdbarch), regcache (regcache), obfd (obfd), + note_data (note_data), note_size (note_size), lwp (lwp), + stop_signal (stop_signal) + {} + + struct gdbarch *gdbarch; + const struct regcache *regcache; + bfd *obfd; + gdb::unique_xmalloc_ptr ¬e_data; + int *note_size; + unsigned long lwp; + enum gdb_signal stop_signal; + bool abort_iteration = false; +}; + +/* Callback for iterate_over_regset_sections that records a single + regset in the corefile note section. */ + +static void +linux_collect_regset_section_cb (const char *sect_name, int supply_size, + int collect_size, const struct regset *regset, + const char *human_name, void *cb_data) +{ + struct linux_collect_regset_section_cb_data *data + = (struct linux_collect_regset_section_cb_data *) cb_data; + bool variable_size_section = (regset != NULL + && regset->flags & REGSET_VARIABLE_SIZE); + + if (!variable_size_section) + gdb_assert (supply_size == collect_size); + + if (data->abort_iteration) + return; + + gdb_assert (regset && regset->collect_regset); + + /* This is intentionally zero-initialized by using std::vector, so + that any padding bytes in the core file will show as 0. */ + std::vector buf (collect_size); + + regset->collect_regset (regset, data->regcache, -1, buf.data (), + collect_size); + + /* PRSTATUS still needs to be treated specially. */ + if (strcmp (sect_name, ".reg") == 0) + data->note_data.reset (elfcore_write_prstatus + (data->obfd, data->note_data.release (), + data->note_size, data->lwp, + gdb_signal_to_host (data->stop_signal), + buf.data ())); + else + data->note_data.reset (elfcore_write_register_note + (data->obfd, data->note_data.release (), + data->note_size, sect_name, buf.data (), + collect_size)); + + if (data->note_data == NULL) + data->abort_iteration = true; +} + +/* Records the thread's register state for the corefile note + section. */ + +static void +linux_collect_thread_registers (const struct regcache *regcache, + ptid_t ptid, bfd *obfd, + gdb::unique_xmalloc_ptr ¬e_data, + int *note_size, + enum gdb_signal stop_signal) +{ + struct gdbarch *gdbarch = regcache->arch (); + + /* For remote targets the LWP may not be available, so use the TID. */ + long lwp = ptid.lwp (); + if (lwp == 0) + lwp = ptid.tid (); + + linux_collect_regset_section_cb_data data (gdbarch, regcache, obfd, note_data, + note_size, lwp, stop_signal); + + gdbarch_iterate_over_regset_sections (gdbarch, + linux_collect_regset_section_cb, + &data, regcache); +} + /* Fetch the siginfo data for the specified thread, if it exists. If there is no data, or we could not read it, return an empty buffer. */ @@ -1649,16 +1746,22 @@ static void linux_corefile_thread (struct thread_info *info, struct linux_corefile_thread_data *args) { - gcore_build_thread_register_notes (args->gdbarch, info, args->stop_signal, - args->obfd, &args->note_data, - args->note_size); + struct regcache *regcache; + + regcache = get_thread_arch_regcache (info->inf->process_target (), + info->ptid, args->gdbarch); + + target_fetch_registers (regcache, -1); + gdb::byte_vector siginfo_data = linux_get_siginfo_data (info, args->gdbarch); + + linux_collect_thread_registers (regcache, info->ptid, args->obfd, + args->note_data, args->note_size, + args->stop_signal); /* Don't return anything if we got no register information above, such a core file is useless. */ if (args->note_data != NULL) { - gdb::byte_vector siginfo_data - = linux_get_siginfo_data (info, args->gdbarch); if (!siginfo_data.empty ()) args->note_data.reset (elfcore_write_note (args->obfd, args->note_data.release (), @@ -1857,6 +1960,30 @@ linux_fill_prpsinfo (struct elf_internal_linux_prpsinfo *p) return 1; } +/* Find the signalled thread. In case there's more than one signalled + thread, prefer the current thread, if it is signalled. If no + thread was signalled, default to the current thread, unless it has + exited, in which case return NULL. */ + +static thread_info * +find_signalled_thread () +{ + thread_info *curr_thr = inferior_thread (); + if (curr_thr->state != THREAD_EXITED + && curr_thr->suspend.stop_signal != GDB_SIGNAL_0) + return curr_thr; + + for (thread_info *thr : current_inferior ()->non_exited_threads ()) + if (thr->suspend.stop_signal != GDB_SIGNAL_0) + return thr; + + /* Default to the current thread, unless it has exited. */ + if (curr_thr->state != THREAD_EXITED) + return curr_thr; + + return nullptr; +} + /* Build the note section for a corefile, and return it in a malloc buffer. */ @@ -1894,7 +2021,7 @@ linux_make_corefile_notes (struct gdbarch *gdbarch, bfd *obfd, int *note_size) /* Like the kernel, prefer dumping the signalled thread first. "First thread" is what tools use to infer the signalled thread. */ - thread_info *signalled_thr = gcore_find_signalled_thread (); + thread_info *signalled_thr = find_signalled_thread (); gdb_signal stop_signal; if (signalled_thr != nullptr) stop_signal = signalled_thr->suspend.stop_signal;