From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from simark.ca by simark.ca with LMTP id Qe3/Mdbl+WmlvhYAWB0awg (envelope-from ) for ; Tue, 05 May 2026 08:43:02 -0400 Received: by simark.ca (Postfix, from userid 112) id CA1CC1E0DA; Tue, 05 May 2026 08:43:02 -0400 (EDT) X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-25) on simark.ca X-Spam-Level: X-Spam-Status: No, score=-2.3 required=5.0 tests=ARC_SIGNED,ARC_VALID,BAYES_00, MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED,RCVD_IN_VALIDITY_RPBL_BLOCKED, RCVD_IN_VALIDITY_SAFE_BLOCKED autolearn=ham autolearn_force=no version=4.0.1 Received: from vm01.sourceware.org (vm01.sourceware.org [38.145.34.32]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange x25519 server-signature ECDSA (prime256v1) server-digest SHA256) (No client certificate requested) by simark.ca (Postfix) with ESMTPS id 7EC151E067 for ; Tue, 05 May 2026 08:43:00 -0400 (EDT) Received: from vm01.sourceware.org (localhost [127.0.0.1]) by sourceware.org (Postfix) with ESMTP id 3A02D4BA9021 for ; Tue, 5 May 2026 12:42:59 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 3A02D4BA9021 Received: from mail-wm1-f49.google.com (mail-wm1-f49.google.com [209.85.128.49]) by sourceware.org (Postfix) with ESMTPS id 3D9BF4BA901E for ; Tue, 5 May 2026 12:42:25 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 3D9BF4BA901E Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=palves.net Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=gmail.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 3D9BF4BA901E Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=209.85.128.49 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1777984945; cv=none; b=JVq13YEKqrhlpNFAJGVFSCfeIgKJdB+xau8ok8Jav1aBBYYCR1PsgER7A5RIqf0TUHXA3J4eLUxvyQsi4AKKYaOxULuD21ylseM5FSOULYgdLOsusEe4jh//4gUfkH/r3rVvAB8kOEOrgTdNwI6nJo/6ffjIj42xDcPeCpZBspM= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1777984945; c=relaxed/simple; bh=oLReXHxgfLX/HcebPrV4yHPxd2vU7/E3qnfvfFe6G2M=; h=From:To:Subject:Date:Message-ID:MIME-Version; b=KH21LWeTse+W6iaDAuvn8LYj8O5+xkX86X/9UORyleQ5TKASNOCOj2DXAI5rcPtW8FbQU1/13upHldpvP+Wp3pOUcm1k5j3u6Fl4PjePtA0zRU2jmJO0+qMz+0Y5iQuFNHNNRKScAlYrt43pm0+fwngBlD+mXfa60leo9KWSqnk= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 3D9BF4BA901E Received: by mail-wm1-f49.google.com with SMTP id 5b1f17b1804b1-48896199cbaso46014715e9.1 for ; Tue, 05 May 2026 05:42:25 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1777984943; x=1778589743; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=UVPr5QWw9QeVtGKCwJ9z7KtUSZ6nUaIx5evLmytxZKA=; b=E/97KhlTwiqIYKk7axIksBqh7Q2XqtBZjUYLLOUuJmllfnfyBcs2o22DxgXQbPESSW FBW80qoGFAodcx2z/zJPuwapDNqWtFfHay4OZZqSwB2fHbyT8stEvgteJTOxCRpKJ8HR q+KLJyKeq9KY+eRT4BVwPzmw42WtN3NZYN6uHhA7qS3rXdrUUu1tjZpDIQjdKDu6lP+l 58Ya6RJlxX9nLMtkRNRfUJ/WBHs6Zgaf6jCHvG4Aj2rIxMN8m1nOIyAYGEhIJZMMbh+y PwyNurHLeS4qCi57y4h0bcQSdZXKJRccoCsNf2UX00+V/+qOWrHgGnE6OdRXwtshrxfv RKqA== X-Gm-Message-State: AOJu0YxM0SCS6rycJM00tHeBg7W7wK+oPaeUt1cGW9lRZKVUYc4qdHQg hCGRuvHTy/qt6d42IE7yOAcllV11mg4QM/xQyHvHKpaupigjDKHUxzZCwr1pHw== X-Gm-Gg: AeBDiesFQTgj5lO/f0uUdkTM5L++4unUuxngbT3akx6bLy55VUm2FTLqNyJbGgdptDi y+3wuGdoOlA0k2IzJcS/RKJU8sZ/zKbLqqdxWmqMjpbqSGDx1e8OCwJsLBhjxMxDCkIuOBx5f0k YjZEGB7K0U8pV2HW1Y7Ga1wD8BEjxFBxNlb9l4O+ZWhcN8VtTBWB+fcWpoWrCme/QieBAycRYpG m2RlPYnALtbdx5QEslAC32Im1jg6N4bYweb534Y1G2ahNdhnkHLEpryzWprUgueSONTRCz2zeOH lENgW5yy+5yivohfQ6MrSxhafKDyA+6y8P0jZrLXbQxJNl8dkUop8MdYp5RDSuPxTHJCTn56vmy V5np3j1RYt1kFOJUuG9QwfcOSAQCy3pTb5x0FzgDOBG/PR6CqyDihlhAb5aJai3nUhYmaTSUmJ4 vcPMEQMdWhwmG1sTtQrjOELo3cfO+JcO2Z X-Received: by 2002:a05:600c:628c:b0:489:1a63:509c with SMTP id 5b1f17b1804b1-48d17fe01admr43677355e9.0.1777984942665; Tue, 05 May 2026 05:42:22 -0700 (PDT) Received: from localhost ([2001:8a0:facb:a800:d362:b803:ffc5:8f78]) by smtp.gmail.com with UTF8SMTPSA id 5b1f17b1804b1-48d1771fb84sm23389465e9.9.2026.05.05.05.42.22 for (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Tue, 05 May 2026 05:42:22 -0700 (PDT) From: Pedro Alves To: gdb-patches@sourceware.org Subject: [PATCH 2/3] Adjust gdb.threads/multiple-successive-infcall.exp for Cygwin Date: Tue, 5 May 2026 13:42:09 +0100 Message-ID: <20260505124210.1450101-3-pedro@palves.net> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260505124210.1450101-1-pedro@palves.net> References: <20260505124210.1450101-1-pedro@palves.net> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit 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~public-inbox=simark.ca@sourceware.org Running gdb.threads/multiple-successive-infcall.exp on Cygwin results in a series of cascading timeouts. There are two problems: #1 - Cygwin/Windows start a few threads for their own use. When you reach "main" with "(gdb) start", "info threads" will already show more than one thread. The testcase spawns four threads with pthread_create, and it assumes that they get GDB thread ids 2 through 5. That is incorrect for Windows. E.g.: (gdb) info threads Id Target Id Frame 1 Thread 4104.0x1e60 "multiple-successive-infcall" 0x00007fff3c44dbb4 in ntdll!ZwWaitForMultipleObjects () from /cygdrive/c/Windows/SYSTEM32/ntdll.dll 2 Thread 4104.0x2490 0x00007fff3c450ad4 in ntdll!ZwWaitForWorkViaWorkerFactory () from /cygdrive/c/Windows/SYSTEM32/ntdll.dll 3 Thread 4104.0x2bdc 0x00007fff3c450ad4 in ntdll!ZwWaitForWorkViaWorkerFactory () from /cygdrive/c/Windows/SYSTEM32/ntdll.dll 4 Thread 4104.0x1714 "sig" 0x00007fff3c44d124 in ntdll!ZwReadFile () from /cygdrive/c/Windows/SYSTEM32/ntdll.dll 5 Thread 4104.0x211c "multiple-successive-infcall" 0x00007fff3c44dbb4 in ntdll!ZwWaitForMultipleObjects () from /cygdrive/c/Windows/SYSTEM32/ntdll.dll 6 Thread 4104.0x2070 "multiple-successive-infcall" 0x00007fff3c44dbb4 in ntdll!ZwWaitForMultipleObjects () from /cygdrive/c/Windows/SYSTEM32/ntdll.dll 7 Thread 4104.0x1d3c "multiple-successive-infcall" 0x00007fff3c44dbb4 in ntdll!ZwWaitForMultipleObjects () from /cygdrive/c/Windows/SYSTEM32/ntdll.dll * 8 Thread 4104.0xa54 "multiple-successive-infcall" thread_function (args=0x10040704c ) at /cygdrive/c/Users/alves/rocm/gdb/src/gdb/testsuite/gdb.threads/multiple-successive-infcall.c:75 #2 - The test enables scheduler locking and switches to each thread in turn, and then does an infcall. On Windows, system calls aren't interruptible like on Linux. There's no concept of EINTR and syscall restart. So if a thread is in a syscall, actually running kernel code, then an infcall will only complete once the syscall returns. If the syscall is blocked waiting for another thread to unblock it, then the infcall never completes. You can pause it with Ctrl-C, but you'll see that the thread hasn't executed any user space instruction. For example: (gdb) t 8 [Switching to thread 8 (Thread 4104.0xa54)] #0 0x00007fff3c44dbb4 in ntdll!ZwWaitForMultipleObjects () from /cygdrive/c/Windows/SYSTEM32/ntdll.dll (gdb) p get_value () * hang * * press ctrl-c * Thread 8 "multiple-successive-infcall" stopped. get_value () at /cygdrive/c/Users/alves/rocm/gdb/src/gdb/testsuite/gdb.threads/multiple-successive-infcall.c:38 38 get_value () The program being debugged was signaled while in a function called from GDB. GDB remains in the frame where the signal was received. To change this behavior use "set unwindonsignal on". Evaluation of the expression containing the function (get_value) will be abandoned. When the function is done executing, GDB will silently stop. (gdb) bt #0 get_value () at /cygdrive/c/Users/alves/rocm/gdb/src/gdb/testsuite/gdb.threads/multiple-successive-infcall.c:38 #1 #2 0x00007fff3c44dbb4 in ntdll!ZwWaitForMultipleObjects () from /cygdrive/c/Windows/SYSTEM32/ntdll.dll #3 0x00007fff39cd1b40 in WaitForMultipleObjectsEx () from /cygdrive/c/Windows/System32/KERNELBASE.dll ... (gdb) si * hang * This results in failures like these: call get_value() FAIL: gdb.threads/multiple-successive-infcall.exp: thread=4: call inferior function (timeout) This commit fixes this by adjusting the testcase to make it work on Cygwin too. First, it makes the .exp file figure out which threads are the ones created by the testcase. The current testcase also tries the infcall on the main thread. It's simpler to not worry about the main thread being blocked in a syscall. So we just no longer test the syscall through that thread. That's OK, because that was not important for the original motivation for the testcase. With this, the testcase now passes cleanly on Cygwin. Change-Id: I5f69bafe6cecb83f18fb22ba7ee2368229fc4f9f commit-id: 717edd68 --- .../gdb.threads/multiple-successive-infcall.c | 10 +- .../multiple-successive-infcall.exp | 103 ++++++++++++++---- 2 files changed, 90 insertions(+), 23 deletions(-) diff --git a/gdb/testsuite/gdb.threads/multiple-successive-infcall.c b/gdb/testsuite/gdb.threads/multiple-successive-infcall.c index 8e397266dff..aa3ebbd9332 100644 --- a/gdb/testsuite/gdb.threads/multiple-successive-infcall.c +++ b/gdb/testsuite/gdb.threads/multiple-successive-infcall.c @@ -41,8 +41,9 @@ get_value () if (pthread_equal (threads[tid], pthread_self ())) return thread_ids[tid]; } - /* Value for the main thread. */ - return 1; + + /* Should not get here. */ + return -1; } /* Return the nth Fibonacci number. */ @@ -93,8 +94,9 @@ main (void) printf ("Spawning worker threads\n"); for (int tid = 0; tid < THREADCOUNT; ++tid) { - /* Add 2 so the value maps to the debugger's thread identifiers. */ - thread_ids[tid] = tid + 2; /* prethreadcreationmarker */ + /* Add 1 so the value maps to the testcase's thread + identifiers. */ + thread_ids[tid] = tid + 1; /* prethreadcreationmarker */ err = pthread_create (&threads[tid], NULL, thread_function, (void *) &thread_ids[tid]); if (err != 0) diff --git a/gdb/testsuite/gdb.threads/multiple-successive-infcall.exp b/gdb/testsuite/gdb.threads/multiple-successive-infcall.exp index 8d438673cf0..7ad841844bb 100644 --- a/gdb/testsuite/gdb.threads/multiple-successive-infcall.exp +++ b/gdb/testsuite/gdb.threads/multiple-successive-infcall.exp @@ -13,8 +13,7 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . */ -# multiple-successive-infcall.exp -- Test if GDB can invoke functions on -# multiple inferiors, one after the other. +# Test invoking functions on multiple threads, one after the other. standard_testfile @@ -29,31 +28,97 @@ if {![runto_main]} { return 0 } -# Ensure that each new thread is detected by GDB in the order that the -# test case creates them, so the thread identifiers match between -# test and test case. +# Ensure that each new pthread is spawned one at a time so we can +# extract its target ID, and not the ID of some auxiliary thread +# spawned by the runtime. gdb_breakpoint [gdb_get_line_number "prethreadcreationmarker"] gdb_continue_to_breakpoint "prethreadcreationmarker" -set after_new_thread_message "created new thread" -foreach_with_prefix thread {5 4 3} { - gdb_test_multiple "continue" "${after_new_thread_message}" { - -re "\\\[New Thread ${hex} \\\(LWP ${::decimal}\\\) \\\(id $decimal\\\)\\\].*${gdb_prompt}" { - pass "${after_new_thread_message}" - } - -re -wrap "\\\[New Thread $decimal\\.$decimal\\\ \\\(id $decimal\\\)]\r\n.*" { - pass $gdb_test_name +set after_new_thread_message "detected new pthread" + +# List of the target ids detected. +set pthread_list {} + +# The first 3 pthreads are detected here. +foreach_with_prefix pthread {1 2 3} { + gdb_test_multiple "continue" "${after_new_thread_message}" { + -re -wrap "\\\[New (Thread \[^\r\n\]+) \\\(id $decimal\\\)\\\]\r\n.*" { + set thr $expect_out(1,string) + verbose -log "detected pthread: $thr" + lappend pthread_list $thr + pass $gdb_test_name + } } - } } +verbose -log "detected pthread list: $pthread_list" + gdb_breakpoint [gdb_get_line_number "testmarker01"] -gdb_continue_to_breakpoint "testmarker01" + +# Continue to breakpoint. This detects that last pthread. It also +# ensures that no pthread ends up blocked in a syscall, which is +# important for Windows -- the infcall wouldn't be able to complete +# until the syscall returns, meaning, the infcall would deadlock. +with_test_prefix "pthread 4" { + gdb_test_multiple "continue" "${after_new_thread_message}" { + -re "\\\[New (Thread \[^\r\n\]+) \\\(id $decimal\\\)\\\]\r\n" { + set thr $expect_out(1,string) + verbose -log "detected pthread: $thr" + lappend pthread_list $thr + pass $gdb_test_name + } + } +} + +# Consume the breakpoint hit and the prompt. +gdb_test_multiple "" "stop at testmarker01" { + -re -wrap "hit Breakpoint .* testmarker01 .*" { + pass $gdb_test_name + } +} + gdb_test_no_output "set scheduler-locking on" gdb_test "show scheduler-locking" \ "Mode for locking scheduler during execution is \"on\"." -foreach_with_prefix thread {5 4 3 2 1} { - gdb_test "thread ${thread}" "Switching to .*" - gdb_test "call get_value()" "= ${thread}" \ - "call inferior function" +set thread_count [get_valueof "" "\$_inferior_thread_count" 0] + +# pthread id to be used in test messages in the loop below. +set testing_pthread 0 + +for {set thread 1} {$thread <= $thread_count} {incr thread} { + + # 1 if found, 0 if not found, -1 if the test failed. + set found -1 + gdb_test_multiple "thread ${thread}" "extract thread target id" { + -re -wrap "Switching to thread $decimal \\((Thread \[^\r\n\]+)\\)\\\]\r\n.*" { + set thr $expect_out(1,string) + verbose -log "extracted: $thr" + if {[lsearch -exact $pthread_list $thr] != -1} { + set found 1 + } else { + set found 0 + } + } + } + if {$found == -1} { + # gdb_test_multiple already issued a FAIL above. No point in + # continuing. + return + } elseif {$found == 0} { + # Not recognized as a testcase pthread, so it must be a thread + # spawned by the runtime or the OS. Don't use it for testing + # the infcall, as the thread may be blocked in a syscall -- on + # Windows, the infcall wouldn't be able to complete until the + # syscall returns, meaning, the infcall would deadlock. + verbose -log "not a known pthread" + continue + } else { + incr testing_pthread + with_test_prefix "pthread $testing_pthread" { + gdb_test "call get_value()" "= $testing_pthread" \ + "call inferior function" + } + } } + +gdb_assert {$testing_pthread == 4} "tested all pthreads" -- 2.53.0