[gdb] Complete stubs for gdb.dap (#14269)

This commit is contained in:
Brian Schubert
2025-07-12 13:16:57 -04:00
committed by GitHub
parent 138a54b00f
commit 9fca76c55f
24 changed files with 571 additions and 34 deletions
-3
View File
@@ -73,6 +73,3 @@ gdb.Progspace.xmethods
# stubtest thinks this can't be sub-classed at runtime, but it is
gdb.disassembler.DisassemblerPart
# incomplete modules
gdb\.dap\.[a-z_]+\.[A-Za-z_]+
+8 -2
View File
@@ -7,7 +7,7 @@ import threading
from _typeshed import Incomplete
from collections.abc import Callable, Iterator, Mapping, Sequence
from contextlib import AbstractContextManager
from typing import Any, Final, Generic, Literal, Protocol, TypeVar, final, overload, type_check_only
from typing import Any, Final, Generic, Literal, Protocol, TypedDict, TypeVar, final, overload, type_check_only
from typing_extensions import TypeAlias, deprecated
import gdb.FrameDecorator
@@ -860,10 +860,16 @@ class LazyString:
# Architectures
@type_check_only
class _Instruction(TypedDict):
addr: int
asm: str
length: int
@final
class Architecture:
def name(self) -> str: ...
def disassemble(self, start_pc: int, end_pc: int = ..., count: int = ...) -> list[dict[str, object]]: ...
def disassemble(self, start_pc: int, end_pc: int = ..., count: int = ...) -> list[_Instruction]: ...
def integer_type(self, size: int, signed: bool = ...) -> Type: ...
def registers(self, reggroup: str = ...) -> RegisterDescriptorIterator: ...
def register_groups(self) -> RegisterGroupsIterator: ...
+16 -8
View File
@@ -1,11 +1,19 @@
from typing import Any
class Server:
def __init__(self, in_stream, out_stream, child_stream) -> None: ...
def main_loop(self) -> None: ...
def send_event(self, event: str, body: Any | None = None) -> None: ... # body is an arbitrary object
def send_event_later(self, event: str, body: Any | None = None) -> None: ... # body is an arbitrary object
def shutdown(self) -> None: ...
from . import (
breakpoint as breakpoint,
bt as bt,
evaluate as evaluate,
launch as launch,
locations as locations,
memory as memory,
modules as modules,
next as next,
pause as pause,
scopes as scopes,
sources as sources,
startup as startup,
threads as threads,
)
from .server import Server as Server
def pre_command_loop() -> None: ...
def run() -> None: ...
+49 -1
View File
@@ -1 +1,49 @@
def __getattr__(name: str): ... # incomplete module
from _typeshed import Incomplete, Unused
from collections.abc import Sequence
from contextlib import AbstractContextManager
from typing import TypedDict, type_check_only
from typing_extensions import NotRequired
import gdb
from .sources import Source
@type_check_only
class _SourceBreakpoint(TypedDict):
source: str
line: int
condition: NotRequired[str | None]
hitCondition: NotRequired[str | None]
logMessage: NotRequired[str | None]
@type_check_only
class _ExceptionFilterOptions(TypedDict):
filderId: str
condition: NotRequired[str | None]
@type_check_only
class _BreakpointDescriptor(TypedDict):
id: int
verified: bool
reason: NotRequired[str] # only present when verified is False. Possibly only literal "pending" or "failed"
message: NotRequired[str] # only present when reason == "failed"
source: NotRequired[Source]
line: NotRequired[int]
instructionReference: NotRequired[str]
@type_check_only
class _SetBreakpointResult(TypedDict):
breakpoints: list[_BreakpointDescriptor]
# frozenset entries are tuples from _SourceBreakpoint.items() or _ExceptionFilterOptions.items()
breakpoint_map: dict[str, dict[frozenset[Incomplete], gdb.Breakpoint]]
def suppress_new_breakpoint_event() -> AbstractContextManager[None]: ...
def set_breakpoint(*, source: Source, breakpoints: Sequence[_SourceBreakpoint] = (), **args: Unused) -> _SetBreakpointResult: ...
def set_fn_breakpoint(*, breakpoints: Sequence[_SourceBreakpoint], **args: Unused) -> _SetBreakpointResult: ...
def set_insn_breakpoints(
*, breakpoints: Sequence[_SourceBreakpoint], offset: int | None = None, **args: Unused
) -> _SetBreakpointResult: ...
def set_exception_breakpoints(
*, filters: Sequence[str], filterOptions: Sequence[_ExceptionFilterOptions] = (), **args: Unused
) -> _SetBreakpointResult: ...
+49 -1
View File
@@ -1 +1,49 @@
def __getattr__(name: str): ... # incomplete module
from _typeshed import Unused
from typing import TypedDict, type_check_only
from typing_extensions import NotRequired
from .sources import Source
from .varref import _ValueFormat
@type_check_only
class _StackFrameFormat(_ValueFormat, total=False):
parameters: bool
parameterTypes: bool
parameterNames: bool
parameterValues: bool
line: bool
module: bool
includeAll: bool
@type_check_only
class _StackFrame(TypedDict):
id: int
name: str
line: int
column: int
instructionPointerReference: str
moduleId: NotRequired[str | None]
source: NotRequired[Source]
@type_check_only
class _StackTraceResult(TypedDict):
stackFrames: list[_StackFrame]
def check_stack_frame(
*,
# From source:
# Note that StackFrameFormat extends ValueFormat, which is why
# "hex" appears here.
hex: bool = False,
parameters: bool = False,
parameterTypes: bool = False,
parameterNames: bool = False,
parameterValues: bool = False,
line: bool = False,
module: bool = False,
includeAll: bool = False,
**rest: Unused,
) -> _StackFrameFormat: ...
def stacktrace(
*, levels: int = 0, startFrame: int = 0, threadId: int, format: _StackFrameFormat | None = None, **extra: Unused
) -> _StackTraceResult: ...
+22 -1
View File
@@ -1 +1,22 @@
def __getattr__(name: str): ... # incomplete module
from _typeshed import Unused
from typing import TypedDict, type_check_only
from typing_extensions import NotRequired
from .sources import Source
@type_check_only
class _Instruction(TypedDict):
address: str
instruction: str
instructionBytes: str
symbol: NotRequired[str] # only set if there's a corresponding label
line: NotRequired[int] # only set if source is available
location: NotRequired[Source] # only set if source is available
@type_check_only
class _DisassembleResult(TypedDict):
instructions: list[_Instruction]
def disassemble(
*, memoryReference: str, offset: int = 0, instructionOffset: int = 0, instructionCount: int, **extra: Unused
) -> _DisassembleResult: ...
+31 -1
View File
@@ -1 +1,31 @@
def __getattr__(name: str): ... # incomplete module
from _typeshed import Unused
from typing import Literal, TypedDict, type_check_only
import gdb
from .varref import VariableReference, _ValueFormat, _VariableReferenceDescriptor
class EvaluateResult(VariableReference):
def __init__(self, value: gdb.Value) -> None: ...
@type_check_only
class _VariablesResult(TypedDict):
variables: list[_VariableReferenceDescriptor]
def eval_request(
*,
expression: str,
frameId: int | None = None,
context: Literal["watch", "variables", "hover", "repl"] = "variables",
format: _ValueFormat | None = None,
**args: Unused,
) -> _VariableReferenceDescriptor: ...
def variables(
*, variablesReference: int, start: int = 0, count: int = 0, format: _ValueFormat | None = None, **args: Unused
) -> _VariablesResult: ...
def set_expression(
*, expression: str, value: str, frameId: int | None = None, format: _ValueFormat | None = None, **args: Unused
) -> _VariableReferenceDescriptor: ...
def set_variable(
*, variablesReference: int, name: str, value: str, format: _ValueFormat | None = None, **args: Unused
) -> _VariableReferenceDescriptor: ...
+12 -1
View File
@@ -1 +1,12 @@
def __getattr__(name: str): ... # incomplete module
import gdb
inferior_running: bool
def send_process_event_once() -> None: ...
def expect_process(reason: str) -> None: ...
def thread_event(event: gdb.ThreadEvent, reason: str) -> None: ...
def expect_stop(reason: str) -> None: ...
def exec_and_expect_stop(cmd: str, expected_pause: bool = False) -> None: ...
# Map from gdb stop reasons to DAP stop reasons.
stop_reason_map: dict[str, str]
+7 -1
View File
@@ -1 +1,7 @@
def __getattr__(name: str): ... # incomplete module
from collections.abc import Generator
import gdb
def frame_for_id(id: int) -> gdb.Frame: ...
def select_frame(id: int) -> None: ...
def dap_frame_generator(frame_low: int, levels: int, include_all: bool) -> Generator[tuple[int, gdb.Frame]]: ...
+16 -1
View File
@@ -1 +1,16 @@
def __getattr__(name: str): ... # incomplete module
from _typeshed import SupportsFlush, SupportsRead, SupportsReadline, SupportsWrite
from typing import Any, type_check_only
import gdb
from .server import _JSONValue
from .startup import DAPQueue
@type_check_only
class _SupportsReadAndReadlineBytes(SupportsRead[bytes], SupportsReadline[bytes]): ...
@type_check_only
class _SupportsWriteAndFlushBytes(SupportsWrite[bytes], SupportsFlush): ...
def read_json(stream: _SupportsReadAndReadlineBytes) -> Any: ... # returns result of json.loads
def start_json_writer(stream: _SupportsWriteAndFlushBytes, queue: DAPQueue[_JSONValue]) -> gdb.Thread: ...
+14 -1
View File
@@ -1 +1,14 @@
def __getattr__(name: str): ... # incomplete module
from _typeshed import Unused
from collections.abc import Mapping, Sequence
def launch(
*,
program: str | None = None,
cwd: str | None = None,
args: Sequence[str] = (),
env: Mapping[str, str] | None = None,
stopAtBeginningOfMainSubprogram: bool = False,
**extra: Unused,
): ...
def attach(*, program: str | None = None, pid: int | None = None, target: str | None = None, **args: Unused) -> None: ...
def config_done(**args: Unused) -> None: ...
+16 -1
View File
@@ -1 +1,16 @@
def __getattr__(name: str): ... # incomplete module
from _typeshed import Unused
from typing import TypedDict, type_check_only
from .sources import Source
@type_check_only
class _Line(TypedDict):
line: int
@type_check_only
class _BreakpointLocationsResult(TypedDict):
breakpoints: list[_Line]
def breakpoint_locations(
*, source: Source, line: int, endLine: int | None = None, **extra: Unused
) -> _BreakpointLocationsResult: ...
+10 -1
View File
@@ -1 +1,10 @@
def __getattr__(name: str): ... # incomplete module
from _typeshed import Unused
from typing import TypedDict, type_check_only
@type_check_only
class _ReadMemoryResult(TypedDict):
address: str
data: str
def read_memory(*, memoryReference: str, offset: int = 0, count: int, **extra: Unused) -> _ReadMemoryResult: ...
def write_memory(*, memoryReference: str, offset: int = 0, data: str, **extra: Unused): ...
+21 -1
View File
@@ -1 +1,21 @@
def __getattr__(name: str): ... # incomplete module
from _typeshed import Unused
from typing import TypedDict, type_check_only
from typing_extensions import NotRequired
import gdb
@type_check_only
class _Module(TypedDict):
id: str | None
name: str | None
path: NotRequired[str | None]
@type_check_only
class _ModulesResult(TypedDict):
modules: list[_Module]
totalModules: int
def module_id(objfile: gdb.Objfile) -> str | None: ...
def is_module(objfile: gdb.Objfile) -> bool: ...
def make_module(objf: gdb.Objfile) -> _Module: ...
def modules(*, startModule: int = 0, moduleCount: int = 0, **args: Unused) -> _ModulesResult: ...
+14 -1
View File
@@ -1 +1,14 @@
def __getattr__(name: str): ... # incomplete module
from _typeshed import Unused
from typing import Literal, TypedDict, type_check_only
from typing_extensions import TypeAlias
@type_check_only
class _ContinueRequestResult(TypedDict):
allThreadsContinued: bool
_Granularity: TypeAlias = Literal["statement", "instruction"]
def next(*, threadId: int, singleThread: bool = False, granularity: _Granularity = "statement", **args: Unused) -> None: ...
def step_in(*, threadId: int, singleThread: bool = False, granularity: _Granularity = "statement", **args: Unused) -> None: ...
def step_out(*, threadId: int, singleThread: bool = False, **args: Unused): ...
def continue_request(*, threadId: int, singleThread: bool = False, **args: Unused) -> _ContinueRequestResult: ...
+3 -1
View File
@@ -1 +1,3 @@
def __getattr__(name: str): ... # incomplete module
from _typeshed import Unused
def pause(**args: Unused) -> None: ...
+47 -1
View File
@@ -1 +1,47 @@
def __getattr__(name: str): ... # incomplete module
from _typeshed import Unused
from collections.abc import Iterable
from typing import TypedDict, type_check_only
from typing_extensions import NotRequired
import gdb
from ..FrameDecorator import FrameDecorator, SymValueWrapper
from .varref import BaseReference, _ReferenceDescriptor
frame_to_scope: dict[int, _ScopeReference]
@type_check_only
class _ScopeReferenceDescriptor(_ReferenceDescriptor):
presentationHint: str
expensive: bool
namedVariables: int
line: NotRequired[int]
@type_check_only
class _ScopesResult(TypedDict):
scopes: list[_ScopeReferenceDescriptor]
def clear_scopes(event: Unused) -> None: ...
def set_finish_value(val: gdb.Value) -> None: ...
def symbol_value(sym: SymValueWrapper, frame: FrameDecorator) -> tuple[str, gdb.Value]: ...
class _ScopeReference(BaseReference):
hint: str
frame: FrameDecorator
inf_frame: gdb.Frame
function: str | None
line: int | None
var_list: tuple[SymValueWrapper, ...]
def __init__(self, name: str, hint: str, frame: FrameDecorator, var_list: Iterable[SymValueWrapper]) -> None: ...
def to_object(self) -> _ScopeReferenceDescriptor: ...
def has_children(self) -> bool: ...
def child_count(self) -> int: ...
# note: parameter named changed from 'index' to 'idx'
def fetch_one_child(self, idx: int) -> tuple[str, gdb.Value]: ...
class _FinishScopeReference(_ScopeReference): ...
class _RegisterReference(_ScopeReference):
def __init__(self, name: str, frame: FrameDecorator) -> None: ...
def scopes(*, frameId: int, **extra: Unused) -> _ScopesResult: ...
+77 -1
View File
@@ -1 +1,77 @@
def __getattr__(name: str): ... # incomplete module
import threading
from _typeshed import Incomplete, SupportsReadline, Unused
from collections.abc import Callable
from contextlib import AbstractContextManager
from typing import Any, Generic, TypeVar, type_check_only
from typing_extensions import TypeAlias
from .io import _SupportsReadAndReadlineBytes, _SupportsWriteAndFlushBytes
from .startup import DAPQueue
_T = TypeVar("_T")
_F = TypeVar("_F", bound=Callable[..., Any])
_RequestID: TypeAlias = int
_EventBody: TypeAlias = Any # arbitrary object, implicitly constrained by the event being sent
_JSONValue: TypeAlias = Any # any object that can be handled by json.dumps/json.loads
class NotStoppedException(Exception): ...
class CancellationHandler:
lock: threading.Lock
reqs: list[_RequestID]
in_flight_dap_thread: _RequestID | None
in_flight_gdb_thread: _RequestID | None
def starting(self, req: _RequestID) -> None: ...
def done(self, req: _RequestID) -> None: ... # req argument is not used
def cancel(self, req: _RequestID) -> None: ...
def interruptable_region(self, req: _RequestID | None) -> AbstractContextManager[None]: ...
class Server:
in_stream: _SupportsReadAndReadlineBytes
out_stream: _SupportsWriteAndFlushBytes
child_stream: SupportsReadline[str]
delay_events: list[tuple[str, _EventBody]]
write_queue: DAPQueue[_JSONValue | None]
read_queue: DAPQueue[_JSONValue | None]
done: bool
canceller: CancellationHandler
config: dict[str, Incomplete]
def __init__(
self,
in_stream: _SupportsReadAndReadlineBytes,
out_stream: _SupportsWriteAndFlushBytes,
child_stream: SupportsReadline[str],
) -> None: ...
def main_loop(self) -> None: ...
def send_event(self, event: str, body: _EventBody | None = None) -> None: ...
def send_event_later(self, event: str, body: _EventBody | None = None) -> None: ...
def shutdown(self) -> None: ...
def send_event(event: str, body: _EventBody | None = None) -> None: ...
@type_check_only
class _Wrapper:
def __call__(self, func: _F) -> _F: ...
def request(name: str, *, response: bool = True, on_dap_thread: bool = False, expect_stopped: bool = True) -> _Wrapper: ...
def capability(name: str, value: bool = True) -> _Wrapper: ...
def client_bool_capability(name: str) -> bool: ...
def initialize(**args) -> dict[str, bool]: ... # args is arbitrary values for Server.config
def terminate(**args: Unused) -> None: ...
def disconnect(*, terminateDebuggee: bool = False, **args: Unused): ...
def cancel(**args: Unused) -> None: ...
class Invoker:
cmd: str
def __init__(self, cmd: str) -> None: ...
def __call__(self) -> None: ...
class Cancellable(Generic[_T]):
fn: Callable[[], _T]
result_q: DAPQueue[_T] | None
req: _RequestID
def __init__(self, fn: Callable[[], _T], result_q: DAPQueue[_T] | None = None) -> None: ...
def __call__(self) -> None: ...
def send_gdb(cmd: str | Callable[[], object]) -> None: ...
def send_gdb_with_response(fn: str | Callable[[], _T]) -> _T: ...
+24 -1
View File
@@ -1 +1,24 @@
def __getattr__(name: str): ... # incomplete module
from _typeshed import Unused
from typing import TypedDict, type_check_only
from typing_extensions import TypeAlias
_SourceReferenceID: TypeAlias = int
@type_check_only
class Source(TypedDict, total=False):
name: str
path: str
sourceReference: _SourceReferenceID
@type_check_only
class _LoadSourcesResult(TypedDict):
sources: list[Source]
@type_check_only
class _SourceResult(TypedDict):
content: str
def make_source(fullname: str, filename: str | None) -> Source: ...
def decode_source(source: Source) -> _SourceReferenceID: ...
def loaded_sources(**extra: Unused) -> _LoadSourcesResult: ...
def source(*, source: Source | None = None, sourceReference: _SourceReferenceID, **extra: Unused) -> _SourceResult: ...
+44 -1
View File
@@ -1 +1,44 @@
def __getattr__(name: str): ... # incomplete module
import enum
import io
import queue
import threading
from collections.abc import Callable, Iterable
from typing import Any, ClassVar, TypeVar
from typing_extensions import TypeAlias
import gdb
_T = TypeVar("_T")
_F = TypeVar("_F", bound=Callable[..., Any])
DAPQueue: TypeAlias = queue.SimpleQueue[_T]
class DAPException(Exception): ...
def parse_and_eval(expression: str, global_context: bool = False) -> gdb.Value: ...
# target and args are passed to gdb.Thread
def start_thread(name: str, target: Callable[..., object], args: Iterable[Any] = ()) -> gdb.Thread: ...
def start_dap(target: Callable[..., object]) -> None: ...
def in_gdb_thread(func: _F) -> _F: ...
def in_dap_thread(func: _F) -> _F: ...
class LogLevel(enum.IntEnum):
DEFAULT = 1
FULL = 2
class LogLevelParam(gdb.Parameter):
def __init__(self) -> None: ...
class LoggingParam(gdb.Parameter):
lock: ClassVar[threading.Lock]
log_file: io.TextIOWrapper | None
def __init__(self) -> None: ...
def get_set_string(self) -> str: ...
dap_log: LoggingParam
def log(something: object, level: LogLevel = LogLevel.DEFAULT) -> None: ...
def thread_log(something: object, level: LogLevel = LogLevel.DEFAULT) -> None: ...
def log_stack(level: LogLevel = LogLevel.DEFAULT) -> None: ...
def exec_and_log(cmd: str) -> None: ...
+1 -1
View File
@@ -1 +1 @@
def __getattr__(name: str): ... # incomplete module
def set_thread(thread_id: int) -> None: ...
+14 -1
View File
@@ -1 +1,14 @@
def __getattr__(name: str): ... # incomplete module
from _typeshed import Unused
from typing import TypedDict, type_check_only
from typing_extensions import NotRequired
@type_check_only
class _Thread(TypedDict):
id: int
name: NotRequired[str]
@type_check_only
class _ThreadsResult(TypedDict):
threads: list[_Thread]
def threads(**args: Unused) -> _ThreadsResult: ...
+6 -1
View File
@@ -1 +1,6 @@
def __getattr__(name: str): ... # incomplete module
from collections.abc import Callable
from typing import Any, TypeVar
_F = TypeVar("_F", bound=Callable[..., Any])
def type_check(func: _F) -> _F: ...
+70 -1
View File
@@ -1 +1,70 @@
def __getattr__(name: str): ... # incomplete module
import abc
from _typeshed import Unused
from collections import defaultdict
from collections.abc import Generator
from contextlib import AbstractContextManager
from typing import TypedDict, type_check_only
from typing_extensions import NotRequired
import gdb
@type_check_only
class _ValueFormat(TypedDict, total=False):
hex: bool
@type_check_only
class _ReferenceDescriptor(TypedDict):
# Result of BaseReference.to_object()
variableReference: int
name: NotRequired[str]
@type_check_only
class _VariableReferenceDescriptor(_ReferenceDescriptor):
# Result of VariableReference.to_object()
indexedVariables: NotRequired[int]
namedVariables: NotRequired[int]
memoryReference: NotRequired[str]
type: NotRequired[str]
# Below key name set by VariableReference.result_name
# Could be modelled with extra_items=str if PEP 728 is accepted.
value: NotRequired[str]
all_variables: list[BaseReference]
def clear_vars(event: Unused) -> None: ...
def apply_format(value_format: _ValueFormat | None) -> AbstractContextManager[None]: ...
class BaseReference(abc.ABC):
ref: int
name: str
children: list[VariableReference | None] | None
by_name: dict[str, VariableReference]
name_counts: defaultdict[str, int]
def __init__(self, name: str) -> None: ...
def to_object(self) -> _ReferenceDescriptor: ...
@abc.abstractmethod
def has_children(self) -> bool: ...
def reset_children(self): ...
@abc.abstractmethod
def fetch_one_child(self, index: int) -> tuple[str, gdb.Value]: ...
@abc.abstractmethod
def child_count(self) -> int: ...
def fetch_children(self, start: int, count: int) -> Generator[VariableReference]: ...
def find_child_by_name(self, name: str) -> VariableReference: ...
class VariableReference(BaseReference):
result_name: str
value: gdb.Value
child_cache: list[tuple[int | str, gdb.Value]] | None
count: int | None
printer: gdb._PrettyPrinter
def __init__(self, name: str, value: gdb.Value, result_name: str = "value") -> None: ...
def assign(self, value: gdb.Value) -> None: ...
def has_children(self) -> bool: ...
def cache_children(self) -> list[tuple[int | str, gdb.Value]]: ...
def child_count(self) -> int: ...
def to_object(self) -> _VariableReferenceDescriptor: ...
# note: parameter named changed from 'index' to 'idx'
def fetch_one_child(self, idx: int) -> tuple[str, gdb.Value]: ...
def find_variable(ref: int) -> BaseReference: ...