GDB (xrefs)
Loading...
Searching...
No Matches
gdb
python
lib
gdb
dap
startup.py
Go to the documentation of this file.
1
# Copyright 2022-2023 Free Software Foundation, Inc.
2
3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation; either version 3 of the License, or
6
# (at your option) any later version.
7
#
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
# GNU General Public License for more details.
12
#
13
# You should have received a copy of the GNU General Public License
14
# along with this program. If not, see <http://www.gnu.org/licenses/>.
15
16
# Do not import other gdbdap modules here -- this module must come
17
# first.
18
import
functools
19
import
gdb
20
import
queue
21
import
threading
22
import
traceback
23
import
sys
24
25
26
# The GDB thread, aka the main thread.
27
_gdb_thread = threading.current_thread()
28
29
30
# The DAP thread.
31
_dap_thread =
None
32
33
34
def
start_thread
(name, target, args=()):
35
"""Start a new thread, invoking TARGET with *ARGS there.
36
This is a helper function that ensures that any GDB signals are
37
correctly blocked."""
38
result =
gdb.Thread
(name=name, target=target, args=args, daemon=
True
)
39
result.start()
40
41
42
def
start_dap
(target):
43
"""Start the DAP thread and invoke TARGET there."""
44
exec_and_log(
"set breakpoint pending on"
)
45
46
# Functions in this thread contain assertions that check for this
47
# global, so we must set it before letting these functions run.
48
def
really_start_dap():
49
global
_dap_thread
50
_dap_thread = threading.current_thread()
51
target()
52
53
start_thread(
"DAP"
, really_start_dap)
54
55
56
def
in_gdb_thread
(func):
57
"""A decorator that asserts that FUNC must be run in the GDB thread."""
58
59
@functools.wraps(func)
60
def
ensure_gdb_thread(*args, **kwargs):
61
assert
threading.current_thread()
is
_gdb_thread
62
return
func
(*args, **kwargs)
63
64
return
ensure_gdb_thread
65
66
67
def
in_dap_thread
(func):
68
"""A decorator that asserts that FUNC must be run in the DAP thread."""
69
70
@functools.wraps(func)
71
def
ensure_dap_thread(*args, **kwargs):
72
assert
threading.current_thread()
is
_dap_thread
73
return
func
(*args, **kwargs)
74
75
return
ensure_dap_thread
76
77
78
class
LoggingParam
(gdb.Parameter):
79
"""Whether DAP logging is enabled."""
80
81
set_doc =
"Set the DAP logging status."
82
show_doc =
"Show the DAP logging status."
83
84
log_file =
None
85
86
def
__init__
(self):
87
super().
__init__
(
88
"debug dap-log-file"
, gdb.COMMAND_MAINTENANCE, gdb.PARAM_OPTIONAL_FILENAME
89
)
90
self.
value
=
None
91
92
def
get_set_string
(self):
93
# Close any existing log file, no matter what.
94
if
self.
log_file
is
not
None
:
95
self.
log_file
.close()
96
self.
log_file
=
None
97
if
self.
value
is
not
None
:
98
self.
log_file
= open(self.
value
,
"w"
)
99
return
""
100
101
102
dap_log =
LoggingParam
()
103
104
105
def
log
(something):
106
"""Log SOMETHING to the log file, if logging is enabled."""
107
if
dap_log.log_file
is
not
None
:
108
print(something, file=dap_log.log_file)
109
dap_log.log_file.flush()
110
111
112
def
log_stack
():
113
"""Log a stack trace to the log file, if logging is enabled."""
114
if
dap_log.log_file
is
not
None
:
115
traceback.print_exc(file=dap_log.log_file)
116
117
118
@in_gdb_thread
119
def
exec_and_log
(cmd):
120
"""Execute the gdb command CMD.
121
If logging is enabled, log the command and its output."""
122
log(
"+++ "
+ cmd)
123
try
:
124
output = gdb.execute(cmd, from_tty=
True
, to_string=
True
)
125
if
output !=
""
:
126
log(
">>> "
+ output)
127
except
gdb.error:
128
log_stack()
129
130
131
class
Invoker
(object):
132
"""A simple class that can invoke a gdb command."""
133
134
def
__init__
(self, cmd):
135
self.
cmd
= cmd
136
137
# This is invoked in the gdb thread to run the command.
138
@in_gdb_thread
139
def
__call__
(self):
140
exec_and_log(self.
cmd
)
141
142
143
def
send_gdb
(cmd):
144
"""Send CMD to the gdb thread.
145
CMD can be either a function or a string.
146
If it is a string, it is passed to gdb.execute."""
147
if
isinstance(cmd, str):
148
cmd =
Invoker
(cmd)
149
gdb.post_event(cmd)
150
151
152
def
send_gdb_with_response
(fn):
153
"""Send FN to the gdb thread and return its result.
154
If FN is a string, it is passed to gdb.execute and None is
155
returned as the result.
156
If FN throws an exception, this function will throw the
157
same exception in the calling thread.
158
"""
159
if
isinstance(fn, str):
160
fn =
Invoker
(fn)
161
if
sys.version_info[0] == 3
and
sys.version_info[1] <= 6:
162
result_q = queue.Queue()
163
else
:
164
result_q = queue.SimpleQueue()
165
166
def
message():
167
try
:
168
val = fn()
169
result_q.put(val)
170
except
Exception
as
e:
171
result_q.put(e)
172
173
send_gdb(message)
174
val = result_q.get()
175
if
isinstance(val, Exception):
176
raise
val
177
return
val
gdb.Thread
Definition
__init__.py:281
gdb.dap.startup.Invoker
Definition
startup.py:131
gdb.dap.startup.Invoker.__call__
__call__(self)
Definition
startup.py:139
gdb.dap.startup.Invoker.cmd
cmd
Definition
startup.py:135
gdb.dap.startup.Invoker.__init__
__init__(self, cmd)
Definition
startup.py:134
gdb.dap.startup.LoggingParam
Definition
startup.py:78
gdb.dap.startup.LoggingParam.value
value
Definition
startup.py:90
gdb.dap.startup.LoggingParam.get_set_string
get_set_string(self)
Definition
startup.py:92
gdb.dap.startup.LoggingParam.__init__
__init__(self)
Definition
startup.py:86
gdb.dap.startup.LoggingParam.log_file
log_file
Definition
startup.py:84
gdb.dap.startup.in_gdb_thread
in_gdb_thread(func)
Definition
startup.py:56
gdb.dap.startup.send_gdb_with_response
send_gdb_with_response(fn)
Definition
startup.py:152
gdb.dap.startup.exec_and_log
exec_and_log(cmd)
Definition
startup.py:119
gdb.dap.startup.log_stack
log_stack()
Definition
startup.py:112
gdb.dap.startup.log
log(something)
Definition
startup.py:105
gdb.dap.startup.start_dap
start_dap(target)
Definition
startup.py:42
gdb.dap.startup.send_gdb
send_gdb(cmd)
Definition
startup.py:143
gdb.dap.startup.start_thread
start_thread(name, target, args=())
Definition
startup.py:34
gdb.dap.startup.in_dap_thread
in_dap_thread(func)
Definition
startup.py:67
func
void(* func)(remote_target *remote, char *)
Definition
remote-fileio.c:1106
Generated by
1.10.0