@@ -27,6 +27,7 @@ public struct FramePointerUnwinder<C: Context, M: MemoryReader>: Sequence, Itera
27
27
var asyncContext : Address
28
28
var first : Bool
29
29
var isAsync : Bool
30
+ var done : Bool
30
31
31
32
#if os(Linux)
32
33
var elf32Cache : [ Int : Elf32Image < FileImageSource > ] = [ : ]
@@ -44,6 +45,7 @@ public struct FramePointerUnwinder<C: Context, M: MemoryReader>: Sequence, Itera
44
45
fp = Address ( context. framePointer)
45
46
first = true
46
47
isAsync = false
48
+ done = false
47
49
asyncContext = 0
48
50
reader = memoryReader
49
51
@@ -134,6 +136,10 @@ public struct FramePointerUnwinder<C: Context, M: MemoryReader>: Sequence, Itera
134
136
}
135
137
136
138
public mutating func next( ) -> Backtrace . Frame ? {
139
+ if done {
140
+ return nil
141
+ }
142
+
137
143
if first {
138
144
first = false
139
145
pc = stripPtrAuth ( pc)
@@ -149,6 +155,7 @@ public struct FramePointerUnwinder<C: Context, M: MemoryReader>: Sequence, Itera
149
155
if strippedFp == 0
150
156
|| !Context. isAlignedForStack ( framePointer:
151
157
Context . Address ( strippedFp) ) {
158
+ done = true
152
159
return nil
153
160
}
154
161
@@ -158,10 +165,12 @@ public struct FramePointerUnwinder<C: Context, M: MemoryReader>: Sequence, Itera
158
165
as: Address . self) )
159
166
next = try reader. fetch ( from: Address ( strippedFp) , as: Address . self)
160
167
} catch {
168
+ done = true
161
169
return nil
162
170
}
163
171
164
172
if next <= fp || pc == 0 {
173
+ done = true
165
174
return nil
166
175
}
167
176
@@ -173,6 +182,7 @@ public struct FramePointerUnwinder<C: Context, M: MemoryReader>: Sequence, Itera
173
182
174
183
isAsync = true
175
184
if !fetchAsyncContext( ) {
185
+ done = true
176
186
return nil
177
187
}
178
188
}
@@ -183,6 +193,7 @@ public struct FramePointerUnwinder<C: Context, M: MemoryReader>: Sequence, Itera
183
193
let strippedCtx = stripPtrAuth ( asyncContext)
184
194
185
195
if strippedCtx == 0 {
196
+ done = true
186
197
return nil
187
198
}
188
199
@@ -197,6 +208,7 @@ public struct FramePointerUnwinder<C: Context, M: MemoryReader>: Sequence, Itera
197
208
next = Address ( next32)
198
209
pc = stripPtrAuth ( Address ( pc32) )
199
210
} catch {
211
+ done = true
200
212
return nil
201
213
}
202
214
#else
@@ -206,6 +218,7 @@ public struct FramePointerUnwinder<C: Context, M: MemoryReader>: Sequence, Itera
206
218
next = try reader. fetch ( from: strippedCtx, as: Address . self)
207
219
pc = stripPtrAuth ( try reader. fetch ( from: strippedCtx + 8 , as: Address . self) )
208
220
} catch {
221
+ done = true
209
222
return nil
210
223
}
211
224
0 commit comments