From patchwork Wed Nov 22 16:41:05 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Marchi X-Patchwork-Id: 24444 Received: (qmail 7357 invoked by alias); 22 Nov 2017 16:42:03 -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 7056 invoked by uid 89); 22 Nov 2017 16:42:03 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-25.4 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= 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; Wed, 22 Nov 2017 16:41:59 +0000 Received: from ESESSHC008.ericsson.se (Unknown_Domain [153.88.183.42]) by sessmg22.ericsson.net (Symantec Mail Security) with SMTP id AF.33.19528.3D8A51A5; Wed, 22 Nov 2017 17:41:56 +0100 (CET) Received: from EUR01-HE1-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:41:55 +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:46 +0000 From: Simon Marchi To: CC: Simon Marchi Subject: [PATCH 2/4] remote: C++ify thread_item and threads_listing_context Date: Wed, 22 Nov 2017 11:41:05 -0500 Message-ID: <1511368867-19365-3-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: cfcaae8e-3fb5-4d74-72aa-08d531c7eda7 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:O0Yc+1DdK+0oUInWCnhFofwyaBcUmx4Yl8+NhYZmZswnHSzXGZFHFXvbSRK6N6cn5eQUVht8nAAWNfLCR0jezW1h9FNnUPxd9T2tj26XO3AKPyTrLOVo1iqbq5iwTkcUJ4z8JYRpJWXhCAxVK9nhayjWzv4auZhjKOjIHXh/3dbGDc1DDGHSu7ucooYDFv4+C1dwrR35rg1HTZw3CtNTQCAGlfvhc4bAP01cOVk2SbudM9kbYfmzwrh3P05AZWGg; 25:Xm4zHxfgA1NQ+iLD8ep4unP7nFxAyU1xQSnApDIh5yx4eeasD8x+phUiPHpt9qr14sIOTKBzPy+gAeTa+ZxSWhNPch1Ol1V8ldfckIlYHFWLZPQznD85ZG/auDY2eF+FCKrjhJGTaj5pFp+r+elD+tFMGPT2qVJOFQ4OSdgDB7zybcteHhnk6mOVl5XpkKTIhI57pJvzfkkBRZ0xt5OE2LPbNPcmlWDIU8VivblxpJFomo622y6ZX/uvw76M+fpsv+Ksh7lybijntOA3/Mlo8I0awsQ/dOqxLHHW/+Ma2AH+S2BqWwpm3F0rYkS3R/xY0KWlDNDsdetkhypoz+SrCQ==; 31:q6XdGnHnbI4lHI1GL/BTkfrz0fuoNfPR4yhao4OFqGzmKa0APRbfOzi2buLsNflAk5sThc09fDAn7X0+iBCe6jQUXErvmFj35c43Vx0iFZ7/6S0SrnSizfTLsVEJC6ap3J1lJcKgO8CepCWQ3IrVAhjenDxiwfwh2vpKV28d8eJSjqR+/CvwZ3ykWLjl2ppTHURxjgpZgX9XEwumcUSFnwk6WJnowBUG7ImH74ySVh8= X-MS-TrafficTypeDiagnostic: AMSPR07MB312: X-Microsoft-Exchange-Diagnostics: 1; AMSPR07MB312; 20:EKqBjGqKnOienoqvgD3/thd4Wjuudm46pe2GCSsfC2Y8qKNUVi02DJ2r0hIaLRUViL0OtBvtFhrVnxRIA+hwfwyhWKLI2I4sWf1Y+HRGXdiT1knLO7H4WzW+hy3plBhOKZRBkBou8st2b8LQgAe28ZrBI1nO0eY1jcMGeSOStCNfLfHY+n6zZpavUcMld6ZSCYlbZuBMBsQNtCU8SVn4pgFghj2I17jQuYuF97P1pLTdX+gjCid2DyKjHX21DtW6Ch5/Te/cwdOGoeUL2KrG2XVxaea/dnDUCLV6uMCD2cs6jp6kxbHdgPu8CQl8vleLhp/DhVqrS22405QFhPKztMac9j81OtkgpHyoGnpuq1hZkJIs2hOg+yMqwTJL30CICsyqs10lBcNWYvoEv2RHur82rY01mdsrBximmUIPgsoTRuGNY9zdgpLQvhEpBTLZnytXb2Jgj8IH+7lA+UwTB3HID/8g3Y4Ruzm/xzYiSafbNokxOvYykT7JqDtYxz60; 4:UG+olmM5zunTCivS1Q6+8S3oipEKZ13AGuWtj5K09qt63XPY9pU13taApULFnPajqgnUn7xoqkoTUBQJwYKT1xM8srbFys62+o1W2D9NMxM5ejBOvZYZBjVA0nrZigdQG0mAzF/OeLQGvSLnnM//Ss9V8rPLk6TcmEp4CgcMLmfbHpqRc+4UdX47Tla06xZ17AYd8Vo8veU6v5cdJyap7BiLZxsa1ShhW9wx3hcAmjJXOmJAUAspEhA3SZTQwlpkGs+1DeTYkQqetCvXPD4HRudix3ni8VHdjOnTUg2r0WqLVactlm+j154JWUe1RNI+JoqyeDqH7rRnt7+deIrMtGTHLQIBFiMa8MkSPoCGk80= X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(250305191791016)(22074186197030); 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)(53936002)(6306002)(6512007)(316002)(69596002)(16586007)(81156014)(53416004)(6506006)(2950100002)(6116002)(6486002)(2906002)(50986999)(47776003)(76176999)(105586002)(86362001)(478600001)(6916009)(8936002)(3846002)(6666003)(2004002); 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:WGARdCDMgqyxABt7Psb8WC/eyKlShZ8PZZmmB+Mr7z?= =?us-ascii?Q?0r6TYVzR3VbpOP8ebhdEQXrxnFqlDeN7cgNVTpDr4kS+qQVB7wn/NnaLK3Dz?= =?us-ascii?Q?0/0UndMui95+n+/9S4DaOSiEF4dI+55s+lQ+y+2EeetrxoOlvvcStB0VMFpg?= =?us-ascii?Q?99e8/s3vN3aoH9czakrUoojgbgZ7QMY8dv6UINd9UH4YSO+FijoB0SqMFnOD?= =?us-ascii?Q?mqW2DiIcX2AUXGgxzDX8e3ndKVadJupWRCM8w0IPXQCMPLMsSs7TvcVfF4wH?= =?us-ascii?Q?7mCy/aLWg9Z2qAPRfmdxvqIY6kOgtt5jjTVwUG4T61EF55bU2YHExJQnpisW?= =?us-ascii?Q?nVtC+mOe1Kt5IOVGdH2buxS8zwbOS4qnuEKXRkRtf027XENKX7mAFPi278jY?= =?us-ascii?Q?UbQbBd0kCSw45tfHN3mcXpK0fEHSx3uUuZruH//7sVKvd6qF8Un+zQ80X3m6?= =?us-ascii?Q?CEc0qjR8X1XoiixYOp2sjwIPUaTaG0ZYaK4HRcylUcfRtycdgHqRwSbm1t9i?= =?us-ascii?Q?JvOkDSECzvu/G5OTVTdwMzowxKRbMBhRhLlFunsWyKS6ZyhuirVJTwoxbJBb?= =?us-ascii?Q?UgvcsC1GXsdNyor/TBfPU76AeJIUWZj9BOUMU0gADhzafp/nhLvRtn/6SkxW?= =?us-ascii?Q?JRbvn2xXWwM/XYMT9NrwtIDKowiqNWeaW/aVwRQg8/ieHxaLFP0Xjfkqbbqy?= =?us-ascii?Q?W+pteu3jDJHcj8d9yanO5k0iS6p+V8a+sJv/PALJPTRmZSKxXtn0KDDP5R/F?= =?us-ascii?Q?e4gh1tLUNqgby0uKoh2IvFPMmUqiG/VQ31x3jJavXGXdSnFUvi7LbIUXLAxP?= =?us-ascii?Q?NE4B4Qs+bWVPgLGwLryvwvvYlp6PeIEjSeWGCV4yRmsX2zM/wKnxxZxB+cbu?= =?us-ascii?Q?8U/vhNnnMAfSxyiAjWKD0sVh2LfTY98D5mVegqSUAEyPXimB/5q8Wefj4rTl?= =?us-ascii?Q?Ddu32r5VMm6lEwoeFgxlh+gmJnMQEHeuAc+J4rQxR2168mig2Oll1FLtibze?= =?us-ascii?Q?VrpPLKw+4l8ITFZMDYh6tjMQIbgADygGU24nuCeNco9zuvYfuu7esUo+lRgj?= =?us-ascii?Q?S1orZzX0qYtf7JRA04tZqENTP2bMgSPm66XtX23pfAbC3iqmWwJKyn2kkciS?= =?us-ascii?Q?Ux2GjSwKD0SW3cmsK7Y79Hq2r/96xySbp14WuYiut6XWNR06WAqmfGncnQQh?= =?us-ascii?Q?Kms9pSCXgeV/PoNUlj9inUi4loxwqtBIzsP2KdQZRWOwFbjE+s893JfQ=3D?= =?us-ascii?Q?=3D?= X-Microsoft-Exchange-Diagnostics: 1; AMSPR07MB312; 6:YH+wXZsimZpSj4lpfWuAC2wYl0ha3gEXiGbWzVaIK9CZqaczmV4D+jzJDMLpiGj07ze9qh4+3D7pkHmijyZzcMkVBfWn/fsfL2IOacPWCHLQbaOGqjeBX4G/9sFwJfKHOTuKmwLaI2CVOUhgKapWDyvfcAaiUf3W0pPxlpa8L1WRsEmTERmYGosZPffRDBWALxjrsdPiyJ7GeGItnh8WXFqOeKI/0FXiKTBLjS2A7fhBaL7ejfC4Xfepao0oJ8fDejSBaQjEpNnSl8t+OpgqZs2wRS8WFKbAsf6GP9nh3f54eEnxxEG9I7jwRJt2xfndZI0fgjRW/z5kHOvhcaxMW0MBmZAiQx6cncxi9TemnRE=; 5:FWZugtQmsHuqS46QuP8MRHOcABxf+10duPPRUe1kQfK1f0RdAjndm8+6edyaMKhR+P+5dq+rmlHA8mo33ooSyws/gZyCoZ47aps+FSYXm4stZ3F+xQipkfzosQMH+xjeey6k14H9R26gszrUZIlx2MX0QWing/AL5kyUGZNqGXI=; 24:UvbwWymNbLtHg6pm4UiZVCX0RiRUWXlf6PKzkr5U2uJc5svbsDAw92Rsf6Lh+m6YVZ1qZWdjrTo4cOIKNZsiAZ7BbAfYA3eelaleesJTB7c=; 7:xVNMVm1Pny2+iDT8JSjRXJBMdkW2S4ypsK3Y1Ezeaa1tmM4g1WNsf4XpuNh4yREzoQ+2fJ9p9jknd7ZpBBx2C/cjOG0MsqBw4ZFOjHf++q/tiJE01nAy67k7HY7Pmdtcp+Zsfe396ypHv5u8+pUy0zt1ly21fB6c8JDGugLrYM8GDaI4EL6M84Sc+BV6suXIvhsAyFfep+CcsCo8KH9H6hW2Mx/8Z91K9nIiivdoYXnkc/lK996gk1e6JCPOzC0j SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-MS-Exchange-CrossTenant-OriginalArrivalTime: 22 Nov 2017 16:41:46.2751 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: cfcaae8e-3fb5-4d74-72aa-08d531c7eda7 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 This patch C++ifies the thread_item and threads_listing_context structures in remote.c. thread_item::{extra,name} are changed to std::string. As a result, there's a bit of awkwardness in remote_update_thread_list, where we have to xstrdup those strings when filling the private_thread_info structure. This is removed in the following patch, where private_thread_info is also C++ified and its corresponding fields made std::string too. The xstrdup then becomes an std::move. Other than that there's nothing really special, it's a usual day-to-day VEC -> vector and char* -> std::string change. It allows removing a cleanup in remote_update_thread_list. Note that an overload of hex2bin that returns a gdb::byte_vector is added, with corresponding selftests. gdb/ChangeLog: * remote.c (struct thread_item): Add constructor and destructor. : Change type to std::string. : Initialize. (thread_item_t): Remove typedef. (DEF_VEC_O(thread_item_t)): Remove. (threads_listing_context) : New method. : New method. : Change type to std::vector. (clear_threads_listing_context): Remove. (threads_listing_context_remove): Remove. (remote_newthread_step): Use thread_item constructor, adjust to change to std::vector. (start_thread): Use thread_item constructor, adjust to change to std::vector. (end_thread): Adjust to change to std::vector and std::string. (remote_get_threads_with_qthreadinfo): Use thread_item constructor, adjust to std::vector. (remote_update_thread_list): Adjust to change to std::vector and std::string, use threads_listing_context methods. (remove_child_of_pending_fork): Adjust. (remove_new_fork_children): Adjust. * Makefile.in (SUBDIR_UNITTESTS_SRCS): Add rsp-low-selftests.c. (SUBDIR_UNITTESTS_OBS): Add rsp-low-selftests.o. * unittests/rsp-low-selftests.c: New file. * common/rsp-low.h: Include common/byte-vector.h. (hex2bin): New overload. * common/rsp-low.c (hex2bin): New overload. --- gdb/Makefile.in | 2 + gdb/common/rsp-low.c | 13 +++ gdb/common/rsp-low.h | 6 ++ gdb/remote.c | 192 +++++++++++++++----------------------- gdb/unittests/rsp-low-selftests.c | 59 ++++++++++++ 5 files changed, 155 insertions(+), 117 deletions(-) create mode 100644 gdb/unittests/rsp-low-selftests.c diff --git a/gdb/Makefile.in b/gdb/Makefile.in index 78a43c5..8f96a1f 100644 --- a/gdb/Makefile.in +++ b/gdb/Makefile.in @@ -539,6 +539,7 @@ SUBDIR_UNITTESTS_SRCS = \ unittests/offset-type-selftests.c \ unittests/optional-selftests.c \ unittests/ptid-selftests.c \ + unittests/rsp-low-selftests.c \ unittests/scoped_restore-selftests.c \ unittests/xml-utils-selftests.c @@ -553,6 +554,7 @@ SUBDIR_UNITTESTS_OBS = \ offset-type-selftests.o \ optional-selftests.o \ ptid-selftests.o \ + rsp-low-selftests.o \ scoped_restore-selftests.o \ xml-utils-selftests.o diff --git a/gdb/common/rsp-low.c b/gdb/common/rsp-low.c index 85987f7..9948fbb 100644 --- a/gdb/common/rsp-low.c +++ b/gdb/common/rsp-low.c @@ -132,6 +132,19 @@ hex2bin (const char *hex, gdb_byte *bin, int count) /* See rsp-low.h. */ +gdb::byte_vector +hex2bin (const char *hex) +{ + size_t bin_len = strlen (hex) / 2; + gdb::byte_vector bin (bin_len); + + hex2bin (hex, bin.data (), bin_len); + + return bin; +} + +/* See rsp-low.h. */ + std::string hex2str (const char *hex) { diff --git a/gdb/common/rsp-low.h b/gdb/common/rsp-low.h index 99dc93f..039f19c 100644 --- a/gdb/common/rsp-low.h +++ b/gdb/common/rsp-low.h @@ -20,6 +20,8 @@ #ifndef COMMON_RSP_LOW_H #define COMMON_RSP_LOW_H +#include "common/byte-vector.h" + /* Convert hex digit A to a number, or throw an exception. */ extern int fromhex (int a); @@ -52,6 +54,10 @@ extern const char *unpack_varlen_hex (const char *buff, ULONGEST *result); extern int hex2bin (const char *hex, gdb_byte *bin, int count); +/* Like the above, but return a gdb::byte_vector. */ + +gdb::byte_vector hex2bin (const char *hex); + /* Like hex2bin, but return a std::string. */ extern std::string hex2str (const char *hex); diff --git a/gdb/remote.c b/gdb/remote.c index f328080..0270f95 100644 --- a/gdb/remote.c +++ b/gdb/remote.c @@ -2972,25 +2972,33 @@ remote_threadlist_iterator (rmt_thread_action stepfunction, void *context, /* A thread found on the remote target. */ -typedef struct thread_item +struct thread_item { + thread_item (ptid_t ptid_) + : ptid (ptid_) + {} + + ~thread_item () + { + delete thread_handle; + } + /* The thread's PTID. */ ptid_t ptid; /* The thread's extra info. May be NULL. */ - char *extra; + std::string extra; /* The thread's name. May be NULL. */ - char *name; + std::string name; /* The core the thread was running on. -1 if not known. */ - int core; + int core = -1; /* The thread handle associated with the thread. */ - gdb::byte_vector *thread_handle; + gdb::byte_vector *thread_handle = NULL; -} thread_item_t; -DEF_VEC_O(thread_item_t); +}; /* Context passed around to the various methods listing remote threads. As new threads are found, they're added to the ITEMS @@ -2998,66 +3006,54 @@ DEF_VEC_O(thread_item_t); struct threads_listing_context { - /* The threads found on the remote target. */ - VEC (thread_item_t) *items; -}; + /* Return true if this object contains an entry for a thread with ptid + PTID. */ -/* Discard the contents of the constructed thread listing context. */ + bool contains_thread (ptid_t ptid) const + { + auto match_ptid = [&] (const thread_item &item) + { + return item.ptid == ptid; + }; -static void -clear_threads_listing_context (void *p) -{ - struct threads_listing_context *context - = (struct threads_listing_context *) p; - int i; - struct thread_item *item; + auto it = std::find_if (this->items.begin (), + this->items.end (), + match_ptid); - for (i = 0; VEC_iterate (thread_item_t, context->items, i, item); ++i) - { - xfree (item->extra); - xfree (item->name); - delete item->thread_handle; - } + return it != this->items.end (); + } - VEC_free (thread_item_t, context->items); -} + /* Remove the thread with ptid PTID. */ -/* Remove the thread specified as the related_pid field of WS - from the CONTEXT list. */ + void remove_thread (ptid_t ptid) + { + auto match_ptid = [&] (const thread_item &item) + { + return item.ptid == ptid; + }; -static void -threads_listing_context_remove (struct target_waitstatus *ws, - struct threads_listing_context *context) -{ - struct thread_item *item; - int i; - ptid_t child_ptid = ws->value.related_pid; + auto it = std::remove_if (this->items.begin (), + this->items.end (), + match_ptid); - for (i = 0; VEC_iterate (thread_item_t, context->items, i, item); ++i) - { - if (ptid_equal (item->ptid, child_ptid)) - { - VEC_ordered_remove (thread_item_t, context->items, i); - break; - } - } -} + if (it != this->items.end ()) + this->items.erase (it); + } + + /* The threads found on the remote target. */ + std::vector items; +}; static int remote_newthread_step (threadref *ref, void *data) { struct threads_listing_context *context = (struct threads_listing_context *) data; - struct thread_item item; - int pid = ptid_get_pid (inferior_ptid); - - item.ptid = ptid_build (pid, threadref_to_int (ref), 0); - item.core = -1; - item.name = NULL; - item.extra = NULL; - item.thread_handle = nullptr; + int pid = inferior_ptid.pid (); + int lwp = threadref_to_int (ref); + ptid_t ptid (pid, lwp); - VEC_safe_push (thread_item_t, context->items, &item); + context->items.emplace_back (ptid); return 1; /* continue iterator */ } @@ -3109,37 +3105,28 @@ start_thread (struct gdb_xml_parser *parser, { struct threads_listing_context *data = (struct threads_listing_context *) user_data; - - struct thread_item item; - char *id; struct gdb_xml_value *attr; - id = (char *) xml_find_attribute (attributes, "id")->value; - item.ptid = read_ptid (id, NULL); + char *id = (char *) xml_find_attribute (attributes, "id")->value; + ptid_t ptid = read_ptid (id, NULL); + + data->items.emplace_back (ptid); + thread_item &item = data->items.back (); attr = xml_find_attribute (attributes, "core"); if (attr != NULL) item.core = *(ULONGEST *) attr->value; - else - item.core = -1; attr = xml_find_attribute (attributes, "name"); - item.name = attr != NULL ? xstrdup ((const char *) attr->value) : NULL; + if (attr != NULL) + item.name = (const char *) attr->value; attr = xml_find_attribute (attributes, "handle"); if (attr != NULL) { - item.thread_handle = new gdb::byte_vector - (strlen ((const char *) attr->value) / 2); - hex2bin ((const char *) attr->value, item.thread_handle->data (), - item.thread_handle->size ()); + item.thread_handle = new gdb::byte_vector; + *item.thread_handle = hex2bin ((const char *) attr->value); } - else - item.thread_handle = nullptr; - - item.extra = 0; - - VEC_safe_push (thread_item_t, data->items, &item); } static void @@ -3150,8 +3137,8 @@ end_thread (struct gdb_xml_parser *parser, struct threads_listing_context *data = (struct threads_listing_context *) user_data; - if (body_text && *body_text) - VEC_last (thread_item_t, data->items)->extra = xstrdup (body_text); + if (body_text != NULL && *body_text != '\0') + data->items.back ().extra = body_text; } const struct gdb_xml_attribute thread_attributes[] = { @@ -3227,15 +3214,8 @@ remote_get_threads_with_qthreadinfo (struct target_ops *ops, { do { - struct thread_item item; - - item.ptid = read_ptid (bufp, &bufp); - item.core = -1; - item.name = NULL; - item.extra = NULL; - item.thread_handle = nullptr; - - VEC_safe_push (thread_item_t, context->items, &item); + ptid_t ptid = read_ptid (bufp, &bufp); + context->items.emplace_back (ptid); } while (*bufp++ == ','); /* comma-separated list */ putpkt ("qsThreadInfo"); @@ -3261,12 +3241,8 @@ static void remote_update_thread_list (struct target_ops *ops) { struct threads_listing_context context; - struct cleanup *old_chain; int got_list = 0; - context.items = NULL; - old_chain = make_cleanup (clear_threads_listing_context, &context); - /* We have a few different mechanisms to fetch the thread list. Try them all, starting with the most preferred one first, falling back to older methods. */ @@ -3275,12 +3251,11 @@ remote_update_thread_list (struct target_ops *ops) || remote_get_threads_with_ql (ops, &context)) { int i; - struct thread_item *item; struct thread_info *tp, *tmp; got_list = 1; - if (VEC_empty (thread_item_t, context.items) + if (context.items.empty () && remote_thread_always_alive (ops, inferior_ptid)) { /* Some targets don't really support threads, but still @@ -3288,7 +3263,6 @@ remote_update_thread_list (struct target_ops *ops) listing packets, instead of replying "packet not supported". Exit early so we don't delete the main thread. */ - do_cleanups (old_chain); return; } @@ -3297,15 +3271,7 @@ remote_update_thread_list (struct target_ops *ops) target. */ ALL_THREADS_SAFE (tp, tmp) { - for (i = 0; - VEC_iterate (thread_item_t, context.items, i, item); - ++i) - { - if (ptid_equal (item->ptid, tp->ptid)) - break; - } - - if (i == VEC_length (thread_item_t, context.items)) + if (!context.contains_thread (tp->ptid)) { /* Not found. */ delete_thread (tp->ptid); @@ -3318,11 +3284,9 @@ remote_update_thread_list (struct target_ops *ops) remove_new_fork_children (&context); /* And now add threads we don't know about yet to our list. */ - for (i = 0; - VEC_iterate (thread_item_t, context.items, i, item); - ++i) + for (thread_item &item : context.items) { - if (!ptid_equal (item->ptid, null_ptid)) + if (item.ptid != null_ptid) { struct private_thread_info *info; /* In non-stop mode, we assume new found threads are @@ -3331,16 +3295,14 @@ remote_update_thread_list (struct target_ops *ops) stopped. */ int executing = target_is_non_stop_p () ? 1 : 0; - remote_notice_new_inferior (item->ptid, executing); + remote_notice_new_inferior (item.ptid, executing); - info = get_private_info_ptid (item->ptid); - info->core = item->core; - info->extra = item->extra; - item->extra = NULL; - info->name = item->name; - item->name = NULL; - info->thread_handle = item->thread_handle; - item->thread_handle = nullptr; + 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; } } } @@ -3353,8 +3315,6 @@ remote_update_thread_list (struct target_ops *ops) no-op. See remote_thread_alive. */ prune_threads (); } - - do_cleanups (old_chain); } /* @@ -6520,7 +6480,7 @@ remove_child_of_pending_fork (QUEUE (stop_reply_p) *q, if (event->ws.kind == TARGET_WAITKIND_FORKED || event->ws.kind == TARGET_WAITKIND_VFORKED || event->ws.kind == TARGET_WAITKIND_THREAD_EXITED) - threads_listing_context_remove (&event->ws, context); + context->remove_thread (event->ws.value.related_pid); return 1; } @@ -6546,9 +6506,7 @@ remove_new_fork_children (struct threads_listing_context *context) struct target_waitstatus *ws = thread_pending_fork_status (thread); if (is_pending_fork_parent (ws, pid, thread->ptid)) - { - threads_listing_context_remove (ws, context); - } + context->remove_thread (ws->value.related_pid); } /* Check for any pending fork events (not reported or processed yet) diff --git a/gdb/unittests/rsp-low-selftests.c b/gdb/unittests/rsp-low-selftests.c new file mode 100644 index 0000000..e20fedf --- /dev/null +++ b/gdb/unittests/rsp-low-selftests.c @@ -0,0 +1,59 @@ +/* Unit tests for the rsp-low.c file. + + 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 "selftest.h" +#include "common/rsp-low.h" + +namespace selftests { +namespace rsp_low { + +/* Test the variant of hex2bin that returns a byte_vector. */ + +static void test_hex2bin_byte_vector () +{ + gdb::byte_vector bv; + + /* Test an empty string. */ + bv = hex2bin (""); + SELF_CHECK (bv.size () == 0); + + /* Test a well-formated hex string. */ + bv = hex2bin ("abcd01"); + SELF_CHECK (bv.size () == 3); + SELF_CHECK (bv[0] == 0xab); + SELF_CHECK (bv[1] == 0xcd); + SELF_CHECK (bv[2] == 0x01); + + /* Test an odd-length hex string. */ + bv = hex2bin ("0123c"); + SELF_CHECK (bv.size () == 2); + SELF_CHECK (bv[0] == 0x01); + SELF_CHECK (bv[1] == 0x23); +} + +} /* namespace rsp_low */ +} /* namespace selftests */ + +void +_initialize_rsp_low_selftests () +{ + selftests::register_test ("hex2bin_byte_vector", + selftests::rsp_low::test_hex2bin_byte_vector); +}