From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from simark.ca by simark.ca with LMTP id Iw0TM1HqlWoLjhgAWB0awg (envelope-from ) for ; Mon, 31 Aug 2026 16:55:45 -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=RRrY8Ota; dkim-atps=neutral Received: by simark.ca (Postfix, from userid 112) id BDC491E033; Mon, 31 Aug 2026 16:55:45 -0400 (EDT) X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-25) on simark.ca X-Spam-Level: X-Spam-Status: No, score=-3.1 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,RCVD_IN_SBL_CSS 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 D44FB1E033 for ; Mon, 31 Aug 2026 16:55:44 -0400 (EDT) Received: from vm01.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id EAB7E4BA7980 for ; Mon, 31 Aug 2026 20:55:43 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org EAB7E4BA7980 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=RRrY8Ota Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by sourceware.org (Postfix) with ESMTP id 5DF554BA2E10 for ; Mon, 31 Aug 2026 20:55:20 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 5DF554BA2E10 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 5DF554BA2E10 Authentication-Results: sourceware.org; arc=none smtp.remote-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1788209720; cv=none; b=TjIeZ3vA/CvbUrB98+CiQIW9S3HZswx89pW0Nplko/WR4dCnhyTGa21xcRk39AN3jT8ecMoUhyEK/tLK2RRiQCpkjvKzuRS/hV51fCKf87EZsV0zGT7+Nz/AJs2w9bDOwpqdFGLBBh/RxAuhmCCuvmGva5WYSA73WPLwae02AK8= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1788209720; c=relaxed/simple; bh=cG1FJFYopNKbJCPEhfT399tfkEKX+0Ka7E17FQnukUE=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=ZZzM/H61r3+JWzLZCpvZItX42TJ2PNLPqwMliPI/4Q1q2pIrKv3ljX3lppE5Z70GkHZvp64GxsrOjrKa4sNTwQEU5lXM4mP0rAEXfIvWd1fyXoEy8djI+O4CHSeD+ezlHUycx0i1VOV7OBy1xOxziGNX7LnQCNmEwH3X2togKqI= 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=RRrY8Ota DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 5DF554BA2E10 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1788209720; 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; bh=ft2XwcVO4bsbO/UWi/YWwWHa4SwctThBi/iUO1MmzEI=; b=RRrY8OtaTqwU2Crf+dLJQO162UWirnoOJzGRPZwGQQPp0n3KsuS2nWgLhSy8mJ7mqSkvB6 td4okwK2vup6EBzlX5po9h2JjfYn7YvWzqBFCQvjjmXmUkYLEgOZ1jZetl5ngzZrnI4PFE lok2xfbRmdhxUuGpRK+CWIPKDFxmulM= Received: from mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-684--mZo7jkuPxiIm6a7ywR-Og-1; Mon, 31 Aug 2026 16:55:18 -0400 X-MC-Unique: -mZo7jkuPxiIm6a7ywR-Og-1 X-Mimecast-MFC-AGG-ID: -mZo7jkuPxiIm6a7ywR-Og_1788209718 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-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 742F319774E5 for ; Mon, 31 Aug 2026 20:55:17 +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 4926B1800347; Mon, 31 Aug 2026 20:55:15 +0000 (UTC) From: =?UTF-8?q?Alexandra=20H=C3=A1jkov=C3=A1?= To: gdb-patches@sourceware.org Cc: ezulian@redhat.com Subject: [RFC PATCH 0/1] gdb/python: add drg_why_sleeping command Date: Mon, 31 Aug 2026 22:54:53 +0200 Message-ID: <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: 1fhU_Xkp12Mg-HtAXnrT8uhPoK4bJ1fa3roBlyvJJ6w_1788209718 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 When using GDB to debug a multithreaded program with a thread in interruptible sleep, we can call `info threads` command in GDB, which shows the userspace frame each thread is stopped at.However, GDB has no way to show why a thread is sleeping on the kernel side—which kernel function it is blocked in, or the full kernel call path that led there. Drgn, on the other hand, can provide this information. Drgn does not use ptrace — it reads /proc/kcore directly which means drgn can run alongside a GDB session without any conflict, since GDB already holds ptrace on the inferior. I wrote a small GDB Python command, drgn_why_sleeping, that demonstrates this cooperation. When invoked on a selected thread (in GDB non-stop mode, so the thread remains in its sleep state), it retrieves the full kernel stack via drgn When debugging a multithreaded program with GDB, `info threads` shows the userspace frame each thread is stopped at, but GDB has no way to show why a thread is sleeping on the kernel side -- which kernel function it is blocked in, or the call path that led there. To run this script drgn and kernel debug has to be installed. I'm using to drgn's sudo helper, which opens /proc/kcore in a transient privileged child and passes the fd back over a unix socket. GDB itself stays unprivileged. Running GDB itsel is another possibility. In order to make things easier, I included sleeping_test.c program as a part of this patch since it's RFC. To demostrate this command, sleep_test has to be compiled and run separetely. Then we need to attach GDB in non-stop mode for example ./gdb/gdb --data-directory=gdb/data-directory -ex "set non-stop on" -p 1979281 then we need to resume the thread before inspecting it: (gdb) info threads (gdb) thread N (gdb) drgn_why_sleeping If the thread stays GDB-stopped, the kernel stack just shows ptrace_stop and not the real reason it was sleeping. Resuming it (continue &) lets it return to its kernel sleep. Id Target Id Frame 2 ... "sleep_test" (LWP 1979284) 0x... in read () from libc.so.6 ... (gdb) thread 2 Running before resuming the thread which means GDB still has it ptrace-stopped, so the kernel stack only shows the ptrace stop, not the real sleep: (gdb) drgn_why_sleeping Task state: t context_switch __schedule schedule ptrace_stop ptrace_signal get_signal ... do_syscall_64 entry_SYSCALL_64 After resuming just this thread (non-stop) so it re-enters its sleep, and running the drgn_why_sleep again we're seeing the real reason it is blocked: (gdb) continue & (gdb) drgn_why_sleeping Task state: S context_switch __schedule schedule anon_pipe_read new_sync_read vfs_read ksys_read do_syscall_64 entry_SYSCALL_64 Given a frame name, the command prints that frame's locals instead. Here the file operations resolve to pipeanon_fops, confirming from the kernel data itself that the thread is blocked on a pipe: (gdb) drgn_why_sleeping vfs_read Task state: S vfs_read file = *(struct file *)0xffff8c8a1d585600 = { .f_op = (const struct file_operations *)pipeanon_fops+0x0 = 0x..., .f_flags = (unsigned int)0, .f_inode = (struct inode *)0xffff8c87c87a7200, ... } Limitations: Secure Boot with lockdown=confidentiality) blocks /proc/kcore despite running as root. ---