From patchwork Thu Apr 6 19:03:28 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Marchi X-Patchwork-Id: 19884 Received: (qmail 81192 invoked by alias); 6 Apr 2017 19:03:53 -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 81181 invoked by uid 89); 6 Apr 2017 19:03:52 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-25.0 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.2 spammy= X-HELO: sessmg22.ericsson.net Received: from sessmg22.ericsson.net (HELO sessmg22.ericsson.net) (193.180.251.58) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 06 Apr 2017 19:03:48 +0000 Received: from ESESSHC002.ericsson.se (Unknown_Domain [153.88.183.24]) by (Symantec Mail Security) with SMTP id 4D.16.21650.31196E85; Thu, 6 Apr 2017 21:03:47 +0200 (CEST) Received: from EUR03-VE1-obe.outbound.protection.outlook.com (153.88.183.145) by oa.msg.ericsson.com (153.88.183.24) with Microsoft SMTP Server (TLS) id 14.3.339.0; Thu, 6 Apr 2017 21:03:46 +0200 Authentication-Results: sourceware.org; dkim=none (message not signed) header.d=none; sourceware.org; dmarc=none action=none header.from=ericsson.com; Received: from elxcz23q12-y4.ca.am.ericsson.se (192.75.88.130) by AM4PR07MB1716.eurprd07.prod.outlook.com (2603:10a6:200:26::24) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1019.8; Thu, 6 Apr 2017 19:03:44 +0000 From: Simon Marchi To: CC: Simon Marchi Subject: [PATCH v2] Class-ify ptid_t Date: Thu, 6 Apr 2017 15:03:28 -0400 Message-ID: <20170406190328.21103-1-simon.marchi@ericsson.com> MIME-Version: 1.0 X-ClientProxiedBy: MWHPR10CA0007.namprd10.prod.outlook.com (2603:10b6:301::17) To AM4PR07MB1716.eurprd07.prod.outlook.com (2603:10a6:200:26::24) X-MS-Office365-Filtering-Correlation-Id: 9a58dee4-4262-42b8-e717-08d47d1fa676 X-Microsoft-Antispam: UriScan:; BCL:0; PCL:0; RULEID:(22001)(201703131423075)(201703031133081); SRVR:AM4PR07MB1716; X-Microsoft-Exchange-Diagnostics: 1; AM4PR07MB1716; 3:biHCsag/XQXkGBqVZnInTA95uofJVpSCeiRuE3O3uyVJOqClxB7OAzLEFEVQo4sbUUnhoxSfrN9dqRl3HF5UBuTbEDqZTTb5oi6zyp55EIpjhnCe1enLynHPWfv1nmILb21E3ZGRKFV+3sOpwRTBaWr4FDWKBAJj+phyUjb694tCWeo2AcE9X0EEiiJkz9GjD0RT9M46CYRvFauZcY6in9bWdnBlXtB6EPNdMTAYZ+UVAJmMMqOO7jMHIprliW50pfzoWTxfm/A9B9UXJQlYJWRAh6ASjq+T2BsFE2eF6fN0K0BcMKjFLxBeTLyWOvMSJOj3hS3KifdQ2wRvTsyp7w==; 25:vO8796vdVM1EB23HUt1BCcrRl2iDFXQv5Rq5u9C34wzXyuTmYwwHxcJ71vc35F83PO6TYm2xeaFIGXlXwmTP0ejSv7RGtqZTs2i9narNPaijZtuR+l3l0PApAirE9+5zwv5lJSrxvluWw/OnpZzncle/PK+NaJjMoSpLtqsXjnflWUDc18kYGUzpyzDFGZ3YE5jpRN29M1YbJHIhPaQMEzdtw2SQ7ZzH0ma6afdw9NmfTvo/EdFfkfaUCuCRzbW/Ll8vMuqaztYsr7gVDfF1ZSBMV/utIMrD3jyoFb2KV7TYallSJyz874EM7LXE0Y2q3jCfKbe9VVYMssh8eIZLMZe4J7/210AjfH9jTDYT489m9oLlXob+JsFPldW/RdZlzf2Y9MvFfXhdEyFMQEzavtC6fYpb/820Wf0J2W/7MrNZvEkpo9BrCGOQbBOruC0u9sQ/OR71ksUnexsht4cM+g== X-Microsoft-Exchange-Diagnostics: 1; AM4PR07MB1716; 31:QE9Q7dofGG53dFC5GNsVOQHLD/4SVWSVCe/whm/Vv0w8fY7grSm/dxOw52JrcqOObkBTT0mK7zbCQWvky10kGOxFxjRv0At1JE12DBWgDCAFSWdINdb8P8mlqd2sXNmR/MyzgdhgawYwuWdUmiCpia/ZNa3tjbVwB0vPPJ2hoJL0g/Warw0Pmzf9n/1Vbo4jaHB0gdHRNMlHyDJsg3kxqis3WQU6JNPdnGsfsIHeGj4=; 20:METvkChnAU7I/Bj84QtCvOIcLXg9coz7Ygq8V/ZqAmrVQXWMBzqFYGzgLtGya0Bs6/x4x8dz+Ue6yas70D+gV5jB97mYVnd0A92h4lM1F50bASky7owZNjqp9VRblBTx+1REw/DKnCf+uNSc204y8dpXFbgTjtB+frI+IP8ezUelbreDhkO6CjWfN/R3KitdVYngk1/I6WhV7ZrhQmyKM1KOCMlydBQqZrrILva/0IfiqdQI+okGdMvkOd2oKPAUfIjpR6g3350s3IJSnHAwiAJuNv1tKWGg8sUqAmWqO2vsLTdovdD3RNKtuKadM97LED9a44tW2kQLX4fJqjgvx/FQ1xaTjpi4pGVz6CygiVC7vkYRdiK4GFHREA5Y0R8vPibW5VtO5iM0lhsLn+eoj05ejB9A5tz4UJFGrrjHhbSAUhBngdmuyg6GNRXSLC6Hr/PGftClZ1ph67X+XAM6Jk+3M5Zpt7oSXaadS94yW4XsIB4yQWqeyRLRDjbsl443 X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(250305191791016)(22074186197030); X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(6040450)(601004)(2401047)(5005006)(8121501046)(93006095)(93001095)(10201501046)(3002001)(6041248)(20161123560025)(20161123564025)(201703131423075)(201702281528075)(201703061421075)(20161123562025)(20161123555025)(6072148); SRVR:AM4PR07MB1716; BCL:0; PCL:0; RULEID:; SRVR:AM4PR07MB1716; X-Microsoft-Exchange-Diagnostics: 1; AM4PR07MB1716; 4:qscJ8mcJsOq+fxGDoWoxFnhoYls6UWsJvMWfZ0tGB/9Plz66rjalDRdfmH2WOHSd+mGrOj+TyhvNAte39GjW78Sd8lI4NIvpPuvrXquFt2/FjpDZNlf9jFdXMuv95F1bq1WZiskrcoudZs83OnnguSnF5zJS03cX7v6e/Xw6ooR9XfPJ/qxo8dGbi6D30SgL8kSLTEj+4SkYCg0XXOebNeqQhHvCXwPYO3Xh7A0C7s8rAYlapRKazr1CC9MTqarQWUh6MDmzLO1/wZDdqA9ycgfhdl9cOLlRNJdsPma9BDi8NbHbZ5z3lEk8/nbHtoISWo7r3mDZQz4MEoXJrUz5QnqqYTPCiJ/ofW+ZEyBxJnmR0BANHSHtpMl0nqc0eU8HrAGqJ6wWxPyHF979PgNi1VM5K/eHah43oA0RFUvAdYO6qNZzuSx8EBTRArKF/EQRAWRqzTvMGcluuob1aFMHr4wTZH3IQKXoiCfCTqSi3IfvlU9kSPFbLFBtNuHnhw1AFj/NVYz7TGUlHEz/TEyI36tKS1RNyyjQajeOuPzLLApFt9DKy+g8lqLT3IZhfA1BJbmYOK4+W93ueMUV5Z9LIk6QjacpxFuzRoapWxxQDDBrJ12c4q+et9cc7HaXWpOwbPUfxlYJDdoS3Du+rjZD45DGbbuk5brYfJPqQh9zE6foh7oujYy/hpM9IIxazcYBdFfLn77QuCGqTWCgt8IQpliLQOQNKPKoWPRswq6McKDM6yZrW8sLxO5DeFcQDiNxMWDPTcL/I0rAere3hYKE1A/v19Qi8JnulvBBAiTLlmg= X-Forefront-PRVS: 02698DF457 X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10009020)(4630300001)(6009001)(39410400002)(39860400002)(39850400002)(39450400003)(39840400002)(39400400002)(2906002)(53936002)(6486002)(5660300001)(6116002)(3846002)(2351001)(7736002)(33646002)(6512007)(42186005)(6306002)(6506006)(305945005)(47776003)(81166006)(66066001)(107886003)(50226002)(6666003)(8676002)(110136004)(50466002)(38730400002)(86362001)(50986999)(4326008)(6916009)(5003940100001)(25786009)(36756003)(189998001)(1076002); DIR:OUT; SFP:1101; SCL:1; SRVR:AM4PR07MB1716; H:elxcz23q12-y4.ca.am.ericsson.se; FPR:; SPF:None; MLV:sfv; LANG:en; X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; AM4PR07MB1716; 23:2sO2PxsgUe/C8JcgQnhopameSqLaph4ACv230CuVl?= =?us-ascii?Q?zyOgNEfn24ESlOJjvDuAzsbVoNLnbRZj8HSrhhjHEUSqVjY/kDa1QF75+BgS?= =?us-ascii?Q?NVMaOuow7UH9twCsYcezQ/PSbCNt+0EZ5/AFscaAy5uqqli5jO6dGa9NHnnW?= =?us-ascii?Q?BFeRtDCqsFRe2/IIYjJRS9exfUESbUMHR72eyUWz00ublNNmab6ptvEAkxig?= =?us-ascii?Q?6F0n+n/J/IM548S7mTgbxzrpme+y+ppg+3/X03T2VLjDFiGQVq4H+b7VvwUm?= =?us-ascii?Q?RiVAUwgJY01bMFSonVouYwwotTxsmetuKYvCELatlOI04fNbjZCGXI2comqY?= =?us-ascii?Q?es0wKu32K9bbklVOHKIzcMywSwfdJA4TF7nvx1f3YTR+OHL5zVhcJSTyHwa3?= =?us-ascii?Q?VHWIiKyQoYH/exwpc8bpHuulwOgcKbv+5NSz7YK4KZSpf5d+ksv8X/7z67pP?= =?us-ascii?Q?uqO78n7uvbOeb68s7vGqdi2kOnTaUQc/AfCYfyrebRnEqENRp6E6c9KBvxTI?= =?us-ascii?Q?X0MyMN/3VVHIoFBkv9GuXuQ97HxA72K/wUjxn1NG7D3csynpAM8FSecIh1CP?= =?us-ascii?Q?6oY3Un6meXLRMnKgg3AyM36BCR07+br6PM1yMNNu85PMlFhtdYBVfQHR4xBX?= =?us-ascii?Q?ewaRn1yXFtg2Iaabn4/FJNtGl/QmK0csBjoVEiD5lBkvxXZkwknGVNU3VERa?= =?us-ascii?Q?J9tOBBZqTfJQnnM8RP0yLWxh1+lRk/lgRmhk2LTNKDRVDHdynFK24c5tut/F?= =?us-ascii?Q?kAgHQp3ErdCX7ZIiIDR8CY3sJMkKh8yb7Z18eW73UL+qy+DBMo+3QCIG48W1?= =?us-ascii?Q?/z4me0SVMiz6mwR42J2Y54zv/6ssnTPBTVqGjkRhFw5y5Ua1mvusWf7Pugv3?= =?us-ascii?Q?wLo7GeWptB94F5yu1GplCweYydhoos9kAcYdxLL88FdyEdKTXW2loS526jT9?= =?us-ascii?Q?lPxGWTZmK2YimPyBe1LT0/eTp4LgJaJ2NTrdU3r0GrBkh/MBmWttEceQhq4+?= =?us-ascii?Q?xQb87sbo5lkj4N4a5YN5VmQT/tGA/6qR+tqUqL5xN1/yg=3D=3D?= X-Microsoft-Exchange-Diagnostics: 1; AM4PR07MB1716; 6:gm2ZcINHzjKUmYZO64/gHbCdGJz9N0dndWD/uKPuaesknNQ4FVz0+RnHpHJrDqEI5+JpV6TUnq98jjlOLUs6q40T91lY3TByQjwX3+VDAwWHKrgLLvKapneIypORtaLyWy/PqAAlb+LcGvLmHzQZArDZk/HgLbQEZDc7XYDp1ksHrXc/iixkIH0XkiPoNyjIDLNhM9C7Azr0QsrpYUrKYYEijBY+sm8udXuqWVO8UtUoQYU25MsELZykcFMOfWf7YlhMb9rSsBJJ07qqSWGrROB0l01t1CkFK65uEWdVWqmAd4/s4Oj2Mk6+ylUmXlzwmp8V+eEXwMI2T05jXjM/CxwCM8DXqbz5+DxpDEFNcmPuvxI61Fsq0jwPOKW6defiwI/UftWEpg4mo7Y8gxYiEpCxdCe5F7lTuH+qrvgMPZPGESoAaffT4RxqA4aAmb99wjZYVV6xHjJqJy9pG0n51w==; 5:VS9bVumRjUxWtFFiqLirLMUHdTE39oa3iw0euN8mcIYBSp7shco4zsyKr4yOs8B7l68rnoCM/vwHeLvYMtG08Cebjw5HvyO4Xa22We/JpPS+CySQTUTUx7bB7bN+YcCUL/Dg1lKuVbyYOKFvPcgnlw==; 24:+odh9ZEtOqXZ+6f2rB45LdA6H6bpwzgRp9F7MUw25L12PY6LD5R2Eo8BY1dY7w26ShWc6IaPiqrgdR05wgfkZrWMTIoyCuS0QSeD+O9gGx8= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1; AM4PR07MB1716; 7:i8U5mmKHlXI76hqwNMb/EvH2JJLJuYhXcySLu5HPZeBiyxslFyshD0E/tjzSnEvKU+7N9/z59gjlTF72hNF2w0C8vX561GupPCgWgZejycwOXGinwfdUJUbImZAEutf4MsvTyslPDGEZetNh0d/2E2ObSrknnrbJdexCek1ge72yFt4XUKPQtxtGZZTI06eWebo4XzWS2k6wB7gr5FEH1VTDdNrAPHT8QUQF5QIfwa6UGh6yhfZCLzouL5fB7GJJGtRXrF5Zw7sLHidFXsyJ0m2JxIlkojgmTWSAJAdztIhgJ0PLaHLbvplhw4MIArZxVoSGWXiNwd5VtsIgLUydxA== X-MS-Exchange-CrossTenant-OriginalArrivalTime: 06 Apr 2017 19:03:44.7273 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM4PR07MB1716 X-OriginatorOrg: ericsson.com X-IsSubscribed: yes New in v2: - Constructor instead of "build" static method. - Keep the "minus_one" terminology instead of switching to "any". While writing the tests, it made me realize it didn't look very good: "some_ptid.is_any ()" sounds always true... Plus, according to its comment, minus_one_ptid is also used to denote an error, not only the concept of "any" thread. - Removed is_null and is_any (which would have been renamed is_minus_one if it had not been removed). Comparison to null_ptid and minus_one_ptid looks good enough: if (ptid != null_ptid) if (ptid != minus_one_ptid) If prefer if there's only one way to check whether a ptid is null/minus_one, so that we don't find two different styles in the code base. - constexpr everywhere, which allows... - Static tests. - Moved comments from existing ptid functions to ptid_t methods. - Added operator!=. - Other things I forgot. I grew a bit tired of using ptid_get_{lwp,pid,tid} and friends, so I decided to make it a bit easier to use by making it a proper class. The fields are now private, so it's not possible to change a ptid_t field by mistake. The new methods of ptid_t map to existing functions/practice like this: ptid_t (pid, lwp, tid) -> ptid_build (pid, lwp, tid) ptid_t (pid) -> pid_to_ptid (pid) ptid.is_pid () -> ptid_is_pid (ptid) ptid == other -> ptid_equal (ptid, other) ptid != other -> !ptid_equal (ptid, other) ptid.pid () -> ptid_get_pid (ptid) ptid.lwp_p () -> ptid_lwp_p (ptid) ptid.lwp () -> ptid_get_lwp (ptid) ptid.tid_p () -> ptid_tid_p (ptid) ptid.tid () -> ptid_get_tid (ptid) ptid.matches (filter) -> ptid_match (ptid, filter) I've replaced the implementation of the existing functions with calls to the new methods. People are encouraged to gradually switch to using the ptid_t methods instead of the functions (or we can change them all in one pass eventually). Also, I'm not sure if it's worth it (because of ptid_t's relatively small size), but I have made the functions and methods take ptid_t arguments by const reference instead of by value. gdb/ChangeLog: * common/ptid.h (struct ptid): Change to... (class ptid_t): ... this. : New constructors. : New methods. : New static methods. : Rename to... : ...this. : Rename to... : ...this. : Rename to... : ...this. (ptid_build, ptid_get_pid, ptid_get_lwp, ptid_get_tid, ptid_equal, ptid_is_pid, ptid_lwp_p, ptid_tid_p, ptid_match): Take ptid arguments as references, move comment to class ptid_t. * common/ptid.c (null_ptid, minus_one_ptid): Initialize with ptid_t static methods. (ptid_build, pid_to_ptid, ptid_get_pid, ptid_get_tid, ptid_equal, ptid_is_pid, ptid_lwp_p, ptid_tid_p, ptid_match): Take ptid arguments as references, implement using ptid_t methods. * unittests/ptid-selftests.c: New file. * Makefile.in (SUBDIR_UNITTESTS_SRCS): Add unittests/ptid-selftests.c. (SUBDIR_UNITTESTS_OBS): Add unittests/ptid-selftests.o. gdb/gdbserver/ChangeLog: * server.c (handle_v_cont): Initialize thread_resume::thread with null_ptid. --- gdb/Makefile.in | 6 +- gdb/common/ptid.c | 61 ++++++-------- gdb/common/ptid.h | 175 ++++++++++++++++++++++++++++++++--------- gdb/gdbserver/server.c | 2 +- gdb/unittests/ptid-selftests.c | 148 ++++++++++++++++++++++++++++++++++ 5 files changed, 315 insertions(+), 77 deletions(-) create mode 100644 gdb/unittests/ptid-selftests.c diff --git a/gdb/Makefile.in b/gdb/Makefile.in index 479d27344b..23e4bed3aa 100644 --- a/gdb/Makefile.in +++ b/gdb/Makefile.in @@ -525,11 +525,13 @@ SUBDIR_PYTHON_CFLAGS = SUBDIR_UNITTESTS_SRCS = \ unittests/function-view-selftests.c \ - unittests/offset-type-selftests.c + unittests/offset-type-selftests.c \ + unittests/ptid-selftests.c SUBDIR_UNITTESTS_OBS = \ function-view-selftests.o \ - offset-type-selftests.o + offset-type-selftests.o \ + ptid-selftests.o # Opcodes currently live in one of two places. Either they are in the # opcode library, typically ../opcodes, or they are in a header file diff --git a/gdb/common/ptid.c b/gdb/common/ptid.c index b56971b9af..81f16d047e 100644 --- a/gdb/common/ptid.c +++ b/gdb/common/ptid.c @@ -22,20 +22,15 @@ /* See ptid.h for these. */ -ptid_t null_ptid = { 0, 0, 0 }; -ptid_t minus_one_ptid = { -1, 0, 0 }; +ptid_t null_ptid = ptid_t::make_null (); +ptid_t minus_one_ptid = ptid_t::make_minus_one (); /* See ptid.h. */ ptid_t ptid_build (int pid, long lwp, long tid) { - ptid_t ptid; - - ptid.pid = pid; - ptid.lwp = lwp; - ptid.tid = tid; - return ptid; + return ptid_t (pid, lwp, tid); } /* See ptid.h. */ @@ -43,81 +38,69 @@ ptid_build (int pid, long lwp, long tid) ptid_t pid_to_ptid (int pid) { - return ptid_build (pid, 0, 0); + return ptid_t (pid); } /* See ptid.h. */ int -ptid_get_pid (ptid_t ptid) +ptid_get_pid (const ptid_t &ptid) { - return ptid.pid; + return ptid.pid (); } /* See ptid.h. */ long -ptid_get_lwp (ptid_t ptid) +ptid_get_lwp (const ptid_t &ptid) { - return ptid.lwp; + return ptid.lwp (); } /* See ptid.h. */ long -ptid_get_tid (ptid_t ptid) +ptid_get_tid (const ptid_t &ptid) { - return ptid.tid; + return ptid.tid (); } /* See ptid.h. */ int -ptid_equal (ptid_t ptid1, ptid_t ptid2) +ptid_equal (const ptid_t &ptid1, const ptid_t &ptid2) { - return (ptid1.pid == ptid2.pid - && ptid1.lwp == ptid2.lwp - && ptid1.tid == ptid2.tid); + return ptid1 == ptid2; } /* See ptid.h. */ int -ptid_is_pid (ptid_t ptid) +ptid_is_pid (const ptid_t &ptid) { - if (ptid_equal (minus_one_ptid, ptid) - || ptid_equal (null_ptid, ptid)) - return 0; - - return (ptid_get_lwp (ptid) == 0 && ptid_get_tid (ptid) == 0); + return ptid.is_pid (); } /* See ptid.h. */ int -ptid_lwp_p (ptid_t ptid) +ptid_lwp_p (const ptid_t &ptid) { - return (ptid_get_lwp (ptid) != 0); + return ptid.lwp_p (); } /* See ptid.h. */ int -ptid_tid_p (ptid_t ptid) +ptid_tid_p (const ptid_t &ptid) { - return (ptid_get_tid (ptid) != 0); + return ptid.tid_p (); } +/* See ptid.h. */ + int -ptid_match (ptid_t ptid, ptid_t filter) +ptid_match (const ptid_t &ptid, const ptid_t &filter) { - if (ptid_equal (filter, minus_one_ptid)) - return 1; - if (ptid_is_pid (filter) - && ptid_get_pid (ptid) == ptid_get_pid (filter)) - return 1; - else if (ptid_equal (ptid, filter)) - return 1; - - return 0; + return ptid.matches (filter); } diff --git a/gdb/common/ptid.h b/gdb/common/ptid.h index 337bfb0899..a6b5ec7ea2 100644 --- a/gdb/common/ptid.h +++ b/gdb/common/ptid.h @@ -32,65 +32,170 @@ thread_stratum target that might want to sit on top. */ -struct ptid +class ptid_t { +public: + /* Must have a trivial defaulted default constructor so that the + type remains POD. */ + ptid_t () noexcept = default; + + /* Make a ptid given the necessary PID, LWP, and TID components. + + A ptid with only a PID (LWP and TID equal to zero) is usually used to + represent a whole process, including all its lwps/threads. */ + + constexpr ptid_t (int pid, long lwp = 0, long tid = 0) + : m_pid (pid), m_lwp (lwp), m_tid (tid) + {} + + /* Fetch the pid (process id) component from the ptid. */ + + constexpr int pid () const + { return m_pid; } + + /* Return true if the ptid's lwp member is non-zero. */ + + constexpr bool lwp_p () const + { return m_lwp != 0; } + + /* Fetch the lwp (lightweight process) component from the ptid. */ + + constexpr long lwp () const + { return m_lwp; } + + /* Return true if the ptid's tid member is non-zero. */ + + constexpr bool tid_p () const + { return m_tid != 0; } + + /* Fetch the tid (thread id) component from a ptid. */ + + constexpr long tid () const + { return m_tid; } + + /* Return true if the ptid represents a whole process, including all its + lwps/threads. Such ptids have the form of (pid, 0, 0), with + pid != -1. */ + + constexpr bool is_pid () const + { + return (*this != make_null () + && *this != make_minus_one () + && m_lwp == 0 + && m_tid == 0); + } + + /* Compare two ptids to see if they are equal. */ + + constexpr bool operator== (const ptid_t &other) const + { + return (m_pid == other.m_pid + && m_lwp == other.m_lwp + && m_tid == other.m_tid); + } + + /* Compare two ptids to see if they are different. */ + + constexpr bool operator!= (const ptid_t &other) const + { + return !(*this == other); + } + + /* Returns true if the ptid matches FILTER. FILTER can be the wild + card MINUS_ONE_PTID (all ptid match it); can be a ptid representing + a process (ptid_is_pid returns true), in which case, all lwps and + threads of that given process match, lwps and threads of other + processes do not; or, it can represent a specific thread, in which + case, only that thread will match true. The ptid must represent a + specific LWP or THREAD, it can never be a wild card. */ + + constexpr bool matches (const ptid_t &filter) const + { + return (/* If filter represents any ptid, it's always a match. */ + filter == make_minus_one () + /* If filter is only a pid, any ptid with that pid + matches. */ + || (filter.is_pid () && m_pid == filter.pid ()) + + /* Otherwise, this ptid only matches if it's exactly equal + to filter. */ + || *this == filter); + } + + /* Make a null ptid. */ + + static constexpr ptid_t + make_null () + { return {0, 0, 0}; } + + /* Make a minus one ptid. */ + + static constexpr ptid_t + make_minus_one () + { return {-1, 0, 0}; } + +private: /* Process id. */ - int pid; + int m_pid; /* Lightweight process id. */ - long lwp; + long m_lwp; /* Thread id. */ - long tid; + long m_tid; }; -typedef struct ptid ptid_t; - /* The null or zero ptid, often used to indicate no process. */ + extern ptid_t null_ptid; /* The (-1,0,0) ptid, often used to indicate either an error condition or a "don't care" condition, i.e, "run all threads." */ + extern ptid_t minus_one_ptid; -/* Make a ptid given the necessary PID, LWP, and TID components. */ -ptid_t ptid_build (int pid, long lwp, long tid); -/* Make a new ptid from just a pid. This ptid is usually used to - represent a whole process, including all its lwps/threads. */ -ptid_t pid_to_ptid (int pid); +/* The following functions are kept for backwards compatibility. The use of + the ptid_t methods is preferred. */ + +/* See ptid_t::ptid_t. */ + +extern ptid_t ptid_build (int pid, long lwp, long tid); + +/* See ptid_t::ptid_t. */ + +extern ptid_t pid_to_ptid (int pid); + +/* See ptid_t::pid. */ + +extern int ptid_get_pid (const ptid_t &ptid); + +/* See ptid_t::lwp. */ + +extern long ptid_get_lwp (const ptid_t &ptid); + +/* See ptid_t::tid. */ + +extern long ptid_get_tid (const ptid_t &ptid); + +/* See ptid_t::operator== and ptid_t::operator!=. */ -/* Fetch the pid (process id) component from a ptid. */ -int ptid_get_pid (ptid_t ptid); +extern int ptid_equal (const ptid_t &ptid1, const ptid_t &ptid2); -/* Fetch the lwp (lightweight process) component from a ptid. */ -long ptid_get_lwp (ptid_t ptid); +/* See ptid_t::is_pid. */ -/* Fetch the tid (thread id) component from a ptid. */ -long ptid_get_tid (ptid_t ptid); +extern int ptid_is_pid (const ptid_t &ptid); -/* Compare two ptids to see if they are equal. */ -int ptid_equal (ptid_t ptid1, ptid_t ptid2); +/* See ptid_t::lwp_p. */ -/* Returns true if PTID represents a whole process, including all its - lwps/threads. Such ptids have the form of (pid,0,0), with pid != - -1. */ -int ptid_is_pid (ptid_t ptid); +extern int ptid_lwp_p (const ptid_t &ptid); -/* Return true if PTID's lwp member is non-zero. */ -int ptid_lwp_p (ptid_t ptid); +/* See ptid_t::tid_p. */ -/* Return true if PTID's tid member is non-zero. */ -int ptid_tid_p (ptid_t ptid); +extern int ptid_tid_p (const ptid_t &ptid); -/* Returns true if PTID matches filter FILTER. FILTER can be the wild - card MINUS_ONE_PTID (all ptid match it); can be a ptid representing - a process (ptid_is_pid returns true), in which case, all lwps and - threads of that given process match, lwps and threads of other - processes do not; or, it can represent a specific thread, in which - case, only that thread will match true. PTID must represent a - specific LWP or THREAD, it can never be a wild card. */ +/* See ptid_t::matches. */ -extern int ptid_match (ptid_t ptid, ptid_t filter); +extern int ptid_match (const ptid_t &ptid, const ptid_t &filter); #endif diff --git a/gdb/gdbserver/server.c b/gdb/gdbserver/server.c index 51f6a28419..9cc6145b05 100644 --- a/gdb/gdbserver/server.c +++ b/gdb/gdbserver/server.c @@ -2654,7 +2654,7 @@ handle_v_cont (char *own_buf) char *p, *q; int n = 0, i = 0; struct thread_resume *resume_info; - struct thread_resume default_action = {{0}}; + struct thread_resume default_action { null_ptid }; /* Count the number of semicolons in the packet. There should be one for every action. */ diff --git a/gdb/unittests/ptid-selftests.c b/gdb/unittests/ptid-selftests.c new file mode 100644 index 0000000000..74cc3e0491 --- /dev/null +++ b/gdb/unittests/ptid-selftests.c @@ -0,0 +1,148 @@ +/* Self tests for ptid_t for GDB, the GNU debugger. + + Copyright (C) 2017 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#include "defs.h" +#include "common/ptid.h" +#include + +namespace selftests { +namespace ptid { + +/* Check that the ptid_t class is POD. + + This isn't a strict requirement. If we have a good reason to change it to + a non-POD type, we can remove this check. */ + +static_assert (std::is_pod::value, "ptid_t is POD"); + +/* Build some useful ptids. */ + +static constexpr ptid_t pid = ptid_t (1); +static constexpr ptid_t lwp = ptid_t (1, 2, 0); +static constexpr ptid_t tid = ptid_t (1, 0, 2); +static constexpr ptid_t both = ptid_t (1, 2, 2); + +/* Build some constexpr version of null_ptid and minus_one_ptid to use in + static_assert. Once the real ones are made constexpr, we can get rid of + these. */ + +static constexpr ptid_t null = ptid_t::make_null (); +static constexpr ptid_t minus_one = ptid_t::make_minus_one (); + +/* Verify pid. */ + +static_assert (pid.pid () == 1, "pid's pid is right"); +static_assert (lwp.pid () == 1, "lwp's pid is right"); +static_assert (tid.pid () == 1, "tid's pid is right"); +static_assert (both.pid () == 1, "both's pid is right"); + +/* Verify lwp_p. */ + +static_assert (!pid.lwp_p (), "pid's lwp_p is right"); +static_assert (lwp.lwp_p (), "lwp's lwp_p is right"); +static_assert (!tid.lwp_p (), "tid's lwp_p is right"); +static_assert (both.lwp_p (), "both's lwp_p is right"); + +/* Verify lwp. */ + +static_assert (pid.lwp () == 0, "pid's lwp is right"); +static_assert (lwp.lwp () == 2, "lwp's lwp is right"); +static_assert (tid.lwp () == 0, "tid's lwp is right"); +static_assert (both.lwp () == 2, "both's lwp is right"); + +/* Verify tid_p. */ + +static_assert (!pid.tid_p (), "pid's tid_p is right"); +static_assert (!lwp.tid_p (), "lwp's tid_p is right"); +static_assert (tid.tid_p (), "tid's tid_p is right"); +static_assert (both.tid_p (), "both's tid_p is right"); + +/* Verify tid. */ + +static_assert (pid.tid () == 0, "pid's tid is right"); +static_assert (lwp.tid () == 0, "lwp's tid is right"); +static_assert (tid.tid () == 2, "tid's tid is right"); +static_assert (both.tid () == 2, "both's tid is right"); + +/* Verify is_pid. */ + +static_assert (pid.is_pid (), "pid is a pid"); +static_assert (!lwp.is_pid (), "lwp isn't a pid"); +static_assert (!tid.is_pid (), "tid isn't a pid"); +static_assert (!both.is_pid (), "both isn't a pid"); +static_assert (!null.is_pid (), "null ptid isn't a pid"); +static_assert (!minus_one.is_pid (), "minus one ptid isn't a pid"); + +/* Verify operator ==. */ + +static_assert (pid == ptid_t (1, 0, 0), "pid operator== is right"); +static_assert (lwp == ptid_t (1, 2, 0), "lwp operator== is right"); +static_assert (tid == ptid_t (1, 0, 2), "tid operator== is right"); +static_assert (both == ptid_t (1, 2, 2), "both operator== is right"); + +/* Verify operator !=. */ + +static_assert (pid != ptid_t (2, 0, 0), "pid isn't equal to a different pid"); +static_assert (pid != lwp, "pid isn't equal to one of its thread"); +static_assert (lwp != tid, "lwp isn't equal to tid"); +static_assert (both != lwp, "both isn't equal to lwp"); +static_assert (both != tid, "both isn't equal to tid"); + +/* Verify matches against minus_one. */ + +static_assert (pid.matches (minus_one), "pid matches minus one"); +static_assert (lwp.matches (minus_one), "lwp matches minus one"); +static_assert (tid.matches (minus_one), "tid matches minus one"); +static_assert (both.matches (minus_one), "both matches minus one"); + +/* Verify matches against pid. */ + +static_assert (pid.matches (pid), "pid matches pid"); +static_assert (lwp.matches (pid), "lwp matches pid"); +static_assert (tid.matches (pid), "tid matches pid"); +static_assert (both.matches (pid), "both matches pid"); +static_assert (!ptid_t (2, 0, 0).matches (pid), "other pid doesn't match pid"); +static_assert (!ptid_t (2, 2, 0).matches (pid), "other lwp doesn't match pid"); +static_assert (!ptid_t (2, 0, 2).matches (pid), "other tid doesn't match pid"); +static_assert (!ptid_t (2, 2, 2).matches (pid), "other both doesn't match pid"); + +/* Verify matches against exact matches. */ + +static_assert (!pid.matches (lwp), "pid matches lwp"); +static_assert (lwp.matches (lwp), "lwp matches lwp"); +static_assert (!tid.matches (lwp), "tid matches lwp"); +static_assert (!both.matches (lwp), "both matches lwp"); +static_assert (!ptid_t (2, 2, 0).matches (lwp), "other lwp doesn't match lwp"); + +static_assert (!pid.matches (tid), "pid matches tid"); +static_assert (!lwp.matches (tid), "lwp matches tid"); +static_assert (tid.matches (tid), "tid matches tid"); +static_assert (!both.matches (tid), "both matches tid"); +static_assert (!ptid_t (2, 0, 2).matches (tid), "other tid doesn't match tid"); + +static_assert (!pid.matches (both), "pid matches both"); +static_assert (!lwp.matches (both), "lwp matches both"); +static_assert (!tid.matches (both), "tid matches both"); +static_assert (both.matches (both), "both matches both"); +static_assert (!ptid_t (2, 2, 2).matches (both), + "other both doesn't match both"); + + +} /* namespace ptid */ +} /* namespace selftests */