]>
git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - gdb/python/lib/gdb/dap/bt.py
a38573fbba899de6e83749006ff59e8d6445c962
1 # Copyright 2022-2023 Free Software Foundation, Inc.
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.
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.
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/>.
19 from .frames
import frame_id
20 from .server
import request
, capability
21 from .startup
import send_gdb_with_response
, in_gdb_thread
22 from .state
import set_thread
25 # Helper function to safely get the name of a frame as a string.
27 def _frame_name(frame
):
34 # Helper function to get a frame's SAL without an error.
38 return frame
.find_sal()
43 # Helper function to compute a stack trace.
45 def _backtrace(thread_id
, levels
, startFrame
):
50 current_frame
= gdb
.newest_frame()
53 # Note that we always iterate over all frames, which is lame, but
54 # seemingly necessary to support the totalFrames response.
55 # FIXME maybe the mildly mysterious note about "monotonically
56 # increasing totalFrames values" would let us fix this.
57 while current_frame
is not None:
58 # This condition handles the startFrame==0 case as well.
59 if current_number
>= startFrame
and (levels
== 0 or len(frames
) < levels
):
61 "id": frame_id(current_frame
),
62 "name": _frame_name(current_frame
),
63 # This must always be supplied, but we will set it
64 # correctly later if that is possible.
66 # GDB doesn't support columns.
68 "instructionPointerReference": hex(current_frame
.pc()),
70 sal
= _safe_sal(current_frame
)
71 if sal
is not None and sal
.symtab
is not None:
72 newframe
["source"] = {
73 "name": os
.path
.basename(sal
.symtab
.filename
),
74 "path": sal
.symtab
.filename
,
75 # We probably don't need this but it doesn't hurt
79 newframe
["line"] = sal
.line
80 frames
.append(newframe
)
81 current_number
= current_number
+ 1
82 current_frame
= current_frame
.older()
84 "stackFrames": frames
,
85 "totalFrames": current_number
,
89 @request("stackTrace")
90 @capability("supportsDelayedStackTraceLoading")
91 def stacktrace(*, levels
: int = 0, startFrame
: int = 0, threadId
: int, **extra
):
92 return send_gdb_with_response(lambda: _backtrace(threadId
, levels
, startFrame
))