11# -*- coding: utf-8 -*-
22'''GDB Extension
3-
43'''
54import gdb
65import threading
98from urllib .parse import urlencode
109
1110
12- CBURL = 'http://localhost:20829/api/v1/event/gdb/'
11+ cb_notify_url = 'http://localhost:20829/api/v1/event/gdb/'
1312
1413
15- def post_event (runner ):
16- if not lock .acquire (timeout = 1.0 ):
14+ def cb_post_event (runner ):
15+ if not cb_lock .acquire (timeout = 1.0 ):
1716 return None
1817 runner ()
19- lock .release ()
18+ cb_lock .release ()
2019
2120
22- def execmd (* cmdlist ):
21+ def cb_execmd (* cmdlist ):
2322
2423 def _runner ():
2524 for cmd in cmdlist :
2625 gdb .execute (cmd )
2726 gdb .flush ()
2827
29- post_event (_runner )
28+ cb_post_event (_runner )
3029
3130
32- def prog_begin ( filename , pk ):
31+ def cb_prog_begin ( pk , filename ):
3332
3433 def _runner ():
3534 i = gdb .selected_inferior ()
@@ -39,19 +38,18 @@ def _runner():
3938 gdb .execute ('inferior %s' % n )
4039 gdb .execute ('set remote exec-file %s' % filename )
4140 gdb .execute ('file %s' % filename )
42- gdb .execute ('start' )
4341 gdb .flush ()
42+
4443 cb_notify_event ({
45- 'event' : 'begin_prog' ,
4644 'pk' : pk ,
47- 'num ' : i .num ,
45+ 'inferior ' : i .num ,
4846 'filename' : filename
4947 })
5048
51- post_event (_runner )
49+ cb_post_event (_runner )
5250
5351
54- def prog_end ( num ):
52+ def cb_prog_end ( pk , num ):
5553
5654 def _runner ():
5755 gdb .execute ('kill inferiors %s' % num )
@@ -62,49 +60,171 @@ def _runner():
6260 gdb .execute ('remove-inferiors %s' % num )
6361 gdb .flush ()
6462
65- post_event (_runner )
63+ cb_notify_event ({
64+ 'pk' : pk ,
65+ })
66+
67+ cb_post_event (_runner )
6668
6769
68- def prog_cmd (num , * cmdlist ):
70+ def cb_prog_cmd_async (pk , cmd , arg = '' , thread = '$_thread' ):
71+ # run / step / stepi / next / nexti / continue / until / finish &
72+ cmdstr = 'thread apply %s -s %s %s &' % (thread , cmd , arg )
6973
7074 def _runner ():
71- gdb .execute ('inferior %s' % num )
72- for cmd in cmdlist :
73- gdb .execute (cmd )
75+ result = gdb .execute (cmdstr , False , True )
7476 gdb .flush ()
77+ cb_notify_event ({
78+ 'pk' : pk ,
79+ 'result' : result
80+ })
7581
76- post_event (_runner )
82+ cb_post_event (_runner )
83+
84+
85+ def cb_prog_cmd (pk , cmd , arg = '' , thread = '$_gthread' , frame = '0' ):
86+ # -stack-list-variables --thread 1 --frame 0 --all-values
87+ # ^done,variables=[{name="x",value="11"},{name="s",value="{a = 1, b = 2}"}]
88+
89+ # -stack-list-frames --thread 1
90+ # ^done,stack=
91+ # [frame={level="0",addr="0x0001076c",func="foo",
92+ # file="recursive2.c",fullname="/home/foo/bar/recursive2.c",line="11",
93+ # arch="i386:x86_64"},
94+ # ...]
95+
96+ # -stack-list-arguments --thread 1 1
97+ # ^done,
98+ # stack-args=[
99+ # frame={level="0",args=[]},
100+ # ...]
101+
102+ # -thread-info
103+ # -thread-list-ids
104+
105+ # -data-disassemble
106+ # -data-evaluate-expression expr
107+ # -data-list-changed-registers
108+ # -data-list-register-names
109+ # -data-list-register-values
110+
111+ # -data-read-memory
112+ # -data-read-memory-bytes
113+ # -data-write-memory-bytes
114+
115+ # -symbol-info-functions
116+ # -symbol-info-module-functions
117+ # -symbol-info-module-variables
118+ # -symbol-info-modules
119+ # -symbol-info-types
120+ # -symbol-info-variables
121+
122+ # -exec-continue
123+ # -exec-finish
124+ # -exec-interrupt
125+ # -exec-next
126+ # -exec-next-instruction
127+ # -exec-return
128+ # -exec-run --start
129+ # -exec-step
130+ # -exec-step-instruction
131+ # -exec-until
132+
133+ # -break-insert
134+ # -break-delete
135+ # -break-condition
136+ # -break-list
137+ # -break-info
138+ # -break-disable
139+ # -break-enable
140+ # -break-watch
141+
142+ cmdstr = ' ' .join (['interpreter-exec mi' , '"' , cmd ,
143+ '--thread' , thread , '--frame' , frame , arg ,
144+ '"' ]
145+
146+ def _runner ():
147+ result = gdb .execute (cmdstr , False , True )
148+ gdb .flush ()
149+ cb_notify_event ({
150+ 'pk' : pk ,
151+ 'result' : result
152+ })
153+
154+ cb_post_event (_runner )
155+
156+
157+ def cb_dispatch (pk , cmd , * args ):
158+ if cmd == 'prog_begin' :
159+ cb_prog_begin (pk , * args )
160+ elif cmd == 'prog_end' :
161+ cb_prog_end (pk , * args )
162+ elif cmd == 'prog_cmd' :
163+ cb_prog_cmd (pk , * args )
164+ elif cmd == 'prog_cmd_async' :
165+ cb_prog_cmd_async (pk , * args )
77166
78167
79168def cb_new_inferior_handler (event ):
80- pass # event.inferior
169+ event .inferior
81170
82171
83172def cb_exited_handler (event ):
84- pass # event.inferior, event.exit_code
173+ event .inferior , event .exit_code
174+
175+
176+ def cb_new_thread_handler (event ):
177+ thread = event .inferior_thread
178+ cb_notify_event ({
179+ 'inferior' : thread .inferior .num ,
180+ 'thread' : thread .num ,
181+ 'gthread' : thread .global_num ,
182+ 'state' : 'new' ,
183+ })
85184
86185
87186def cb_stop_handler (event ):
88- pass # event.stop_signal, event.breakpoints
187+ thread = event .inferior_thread
188+ if hasattr (event , 'breakpoints' ):
189+ reason = [(bp .thread , bp .number , bp .type , bp .location )
190+ for bp in event .breakpoints ]
191+ elif hasattr (event , 'stop_signal' ):
192+ reason = event .stop_signal
193+ else :
194+ reason = ''
195+ cb_notify_event ({
196+ 'inferior' : thread .inferior .num ,
197+ 'thread' : thread .num ,
198+ 'gthread' : thread .global_num ,
199+ 'state' : 'exited' if thread .is_exited () else 'stopped' ,
200+ 'reason' : reason
201+ })
89202
90203
91204def cb_cont_handler (event ):
92- pass # event.inferior_thread
205+ thread = event .inferior_thread
206+ cb_notify_event ({
207+ 'inferior' : thread .inferior .num ,
208+ 'thread' : thread .num ,
209+ 'state' : 'running' ,
210+ })
93211
94212
95213def cb_notify_event (args ):
96214 data = urlencode (args )
97- r = urlopen (CBURL , data .encode ('ascii' ))
215+ r = urlopen (cb_notify_url , data .encode ('ascii' ))
98216 if r .status == 200 :
99217 return r .read ().decode ('utf-8' )
100218
101219
102220#
103221# Hook event
104222#
105- gdb .events .new_inferior .connect (cb_new_inferior_handler )
106- gdb .events .exited .connect (cb_exited_handler )
223+ # gdb.events.new_inferior.connect(cb_new_inferior_handler)
224+ # gdb.events.exited.connect(cb_exited_handler)
225+ # gdb.events.cont.connect(cb_cont_handler)
226+
227+ gdb .events .new_thread .connect (cb_new_thread_handler )
107228gdb .events .stop .connect (cb_stop_handler )
108- gdb .events .cont .connect (cb_cont_handler )
109229
110- lock = threading .Lock ()
230+ cb_lock = threading .Lock ()
0 commit comments