Skip to content

Commit cb2519d

Browse files
committed
[lldb] Introduce SBFrameList for lazy frame iteration
This patch introduces `SBFrameList`, a new SBAPI class that allows iterating over stack frames lazily without calling `SBThread::GetFrameAtIndex` in a loop. The new `SBThread::GetFrames()` method returns an `SBFrameList` that supports Python iteration (`for frame in frame_list:`), indexing (`frame_list[0]`, `frame_list[-1]`), and length queries (`len()`). The implementation uses `StackFrameListSP` as the opaque pointer, sharing the thread's underlying frame list to ensure frames are materialized on-demand. This is particularly useful for ScriptedFrameProviders, where user scripts can now iterate, filter, and replace frames lazily without materializing the entire stack upfront. Signed-off-by: Med Ismail Bennani <[email protected]>
1 parent 9abae17 commit cb2519d

File tree

18 files changed

+480
-3
lines changed

18 files changed

+480
-3
lines changed
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
%feature("docstring",
2+
"Represents a list of :py:class:`SBFrame` objects."
3+
) lldb::SBFrameList;
4+
5+
%feature("autodoc", "GetSize(SBFrameList self) -> uint32_t") lldb::SBFrameList::GetSize;
6+
%feature("docstring", "
7+
Returns the number of frames in the list."
8+
) lldb::SBFrameList::GetSize;
9+
10+
%feature("autodoc", "GetFrameAtIndex(SBFrameList self, uint32_t idx) -> SBFrame") lldb::SBFrameList::GetFrameAtIndex;
11+
%feature("docstring", "
12+
Returns the frame at the given index."
13+
) lldb::SBFrameList::GetFrameAtIndex;
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
%extend lldb::SBFrameList {
2+
3+
#ifdef SWIGPYTHON
4+
%nothreadallow;
5+
#endif
6+
std::string lldb::SBFrameList::__str__ (){
7+
lldb::SBStream description;
8+
if (!$self->GetDescription(description))
9+
return std::string("<empty> lldb.SBFrameList()");
10+
const char *desc = description.GetData();
11+
size_t desc_len = description.GetSize();
12+
if (desc_len > 0 && (desc[desc_len-1] == '\n' || desc[desc_len-1] == '\r'))
13+
--desc_len;
14+
return std::string(desc, desc_len);
15+
}
16+
#ifdef SWIGPYTHON
17+
%clearnothreadallow;
18+
#endif
19+
20+
#ifdef SWIGPYTHON
21+
%pythoncode %{
22+
def __iter__(self):
23+
'''Iterate over all frames in a lldb.SBFrameList object.'''
24+
return lldb_iter(self, 'GetSize', 'GetFrameAtIndex')
25+
26+
def __len__(self):
27+
return int(self.GetSize())
28+
29+
def __getitem__(self, key):
30+
if type(key) is not int:
31+
return None
32+
if key < 0:
33+
count = len(self)
34+
if -count <= key < count:
35+
key %= count
36+
37+
frame = self.GetFrameAtIndex(key)
38+
return frame if frame.IsValid() else None
39+
%}
40+
#endif
41+
}

lldb/bindings/interface/SBThreadExtensions.i

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,8 @@ STRING_EXTENSION_OUTSIDE(SBThread)
4141
def get_thread_frames(self):
4242
'''An accessor function that returns a list() that contains all frames in a lldb.SBThread object.'''
4343
frames = []
44-
for frame in self:
44+
frame_list = self.GetFrames()
45+
for frame in frame_list:
4546
frames.append(frame)
4647
return frames
4748

lldb/bindings/interfaces.swig

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
%include "./interface/SBFileSpecListDocstrings.i"
4040
%include "./interface/SBFormatDocstrings.i"
4141
%include "./interface/SBFrameDocstrings.i"
42+
%include "./interface/SBFrameListDocstrings.i"
4243
%include "./interface/SBFunctionDocstrings.i"
4344
%include "./interface/SBHostOSDocstrings.i"
4445
%include "./interface/SBInstructionDocstrings.i"
@@ -119,6 +120,7 @@
119120
%include "lldb/API/SBFileSpecList.h"
120121
%include "lldb/API/SBFormat.h"
121122
%include "lldb/API/SBFrame.h"
123+
%include "lldb/API/SBFrameList.h"
122124
%include "lldb/API/SBFunction.h"
123125
%include "lldb/API/SBHostOS.h"
124126
%include "lldb/API/SBInstruction.h"
@@ -193,6 +195,7 @@
193195
%include "./interface/SBFileSpecExtensions.i"
194196
%include "./interface/SBFileSpecListExtensions.i"
195197
%include "./interface/SBFrameExtensions.i"
198+
%include "./interface/SBFrameListExtensions.i"
196199
%include "./interface/SBFunctionExtensions.i"
197200
%include "./interface/SBInstructionExtensions.i"
198201
%include "./interface/SBInstructionListExtensions.i"

