all repos — mgba @ 531d4c7bae4139a0caedbb5b1e83c7e532be0ab8

mGBA Game Boy Advance Emulator

src/platform/python/mgba/debugger.py (view raw)

 1# Copyright (c) 2013-2017 Jeffrey Pfau
 2#
 3# This Source Code Form is subject to the terms of the Mozilla Public
 4# License, v. 2.0. If a copy of the MPL was not distributed with this
 5# file, You can obtain one at http://mozilla.org/MPL/2.0/.
 6from ._pylib import ffi, lib
 7from .core import IRunner, ICoreOwner, Core
 8
 9class DebuggerCoreOwner(ICoreOwner):
10    def __init__(self, debugger):
11        self.debugger = debugger
12        self.wasPaused = False
13
14    def claim(self):
15        if self.debugger.isRunning():
16            self.wasPaused = True
17            self.debugger.pause()
18        return self.debugger._core
19
20    def release(self):
21        if self.wasPaused:
22            self.debugger.unpause()
23
24class NativeDebugger(IRunner):
25    WATCHPOINT_WRITE = lib.WATCHPOINT_WRITE
26    WATCHPOINT_READ = lib.WATCHPOINT_READ
27    WATCHPOINT_RW = lib.WATCHPOINT_RW
28
29    BREAKPOINT_HARDWARE = lib.BREAKPOINT_HARDWARE
30    BREAKPOINT_SOFTWARE = lib.BREAKPOINT_SOFTWARE
31
32    ENTER_MANUAL = lib.DEBUGGER_ENTER_MANUAL
33    ENTER_ATTACHED = lib.DEBUGGER_ENTER_ATTACHED
34    ENTER_BREAKPOINT = lib.DEBUGGER_ENTER_BREAKPOINT
35    ENTER_WATCHPOINT = lib.DEBUGGER_ENTER_WATCHPOINT
36    ENTER_ILLEGAL_OP = lib.DEBUGGER_ENTER_ILLEGAL_OP
37
38    def __init__(self, native):
39        self._native = native
40        self._cbs = []
41        self._core = Core._detect(native.core)
42        self._core._wasReset = True
43
44    def pause(self):
45        lib.mDebuggerEnter(self._native, lib.DEBUGGER_ENTER_MANUAL, ffi.NULL)
46
47    def unpause(self):
48        self._native.state = lib.DEBUGGER_RUNNING
49
50    def isRunning(self):
51        return self._native.state == lib.DEBUGGER_RUNNING
52
53    def isPaused(self):
54        return self._native.state in (lib.DEBUGGER_PAUSED, lib.DEBUGGER_CUSTOM)
55
56    def useCore(self):
57        return DebuggerCoreOwner(self)
58
59    def setBreakpoint(self, address):
60        if not self._native.platform.setBreakpoint:
61            raise RuntimeError("Platform does not support breakpoints")
62        self._native.platform.setBreakpoint(self._native.platform, address)
63
64    def clearBreakpoint(self, address):
65        if not self._native.platform.setBreakpoint:
66            raise RuntimeError("Platform does not support breakpoints")
67        self._native.platform.clearBreakpoint(self._native.platform, address)
68
69    def setWatchpoint(self, address):
70        if not self._native.platform.setWatchpoint:
71            raise RuntimeError("Platform does not support watchpoints")
72        self._native.platform.setWatchpoint(self._native.platform, address)
73
74    def clearWatchpoint(self, address):
75        if not self._native.platform.clearWatchpoint:
76            raise RuntimeError("Platform does not support watchpoints")
77        self._native.platform.clearWatchpoint(self._native.platform, address)
78
79    def addCallback(self, cb):
80        self._cbs.append(cb)