Skip to content

Commit b171aaf

Browse files
committed
Add a global debug events handler to fix dumb approach
1 parent eb2e296 commit b171aaf

File tree

4 files changed

+307
-100
lines changed

4 files changed

+307
-100
lines changed

api/globalvars.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@
1818
lock = False
1919
terminal_id = None
2020
debugFlags = None
21-
httpServer: http_server.GDBFrontendHTTPServer = None
21+
debugHandler = None
22+
httpServer = None
2223
inferior_run_times = {}
2324
step_time = False
2425
is_enhanced_collabration = False
@@ -46,6 +47,7 @@ def init():
4647
debugFlags = api.flags.AtomicDebugFlags()
4748

4849
global terminal_id
50+
global debugHandler
4951
global httpServer
5052
global inferior_run_times
5153
global step_time
@@ -58,6 +60,7 @@ def access(function):
5860
global lock
5961
global terminal_id
6062
global debugFlags
63+
global debugHandler
6164
global httpServer
6265
global inferior_run_times
6366
global step_time

debug_events.py

Lines changed: 293 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,293 @@
1+
# -*- coding: utf-8 -*-
2+
#
3+
# gdb-frontend is a easy, flexible and extensionable gui debugger
4+
#
5+
# https://github.com/rohanrhu/gdb-frontend
6+
# https://oguzhaneroglu.com/projects/gdb-frontend/
7+
#
8+
# Licensed under GNU/GPLv3
9+
# Copyright (C) 2019, Oğuzhan Eroğlu (https://oguzhaneroglu.com/) <[email protected]>
10+
11+
import importlib
12+
import json
13+
import time
14+
import traceback
15+
16+
import config
17+
config.init()
18+
import plugin
19+
import util
20+
import api.debug
21+
import api.collabration
22+
import api.flags
23+
import api.globalvars
24+
import api.collabration
25+
import websocket
26+
import terminal_daemon
27+
28+
gdb = importlib.import_module("gdb")
29+
30+
api.globalvars.init()
31+
plugin.init()
32+
api.collabration.init()
33+
34+
class GDBFrontendDebugEventsHandler:
35+
cont_time = False
36+
37+
def __init__(self):
38+
self.connectGDBEvents()
39+
40+
def connectGDBEvents(self):
41+
gdb.events.new_objfile.connect(self.gdb_on_new_objfile)
42+
gdb.events.clear_objfiles.connect(self.gdb_on_clear_objfiles)
43+
gdb.events.breakpoint_created.connect(self.gdb_on_breakpoint_created)
44+
gdb.events.breakpoint_modified.connect(self.gdb_on_breakpoint_modified)
45+
gdb.events.breakpoint_deleted.connect(self.gdb_on_breakpoint_deleted)
46+
gdb.events.stop.connect(self.gdb_on_stop)
47+
gdb.events.new_thread.connect(self.gdb_on_new_thread)
48+
gdb.events.cont.connect(self.gdb_on_cont)
49+
gdb.events.exited.connect(self.gdb_on_exited)
50+
gdb.events.inferior_deleted.connect(self.gdb_on_inferior_deleted)
51+
gdb.events.new_inferior.connect(self.gdb_on_new_inferior)
52+
53+
def disconnectGDBEvents(self):
54+
gdb.events.new_objfile.disconnect(self.gdb_on_new_objfile)
55+
gdb.events.clear_objfiles.disconnect(self.gdb_on_clear_objfiles)
56+
gdb.events.breakpoint_created.disconnect(self.gdb_on_breakpoint_created)
57+
gdb.events.breakpoint_modified.disconnect(self.gdb_on_breakpoint_modified)
58+
gdb.events.breakpoint_deleted.disconnect(self.gdb_on_breakpoint_deleted)
59+
gdb.events.stop.disconnect(self.gdb_on_stop)
60+
gdb.events.new_thread.disconnect(self.gdb_on_new_thread)
61+
gdb.events.cont.disconnect(self.gdb_on_cont)
62+
gdb.events.exited.disconnect(self.gdb_on_exited)
63+
gdb.events.inferior_deleted.disconnect(self.gdb_on_inferior_deleted)
64+
gdb.events.new_inferior.disconnect(self.gdb_on_new_inferior)
65+
66+
def gdb_on_new_objfile(self, event):
67+
util.verbose("GDBFrontendDebugEventsHandler", "gdb_on_new_objfile()")
68+
69+
api.globalvars.inferior_run_times[gdb.selected_inferior().num] = int(time.time())
70+
71+
def _mt():
72+
self.gdb_on_new_objfile__mT(event)
73+
74+
gdb.post_event(_mt)
75+
76+
def gdb_on_new_objfile__mT(self, event):
77+
pass
78+
79+
def gdb_on_clear_objfiles(self, event):
80+
util.verbose("GDBFrontendDebugEventsHandler", "gdb_on_clear_objfiles()")
81+
82+
if api.globalvars.dont_emit_until_stop_or_exit: return
83+
84+
gdb.post_event(self.gdb_on_clear_objfiles__mT)
85+
86+
def gdb_on_clear_objfiles__mT(self):
87+
pass
88+
89+
def gdb_on_breakpoint_created(self, event):
90+
util.verbose("GDBFrontendDebugEventsHandler", "gdb_on_breakpoint_created()")
91+
92+
gdb.post_event(self.gdb_on_breakpoint_created__mT)
93+
94+
def gdb_on_breakpoint_created__mT(self):
95+
interrupted = api.globalvars.debugFlags.get(api.flags.AtomicDebugFlags.IS_INTERRUPTED_FOR_BREAKPOINT_ADD)
96+
97+
def gdb_on_breakpoint_modified(self, event):
98+
util.verbose("GDBFrontendDebugEventsHandler", "gdb_on_breakpoint_modified()")
99+
100+
gdb.post_event(self.gdb_on_breakpoint_modified__mT)
101+
102+
def gdb_on_breakpoint_modified__mT(self):
103+
interrupted = api.globalvars.debugFlags.get(api.flags.AtomicDebugFlags.IS_INTERRUPTED_FOR_BREAKPOINT_MOD)
104+
interrupted = interrupted or api.globalvars.debugFlags.get(api.flags.AtomicDebugFlags.IS_INTERRUPTED_FOR_BREAKPOINT_SET)
105+
106+
def gdb_on_breakpoint_deleted(self, event):
107+
util.verbose("GDBFrontendDebugEventsHandler", "gdb_on_breakpoint_deleted()")
108+
109+
if api.globalvars.dont_emit_until_stop_or_exit: return
110+
111+
gdb.post_event(self.gdb_on_breakpoint_deleted__mT)
112+
113+
def gdb_on_breakpoint_deleted__mT(self):
114+
interrupted = api.globalvars.debugFlags.get(api.flags.AtomicDebugFlags.IS_INTERRUPTED_FOR_BREAKPOINT_DEL)
115+
116+
def gdb_on_stop(self, event):
117+
util.verbose("GDBFrontendDebugEventsHandler", "gdb_on_stop()")
118+
119+
api.globalvars.debugFlags.set(api.flags.AtomicDebugFlags.IS_RUNNING, False)
120+
121+
api.globalvars.dont_emit_until_stop_or_exit = False
122+
api.globalvars.step_time = time.time() * 1000 - self.cont_time
123+
124+
gdb.post_event(self.gdb_on_stop__mT)
125+
126+
def gdb_on_stop__mT(self):
127+
interrupted_for_thread_safety = api.globalvars.debugFlags.get(api.flags.AtomicDebugFlags.IS_INTERRUPTED_FOR_THREAD_SAFETY)
128+
interrupted_for_terminate = api.globalvars.debugFlags.get(api.flags.AtomicDebugFlags.IS_INTERRUPTED_FOR_TERMINATE)
129+
interrupted_for_signal = api.globalvars.debugFlags.get(api.flags.AtomicDebugFlags.IS_INTERRUPTED_FOR_SIGNAL)
130+
interrupted_for_breakpoint_add = api.globalvars.debugFlags.get(api.flags.AtomicDebugFlags.IS_INTERRUPTED_FOR_BREAKPOINT_ADD)
131+
interrupted_for_breakpoint_del = api.globalvars.debugFlags.get(api.flags.AtomicDebugFlags.IS_INTERRUPTED_FOR_BREAKPOINT_DEL)
132+
interrupted_for_breakpoint_mod = api.globalvars.debugFlags.get(api.flags.AtomicDebugFlags.IS_INTERRUPTED_FOR_BREAKPOINT_MOD)
133+
interrupted_for_breakpoint_set = api.globalvars.debugFlags.get(api.flags.AtomicDebugFlags.IS_INTERRUPTED_FOR_BREAKPOINT_SET)
134+
135+
if interrupted_for_thread_safety:
136+
api.globalvars.debugFlags.set(api.flags.AtomicDebugFlags.IS_INTERRUPTED_FOR_THREAD_SAFETY, False)
137+
138+
util.verbose("GDBFrontendDebugEventsHandler", "Continuing for interrupt: THREAD_SAFETY.")
139+
140+
try:
141+
gdb.execute("c")
142+
except Exception as e:
143+
print("[Error] (GDBFrontendSocket.gdb_on_stop__mT)", e)
144+
elif interrupted_for_terminate:
145+
util.verbose("GDBFrontendDebugEventsHandler", "Terminating for interrupt: TERMINATE.")
146+
147+
api.globalvars.debugFlags.set(api.flags.AtomicDebugFlags.IS_INTERRUPTED_FOR_TERMINATE, False)
148+
149+
try:
150+
gdb.execute("kill")
151+
except Exception as e:
152+
print("[Error] (GDBFrontendSocket.gdb_on_stop__mT)", e)
153+
elif interrupted_for_signal:
154+
try:
155+
util.verbose("GDBFrontendDebugEventsHandler", "Continuing for interrupt: SIGNAL.")
156+
gdb.execute("c")
157+
except Exception as e:
158+
print("[Error] (GDBFrontendSocket().gdb_on_stop__mT)", e)
159+
elif interrupted_for_breakpoint_add:
160+
util.verbose("GDBFrontendDebugEventsHandler", "Continuing for interrupt: BREAKPOINT_ADD.")
161+
162+
api.globalvars.debugFlags.set(api.flags.AtomicDebugFlags.IS_INTERRUPTED_FOR_BREAKPOINT_ADD, False)
163+
164+
if "address" in interrupted_for_breakpoint_add:
165+
bp = api.debug.Breakpoint(
166+
address = interrupted_for_breakpoint_add["address"]
167+
)
168+
else:
169+
bp = api.debug.Breakpoint(
170+
source = interrupted_for_breakpoint_add["file"],
171+
line = interrupted_for_breakpoint_add["line"]
172+
)
173+
174+
try:
175+
gdb.execute("c")
176+
except Exception as e:
177+
print("[Error] (GDBFrontendSocket().gdb_on_stop__mT)", e)
178+
elif interrupted_for_breakpoint_del:
179+
util.verbose("GDBFrontendDebugEventsHandler", "Continuing for interrupt: BREAKPOINT_DEL.")
180+
181+
interrupted_for_breakpoint_del.delete()
182+
183+
api.globalvars.debugFlags.set(api.flags.AtomicDebugFlags.IS_INTERRUPTED_FOR_BREAKPOINT_DEL, False)
184+
185+
try:
186+
gdb.execute("c")
187+
except Exception as e:
188+
print("[Error] (GDBFrontendSocket().gdb_on_stop__mT)", e)
189+
elif interrupted_for_breakpoint_mod:
190+
util.verbose("GDBFrontendDebugEventsHandler", "Continuing for interrupt: BREAKPOINT_MOD.")
191+
192+
api.globalvars.debugFlags.set(api.flags.AtomicDebugFlags.IS_INTERRUPTED_FOR_BREAKPOINT_MOD, False)
193+
194+
interrupted_for_breakpoint_mod["breakpoint"].condition = interrupted_for_breakpoint_mod["condition"]
195+
196+
try:
197+
gdb.execute("c")
198+
except Exception as e:
199+
print("[Error] (GDBFrontendSocket().gdb_on_stop__mT)", e)
200+
elif interrupted_for_breakpoint_set:
201+
util.verbose("GDBFrontendDebugEventsHandler", "Continuing for interrupt: BREAKPOINT_SET.")
202+
203+
api.globalvars.debugFlags.set(api.flags.AtomicDebugFlags.IS_INTERRUPTED_FOR_BREAKPOINT_SET, False)
204+
205+
interrupted_for_breakpoint_set["breakpoint"].enabled = interrupted_for_breakpoint_set["is_enabled"]
206+
207+
try:
208+
gdb.execute("c")
209+
except Exception as e:
210+
print("[Error] (GDBFrontendSocket().gdb_on_stop__mT)", e)
211+
212+
def gdb_on_new_thread(self, event):
213+
util.verbose("GDBFrontendDebugEventsHandler", "gdb_on_new_thread()")
214+
215+
def _mt():
216+
self.gdb_on_new_thread__mT(event)
217+
218+
gdb.post_event(_mt)
219+
220+
def gdb_on_new_thread__mT(self, event):
221+
inferior_thread = event.inferior_thread
222+
223+
if isinstance(inferior_thread, gdb.InferiorThread):
224+
api.globalvars.inferior_run_times[event.inferior_thread.inferior.num] = int(time.time())
225+
elif isinstance(inferior_thread, gdb.Inferior):
226+
api.globalvars.inferior_run_times[event.inferior_thread.num] = int(time.time())
227+
228+
def gdb_on_cont(self, event):
229+
util.verbose("GDBFrontendDebugEventsHandler", "gdb_on_cont()")
230+
231+
api.globalvars.debugFlags.set(api.flags.AtomicDebugFlags.IS_RUNNING, True)
232+
233+
self.cont_time = time.time() * 1000
234+
235+
if api.globalvars.dont_emit_until_stop_or_exit: return
236+
237+
gdb.post_event(self.gdb_on_cont__mT)
238+
239+
def gdb_on_cont__mT(self):
240+
pass
241+
242+
def gdb_on_exited(self, event):
243+
util.verbose("GDBFrontendDebugEventsHandler", "gdb_on_exited()")
244+
245+
api.globalvars.debugFlags.set(api.flags.AtomicDebugFlags.IS_RUNNING, False)
246+
247+
api.globalvars.dont_emit_until_stop_or_exit = False
248+
api.globalvars.step_time = False
249+
250+
def _mt():
251+
self.gdb_on_exited__mT(event)
252+
253+
gdb.post_event(_mt)
254+
255+
def gdb_on_exited__mT(self, event):
256+
response = {}
257+
258+
try:
259+
del api.globalvars.inferior_run_times[event.inferior.num]
260+
except Exception as e:
261+
util.verbose("GDBFrontendDebugEventsHandler", e, traceback.format_exc())
262+
263+
api.globalvars.debugFlags.set(api.flags.AtomicDebugFlags.SELECTED_FRAMES, {})
264+
265+
def gdb_on_new_inferior(self, event):
266+
util.verbose("GDBFrontendDebugEventsHandler", "gdb_on_new_inferior()")
267+
268+
api.globalvars.inferior_run_times[event.inferior.num] = int(time.time())
269+
270+
if api.globalvars.dont_emit_until_stop_or_exit: return
271+
272+
def _mt():
273+
self.gdb_on_new_inferior__mT(event)
274+
275+
gdb.post_event(_mt)
276+
277+
def gdb_on_new_inferior__mT(self, event):
278+
pass
279+
280+
def gdb_on_inferior_deleted(self, event):
281+
util.verbose("GDBFrontendDebugEventsHandler", "gdb_on_inferior_deleted()")
282+
283+
def _mt():
284+
self.gdb_on_inferior_deleted__mT(event)
285+
286+
gdb.post_event(_mt)
287+
288+
def gdb_on_inferior_deleted__mT(self, event):
289+
response = {}
290+
291+
del api.globalvars.inferior_run_times[event.inferior.num]
292+
293+
if api.globalvars.dont_emit_until_stop_or_exit: return

0 commit comments

Comments
 (0)