From patchwork Wed Nov 22 16:41:06 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Marchi X-Patchwork-Id: 24446 Received: (qmail 18263 invoked by alias); 22 Nov 2017 16:42:20 -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 18010 invoked by uid 89); 22 Nov 2017 16:42:20 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-25.9 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_SHORT, KB_WAM_FROM_NAME_SINGLEWORD, SPF_PASS autolearn=ham version=3.3.2 spammy=dying X-HELO: sesbmg23.ericsson.net Received: from sesbmg23.ericsson.net (HELO sesbmg23.ericsson.net) (193.180.251.37) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Wed, 22 Nov 2017 16:42:15 +0000 Received: from ESESSHC008.ericsson.se (Unknown_Domain [153.88.183.42]) by sesbmg23.ericsson.net (Symantec Mail Security) with SMTP id BF.AE.08439.4E8A51A5; Wed, 22 Nov 2017 17:42:12 +0100 (CET) Received: from EUR01-DB5-obe.outbound.protection.outlook.com (153.88.183.145) by oa.msg.ericsson.com (153.88.183.42) with Microsoft SMTP Server (TLS) id 14.3.352.0; Wed, 22 Nov 2017 17:42:12 +0100 Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=simon.marchi@ericsson.com; Received: from elxacz23q12.ericsson.se (129.192.64.65) by AMSPR07MB312.eurprd07.prod.outlook.com (2a01:111:e400:802f::24) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P256) id 15.20.260.2; Wed, 22 Nov 2017 16:41:52 +0000 From: Simon Marchi To: CC: Simon Marchi Subject: [PATCH 3/4] Create private_thread_info hierarchy Date: Wed, 22 Nov 2017 11:41:06 -0500 Message-ID: <1511368867-19365-4-git-send-email-simon.marchi@ericsson.com> In-Reply-To: <1511368867-19365-1-git-send-email-simon.marchi@ericsson.com> References: <1511368867-19365-1-git-send-email-simon.marchi@ericsson.com> MIME-Version: 1.0 X-ClientProxiedBy: MWHPR17CA0061.namprd17.prod.outlook.com (2603:10b6:300:93::23) To AMSPR07MB312.eurprd07.prod.outlook.com (2a01:111:e400:802f::24) X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: b16b39c5-8bf3-4539-5a44-08d531c7f15c X-Microsoft-Antispam: UriScan:; BCL:0; PCL:0; RULEID:(5600022)(4604075)(4534020)(4602075)(4627115)(201703031133081)(201702281549075)(2017052603258); SRVR:AMSPR07MB312; X-Microsoft-Exchange-Diagnostics: 1; AMSPR07MB312; 3:TbBRDP9bpDBE8uVsNCXlIabOU7GDSmZGNE8IU4TK7B/W+vDNHaSSGtWrY+9WH/0xOSeZFBoI2gISrdgRS9CFnOajs/WE4u5prtxyJo7lB3yL/JiJalPYYRLmlUjCx8Ju2TSyhcK6N4AaIj116vZqDLkdlfOK0gfV6fOzo7uWokkvZ3qWkwKJC0bHaffLd857/OB+Ytelg/F5+ZLitT4c9XnwrAUw2fhUJntFGpnRHruzuyV4z3dKCtz+sqrucTp1; 25:Mdjc0lRlss9K2ISobiE7twokry12pys7ftTUiuEixOruX6v9Md1forT39jk3OudzGR7Q9mRf/2b+HODPae9mQB+t8N1EThWAkbv7gI+YAbucvBD1OywbVnz2El65zEFcbYKrvsxhnohmZ7zCB28/b3BeuD3UwSott9bvtRUkjSn0jUx1Y+Go9diVjPz2dCKAdbPVSflW1GNlLkSPrB7jWblZeEiE4L5mnMtb/wFIA6Y/VpLuq19EboLdCO6OuxESS708z51JgjYhpxJhCQj6cBL+a6yTsUBOI9sES6UxrkxooL2+y3TYldOzCZ+CcGqgbqbjkyw/IKY/YSzq8DU+KA==; 31:MBAFkosb34veeTE3KRrWLIJMceKMDSjMeTQaFdUBrwwLnBq2cjzqoTU9rovXN14IMlxeXrzOixHv5ZIpKhuhpHdzbNSSTaaqo+hfNSRY0AxRGybpswrX1Tt9pEOzc/JMN3vhna12JGAhRb5RZP1rh37tAPeyGcPRSx4nJsEDXtvM6iEyyZFV3jygt028CEc+U7tC9e7VnQAXU+1XYrDsDPqXItxu4QTV1NaRPTSEcYM= X-MS-TrafficTypeDiagnostic: AMSPR07MB312: X-Microsoft-Exchange-Diagnostics: 1; AMSPR07MB312; 20:DFQWRNbN5DHKkNDOntb+RogFT7Uw390++qKg/ccuc8WPDYXPF9dcVbzvmJV7zNeNSpTxBuCDG9RQTDuEfh2DhqEaYwS+Z467OCkTQmQv9Kb9zuLa18XitYHqR3nXIF5vEDzpB3zGk9PaCq2LnuMhyMUphFQpe+mPoYJRfHz+BtiWpB0uQjtL+WaMmtXsPxBjZgd/bjeUdJv03URCzFELN2N77YRkPXPfnTQKyO0SpYStx88mzuEIB1zUBSIZPVCxFcA+UZgll37S19qTMmAxT3SkbMtwvbh7MJeiUaHakbsppDRa3zL4pBWbCl3wtynjHXhfqkB1Inooui5yQBh1IPiAYJ91JO3vCIRPudaw4w1/2ApoqadE7KAgT4ztdBoB0pR5MMirQ8UANwd8968kVhtVY9jOBFM9VY0tUQky1qxxGyVM0imZnJK6LCpSV5ffevzPlHJxBttBIlKWDihtrg79BtAo90tpq4oaSlqabMQjz/0rz5sHap7mluEog2Yi; 4:r4MzLRg9Yyd6i0PO8UeVDNvKuwX1NwAi21H/4a+MZxy+teLKDNHSVHp8xkep4uTGTfKIfiCtLp/i3Oz1HXBWdN5QtFb9CPiM3wnV9OhQWkSpzvVCBZHeeCKOlqGvwh9AQOlVXib2He6qsOkcenJg+/BPpis3gFyRdaRcC/5nERi6gEWyzSTHDCvRJ7KJ5akHDP0nd90L0bAD1iagCGpiyDvEopln/FszXtR+ui2lh4s72o+/g9fxBnWv2BW26nL/yFGCg+w76T/1IxUOQhRoiAgULVpNWPynh3uRxreMt+AMkkKIv0jP3lItnJGUUMi+ X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(160773892695471); X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(100000700101)(100105000095)(100000701101)(100105300095)(100000702101)(100105100095)(6040450)(2401047)(5005006)(8121501046)(100000703101)(100105400095)(10201501046)(3002001)(3231022)(93006095)(93001095)(6041248)(20161123560025)(20161123558100)(20161123555025)(20161123562025)(20161123564025)(201703131423075)(201702281528075)(201703061421075)(201703061406153)(6072148)(201708071742011)(100000704101)(100105200095)(100000705101)(100105500095); SRVR:AMSPR07MB312; BCL:0; PCL:0; RULEID:(100000800101)(100110000095)(100000801101)(100110300095)(100000802101)(100110100095)(100000803101)(100110400095)(100000804101)(100110200095)(100000805101)(100110500095); SRVR:AMSPR07MB312; X-Forefront-PRVS: 0499DAF22A X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10009020)(6009001)(346002)(376002)(39860400002)(199003)(189002)(54534003)(4326008)(2351001)(81166006)(97736004)(2361001)(5660300001)(25786009)(7736002)(5003940100001)(48376002)(106356001)(50466002)(66066001)(189998001)(50226002)(33646002)(68736007)(305945005)(101416001)(16526018)(8676002)(36756003)(966005)(53936002)(6306002)(6512007)(53946003)(316002)(69596002)(16586007)(81156014)(53416004)(5890100001)(6506006)(2950100002)(6116002)(6486002)(2906002)(50986999)(47776003)(76176999)(105586002)(86362001)(478600001)(6916009)(8936002)(3846002)(6666003); DIR:OUT; SFP:1101; SCL:1; SRVR:AMSPR07MB312; H:elxacz23q12.ericsson.se; FPR:; SPF:None; PTR:InfoNoRecords; A:1; MX:1; LANG:en; Received-SPF: None (protection.outlook.com: ericsson.com does not designate permitted sender hosts) X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; AMSPR07MB312; 23:eNXTIiLGAutcwrByd1mCZ/CSrYLrAck0W1Lhi6nxLQ?= =?us-ascii?Q?K3pCeaBdBwvbB4iD7d2i/Ay5OMeX5hFvPqQFNqFzRUH34CefbVQREXdQD301?= =?us-ascii?Q?SnLeTEAyOPRbOSbNyVJyNVYlEmUAdZZhlsrWu1dlDc9mhDOzlU0fthB5wgQJ?= =?us-ascii?Q?itaKgiddWgSYdEKDi8B04wTpFupPScasIgzQ8rJIXWzIIqjfbLV6IcpzTDmA?= =?us-ascii?Q?OGKH2NWrQoaekZbcHU++G5cWJsfkV+HtK8cvuldB538upKyaqlSwdfhlTCdw?= =?us-ascii?Q?91wSMYrnNvDU1SpWJfflKx7Pw933/yA0VPT5UxB9cIkvMSwcpJkmE9XYVGhO?= =?us-ascii?Q?jZLjkwhAMAk83ZeSSxh5Vtn904LUAZD8NahXhR418BOAL4EmoCs4lUPwpCm+?= =?us-ascii?Q?+LB6zHQ8YvxKHmMpiV8I7TYknQKdvLnvF3LCE50QCjnEoC0K1EKIDrU8CF+i?= =?us-ascii?Q?8pZzQ5BP5AjWKQEx1UanCZYm48pmJsxGxSCIsrx/vxMMVMLRX1jaNfJkCM2p?= =?us-ascii?Q?EC584DqIb9JAP1m50KtRo1I/t06GZ0VSC9VP5XQNg9hKZsu3CkGJxemJ/k5C?= =?us-ascii?Q?TXtZ97M8uHPxozkML045yrg5z4Vcrz18cKzx3VE+RYMgWpbyC7vjdSG8WToB?= =?us-ascii?Q?3TtG4tgnc/BzC4BjRnfjbAE1lfqJGqq0+SWCMQlBeDkcyDTSeZVLRQTSwaoy?= =?us-ascii?Q?PahaoABRMnNbmEFnzTG7U/kXng2+uWIbgXjfEMvIkxp8Sv5cqQYXkksQmzHm?= =?us-ascii?Q?adjv6GUVhE9Hl/ADaHpkfckGDcM+3jXUUoSYBz+5KYolNoPefMawN7Y3Th74?= =?us-ascii?Q?tRoH/Q2V/l/plz6bWQ+IanYiAkLx6HZgOcoKERIElRXjxw7NQRZSBIKQ90C3?= =?us-ascii?Q?5086rNxozhuOUB/LbvO9eTmfgXnWjRscuWpSxzDsmSVHT9KEJpAJBksgCKP2?= =?us-ascii?Q?CozSS3i3k41vxcnBsAn+dg3aPx+cvpANZKCia9YsUpRekYN423ACWUHZbjnL?= =?us-ascii?Q?2q5oJV+/yRbgqsiF+sQpGeF++/BO/1jcjc84hzE9DMn3QoEOsDnP4i0qfwSI?= =?us-ascii?Q?6hEDyXK6jAnah2GYPck33qDe8oDIr4VSRSVuWReRanuBdUjr6VMrqMP9LJnq?= =?us-ascii?Q?2VqOa722xJr1RZ+c1kFXswpwJDG157taFJmdfo0shXD4iKi39uKwH5JtnuCs?= =?us-ascii?Q?bLjVv/gIxEMSbHgdnjAH1jfT9tgzUENOYxV+htu3NCXPD+C6iJYG7lGqYCXd?= =?us-ascii?Q?HDxs3GdLxYb+/rxiepXMJxKkrlz49MvVg2Dx4W?= X-Microsoft-Exchange-Diagnostics: 1; AMSPR07MB312; 6:nDpcjQm5jJmmGecwPENdLptbtti1mD3Jx9K2eVD9qG3a51KSbqziyZBpcZnUlyJjrrydts/V15Z9gtQHyOBqFwC00+nnCaqqAL9XIFc3+6KL+uFcpIb10DQu69zVyn6YuiehDwIcPaPsTctuR4ogSLn6RjQNcsgci+UrW2Vj0K+Y0Wl5wKcrskpyXnnb3bWwN8x0XLlS/x6Bo94TC2oosoGtZIF/vdHPW5amtvvMw/Ty/PNoq4zjI+8+7vzhPaOJyrYeXyM3rTAZvVfRzdeM8D0l3EJx+UYmuqvvhs9iuc2qz0487ELj042hL/dpZRbXJJAQ1vn6Vk0FvKVK7dXRG47xVeDqYMInFvmjji5fXq0=; 5:FundOwGr0D3uu4Dq5ldxLD+/Li5VjFxXQMQgtbWoQ83YsqgL5C1XrY02YR2vbKl9yFJubEJJgmnry5uR7iQRaPiZb7vSjQPdRSl3bbTwkGE7hfIOUTsY0THEtsgLz/2VF9OEtC5MdBxuRVwo3SLdenTeH3gXOGvOXQTst8h5T7Y=; 24:St+AuBhKuLQ4kBFTxFO19qwBI62RbwNomf7l6/+eL6Dkbhd5p5QgWPq+0l2peGX++AaAI+JekInw6hCMi9ovn85fcwZJcK4UA+gCdSG10JE=; 7:MnYxATgcQmovHENFtYaK9VBW2CpdcaeTyJDbuLTXTorR/Dh4qBWl0pfiPYfT7yFb14PPtL01aOuwmNZyUiP7pgHA3Run5b6SWpFwX0J56MsU8romhR+e91wnjEjdes6hvOY9ZHYxZViLVoAXLiVBWkj3STFaduv6wdD2LXarOZv901XB4hvrA+GdfplSZ15yzHi26L0NQ1HA6rRIKc/QK9/tB+OZbBferThQ38kuC0nslcu/+sMzHOQ3PAv3uTJs SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-MS-Exchange-CrossTenant-OriginalArrivalTime: 22 Nov 2017 16:41:52.5407 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: b16b39c5-8bf3-4539-5a44-08d531c7f15c X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 92e84ceb-fbfd-47ab-be52-080c6b87953f X-MS-Exchange-Transport-CrossTenantHeadersStamped: AMSPR07MB312 X-OriginatorOrg: ericsson.com X-IsSubscribed: yes From: Simon Marchi There are multiple definitions of the private_thread_info structure compiled in the same GDB build. Because of the one definition rule, we need to change this if we want to be able to make them non-POD (e.g. use std::vector fields). This patch creates a class hierarchy, with private_thread_info being an abstract base class, and all the specific implementations inheriting from it. In order to poison XNEW/xfree for non-POD types, it is also needed to get rid of the xfree in thread_info::~thread_info, which operates on an opaque type. This is replaced by thread_info::priv now being a unique_ptr, which calls the destructor of the private_thread_info subclass when the thread is being destroyed. Including gdbthread.h from darwin-nat.h gave these errors: /Users/simark/src/binutils-gdb/gdb/gdbthread.h:609:3: error: must use 'class' tag to refer to type 'thread_info' in this scope thread_info *m_thread; ^ class /usr/include/mach/thread_act.h:240:15: note: class 'thread_info' is hidden by a non-type declaration of 'thread_info' here kern_return_t thread_info ^ It turns out that there is a thread_info function in the Darwin/XNU/mach API: http://web.mit.edu/darwin/src/modules/xnu/osfmk/man/thread_info.html Therefore, I had to add the class keyword at a couple of places in gdbthread.h, I don't really see a way around it. gdb/ChangeLog: * gdbthread.h (private_thread_info): Define structure type, add virtual pure destructor. (thread_info) : Change type to unique_ptr. : Remove. * thread.c (add_thread_with_info): Adjust to use of unique_ptr. (private_thread_info::~private_thread_info): Provide default implementation. (thread_info::~thread_info): Don't call private_dtor nor manually free priv. * aix-thread.c (private_thread_info): Rename to ... (aix_thread_info): ... this. (sync_threadlists): Adjust. (iter_tid): Adjust. (aix_thread_resume): Adjust. (aix_thread_fetch_registers): Adjust. (aix_thread_store_registers): Adjust. (aix_thread_extra_thread_info): Adjust. * darwin-nat.h (private_thread_info): Rename to ... (darwin_thread_info): ... this. * darwin-nat.c (darwin_init_thread_list): Adjust. (darwin_check_new_threads): Adjust. (thread_info_from_private_thread_info): Adjust. * linux-thread-db.c (private_thread_info): Rename to ... (thread_db_thread_info): ... this, initialize fields. : Change type to bool. (update_thread_state): Adjust to type rename. (record_thread): Adjust to type rename an use of unique_ptr. (thread_db_pid_to_str): Likewise. (thread_db_extra_thread_info): Likewise. (thread_db_thread_handle_to_thread_info): Likewise. (thread_db_get_thread_local_address): Likewise. * nto-tdep.h (private_thread_info): Rename to ... (nto_thread_info): ... this, initialize fields. : Change type to std::string. * nto-tdep.c (nto_extra_thread_info): Adjust to type rename and use of unique_ptr. * nto-procfs.c (update_thread_private_data_name): Adjust to std::string change, allocate nto_private_thread_info with new. (update_thread_private_data): Adjust to unique_ptr. * remote.c (private_thread_info): Rename to ... (remote_thread_info): ... this, initialize data members with default values. : Change type to std::string. : Change type to non-pointer. (free_private_thread_info): Remove. (get_private_info_thread): Change return type, adjust to use of unique_ptr, use remote_thread_info constructor. (get_private_info_ptid): Change return type. (remote_thread_name): Use get_private_info_thread, adjust to change to std::string. (struct thread_item) <~thread_item>: Remove. : Make non pointer. (start_thread): Adjust to thread_item::thread_handle type change. (remote_update_thread_list): Adjust to type name change, move strings from temporary to long-lived object instead of duplicating. (remote_threads_extra_info): Use get_private_info_thread. (process_initial_stop_replies): Likewise. (resume_clear_thread_private_info): Likewise. (remote_resume): Adjust to type name change. (remote_commit_resume): Use get_private_info_thread. (process_stop_reply): Adjust to type name change. (remote_stopped_by_sw_breakpoint): Use get_private_info_thread. (remote_stopped_by_hw_breakpoint): Likewise. (remote_stopped_by_watchpoint): Likewise. (remote_stopped_data_address): Likewise. (remote_core_of_thread): Likewise. (remote_thread_handle_to_thread_info): Use get_private_info_thread, adjust to thread_handle field type change. --- gdb/aix-thread.c | 49 ++++++++++++------- gdb/darwin-nat.c | 14 +++--- gdb/darwin-nat.h | 5 +- gdb/gdbthread.h | 18 ++++--- gdb/linux-thread-db.c | 41 ++++++++-------- gdb/nto-procfs.c | 30 +++--------- gdb/nto-tdep.c | 10 ++-- gdb/nto-tdep.h | 10 ++-- gdb/remote.c | 133 ++++++++++++++++++++------------------------------ gdb/thread.c | 14 ++---- 10 files changed, 151 insertions(+), 173 deletions(-) diff --git a/gdb/aix-thread.c b/gdb/aix-thread.c index b5c9f3b..efbc047 100644 --- a/gdb/aix-thread.c +++ b/gdb/aix-thread.c @@ -84,7 +84,8 @@ static int debug_aix_thread; /* Private data attached to each element in GDB's thread list. */ -struct private_thread_info { +struct aix_thread_info : public private_thread_info +{ pthdb_pthread_t pdtid; /* thread's libpthdebug id */ pthdb_tid_t tid; /* kernel thread id */ }; @@ -756,10 +757,12 @@ sync_threadlists (void) } else if (gi == gcount) { - thread = add_thread (ptid_build (infpid, 0, pbuf[pi].pthid)); - thread->priv = XNEW (struct private_thread_info); - thread->priv->pdtid = pbuf[pi].pdtid; - thread->priv->tid = pbuf[pi].tid; + aix_thread_info *priv = new aix_thread_info; + priv->pdtid = pbuf[pi].pdtid; + priv->tid = pbuf[pi].tid; + + thread = add_thread_with_info (ptid_t (infpid, 0, pbuf[pi].pthid), priv); + pi++; } else @@ -776,8 +779,10 @@ sync_threadlists (void) if (cmp_result == 0) { - gbuf[gi]->priv->pdtid = pdtid; - gbuf[gi]->priv->tid = tid; + aix_thread_info *priv = (aix_thread_info *) gbuf[gi]->priv.get (); + + priv->pdtid = pdtid; + priv->tid = tid; pi++; gi++; } @@ -789,9 +794,11 @@ sync_threadlists (void) else { thread = add_thread (pptid); - thread->priv = XNEW (struct private_thread_info); - thread->priv->pdtid = pdtid; - thread->priv->tid = tid; + + aix_thread_info *priv = new aix_thread_info; + thread->priv.reset (priv); + priv->pdtid = pdtid; + priv->tid = tid; pi++; } } @@ -808,8 +815,9 @@ static int iter_tid (struct thread_info *thread, void *tidp) { const pthdb_tid_t tid = *(pthdb_tid_t *)tidp; + aix_thread_info *priv = (aix_thread_info *) thread->priv.get (); - return (thread->priv->tid == tid); + return priv->tid == tid; } /* Synchronize libpthdebug's state with the inferior and with GDB, @@ -998,7 +1006,9 @@ aix_thread_resume (struct target_ops *ops, error (_("aix-thread resume: unknown pthread %ld"), ptid_get_lwp (ptid)); - tid[0] = thread->priv->tid; + aix_thread_info *priv = (aix_thread_info *) thread->priv.get (); + + tid[0] = priv->tid; if (tid[0] == PTHDB_INVALID_TID) error (_("aix-thread resume: no tid for pthread %ld"), ptid_get_lwp (ptid)); @@ -1314,10 +1324,11 @@ aix_thread_fetch_registers (struct target_ops *ops, else { thread = find_thread_ptid (regcache_get_ptid (regcache)); - tid = thread->priv->tid; + aix_thread_info *priv = (aix_thread_info *) thread->priv.get (); + tid = priv->tid; if (tid == PTHDB_INVALID_TID) - fetch_regs_user_thread (regcache, thread->priv->pdtid); + fetch_regs_user_thread (regcache, priv->pdtid); else fetch_regs_kernel_thread (regcache, regno, tid); } @@ -1668,10 +1679,11 @@ aix_thread_store_registers (struct target_ops *ops, else { thread = find_thread_ptid (regcache_get_ptid (regcache)); - tid = thread->priv->tid; + aix_thread_info *priv = (aix_thread_info *) thread->priv.get (); + tid = priv->tid; if (tid == PTHDB_INVALID_TID) - store_regs_user_thread (regcache, thread->priv->pdtid); + store_regs_user_thread (regcache, priv->pdtid); else store_regs_kernel_thread (regcache, regno, tid); } @@ -1759,9 +1771,10 @@ aix_thread_extra_thread_info (struct target_ops *self, return NULL; string_file buf; + aix_thread_info *priv = (aix_thread_info *) thread->priv.get (); - pdtid = thread->priv->pdtid; - tid = thread->priv->tid; + pdtid = priv->pdtid; + tid = priv->tid; if (tid != PTHDB_INVALID_TID) /* i18n: Like "thread-identifier %d, [state] running, suspended" */ diff --git a/gdb/darwin-nat.c b/gdb/darwin-nat.c index f4ed455..0de3eb2 100644 --- a/gdb/darwin-nat.c +++ b/gdb/darwin-nat.c @@ -363,9 +363,8 @@ darwin_check_new_threads (struct inferior *inf) if (new_ix < new_nbr && (old_ix == old_nbr || new_id < old_id)) { /* A thread was created. */ - struct private_thread_info *pti; + darwin_thread_info *pti = new darwin_thread_info; - pti = XCNEW (darwin_thread_t); pti->gdb_port = new_id; pti->msg_state = DARWIN_RUNNING; @@ -1692,16 +1691,19 @@ darwin_attach_pid (struct inferior *inf) push_target (darwin_ops); } -/* Get the thread_info object corresponding to this private_thread_info. */ +/* Get the thread_info object corresponding to this darwin_thread_info. */ static struct thread_info * -thread_info_from_private_thread_info (private_thread_info *pti) +thread_info_from_private_thread_info (darwin_thread_info *pti) { struct thread_info *it; ALL_THREADS (it) { - if (it->priv->gdb_port == pti->gdb_port) + darwin_thread_info *iter_pti + = (darwin_thread_info *) it->priv.get (); + + if (iter_pti->gdb_port == pti->gdb_port) break; } @@ -1719,7 +1721,7 @@ darwin_init_thread_list (struct inferior *inf) gdb_assert (!priv->threads.empty ()); - private_thread_info *first_pti = priv->threads.front (); + darwin_thread_info *first_pti = priv->threads.front (); struct thread_info *first_thread = thread_info_from_private_thread_info (first_pti); diff --git a/gdb/darwin-nat.h b/gdb/darwin-nat.h index 24c10b5..e7b029a 100644 --- a/gdb/darwin-nat.h +++ b/gdb/darwin-nat.h @@ -18,6 +18,7 @@ #define __DARWIN_NAT_H__ #include +#include "gdbthread.h" /* Describe the mach exception handling state for a task. This state is saved before being changed and restored when a process is detached. @@ -69,7 +70,7 @@ enum darwin_msg_state DARWIN_MESSAGE }; -struct private_thread_info +struct darwin_thread_info : public private_thread_info { /* The thread port from a GDB point of view. */ thread_t gdb_port; @@ -92,7 +93,7 @@ struct private_thread_info /* The last exception received. */ struct darwin_exception_msg event; }; -typedef struct private_thread_info darwin_thread_t; +typedef struct darwin_thread_info darwin_thread_t; /* Describe an inferior. */ struct darwin_inferior : public private_inferior diff --git a/gdb/gdbthread.h b/gdb/gdbthread.h index 49fc80f..90cc2b1 100644 --- a/gdb/gdbthread.h +++ b/gdb/gdbthread.h @@ -179,6 +179,12 @@ typedef struct value *value_ptr; DEF_VEC_P (value_ptr); typedef VEC (value_ptr) value_vec; +/* Base class for target-specific thread data. */ +struct private_thread_info +{ + virtual ~private_thread_info () = 0; +}; + /* Threads are intrusively refcounted objects. Being the user-selected thread is normally considered an implicit strong reference and is thus not accounted in the refcount, unlike @@ -345,11 +351,7 @@ public: struct frame_id initiating_frame = null_frame_id; /* Private data used by the target vector implementation. */ - struct private_thread_info *priv = NULL; - - /* Function that is called to free PRIVATE. If this is NULL, then - xfree will be called on PRIVATE. */ - void (*private_dtor) (struct private_thread_info *) = NULL; + std::unique_ptr priv; /* Branch trace information for this thread. */ struct btrace_thread_info btrace {}; @@ -604,7 +606,9 @@ public: DISABLE_COPY_AND_ASSIGN (scoped_restore_current_thread); private: - thread_info *m_thread; + /* Use the "class" keyword here, because of a class with a "thread_info" + function in the Darwin API. */ + class thread_info *m_thread; inferior *m_inf; frame_id m_selected_frame_id; int m_selected_frame_level; @@ -683,7 +687,7 @@ extern void print_selected_thread_frame (struct ui_out *uiout, Selects thread THR. TIDSTR is the original string the thread ID was parsed from. This is used in the error message if THR is not alive anymore. */ -extern void thread_select (const char *tidstr, thread_info *thr); +extern void thread_select (const char *tidstr, class thread_info *thr); extern struct thread_info *thread_list; diff --git a/gdb/linux-thread-db.c b/gdb/linux-thread-db.c index ea032fc..9b8b3bf 100644 --- a/gdb/linux-thread-db.c +++ b/gdb/linux-thread-db.c @@ -251,14 +251,14 @@ delete_thread_db_info (int pid) /* Use "struct private_thread_info" to cache thread state. This is a substantial optimization. */ -struct private_thread_info +struct thread_db_thread_info : public private_thread_info { /* Flag set when we see a TD_DEATH event for this thread. */ - unsigned int dying:1; + bool dying = false; /* Cached thread state. */ - td_thrhandle_t th; - thread_t tid; + td_thrhandle_t th {}; + thread_t tid {}; }; @@ -1040,7 +1040,7 @@ thread_db_inferior_created (struct target_ops *target, int from_tty) from libthread_db thread state information. */ static void -update_thread_state (struct private_thread_info *priv, +update_thread_state (thread_db_thread_info *priv, const td_thrinfo_t *ti_p) { priv->dying = (ti_p->ti_state == TD_THR_UNKNOWN @@ -1057,8 +1057,6 @@ record_thread (struct thread_db_info *info, ptid_t ptid, const td_thrhandle_t *th_p, const td_thrinfo_t *ti_p) { - struct private_thread_info *priv; - /* A thread ID of zero may mean the thread library has not initialized yet. Leave private == NULL until the thread library has initialized. */ @@ -1066,7 +1064,7 @@ record_thread (struct thread_db_info *info, return tp; /* Construct the thread's private data. */ - priv = XCNEW (struct private_thread_info); + thread_db_thread_info *priv = new thread_db_thread_info; priv->th = *th_p; priv->tid = ti_p->ti_tid; @@ -1078,7 +1076,7 @@ record_thread (struct thread_db_info *info, if (tp == NULL || tp->state == THREAD_EXITED) tp = add_thread_with_info (ptid, priv); else - tp->priv = priv; + tp->priv.reset (priv); if (target_has_execution) check_thread_signals (); @@ -1381,11 +1379,11 @@ thread_db_pid_to_str (struct target_ops *ops, ptid_t ptid) if (thread_info != NULL && thread_info->priv != NULL) { static char buf[64]; - thread_t tid; + thread_db_thread_info *priv + = (thread_db_thread_info *) thread_info->priv.get (); - tid = thread_info->priv->tid; snprintf (buf, sizeof (buf), "Thread 0x%lx (LWP %ld)", - (unsigned long) tid, ptid_get_lwp (ptid)); + (unsigned long) priv->tid, ptid_get_lwp (ptid)); return buf; } @@ -1404,7 +1402,9 @@ thread_db_extra_thread_info (struct target_ops *self, if (info->priv == NULL) return NULL; - if (info->priv->dying) + thread_db_thread_info *priv = (thread_db_thread_info *) info->priv.get (); + + if (priv->dying) return "Exiting"; return NULL; @@ -1434,7 +1434,9 @@ thread_db_thread_handle_to_thread_info (struct target_ops *ops, ALL_NON_EXITED_THREADS (tp) { - if (tp->inf == inf && tp->priv != NULL && handle_tid == tp->priv->tid) + thread_db_thread_info *priv = (thread_db_thread_info *) tp->priv.get (); + + if (tp->inf == inf && priv != NULL && handle_tid == priv->tid) return tp; } @@ -1464,9 +1466,9 @@ thread_db_get_thread_local_address (struct target_ops *ops, { td_err_e err; psaddr_t address; - struct thread_db_info *info; - - info = get_thread_db_info (ptid_get_pid (ptid)); + thread_db_info *info = get_thread_db_info (ptid_get_pid (ptid)); + thread_db_thread_info *priv + = (thread_db_thread_info *) thread_info->priv.get (); /* Finally, get the address of the variable. */ if (lm != 0) @@ -1479,7 +1481,7 @@ thread_db_get_thread_local_address (struct target_ops *ops, /* Note the cast through uintptr_t: this interface only works if a target address fits in a psaddr_t, which is a host pointer. So a 32-bit debugger can not access 64-bit TLS through this. */ - err = info->td_thr_tls_get_addr_p (&thread_info->priv->th, + err = info->td_thr_tls_get_addr_p (&priv->th, (psaddr_t)(uintptr_t) lm, offset, &address); } @@ -1497,8 +1499,7 @@ thread_db_get_thread_local_address (struct target_ops *ops, PR libc/16831 due to GDB PR threads/16954 LOAD_MODULE is also NULL. The constant number 1 depends on GNU __libc_setup_tls initialization of l_tls_modid to 1. */ - err = info->td_thr_tlsbase_p (&thread_info->priv->th, - 1, &address); + err = info->td_thr_tlsbase_p (&priv->th, 1, &address); address = (char *) address + offset; } diff --git a/gdb/nto-procfs.c b/gdb/nto-procfs.c index 1da1a98..5906eb6 100644 --- a/gdb/nto-procfs.c +++ b/gdb/nto-procfs.c @@ -248,38 +248,24 @@ static void update_thread_private_data_name (struct thread_info *new_thread, const char *newname) { - int newnamelen; - struct private_thread_info *pti; + nto_thread_info *pti = (nto_thread_info *) new_thread->priv.get (); gdb_assert (newname != NULL); gdb_assert (new_thread != NULL); - newnamelen = strlen (newname); - if (!new_thread->priv) - { - new_thread->priv = xmalloc (offsetof (struct private_thread_info, - name) - + newnamelen + 1); - memcpy (new_thread->priv->name, newname, newnamelen + 1); - } - else if (strcmp (newname, new_thread->priv->name) != 0) + + if (pti) { - /* Reallocate if neccessary. */ - int oldnamelen = strlen (new_thread->priv->name); - - if (oldnamelen < newnamelen) - new_thread->priv = xrealloc (new_thread->priv, - offsetof (struct private_thread_info, - name) - + newnamelen + 1); - memcpy (new_thread->priv->name, newname, newnamelen + 1); + pti = new nto_thread_info; + new_thread->priv.reset (pti); } + + pti->name = newname; } static void update_thread_private_data (struct thread_info *new_thread, pthread_t tid, int state, int flags) { - struct private_thread_info *pti; procfs_info pidinfo; struct _thread_name *tn; procfs_threadctl tctl; @@ -306,7 +292,7 @@ update_thread_private_data (struct thread_info *new_thread, update_thread_private_data_name (new_thread, tn->name_buf); - pti = (struct private_thread_info *) new_thread->priv; + nto_thread_info *pti = (nto_thread_info *) new_thread->priv.get (); pti->tid = tid; pti->state = state; pti->flags = flags; diff --git a/gdb/nto-tdep.c b/gdb/nto-tdep.c index 27bd191..97b940a 100644 --- a/gdb/nto-tdep.c +++ b/gdb/nto-tdep.c @@ -380,9 +380,13 @@ static const char *nto_thread_state_str[] = const char * nto_extra_thread_info (struct target_ops *self, struct thread_info *ti) { - if (ti && ti->priv - && ti->priv->state < ARRAY_SIZE (nto_thread_state_str)) - return (char *)nto_thread_state_str [ti->priv->state]; + if (ti != NULL && ti->priv != NULL) + { + nto_thread_info *priv = (nto_thread_info *) ti->priv.get (); + + if (priv->state < ARRAY_SIZE (nto_thread_state_str)) + return nto_thread_state_str [priv->state]; + } return ""; } diff --git a/gdb/nto-tdep.h b/gdb/nto-tdep.h index afe3452..46acba2 100644 --- a/gdb/nto-tdep.h +++ b/gdb/nto-tdep.h @@ -134,12 +134,12 @@ typedef struct _debug_regs qnx_reg64 padding[1024]; } nto_regset_t; -struct private_thread_info +struct nto_thread_info : public private_thread_info { - short tid; - unsigned char state; - unsigned char flags; - char name[1]; + short tid = 0; + unsigned char state = 0; + unsigned char flags = 0; + std::string name; }; /* Per-inferior data, common for both procfs and remote. */ diff --git a/gdb/remote.c b/gdb/remote.c index 0270f95..244ab32 100644 --- a/gdb/remote.c +++ b/gdb/remote.c @@ -439,23 +439,23 @@ struct remote_state struct readahead_cache readahead_cache; }; -/* Private data that we'll store in (struct thread_info)->private. */ -struct private_thread_info +/* Private data that we'll store in (struct thread_info)->priv. */ +struct remote_thread_info : public private_thread_info { - char *extra; - char *name; - int core; + std::string extra; + std::string name; + int core = -1; /* Thread handle, perhaps a pthread_t or thread_t value, stored as a sequence of bytes. */ - gdb::byte_vector *thread_handle; + gdb::byte_vector thread_handle; /* Whether the target stopped for a breakpoint/watchpoint. */ - enum target_stop_reason stop_reason; + enum target_stop_reason stop_reason = TARGET_STOPPED_BY_NO_REASON; /* This is set to the data address of the access causing the target to stop for a watchpoint. */ - CORE_ADDR watch_data_address; + CORE_ADDR watch_data_address = 0; /* Fields used by the vCont action coalescing implemented in remote_resume / remote_commit_resume. remote_resume stores each @@ -465,26 +465,17 @@ struct private_thread_info /* True if the last target_resume call for this thread was a step request, false if a continue request. */ - int last_resume_step; + int last_resume_step = 0; /* The signal specified in the last target_resume call for this thread. */ - enum gdb_signal last_resume_sig; + gdb_signal last_resume_sig = GDB_SIGNAL_0; /* Whether this thread was already vCont-resumed on the remote side. */ - int vcont_resumed; + int vcont_resumed = 0; }; -static void -free_private_thread_info (struct private_thread_info *info) -{ - xfree (info->extra); - xfree (info->name); - delete info->thread_handle; - xfree (info); -} - /* This data could be associated with a target, but we do not always have access to the current target when we need it, so for now it is static. This will be fine for as long as only one target is in use @@ -1826,8 +1817,8 @@ remote_add_inferior (int fake_pid_p, int pid, int attached, return inf; } -static struct private_thread_info * - get_private_info_thread (struct thread_info *info); +static remote_thread_info * + get_private_info_thread (thread_info *thread); /* Add thread PTID to GDB's thread list. Tag it as executing/running according to RUNNING. */ @@ -1946,34 +1937,20 @@ remote_notice_new_inferior (ptid_t currthread, int executing) /* Return THREAD's private thread data, creating it if necessary. */ -static struct private_thread_info * -get_private_info_thread (struct thread_info *thread) +static remote_thread_info * +get_private_info_thread (thread_info *thread) { gdb_assert (thread != NULL); if (thread->priv == NULL) - { - struct private_thread_info *priv = XNEW (struct private_thread_info); - - thread->private_dtor = free_private_thread_info; - thread->priv = priv; + thread->priv.reset (new remote_thread_info); - priv->core = -1; - priv->extra = NULL; - priv->name = NULL; - priv->name = NULL; - priv->last_resume_step = 0; - priv->last_resume_sig = GDB_SIGNAL_0; - priv->vcont_resumed = 0; - priv->thread_handle = nullptr; - } - - return thread->priv; + return (remote_thread_info *) thread->priv.get (); } /* Return PTID's private thread data, creating it if necessary. */ -static struct private_thread_info * +static remote_thread_info * get_private_info_ptid (ptid_t ptid) { struct thread_info *info = find_thread_ptid (ptid); @@ -2294,7 +2271,7 @@ static const char * remote_thread_name (struct target_ops *ops, struct thread_info *info) { if (info->priv != NULL) - return info->priv->name; + return get_private_info_thread (info)->name.c_str (); return NULL; } @@ -2978,11 +2955,6 @@ struct thread_item : ptid (ptid_) {} - ~thread_item () - { - delete thread_handle; - } - /* The thread's PTID. */ ptid_t ptid; @@ -2996,8 +2968,7 @@ struct thread_item int core = -1; /* The thread handle associated with the thread. */ - gdb::byte_vector *thread_handle = NULL; - + gdb::byte_vector thread_handle; }; /* Context passed around to the various methods listing remote @@ -3123,10 +3094,7 @@ start_thread (struct gdb_xml_parser *parser, attr = xml_find_attribute (attributes, "handle"); if (attr != NULL) - { - item.thread_handle = new gdb::byte_vector; - *item.thread_handle = hex2bin ((const char *) attr->value); - } + item.thread_handle = hex2bin ((const char *) attr->value); } static void @@ -3288,7 +3256,6 @@ remote_update_thread_list (struct target_ops *ops) { if (item.ptid != null_ptid) { - struct private_thread_info *info; /* In non-stop mode, we assume new found threads are executing until proven otherwise with a stop reply. In all-stop, we can only get here if all threads are @@ -3297,12 +3264,12 @@ remote_update_thread_list (struct target_ops *ops) remote_notice_new_inferior (item.ptid, executing); - info = get_private_info_ptid (item.ptid); + remote_thread_info *info + = get_private_info_ptid (item.ptid); info->core = item.core; - info->extra = xstrdup (item.extra.c_str ()); - info->name = xstrdup (item.name.c_str ()); - info->thread_handle = item.thread_handle; - item.thread_handle = nullptr; + info->extra = std::move (item.extra); + info->name = std::move (item.name); + info->thread_handle = std::move (item.thread_handle); } } } @@ -3351,8 +3318,8 @@ remote_threads_extra_info (struct target_ops *self, struct thread_info *tp) { struct thread_info *info = find_thread_ptid (tp->ptid); - if (info && info->priv) - return info->priv->extra; + if (info != NULL && info->priv != NULL) + return get_private_info_thread (info)->extra.c_str (); else return NULL; } @@ -3928,7 +3895,7 @@ process_initial_stop_replies (int from_tty) set_executing (event_ptid, 0); set_running (event_ptid, 0); - thread->priv->vcont_resumed = 0; + get_private_info_thread (thread)->vcont_resumed = 0; } /* "Notice" the new inferiors before anything related to @@ -5552,8 +5519,10 @@ resume_clear_thread_private_info (struct thread_info *thread) { if (thread->priv != NULL) { - thread->priv->stop_reason = TARGET_STOPPED_BY_NO_REASON; - thread->priv->watch_data_address = 0; + remote_thread_info *priv = get_private_info_thread (thread); + + priv->stop_reason = TARGET_STOPPED_BY_NO_REASON; + priv->watch_data_address = 0; } } @@ -5733,12 +5702,13 @@ remote_resume (struct target_ops *ops, to do vCont action coalescing. */ if (target_is_non_stop_p () && execution_direction != EXEC_REVERSE) { - struct private_thread_info *remote_thr; + remote_thread_info *remote_thr; if (ptid_equal (minus_one_ptid, ptid) || ptid_is_pid (ptid)) remote_thr = get_private_info_ptid (inferior_ptid); else remote_thr = get_private_info_ptid (ptid); + remote_thr->last_resume_step = step; remote_thr->last_resume_sig = siggnal; return; @@ -6003,7 +5973,7 @@ remote_commit_resume (struct target_ops *ops) /* Threads first. */ ALL_NON_EXITED_THREADS (tp) { - struct private_thread_info *remote_thr = tp->priv; + remote_thread_info *remote_thr = get_private_info_thread (tp); if (!tp->executing || remote_thr->vcont_resumed) continue; @@ -7220,8 +7190,6 @@ process_stop_reply (struct stop_reply *stop_reply, && status->kind != TARGET_WAITKIND_SIGNALLED && status->kind != TARGET_WAITKIND_NO_RESUMED) { - struct private_thread_info *remote_thr; - /* Expedited registers. */ if (stop_reply->regcache) { @@ -7242,7 +7210,7 @@ process_stop_reply (struct stop_reply *stop_reply, } remote_notice_new_inferior (ptid, 0); - remote_thr = get_private_info_ptid (ptid); + remote_thread_info *remote_thr = get_private_info_ptid (ptid); remote_thr->core = stop_reply->core; remote_thr->stop_reason = stop_reply->stop_reason; remote_thr->watch_data_address = stop_reply->watch_data_address; @@ -10039,7 +10007,8 @@ remote_stopped_by_sw_breakpoint (struct target_ops *ops) struct thread_info *thread = inferior_thread (); return (thread->priv != NULL - && thread->priv->stop_reason == TARGET_STOPPED_BY_SW_BREAKPOINT); + && (get_private_info_thread (thread)->stop_reason + == TARGET_STOPPED_BY_SW_BREAKPOINT)); } /* The to_supports_stopped_by_sw_breakpoint method of target @@ -10059,7 +10028,8 @@ remote_stopped_by_hw_breakpoint (struct target_ops *ops) struct thread_info *thread = inferior_thread (); return (thread->priv != NULL - && thread->priv->stop_reason == TARGET_STOPPED_BY_HW_BREAKPOINT); + && (get_private_info_thread (thread)->stop_reason + == TARGET_STOPPED_BY_HW_BREAKPOINT)); } /* The to_supports_stopped_by_hw_breakpoint method of target @@ -10077,7 +10047,8 @@ remote_stopped_by_watchpoint (struct target_ops *ops) struct thread_info *thread = inferior_thread (); return (thread->priv != NULL - && thread->priv->stop_reason == TARGET_STOPPED_BY_WATCHPOINT); + && (get_private_info_thread (thread)->stop_reason + == TARGET_STOPPED_BY_WATCHPOINT)); } static int @@ -10086,9 +10057,10 @@ remote_stopped_data_address (struct target_ops *target, CORE_ADDR *addr_p) struct thread_info *thread = inferior_thread (); if (thread->priv != NULL - && thread->priv->stop_reason == TARGET_STOPPED_BY_WATCHPOINT) + && (get_private_info_thread (thread)->stop_reason + == TARGET_STOPPED_BY_WATCHPOINT)) { - *addr_p = thread->priv->watch_data_address; + *addr_p = get_private_info_thread (thread)->watch_data_address; return 1; } @@ -12925,8 +12897,9 @@ remote_core_of_thread (struct target_ops *ops, ptid_t ptid) { struct thread_info *info = find_thread_ptid (ptid); - if (info && info->priv) - return info->priv->core; + if (info != NULL && info->priv != NULL) + return get_private_info_thread (info)->core; + return -1; } @@ -13523,14 +13496,14 @@ remote_thread_handle_to_thread_info (struct target_ops *ops, ALL_NON_EXITED_THREADS (tp) { - struct private_thread_info *priv = get_private_info_thread (tp); + remote_thread_info *priv = get_private_info_thread (tp); if (tp->inf == inf && priv != NULL) { - if (handle_len != priv->thread_handle->size ()) + if (handle_len != priv->thread_handle.size ()) error (_("Thread handle size mismatch: %d vs %zu (from remote)"), - handle_len, priv->thread_handle->size ()); - if (memcmp (thread_handle, priv->thread_handle->data (), + handle_len, priv->thread_handle.size ()); + if (memcmp (thread_handle, priv->thread_handle.data (), handle_len) == 0) return tp; } diff --git a/gdb/thread.c b/gdb/thread.c index d71568e..052549a 100644 --- a/gdb/thread.c +++ b/gdb/thread.c @@ -316,11 +316,11 @@ add_thread_silent (ptid_t ptid) } struct thread_info * -add_thread_with_info (ptid_t ptid, struct private_thread_info *priv) +add_thread_with_info (ptid_t ptid, private_thread_info *priv) { struct thread_info *result = add_thread_silent (ptid); - result->priv = priv; + result->priv.reset (priv); if (print_thread_events) printf_unfiltered (_("[New %s]\n"), target_pid_to_str (ptid)); @@ -335,6 +335,8 @@ add_thread (ptid_t ptid) return add_thread_with_info (ptid, NULL); } +private_thread_info::~private_thread_info () = default; + thread_info::thread_info (struct inferior *inf_, ptid_t ptid_) : ptid (ptid_), inf (inf_) { @@ -351,14 +353,6 @@ thread_info::thread_info (struct inferior *inf_, ptid_t ptid_) thread_info::~thread_info () { - if (this->priv) - { - if (this->private_dtor) - this->private_dtor (this->priv); - else - xfree (this->priv); - } - xfree (this->name); }