diff options
Diffstat (limited to 'gdb-helpers/libcr.py')
-rw-r--r-- | gdb-helpers/libcr.py | 59 |
1 files changed, 32 insertions, 27 deletions
diff --git a/gdb-helpers/libcr.py b/gdb-helpers/libcr.py index 3ffafce..f74a702 100644 --- a/gdb-helpers/libcr.py +++ b/gdb-helpers/libcr.py @@ -7,11 +7,14 @@ import contextlib import time import typing -import gdb -import gdb.unwinder +import gdb # pylint: disable=import-error +import gdb.unwinder # pylint: disable=import-error # GDB helpers ################################################################## +# https://sourceware.org/bugzilla/show_bug.cgi?id=32428 +gdb_bug_32428 = True + class _gdb_Locus(typing.Protocol): @property @@ -125,19 +128,19 @@ class CrGlobals: return if self.coroutine_running: if not self.coroutine_running.is_selected(): - if True: # https://sourceware.org/bugzilla/show_bug.cgi?id=32428 + if gdb_bug_32428: print("Must return to running coroutine before continuing.") print("Hit ^C twice then run:") print(f" cr select {self.coroutine_running.id}") while True: time.sleep(1) - assert self.coroutine_running._cont_env - gdb_longjmp(self.coroutine_running._cont_env) + assert self.coroutine_running.cont_env + gdb_longjmp(self.coroutine_running.cont_env) for cr in self.coroutines: - cr._cont_env = None + cr.cont_env = None def is_valid_cid(self, cid: int) -> bool: - return 0 < cid and cid <= len(self.coroutines) + return 0 < cid <= len(self.coroutines) @property def coroutine_running(self) -> "CrCoroutine | None": @@ -211,6 +214,8 @@ class CrBreakpoint(gdb.Breakpoint): @enabled.setter def enabled(self, value: bool) -> None: self._unwinder.enabled = value + # Use a dunder-call to avoid an infinite loop. + # pylint: disable=unnecessary-dunder-call gdb.Breakpoint.enabled.__set__(self, value) # type: ignore def stop(self) -> bool: @@ -243,12 +248,12 @@ def cr_select_top_frame() -> None: class CrCoroutine: cr_globals: CrGlobals cid: int - _cont_env: gdb_JmpBuf | None + cont_env: gdb_JmpBuf | None def __init__(self, cr_globals: CrGlobals, cid: int) -> None: self.cr_globals = cr_globals self.cid = cid - self._cont_env = None + self.cont_env = None @property def id(self) -> int: @@ -269,18 +274,18 @@ class CrCoroutine: sp = int(gdb.parse_and_eval("$sp")) lo = int(gdb.parse_and_eval(f"coroutine_table[{self.id-1}].stack")) hi = lo + int(gdb.parse_and_eval(f"coroutine_table[{self.id-1}].stack_size")) - return lo <= sp and sp < hi + return lo <= sp < hi def select(self, level: int = -1) -> None: if self.cr_globals.coroutine_selected: - self.cr_globals.coroutine_selected._cont_env = gdb_setjmp() + self.cr_globals.coroutine_selected.cont_env = gdb_setjmp() - if self._cont_env: - gdb_longjmp(self._cont_env) + if self.cont_env: + gdb_longjmp(self.cont_env) else: env: gdb_JmpBuf if self == self.cr_globals.coroutine_running: - assert False # self._cont_env should have been set + assert False # self.cont_env should have been set elif self.state == self.cr_globals.CR_RUNNING: env = self.cr_globals.readjmp("&coroutine_add_env") else: @@ -332,7 +337,7 @@ class CrListCommand(gdb.Command): def invoke(self, arg: str, from_tty: bool) -> None: argv = gdb.string_to_argv(arg) if len(argv) != 0: - raise gdb.GdbError(f"Usage: cr list") + raise gdb.GdbError("Usage: cr list") rows: list[tuple[str, str, str, str, str]] = [ ("", "Id", "Name", "State", "Frame") @@ -384,7 +389,7 @@ class CrListCommand(gdb.Command): cr_select_top_frame() full = gdb.execute("frame", from_tty=from_tty, to_string=True) gdb.execute(f"select-frame level {saved_level}") - except Exception as e: + except Exception as e: # pylint: disable=broad-exception-caught full = "#0 err: " + str(e) line = full.split("\n", maxsplit=1)[0] return line.split(maxsplit=1)[1] @@ -432,23 +437,23 @@ class CrSelectCommand(gdb.Command): # Wire it all in ############################################################### -cr_globals: CrGlobals | None = None +_cr_globals: CrGlobals | None = None def cr_initialize() -> None: - global cr_globals - if cr_globals: - old = cr_globals + global _cr_globals + if _cr_globals: + old = _cr_globals new = CrGlobals() for i in range(min(len(old.coroutines), len(new.coroutines))): - new.coroutines[i]._cont_env = old.coroutines[i]._cont_env + new.coroutines[i].cont_env = old.coroutines[i].cont_env old.delete() - cr_globals = new + _cr_globals = new else: - cr_globals = CrGlobals() - CrCommand(cr_globals) - CrListCommand(cr_globals) - CrSelectCommand(cr_globals) + _cr_globals = CrGlobals() + CrCommand(_cr_globals) + CrListCommand(_cr_globals) + CrSelectCommand(_cr_globals) def cr_on_new_objfile(event: gdb.Event) -> None: @@ -460,7 +465,7 @@ def cr_on_new_objfile(event: gdb.Event) -> None: gdb.events.new_objfile.disconnect(cr_on_new_objfile) -if cr_globals: +if _cr_globals: cr_initialize() else: gdb.events.new_objfile.connect(cr_on_new_objfile) |