Skip to content

Commit 47661af

Browse files
committed
Fix getting frame backrefs from a traceback in uncached-only interpreter
1 parent 73a9cec commit 47661af

1 file changed

Lines changed: 20 additions & 0 deletions

File tree

  • graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/traceback

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/traceback/TracebackBuiltins.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,18 +189,38 @@ static void doMaterialize(Node inliningTarget, PTraceback tb,
189189
* must be the same.
190190
*/
191191
PException pException = lazyTraceback.getException();
192+
PFrame outermostVisibleFrame = null;
193+
PFrame calleeFrame = null;
192194
List<TruffleStackTraceElement> stackTrace = TruffleStackTrace.getStackTrace(pException);
193195
if (stackTrace != null) {
194196
for (int truffleIndex = pException.getTracebackStartIndex(), pyIndex = 0; truffleIndex < stackTrace.size() && pyIndex < pException.getTracebackFrameCount(); truffleIndex++) {
195197
TruffleStackTraceElement element = stackTrace.get(truffleIndex);
196198
if (LazyTraceback.elementWantedForTraceback(element)) {
197199
PFrame pFrame = materializeFrame(element, materializeFrameNode, pException, stackTrace);
200+
// When the traceback frames are already popped off the stack, f_back can
201+
// only work through the escaped Reference chain. In cached mode we have
202+
// the assumptions on the root nodes that set the caller info, but in
203+
// uncached we explicitly avoid invalidating the assumptions. So it can
204+
// happen that we are walking here during an uncached execution and we'll
205+
// need the caller frame later. We connect links between the freshly
206+
// materialized traceback frames explicitly in that case.
207+
//
208+
// (tfel): I would like to assert this, but I'm not sure how I can.
209+
if (calleeFrame != null && calleeFrame.getRef().getCallerInfo() == null) {
210+
calleeFrame.getRef().setCallerInfo(pFrame.getRef());
211+
}
198212
next = PFactory.createTraceback(language, pFrame, pFrame.getLine(), next);
199213
next.setLocation(pFrame.getBci(), pFrame.getBytecodeNode());
214+
outermostVisibleFrame = pFrame;
215+
calleeFrame = pFrame;
200216
pyIndex++;
201217
}
202218
}
203219
}
220+
// see comment in the loop, same idea.
221+
if (outermostVisibleFrame != null && lazyTraceback.getFrameInfo() != null && outermostVisibleFrame.getRef().getCallerInfo() == null) {
222+
outermostVisibleFrame.getRef().setCallerInfo(lazyTraceback.getFrameInfo());
223+
}
204224
if (lazyTraceback.catchingFrameWantedForTraceback()) {
205225
tb.setLocation(pException.getCatchBci(), pException.getBytecodeNode());
206226
tb.setLineno(pException.getCatchLine());

0 commit comments

Comments
 (0)