public inbox for gdb@sourceware.org
 help / color / mirror / Atom feed
From: Tom Tromey <tom@tromey.com>
To: Tom Tromey <tom@tromey.com>
Cc: Andrey Turkin <andrey.turkin@gmail.com>,
	 Andrey Turkin via Gdb <gdb@sourceware.org>
Subject: Re: "previous frame inner to this frame" error when unwinding fibers
Date: Fri, 22 Dec 2023 12:19:26 -0700	[thread overview]
Message-ID: <87edfedozl.fsf@tromey.com> (raw)
In-Reply-To: <87msu3dqp4.fsf@tromey.com> (Tom Tromey's message of "Thu, 21 Dec 2023 17:30:15 -0700")

Tom> Yeah, the API on the branch is very simple.

I made a new branch and reworked it a bit, dropping a few stale parts.
It's in my github as "green-threads-v2"; you can try it if you want.

I've appended a sample .py that works with the "vireo" user-space
threads package so you can see how it works.

I still haven't implemented a way for green threads to know when to stop
unwinding.  And, I haven't added a way to indicate that the "inner than"
requirement should be lifted.

If you have ideas for how those ought to work, that would be good to
hear.  We talked about doing this in an unwinder but it seems kind of
heavy to require an unwinder to supplement green threads; though maybe
in your case that's ok.

One thought I had was to have a callback on the green thread object that
could be passed a frame to see if it is the outermost frame.  This way
green threads, at least, could stop unwinding at their scheduler; and
users wanting to debug a scheduler could switch to a "real" thread to
see that.

Maybe inner-than could just be an optional flag passed to
create_green_thread.

Tom


import gdb

thread_map = {}

main_thread = None

# From glibc/sysdeps/unix/sysv/linux/x86/sys/ucontext.h
x8664_regs = [ 'r8', 'r9', 'r10', 'r11', 'r12', 'r13', 'r14',
               'r15', 'rdi', 'rsi', 'rbp', 'rbx', 'rdx', 'rax',
               'rcx', 'rsp', 'rip', 'efl', 'csgsfs', 'err',
               'trapno', 'oldmask', 'cr2' ]

def vireo_current():
    return int(gdb.parse_and_eval('curenv')) + 1

class VireoGreenThread:
    def __init__(self, tid):
        self.tid = tid

    def _get_state(self):
        return gdb.parse_and_eval('envs')[self.tid]['state']

    def fetch(self, reg):
        """Fetch REG from memory."""
        global x8664_regs
        global thread_map
        thread = thread[self.tid]
        state = self._get_state()
        gregs = state['uc_mcontext']['gregs']
        for i in range(0, len(x8664_regs)):
            if reg is None or reg == x8664_regs[i]:
                thread.write_register(x8664_regs[i], gregs[i])

    def store(self, reg):
        global x8664_regs
        global thread_map
        thread = thread[self.tid]
        state = self._get_state()
        gregs = state['uc_mcontext']['gregs']
        for i in range(0, len(x8664_regs)):
            if reg is None or reg == x8664_regs[i]:
                gregs[i] = thread.read_register(x8664_regs[i])

    def name(self):
        return "Vireo Thread " + str(self.tid)

    def underlying_thread(self):
        if vireo_current() == self.tid:
            global main_thread
            return main_thread
        return None

class VFinish(gdb.FinishBreakpoint):
    def stop(self):
        tid = int(self.return_value) + 1
        global thread_map
        thread_map[tid] = gdb.create_green_thread(tid, VireoGreenThread(tid))
        return False

class VCreate(gdb.Breakpoint):
    def stop(self):
        VFinish(gdb.newest_frame(), True)
        return False

class VExit(gdb.Breakpoint):
    def stop(self):
        global main_thread
        if main_thread is None:
            main_thread = gdb.selected_thread()
        global thread_map
        tid = vireo_current()
        if tid in thread_map:
            thread_map[tid].set_exited()
            del thread_map[tid]

VCreate('vireo_create', internal=True)
VExit('vireo_exit', internal=True)

  reply	other threads:[~2023-12-22 19:19 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-12-08 17:50 Andrey Turkin
2023-12-10 22:30 ` Tom Tromey
2023-12-11  7:44   ` Andrey Turkin
2023-12-11 17:46     ` Tom Tromey
2023-12-20 14:18       ` Andrey Turkin
2023-12-22  0:30         ` Tom Tromey
2023-12-22 19:19           ` Tom Tromey [this message]
2024-01-04 10:00             ` Andrey Turkin
2024-01-21 16:57               ` Tom Tromey

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=87edfedozl.fsf@tromey.com \
    --to=tom@tromey.com \
    --cc=andrey.turkin@gmail.com \
    --cc=gdb@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;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).