binutils-gdb/gdb/python/lib/gdb/dap/events.py
Simon Marchi 14ade91660 gdb: update some copyright years (2022 -> 2023)
The copyright years in the ROCm files (e.g. solib-rocm.c) are wrong,
they end in 2022 instead of 2023.  I suppose because I posted (or at
least prepared) the patches in 2022 but merged them in 2023, and forgot
to update the year.  I found a bunch of other files that are in the same
situation.  Fix them all up.

Change-Id: Ia55f5b563606c2ba6a89046f22bc0bf1c0ff2e10
Reviewed-By: Tom Tromey <tom@tromey.com>
2023-03-01 20:54:56 -05:00

166 lines
4.2 KiB
Python

# Copyright 2022-2023 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import enum
import gdb
from .server import send_event
from .startup import in_gdb_thread, Invoker, log
from .breakpoint import breakpoint_descriptor
@in_gdb_thread
def _on_exit(event):
code = 0
if hasattr(event, "exit_code"):
code = event.exit_code
send_event(
"exited",
{
"exitCode": code,
},
)
@in_gdb_thread
def _bp_modified(event):
send_event(
"breakpoint",
{
"reason": "changed",
"breakpoint": breakpoint_descriptor(event),
},
)
@in_gdb_thread
def _bp_created(event):
send_event(
"breakpoint",
{
"reason": "new",
"breakpoint": breakpoint_descriptor(event),
},
)
@in_gdb_thread
def _bp_deleted(event):
send_event(
"breakpoint",
{
"reason": "removed",
"breakpoint": breakpoint_descriptor(event),
},
)
@in_gdb_thread
def _new_thread(event):
send_event(
"thread",
{
"reason": "started",
"threadId": event.inferior_thread.global_num,
},
)
_suppress_cont = False
@in_gdb_thread
def _cont(event):
global _suppress_cont
if _suppress_cont:
log("_suppress_cont case")
_suppress_cont = False
else:
send_event(
"continued",
{
"threadId": gdb.selected_thread().global_num,
"allThreadsContinued": True,
},
)
class StopKinds(enum.Enum):
# The values here are chosen to follow the DAP spec.
STEP = "step"
BREAKPOINT = "breakpoint"
PAUSE = "pause"
EXCEPTION = "exception"
_expected_stop = None
@in_gdb_thread
def expect_stop(reason):
"""Indicate that a stop is expected, for the reason given."""
global _expected_stop
_expected_stop = reason
# A wrapper for Invoker that also sets the expected stop.
class ExecutionInvoker(Invoker):
"""A subclass of Invoker that sets the expected stop.
Note that this assumes that the command will restart the inferior,
so it will also cause ContinuedEvents to be suppressed."""
def __init__(self, cmd, expected):
super().__init__(cmd)
self.expected = expected
@in_gdb_thread
def __call__(self):
expect_stop(self.expected)
global _suppress_cont
_suppress_cont = True
# FIXME if the call fails should we clear _suppress_cont?
super().__call__()
@in_gdb_thread
def _on_stop(event):
log("entering _on_stop: " + repr(event))
global _expected_stop
obj = {
"threadId": gdb.selected_thread().global_num,
# FIXME we don't support non-stop for now.
"allThreadsStopped": True,
}
if isinstance(event, gdb.BreakpointEvent):
# Ignore the expected stop, we hit a breakpoint instead.
# FIXME differentiate between 'breakpoint', 'function breakpoint',
# 'data breakpoint' and 'instruction breakpoint' here.
_expected_stop = StopKinds.BREAKPOINT
obj["hitBreakpointIds"] = [x.number for x in event.breakpoints]
elif _expected_stop is None:
# FIXME what is even correct here
_expected_stop = StopKinds.EXCEPTION
obj["reason"] = _expected_stop.value
_expected_stop = None
send_event("stopped", obj)
gdb.events.stop.connect(_on_stop)
gdb.events.exited.connect(_on_exit)
gdb.events.breakpoint_created.connect(_bp_created)
gdb.events.breakpoint_modified.connect(_bp_modified)
gdb.events.breakpoint_deleted.connect(_bp_deleted)
gdb.events.new_thread.connect(_new_thread)
gdb.events.cont.connect(_cont)