Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: "Alexandra Hájková" <ahajkova@redhat.com>
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	[thread overview]
Message-ID: <20260831205514.1987454-1-ahajkova@redhat.com> (raw)

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.

---
<git format-patch will append the diffstat here>


             reply	other threads:[~2026-08-31 20:55 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-31 20:54 Alexandra Hájková [this message]
2026-08-31 20:54 ` [PATCH] Add drg_why_sleeping.py Alexandra Hájková
2026-09-01 16:52   ` Tom Tromey
2026-09-02 15:29     ` Alexandra Petlanova Hajkova

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260831205514.1987454-1-ahajkova@redhat.com \
    --to=ahajkova@redhat.com \
    --cc=ezulian@redhat.com \
    --cc=gdb-patches@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox