+bool Parser::parse_call_backtrace(Call *call, Mode mode) {
+ unsigned num_frames = read_uint();
+ Backtrace* backtrace = new Backtrace(num_frames);
+ for (unsigned i = 0; i < num_frames; ++i) {
+ (*backtrace)[i] = parse_backtrace_frame(mode);
+ }
+ call->backtrace = backtrace;
+ return true;
+}
+
+StackFrame * Parser::parse_backtrace_frame(Mode mode) {
+ size_t id = read_uint();
+
+ StackFrameState *frame = lookup(frames, id);
+
+ if (!frame) {
+ frame = new StackFrameState;
+ int c = read_byte();
+ while (c != trace::BACKTRACE_END &&
+ c != -1) {
+ switch (c) {
+ case trace::BACKTRACE_MODULE:
+ frame->module = read_string();
+ break;
+ case trace::BACKTRACE_FUNCTION:
+ frame->function = read_string();
+ break;
+ case trace::BACKTRACE_FILENAME:
+ frame->filename = read_string();
+ break;
+ case trace::BACKTRACE_LINENUMBER:
+ frame->linenumber = read_uint();
+ break;
+ case trace::BACKTRACE_OFFSET:
+ frame->offset = read_uint();
+ break;
+ default:
+ std::cerr << "error: unknown backtrace detail "
+ << c << "\n";
+ exit(1);
+ }
+ c = read_byte();
+ }
+
+ frame->fileOffset = file->currentOffset();
+ frames[id] = frame;
+ } else if (file->currentOffset() < frame->fileOffset) {
+ int c = read_byte();
+ while (c != trace::BACKTRACE_END &&
+ c != -1) {
+ switch (c) {
+ case trace::BACKTRACE_MODULE:
+ scan_string();
+ break;
+ case trace::BACKTRACE_FUNCTION:
+ scan_string();
+ break;
+ case trace::BACKTRACE_FILENAME:
+ scan_string();
+ break;
+ case trace::BACKTRACE_LINENUMBER:
+ scan_uint();
+ break;
+ case trace::BACKTRACE_OFFSET:
+ scan_uint();
+ break;
+ default:
+ std::cerr << "error: unknown backtrace detail "
+ << c << "\n";
+ exit(1);
+ }
+ c = read_byte();
+ }
+ }
+
+ return frame;
+}
+
+/**
+ * Make adjustments to this particular call flags.
+ *
+ * NOTE: This is called per-call so no string comparisons should be done here.
+ * All name comparisons should be done when the signature is parsed instead.
+ */
+void Parser::adjust_call_flags(Call *call) {
+ // Mark glGetError() = GL_NO_ERROR as verbose
+ if (call->sig == glGetErrorSig &&
+ call->ret &&
+ call->ret->toSInt() == 0) {
+ call->flags |= CALL_FLAG_VERBOSE;
+ }
+}