lldb/include/lldb/API/LLDB.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
#include "lldb/API/SBFileSpecList.h"
3838
#include "lldb/API/SBFormat.h"
3939
#include "lldb/API/SBFrame.h"
40+
#include "lldb/API/SBFrameList.h"
4041
#include "lldb/API/SBFunction.h"
4142
#include "lldb/API/SBHostOS.h"
4243
#include "lldb/API/SBInstruction.h"

lldb/include/lldb/API/SBDefines.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ class LLDB_API SBFileSpec;
7676
class LLDB_API SBFileSpecList;
7777
class LLDB_API SBFormat;
7878
class LLDB_API SBFrame;
79+
class LLDB_API SBFrameList;
7980
class LLDB_API SBFunction;
8081
class LLDB_API SBHostOS;
8182
class LLDB_API SBInstruction;

lldb/include/lldb/API/SBFrame.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,7 @@ class LLDB_API SBFrame {
222222
protected:
223223
friend class SBBlock;
224224
friend class SBExecutionContext;
225+
friend class SBFrameList;
225226
friend class SBInstruction;
226227
friend class SBThread;
227228
friend class SBValue;
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
//===------------------------------------------------------------*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#ifndef LLDB_API_SBFRAMELIST_H
10+
#define LLDB_API_SBFRAMELIST_H
11+
12+
#include "lldb/API/SBDefines.h"
13+
14+
namespace lldb {
15+
16+
class LLDB_API SBFrameList {
17+
public:
18+
SBFrameList();
19+
20+
SBFrameList(const lldb::SBFrameList &rhs);
21+
22+
~SBFrameList();
23+
24+
const lldb::SBFrameList &operator=(const lldb::SBFrameList &rhs);
25+
26+
explicit operator bool() const;
27+
28+
bool IsValid() const;
29+
30+
uint32_t GetSize() const;
31+
32+
lldb::SBFrame GetFrameAtIndex(uint32_t idx) const;
33+
34+
lldb::SBThread GetThread() const;
35+
36+
void Clear();
37+
38+
void Append(const lldb::SBFrame &frame);
39+
40+
void Append(const lldb::SBFrameList &frame_list);
41+
42+
bool GetDescription(lldb::SBStream &description) const;
43+
44+
protected:
45+
friend class SBThread;
46+
47+
private:
48+
SBFrameList(const lldb::StackFrameListSP &frame_list_sp);
49+
50+
void SetFrameList(const lldb::StackFrameListSP &frame_list_sp);
51+
52+
lldb::StackFrameListSP m_opaque_sp;
53+
};
54+
55+
} // namespace lldb
56+
57+
#endif // LLDB_API_SBFRAMELIST_H

lldb/include/lldb/API/SBStream.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ class LLDB_API SBStream {
8181
friend class SBFileSpec;
8282
friend class SBFileSpecList;
8383
friend class SBFrame;
84+
friend class SBFrameList;
8485
friend class SBFunction;
8586
friend class SBInstruction;
8687
friend class SBInstructionList;

lldb/include/lldb/API/SBThread.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,8 @@ class LLDB_API SBThread {
178178

179179
lldb::SBFrame GetFrameAtIndex(uint32_t idx);
180180

181+
lldb::SBFrameList GetFrames();
182+
181183
lldb::SBFrame GetSelectedFrame();
182184

183185
lldb::SBFrame SetSelectedFrame(uint32_t frame_idx);
@@ -236,6 +238,7 @@ class LLDB_API SBThread {
236238
friend class SBSaveCoreOptions;
237239
friend class SBExecutionContext;
238240
friend class SBFrame;
241+
friend class SBFrameList;
239242
friend class SBProcess;
240243
friend class SBDebugger;
241244
friend class SBValue;

0 commit comments

Comments
 (0)