From patchwork Thu Mar 21 23:11:49 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thiago Jung Bauermann X-Patchwork-Id: 781595 Delivered-To: patch@linaro.org Received: by 2002:adf:cf01:0:b0:33e:7753:30bd with SMTP id o1csp1077738wrj; Thu, 21 Mar 2024 16:12:27 -0700 (PDT) X-Forwarded-Encrypted: i=3; AJvYcCW9tqL7PjnlvNNnDqzZMNgYpVqDsQnc/POwiaApJhysqWa8E70p9yLWUC26CwJiIdvRSwYrFE7l82NZSpBwiSiy X-Google-Smtp-Source: AGHT+IGwYDi6Yl/k7el9woUe6mFykXvIdR6hBFirq3MV2q6ReZcIym7AcWMGyTz5Cv611UcgR/vv X-Received: by 2002:a05:620a:3bc1:b0:788:6375:4577 with SMTP id yf1-20020a05620a3bc100b0078863754577mr672273qkn.65.1711062747127; Thu, 21 Mar 2024 16:12:27 -0700 (PDT) ARC-Seal: i=2; a=rsa-sha256; t=1711062747; cv=pass; d=google.com; s=arc-20160816; b=DbszRetvqcsTEVNforEdSGEp3sBi4dfnuW3rTTw6NAAqMREWTza4X99SUhPLyt/DvT /A6mLBjiHcif3C7sPjBNqK1U+xk3JIdDqarumDd6wBGm/6nXSrtQMPgSfR8zYJSqLs3D wWgUJnisrMZbacJWVLHPDX8c5nb0ePKiOGz/be0n8/hGfYx2sFllPIGuvCiMeGG0A3pc LGFfz26hLz2wh4wJ6maD97zrI04uth73/Y2qR27VayMgYgn4zBsZIytBUQwag47sAukx eg1ddLdOvQXKdVXdJBNinNmki62GFTxIXj7gvGY1EsmfjKgHvXnvo4/6puNGI9A/GUct ysLw== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:to:from :dkim-signature:arc-filter:dmarc-filter:delivered-to; bh=a+Z4bhIfz3C2lA0gF6f2QF56TZJlgwzNAgggQlmVHTY=; fh=72kqq0iQhigvR9Vv/oqX5ebs3Yyyw7XhzWxOOEPdupI=; b=0eWjUVGtL5PH4Sl/Z0FFJtgFXcKjQf2+p22wZV+NnyAiw925FnufHSoCtn0yuyRpo9 tRon1mTx4mdESqX2ZBkRQH0OuhJNFx3ba+NbMK9gXcgiA2CQZz21qGnqaBFW0pgpJnpu bm2rgN47uijQoYSqGhdbxoR2eX3T2vK/a9Ub4Tou6SUV+E9jg+cowjxdL01pWasu+adV 8bMZjC6ehrpvrXl622y0yH63CjewbPiQJoifkICpR9Y2CdDTeEIuqQUlyaUCKF8tJY4K gjbOZa1CrW6UFvxhybJdBr9IHokXZtHtobmswdHZZBwuddtdqhwqL9uG5gBRw0EWxfmh pfLQ==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=laS3ar0Z; arc=pass (i=1); spf=pass (google.com: domain of gdb-patches-bounces+patch=linaro.org@sourceware.org designates 8.43.85.97 as permitted sender) smtp.mailfrom="gdb-patches-bounces+patch=linaro.org@sourceware.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from server2.sourceware.org (server2.sourceware.org. [8.43.85.97]) by mx.google.com with ESMTPS id e14-20020a05620a208e00b00789febb0f09si772704qka.534.2024.03.21.16.12.26 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 21 Mar 2024 16:12:27 -0700 (PDT) Received-SPF: pass (google.com: domain of gdb-patches-bounces+patch=linaro.org@sourceware.org designates 8.43.85.97 as permitted sender) client-ip=8.43.85.97; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=laS3ar0Z; arc=pass (i=1); spf=pass (google.com: domain of gdb-patches-bounces+patch=linaro.org@sourceware.org designates 8.43.85.97 as permitted sender) smtp.mailfrom="gdb-patches-bounces+patch=linaro.org@sourceware.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id BCA39385829F for ; Thu, 21 Mar 2024 23:12:26 +0000 (GMT) X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from mail-pl1-x635.google.com (mail-pl1-x635.google.com [IPv6:2607:f8b0:4864:20::635]) by sourceware.org (Postfix) with ESMTPS id 319693858403 for ; Thu, 21 Mar 2024 23:12:03 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 319693858403 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=linaro.org ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 319693858403 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2607:f8b0:4864:20::635 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1711062726; cv=none; b=K8mrCEBDBLCevBTv9u1nGSi8LeAarWTVzQKy0EjZ2p16GR/JSHldUVynYx0ER65sP8HTIOrJQi31SnCF9E8DfFy40IDI8JsAnJH/Zm8wJnzEPGZ/Z0Siutq6pQOHH2QnF63ZEPSzy9Ju6dmByuQgK+CrTTBM07k4Rw1Xwird+Xk= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1711062726; c=relaxed/simple; bh=818FEv4/frxkFsGU1SsjCA0NgV1W90ucluEEANX2nH4=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=kw3ES8nyl/OsfogtfcUXcBmZfYml+z2YuSXXVCAoh8mdy50lZd5eKnwP8xq1fnZTuITVvGSMFAHgJa/pz6uqqHdx7rWedhS4vR6GIt52Sp5Z4Rg5NZGH9zmyLsc73+1T5EQJt7bJCOa89kq+8VrwkAU8155cCYkfztuasQ5cSus= ARC-Authentication-Results: i=1; server2.sourceware.org Received: by mail-pl1-x635.google.com with SMTP id d9443c01a7336-1df01161b39so11676355ad.3 for ; Thu, 21 Mar 2024 16:12:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1711062722; x=1711667522; darn=sourceware.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=a+Z4bhIfz3C2lA0gF6f2QF56TZJlgwzNAgggQlmVHTY=; b=laS3ar0ZGVQlZboUAKkaE0mnk71i7sFQ4XKWLOMIZqXsU5c3/JXVbD6jpky7ZN0X4L 4iMi0b4f+k+Va0RCc5rWlvzwRMPgUbkEisxzfoUwGuGJmjFuS5tVwehELdUZ2b7SsIcu M7yo99QFVWIxoqATwjjR+k8i19cVFGRta43hxWWngvON8zPs30qClnwRmmmtCQG3llOq Ym83estK36tiS73Y3P9/ytnwluD+0wp58WoBb0Zhzeht+xieybrN49o6aLWyYYAeEBbf DsD8FEOBLYDmPsDle540ccHws7TBE0dVZepooodzeLuxCgYy/oi+0GkZsnDhCvy1SkFX kpcA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1711062722; x=1711667522; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=a+Z4bhIfz3C2lA0gF6f2QF56TZJlgwzNAgggQlmVHTY=; b=FMj+Co9SaLRouaKKeEtr2VbalNjQK/BCsS00lxwGycbuyXoiC5e4cc+DyXf95OFy14 mNUDDICM9hkw5KMFko3G0qZuUR4MOKi3Cvx3sTkmauY9/8tWGRi3CBYHHKIngaJP6OXR s6vIyAJHqIiPLlGPF4HJ7GbUmVZ/laqkUHqkK8nBEH5hjIvePAn+a/OF+BHkTIOvPP3R PjC6v1HKBeQHCCucOjqKtx59HjoE6ASvzoCxZO3WnkAfw/9atvkuVEn3UwtP2vtCU0dn Rfsx/ntyGG7vVlw9FqlBAP0XHTt4H2sBPxE0dWuqt3jFIlCs6+GUZl2yLXMNb0f59WP9 UuUw== X-Gm-Message-State: AOJu0YwHTbSbTcqgHuNpWiO+xBjs5FjmcNtX+S9809uxJHFgH27Pxoqk GVxuh2ueHDpkJg5orMtpPwuyneauf8FWSvK/LQ/S7W23UprowqsZdhdBhq/niPdT7Nu4kBMsKA9 x X-Received: by 2002:a17:903:2609:b0:1e0:2a5f:5e21 with SMTP id jd9-20020a170903260900b001e02a5f5e21mr940890plb.26.1711062722111; Thu, 21 Mar 2024 16:12:02 -0700 (PDT) Received: from localhost ([2804:14d:7e39:8470:e28:f7d5:8d63:c544]) by smtp.gmail.com with ESMTPSA id i17-20020a17090332d100b001dd922cbb58sm417977plr.62.2024.03.21.16.12.01 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 21 Mar 2024 16:12:01 -0700 (PDT) From: Thiago Jung Bauermann To: gdb-patches@sourceware.org Subject: [RFC PATCH 3/3] gdb/nat/linux: Fix attaching to process when it has zombie threads Date: Thu, 21 Mar 2024 20:11:49 -0300 Message-ID: <20240321231149.519549-4-thiago.bauermann@linaro.org> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20240321231149.519549-1-thiago.bauermann@linaro.org> References: <20240321231149.519549-1-thiago.bauermann@linaro.org> MIME-Version: 1.0 X-Spam-Status: No, score=-11.1 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gdb-patches-bounces+patch=linaro.org@sourceware.org When GDB attaches to a multi-threaded process, it calls linux_proc_attach_tgid_threads () to go through all threads found in /proc/PID/task/ and call attach_proc_task_lwp_callback () on each of them. If it does that twice without the callback reporting that a new thread was found, then it considers that all inferior threads have been found and returns. The problem is that the callback considers any thread that it hasn't attached to yet as new. This causes problems if the process has one or more zombie threads, because GDB can't attach to it and the loop will always "find" a new thread (the zombie one), and get stuck in an infinite loop. This is easy to trigger (at least on aarch64-linux and powerpc64le-linux) with the gdb.threads/attach-many-short-lived-threads.exp testcase, because its test program constantly creates and finishes joinable threads so the chance of having zombie threads is high. This problem causes the following failures: FAIL: gdb.threads/attach-many-short-lived-threads.exp: iter 8: attach (timeout) FAIL: gdb.threads/attach-many-short-lived-threads.exp: iter 8: no new threads (timeout) FAIL: gdb.threads/attach-many-short-lived-threads.exp: iter 8: set breakpoint always-inserted on (timeout) FAIL: gdb.threads/attach-many-short-lived-threads.exp: iter 8: break break_fn (timeout) FAIL: gdb.threads/attach-many-short-lived-threads.exp: iter 8: break at break_fn: 1 (timeout) FAIL: gdb.threads/attach-many-short-lived-threads.exp: iter 8: break at break_fn: 2 (timeout) FAIL: gdb.threads/attach-many-short-lived-threads.exp: iter 8: break at break_fn: 3 (timeout) FAIL: gdb.threads/attach-many-short-lived-threads.exp: iter 8: reset timer in the inferior (timeout) FAIL: gdb.threads/attach-many-short-lived-threads.exp: iter 8: print seconds_left (timeout) FAIL: gdb.threads/attach-many-short-lived-threads.exp: iter 8: detach (timeout) FAIL: gdb.threads/attach-many-short-lived-threads.exp: iter 8: set breakpoint always-inserted off (timeout) FAIL: gdb.threads/attach-many-short-lived-threads.exp: iter 8: delete all breakpoints, watchpoints, tracepoints, and catchpoints in delete_breakpoints (timeout) ERROR: breakpoints not deleted The iteration number is random, and all tests in the subsequent iterations fail too, because GDB is stuck in the attach command at the beginning of the iteration. The solution is to make linux_proc_attach_tgid_threads () remember when it has already processed a given LWP and skip it in the subsequent iterations. PR testsuite/31312 Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31312 Reviewed-By: Luis Machado --- gdb/nat/linux-osdata.c | 22 ++++++++++++++++++++++ gdb/nat/linux-osdata.h | 4 ++++ gdb/nat/linux-procfs.c | 19 +++++++++++++++++++ 3 files changed, 45 insertions(+) diff --git a/gdb/nat/linux-osdata.c b/gdb/nat/linux-osdata.c index c254f2e4f05b..998279377433 100644 --- a/gdb/nat/linux-osdata.c +++ b/gdb/nat/linux-osdata.c @@ -112,6 +112,28 @@ linux_common_core_of_thread (ptid_t ptid) return core; } +/* See linux-osdata.h. */ + +std::optional +linux_get_starttime (ptid_t ptid) +{ + std::optional field = linux_find_proc_stat_field (ptid, 22); + + if (!field.has_value ()) + return {}; + + errno = 0; + const char *trailer; + ULONGEST starttime = strtoulst (field->c_str (), &trailer, 10); + if (starttime == ULONGEST_MAX && errno == ERANGE) + return {}; + else if (*trailer != '\0') + /* There were unexpected characters. */ + return {}; + + return starttime; +} + /* Finds the command-line of process PID and copies it into COMMAND. At most MAXLEN characters are copied. If the command-line cannot be found, PID is copied into command in text-form. */ diff --git a/gdb/nat/linux-osdata.h b/gdb/nat/linux-osdata.h index a82fb08b998e..1cdc687aa9cf 100644 --- a/gdb/nat/linux-osdata.h +++ b/gdb/nat/linux-osdata.h @@ -27,4 +27,8 @@ extern int linux_common_core_of_thread (ptid_t ptid); extern LONGEST linux_common_xfer_osdata (const char *annex, gdb_byte *readbuf, ULONGEST offset, ULONGEST len); +/* Get the start time of thread PTID. */ + +extern std::optional linux_get_starttime (ptid_t ptid); + #endif /* NAT_LINUX_OSDATA_H */ diff --git a/gdb/nat/linux-procfs.c b/gdb/nat/linux-procfs.c index b17e3120792e..b01bf36c0b53 100644 --- a/gdb/nat/linux-procfs.c +++ b/gdb/nat/linux-procfs.c @@ -17,10 +17,13 @@ along with this program. If not, see . */ #include "gdbsupport/common-defs.h" +#include "linux-osdata.h" #include "linux-procfs.h" #include "gdbsupport/filestuff.h" #include #include +#include +#include /* Return the TGID of LWPID from /proc/pid/status. Returns -1 if not found. */ @@ -290,6 +293,10 @@ linux_proc_attach_tgid_threads (pid_t pid, return; } + /* Keeps track of the LWPs we have already visited in /proc, + identified by their PID and starttime to detect PID reuse. */ + std::set> visited_lwps; + /* Scan the task list for existing threads. While we go through the threads, new threads may be spawned. Cycle through the list of threads until we have done two iterations without finding new @@ -308,6 +315,18 @@ linux_proc_attach_tgid_threads (pid_t pid, if (lwp != 0) { ptid_t ptid = ptid_t (pid, lwp); + std::optional starttime = linux_get_starttime (ptid); + + if (starttime.has_value ()) + { + std::pair key (lwp, *starttime); + + /* If we already visited this LWP, skip it this time. */ + if (visited_lwps.find (key) != visited_lwps.cend ()) + continue; + + visited_lwps.insert (key); + } if (attach_lwp (ptid)) new_threads_found = 1;