From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from simark.ca by simark.ca with LMTP id wRogAHrqlWoLjhgAWB0awg (envelope-from ) for ; Mon, 31 Aug 2026 16:56:26 -0400 Authentication-Results: simark.ca; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=dY0dhMJ6; dkim-atps=neutral Received: by simark.ca (Postfix, from userid 112) id EF81E1E166; Mon, 31 Aug 2026 16:56:25 -0400 (EDT) X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-25) on simark.ca X-Spam-Level: X-Spam-Status: No, score=-6.4 required=5.0 tests=ARC_SIGNED,ARC_VALID,BAYES_00, DKIMWL_WL_HIGH,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham autolearn_force=no version=4.0.1 Received: from vm01.sourceware.org (vm01.sourceware.org [IPv6:2620:52:6:3111::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 1B0A41E033 for ; Mon, 31 Aug 2026 16:56:22 -0400 (EDT) Received: from vm01.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 5E9904BA2E2B for ; Mon, 31 Aug 2026 20:56:20 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 5E9904BA2E2B Authentication-Results: sourceware.org; dkim=pass (1024-bit key, unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=dY0dhMJ6 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by sourceware.org (Postfix) with ESMTP id 8E4E54BA2E13 for ; Mon, 31 Aug 2026 20:55:22 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 8E4E54BA2E13 Authentication-Results: sourceware.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 8E4E54BA2E13 Authentication-Results: sourceware.org; arc=none smtp.remote-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1788209722; cv=none; b=kdlF2NK8kMZ5JcsDh1rZHvrje1lop+OEMUxNM39Nmr1TcYLa70Xr1QmKz4cGQ+gf6KfGrrbRpzw3ajbdE8daqks0bLbNhIRzyH2IX3b1Q3eQgtJUHXV2GjuFtO27+UZ51qTOyDxmaJ+hxSzXwWY2xG7FV+a8Bob1B1Tw/kBgHW0= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1788209722; c=relaxed/simple; bh=R0dcIC4YHgkmwUOujAmDDvU/pBRyMz/gDg4L4ZFAOz4=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=LskLhDGa/qbVuWPPWozjb9SkZQzvDPeRsq5xHVuR2uisyQypaAB44ZjQ4L1C3+4KwtgxCpTqV3Hx9hr1vZCHaYAmEooYQuGxnUdeG4eorHGj733kQJXbAMSiuS5YQ4GbTiQQOigsMn45599uLvER3Za+3UeoegI+ITEKvQFaaCU= ARC-Authentication-Results: i=1; sourceware.org; dkim=pass (1024-bit key, unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=dY0dhMJ6 DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 8E4E54BA2E13 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1788209722; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=DT5Mf95B4WdIrwyrRNngXN0Zi2h29iMDnkR8qB0sVgo=; b=dY0dhMJ6gz15LHt3UwqUQqSx63BI6MgHZW+uAy/jBB4DDXk+GZFAT/T6oopIZJJJTkxl9C 93J2/S3/O1X/EwTP/5O+q+wLQfObNOfjTVMKEs3On2F1RKTDmZCEt9xF009K0Ge/xA6V+p PofuhPXE1IB2Gxmpb1TcAwhHQlwpAOE= Received: from mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-375-OawwBri4P2WI4WW6f7Ebow-1; Mon, 31 Aug 2026 16:55:20 -0400 X-MC-Unique: OawwBri4P2WI4WW6f7Ebow-1 X-Mimecast-MFC-AGG-ID: OawwBri4P2WI4WW6f7Ebow_1788209719 Received: from mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.93]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 6B0A61834511 for ; Mon, 31 Aug 2026 20:55:19 +0000 (UTC) Received: from fedora.home (unknown [10.44.22.4]) by mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 44A761800577; Mon, 31 Aug 2026 20:55:17 +0000 (UTC) From: =?UTF-8?q?Alexandra=20H=C3=A1jkov=C3=A1?= To: gdb-patches@sourceware.org Cc: ezulian@redhat.com Subject: [PATCH] Add drg_why_sleeping.py Date: Mon, 31 Aug 2026 22:54:54 +0200 Message-ID: <20260831205514.1987454-2-ahajkova@redhat.com> In-Reply-To: <20260831205514.1987454-1-ahajkova@redhat.com> References: <20260831205514.1987454-1-ahajkova@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.93 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: Dhn11bh0kzbtRyJfuyNxH_HNSX-EmeInbHRmHDenQ44_1788209719 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset=UTF-8 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 --- .../lib/gdb/command/drgn_why_sleeping.py | 72 ++++++++++++++++++ sleep_test.c | 76 +++++++++++++++++++ 2 files changed, 148 insertions(+) create mode 100644 gdb/python/lib/gdb/command/drgn_why_sleeping.py create mode 100644 sleep_test.c diff --git a/gdb/python/lib/gdb/command/drgn_why_sleeping.py b/gdb/python/lib/gdb/command/drgn_why_sleeping.py new file mode 100644 index 00000000000..ea11a73faae --- /dev/null +++ b/gdb/python/lib/gdb/command/drgn_why_sleeping.py @@ -0,0 +1,72 @@ +# GDB 'drgn_why_sleeping' command. +# Copyright (C) 2026 Free Software Foundation, Inc. + +# 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 . + +"""Implementation of the GDB 'drgn_why_sleeping' command using the GDB Python API.""" + +import gdb +import drgn +from drgn.helpers.linux.pid import find_task +from drgn.helpers.linux.sched import task_state_to_char + +class DrgnWhySleeping(gdb.Command): + """Look at kernel stack and show what is the thread blocked at. + + Usage: Run GDB as root to be able to read from /proc/kcore. + The command needs debugging symbols for the running kernel. + (gdb) source ~/binutils-gdb/gdb/python/lib/gdb/command/drgn_why_sleeping.py + (gdb) info threads + (gdb) thread n + (gdb) drgn_why_sleeping + """ + + def __init__(self): + super(DrgnWhySleeping, self).__init__( + name="drgn_why_sleeping", command_class=gdb.COMMAND_STATUS, prefix=False + ) + + def invoke(self, arg_str, from_tty): + if gdb.selected_thread() is None: + raise gdb.GdbError( + ( + "Can't find selected thread. " + ) + ) + tid = gdb.selected_thread().ptid[1] + + try: + prog = drgn.program_from_kernel() + except Exception as e: + raise gdb.GdbError( + "Can't read /proc/kcore, %s. Try running GDB as root. " % str(e) + ) + task = find_task(prog, tid) + task_state = task_state_to_char(task) + stack = prog.stack_trace(task) + print(f"Task state: {task_state}") + if arg_str: + for frame in stack: + if frame.name == arg_str: + print(frame.name) + for var in frame.locals(): + print(f" {var} = {frame[var]}") + break + else: + print("Frame not found: %s" % arg_str) + else: + for frame in stack: + print(frame.name) + +DrgnWhySleeping() diff --git a/sleep_test.c b/sleep_test.c new file mode 100644 index 00000000000..c324e55944c --- /dev/null +++ b/sleep_test.c @@ -0,0 +1,76 @@ +/* + * sleep_test.c - reproducer for testing drgn_why_sleeping GDB command + * + * Creates three threads, each blocked in a different kind of interruptible + * sleep, then prints the PID and waits so GDB can attach. + * + * Compile: gcc -g -o sleep_test sleep_test.c -lpthread + */ + +#include +#include +#include + +static pthread_mutex_t mutex_a = PTHREAD_MUTEX_INITIALIZER; +static pthread_mutex_t mutex_b = PTHREAD_MUTEX_INITIALIZER; +static pthread_cond_t cond = PTHREAD_COND_INITIALIZER; +static int pipe_fds[2]; + +/* Blocked trying to acquire mutex_a, which main holds. */ +static void *mutex_waiter(void *arg) +{ + printf("[thread 1] blocking on mutex_a...\n"); + fflush(stdout); + pthread_mutex_lock(&mutex_a); + /* never reached during the test */ + pthread_mutex_unlock(&mutex_a); + return NULL; +} + +/* Blocked in pthread_cond_wait; nobody will ever signal cond. */ +static void *cond_waiter(void *arg) +{ + pthread_mutex_lock(&mutex_b); + printf("[thread 2] blocking on cond...\n"); + fflush(stdout); + pthread_cond_wait(&cond, &mutex_b); + /* never reached during the test */ + pthread_mutex_unlock(&mutex_b); + return NULL; +} + +/* Blocked in read(); nobody will write to the pipe. */ +static void *pipe_reader(void *arg) +{ + char buf[16]; + printf("[thread 3] blocking on pipe read...\n"); + fflush(stdout); + read(pipe_fds[0], buf, sizeof(buf)); + /* never reached during the test */ + return NULL; +} + +int main(void) +{ + pthread_t t1, t2, t3; + + pipe(pipe_fds); + + /* Hold mutex_a before creating thread 1 so it blocks immediately. */ + pthread_mutex_lock(&mutex_a); + + pthread_create(&t1, NULL, mutex_waiter, NULL); + pthread_create(&t2, NULL, cond_waiter, NULL); + pthread_create(&t3, NULL, pipe_reader, NULL); + + /* Give threads time to reach their blocking calls. */ + sleep(1); + + printf("\n[main] PID %d ready — attach GDB now\n", getpid()); + fflush(stdout); + + /* Block here so GDB has time to attach. */ + pause(); + + return 0; +} -- 2.52.0