CallFlags flags;
- Call(FunctionSig *_sig, const CallFlags &_flags, unsigned _thread_id) :
+ Call(const FunctionSig *_sig, const CallFlags &_flags, unsigned _thread_id) :
thread_id(_thread_id),
sig(_sig),
args(_sig->num_args),
std::cerr << "\tLEAVE\n";
#endif
call = parse_leave(mode);
- adjust_call_flags(call);
- return call;
+ if (call) {
+ adjust_call_flags(call);
+ return call;
+ }
+ break;
default:
std::cerr << "error: unknown event " << c << "\n";
exit(1);
}
}
if (!call) {
+ /* This might happen on random access, when an asynchronous call is stranded
+ * between two frames. We won't return this call, but we still need to skip
+ * over its data.
+ */
+ const FunctionSig sig = {0, NULL, 0, NULL};
+ call = new Call(&sig, 0, 0);
+ parse_call_details(call, SCAN);
+ delete call;
return NULL;
}
const QVector<ApiTraceCall*> &calls,
quint64 binaryDataSize)
{
- Q_ASSERT(frame->numChildrenToLoad() == calls.size());
+ Q_ASSERT(frame->numChildrenToLoad() >= calls.size());
if (!frame->isLoaded()) {
emit beginLoadingFrame(frame, calls.size());
ApiTraceCall *apiCall =
apiCallFromTraceCall(call, m_helpHash,
currentFrame, this);
- calls[parsedCalls] = apiCall;
- Q_ASSERT(calls[parsedCalls]);
+ Q_ASSERT(apiCall);
+ Q_ASSERT(parsedCalls < calls.size());
+ calls[parsedCalls++] = apiCall;
if (apiCall->hasBinaryData()) {
QByteArray data =
apiCall->arguments()[
binaryDataSize += data.size();
}
- ++parsedCalls;
-
delete call;
if (apiCall->flags() & trace::CALL_FLAG_END_FRAME) {
}
}
- assert(parsedCalls == numOfCalls);
- Q_ASSERT(parsedCalls == calls.size());
+ // There can be fewer parsed calls when call in different
+ // threads cross the frame boundary
+ Q_ASSERT(parsedCalls <= numOfCalls);
+ Q_ASSERT(parsedCalls <= calls.size());
+ calls.resize(parsedCalls);
calls.squeeze();
- Q_ASSERT(parsedCalls == currentFrame->numChildrenToLoad());
+ Q_ASSERT(parsedCalls <= currentFrame->numChildrenToLoad());
emit frameContentsLoaded(currentFrame,
calls, binaryDataSize);
return calls;
call = *itr;
}
}
- Q_ASSERT(call);
- emit foundCallIndex(call);
+ if (call) {
+ emit foundCallIndex(call);
+ }
}
void TraceLoader::search(const ApiTrace::SearchRequest &request)