From ac55ba8608d9f5cb2407fddcb21257c595d1e801 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jos=C3=A9=20Fonseca?= Date: Sun, 5 May 2013 08:11:23 +0100 Subject: [PATCH] Cleanup the backtrace representation. Use strings and unsigned, instead of string values and unsigned values. --- common/trace_backtrace.cpp | 7 ++- common/trace_backtrace.hpp | 16 ------- common/trace_dump.cpp | 34 ++++++-------- common/trace_format.hpp | 30 ++++++++---- common/trace_model.cpp | 20 ++------ common/trace_model.hpp | 37 ++++++++------- common/trace_parser.cpp | 46 +++++++++---------- common/trace_parser.hpp | 1 + common/trace_writer.cpp | 86 +++++++++++------------------------ common/trace_writer.hpp | 20 ++------ common/trace_writer_local.cpp | 6 ++- common/trace_writer_model.cpp | 44 ++---------------- gui/apitracecall.cpp | 30 +++++------- 13 files changed, 134 insertions(+), 243 deletions(-) diff --git a/common/trace_backtrace.cpp b/common/trace_backtrace.cpp index 9a837da..6807d3d 100644 --- a/common/trace_backtrace.cpp +++ b/common/trace_backtrace.cpp @@ -256,13 +256,14 @@ public: rawBacktrace_it++; } if (*rawBacktrace_it == ':') { - stackFrame.linenumber = rawBacktrace_it + 1; + const char *linenumber = rawBacktrace_it + 1; *rawBacktrace_it = '\0'; while (*rawBacktrace_it != ')') { rawBacktrace_it++; } *rawBacktrace_it = '\0'; rawBacktrace_it++; + stackFrame.linenumber = atoi(linenumber); } else { stackFrame.filename = NULL; @@ -358,6 +359,7 @@ private: RawStackFrame* parsedFrame = new RawStackFrame; char* frame_it = frame_symbol_copy; parsedFrame->module = frame_it; + char* offset = NULL; while (true) { switch (*frame_it) { case '(': @@ -375,10 +377,11 @@ private: case '[': *frame_it = '\0'; frame_it++; - parsedFrame->offset = frame_it; + offset = frame_it; break; case ']': *frame_it = '\0'; + sscanf(offset, "%llx", &parsedFrame->offset); cache[frame] = parsedFrame; return parsedFrame; case '\0': diff --git a/common/trace_backtrace.hpp b/common/trace_backtrace.hpp index e3c726c..8320b55 100644 --- a/common/trace_backtrace.hpp +++ b/common/trace_backtrace.hpp @@ -8,22 +8,6 @@ namespace trace { -struct RawStackFrame { - char* module; - char* function; - char* filename; - char* linenumber; - char* offset; - RawStackFrame() : - module(0), - function(0), - filename(0), - linenumber(0), - offset(0) - { - } -}; - #if defined(ANDROID) or defined(__linux__) std::vector get_backtrace(); diff --git a/common/trace_dump.cpp b/common/trace_dump.cpp index 5d54535..c757cb8 100644 --- a/common/trace_dump.cpp +++ b/common/trace_dump.cpp @@ -229,34 +229,28 @@ public: } void visit(StackFrame *frame) { - String* tmp; - tmp = frame->module; - if (tmp != NULL) { - os << tmp->toString() << " "; + if (frame->module != NULL) { + os << frame->module << " "; } - tmp = frame->function; - if (tmp != NULL) { - os << "at " << tmp->toString() << "() "; + if (frame->function != NULL) { + os << "at " << frame->function << "() "; } - tmp = frame->filename; - if (tmp != NULL) { - os << "at " << tmp->toString(); - tmp = frame->linenumber; - if (tmp != NULL) { - os << ":" << tmp->toString() << " "; + if (frame->filename != NULL) { + os << "at " << frame->filename; + if (frame->linenumber >= 0) { + os << ":" << frame->linenumber << " "; } } else { - tmp = frame->offset; - if (tmp != NULL) { - os << "[" << tmp->toString() << "]"; + if (frame->offset >= 0) { + os << "[" << "0x" << std::hex << frame->offset << std::dec << "]"; } } } - void visit(Backtrace* backtrace) { - for (int i = 0; i < backtrace->frames.size(); i ++) { - visit(backtrace->frames[i]); + void visit(Backtrace & backtrace) { + for (int i = 0; i < backtrace.size(); i ++) { + visit(&backtrace[i]); os << "\n"; } } @@ -306,7 +300,7 @@ public: if (call->backtrace != NULL) { os << bold << red << "Backtrace:\n" << normal; - visit(call->backtrace); + visit(*call->backtrace); } if (callFlags & CALL_FLAG_END_FRAME) { os << "\n"; diff --git a/common/trace_format.hpp b/common/trace_format.hpp index 5557a31..21dbd55 100644 --- a/common/trace_format.hpp +++ b/common/trace_format.hpp @@ -88,6 +88,8 @@ namespace trace { * * call_detail = ARG index value * | RET value + * | THREAD int + * | BACKTRACE int frame* * | END * * value = NULL @@ -106,6 +108,15 @@ namespace trace { * | OPAQUE int * | REPR value value * + * frame = frame_detail+ + * + * frame_detail = MODULE string + * | FUNCTION string + * | FILENAME string + * | LINENUMBER uint + * | OFFSET uint + * | END + * * call_sig = id name arg_name* * | id * @@ -133,16 +144,6 @@ enum CallDetail { CALL_BACKTRACE, }; -enum CallBacktrace { - CALL_BACKTRACE_FRAME = 0, - CALL_BACKTRACE_MODULE, - CALL_BACKTRACE_FUNCTION, - CALL_BACKTRACE_FILENAME, - CALL_BACKTRACE_LINENUMBER, - CALL_BACKTRACE_OFFSET, - CALL_BACKTRACE_END, -}; - enum Type { TYPE_NULL = 0, TYPE_FALSE, @@ -161,6 +162,15 @@ enum Type { TYPE_REPR, }; +enum BacktraceDetail { + BACKTRACE_END = 0, + BACKTRACE_MODULE, + BACKTRACE_FUNCTION, + BACKTRACE_FILENAME, + BACKTRACE_LINENUMBER, + BACKTRACE_OFFSET, +}; + } /* namespace trace */ diff --git a/common/trace_model.cpp b/common/trace_model.cpp index 88061f0..2c0fafa 100644 --- a/common/trace_model.cpp +++ b/common/trace_model.cpp @@ -74,27 +74,16 @@ Blob::~Blob() { StackFrame::~StackFrame() { if (module != NULL) { - delete module; + delete [] module; } if (function != NULL) { - delete function; + delete [] function; } if (filename != NULL) { - delete filename; - } - if (linenumber != NULL) { - delete linenumber; - } - if (offset != NULL) { - delete offset; + delete [] filename; } } -Backtrace::~Backtrace() { - for (int i = 0; i < frames.size(); i++) { - delete frames[i]; - } -} // bool cast bool Null ::toBool(void) const { return false; } @@ -199,9 +188,6 @@ void Blob ::visit(Visitor &visitor) { visitor.visit(this); } void Pointer::visit(Visitor &visitor) { visitor.visit(this); } void Repr ::visit(Visitor &visitor) { visitor.visit(this); } -void Backtrace::addFrame(StackFrame* frame) { - frames.push_back(frame); -} void Visitor::visit(Null *) { assert(0); } void Visitor::visit(Bool *) { assert(0); } diff --git a/common/trace_model.hpp b/common/trace_model.hpp index fbfa1fb..531a79a 100644 --- a/common/trace_model.hpp +++ b/common/trace_model.hpp @@ -348,30 +348,29 @@ public: void visit(Visitor &visitor); }; -class StackFrame { -public: - String* module; - String* function; - String* filename; - String* linenumber; - String* offset; - StackFrame() : - module(NULL), - function(NULL), - filename(NULL), - linenumber(NULL), - offset(NULL) - {} - ~StackFrame(); +struct RawStackFrame { + const char * module; + const char * function; + const char * filename; + int linenumber; + long long offset; + RawStackFrame() : + module(0), + function(0), + filename(0), + linenumber(-1), + offset(-1) + { + } }; -class Backtrace { +class StackFrame : public RawStackFrame { public: - std::vector frames; - ~Backtrace(); - void addFrame(StackFrame* frame); + ~StackFrame(); }; +typedef std::vector Backtrace; + class Visitor { public: diff --git a/common/trace_parser.cpp b/common/trace_parser.cpp index 6ccc68d..5161663 100644 --- a/common/trace_parser.cpp +++ b/common/trace_parser.cpp @@ -517,40 +517,38 @@ bool Parser::parse_call_details(Call *call, Mode mode) { } bool Parser::parse_call_backtrace(Call *call, Mode mode) { - Backtrace* backtrace = new Backtrace(); - StackFrame* frame = NULL; + unsigned num_frames = read_uint(); + Backtrace* backtrace = new Backtrace(num_frames); + for (unsigned i = 0; i < num_frames; ++i) { + parse_backtrace_frame(&(*backtrace)[i], mode); + } + call->backtrace = backtrace; + return true; +} + +bool Parser::parse_backtrace_frame(StackFrame *frame, Mode mode) { do { int c = read_byte(); switch (c) { - case trace::CALL_BACKTRACE_FRAME: - if (frame != NULL) { - backtrace->addFrame(frame); - } - frame = new StackFrame(); - break; - case trace::CALL_BACKTRACE_END: - if (frame != NULL) { - backtrace->addFrame(frame); - } - call->backtrace = backtrace; + case trace::BACKTRACE_END: return true; - case trace::CALL_BACKTRACE_MODULE: - frame->module = static_cast(parse_value(mode)); + case trace::BACKTRACE_MODULE: + frame->module = read_string(); break; - case trace::CALL_BACKTRACE_FUNCTION: - frame->function = static_cast(parse_value(mode)); + case trace::BACKTRACE_FUNCTION: + frame->function = read_string(); break; - case trace::CALL_BACKTRACE_FILENAME: - frame->filename = static_cast(parse_value(mode)); + case trace::BACKTRACE_FILENAME: + frame->filename = read_string(); break; - case trace::CALL_BACKTRACE_LINENUMBER: - frame->linenumber = static_cast(parse_value(mode)); + case trace::BACKTRACE_LINENUMBER: + frame->linenumber = read_uint(); break; - case trace::CALL_BACKTRACE_OFFSET: - frame->offset = static_cast(parse_value(mode)); + case trace::BACKTRACE_OFFSET: + frame->offset = read_uint(); break; default: - std::cerr << "error: ("<< call->name() << ") unknown call backtrace detail " + std::cerr << "error: unknown backtrace detail " << c << "\n"; exit(1); case -1: diff --git a/common/trace_parser.hpp b/common/trace_parser.hpp index 881b025..e0f8434 100644 --- a/common/trace_parser.hpp +++ b/common/trace_parser.hpp @@ -148,6 +148,7 @@ protected: bool parse_call_details(Call *call, Mode mode); bool parse_call_backtrace(Call *call, Mode mode); + bool parse_backtrace_frame(StackFrame *frame, Mode mode); void adjust_call_flags(Call *call); diff --git a/common/trace_writer.cpp b/common/trace_writer.cpp index be01376..9ecfa2c 100644 --- a/common/trace_writer.cpp +++ b/common/trace_writer.cpp @@ -135,69 +135,35 @@ inline bool lookup(std::vector &map, size_t index) { } } -void Writer::writeBacktrace(std::vector backtrace) { - - for (int i = 0; i < backtrace.size(); i++) { - beginStackFrame(); - if (backtrace[i].module != NULL) { - beginStackFrameModule(); - writeString(backtrace[i].module); - endStackFrameModule(); - } - if (backtrace[i].function != NULL) { - beginStackFrameFunction(); - writeString(backtrace[i].function); - endStackFrameFunction(); - } - if (backtrace[i].filename != NULL) { - beginStackFrameFilename(); - writeString(backtrace[i].filename); - endStackFrameFilename(); - } - if (backtrace[i].linenumber != NULL) { - beginStackFrameLinenumber(); - writeString(backtrace[i].linenumber); - endStackFrameLinenumber(); - } - if (backtrace[i].offset != NULL) { - beginStackFrameOffset(); - writeString(backtrace[i].offset); - endStackFrameOffset(); - } - endStackFrame(); +void Writer::beginBacktrace(unsigned num_frames) { + if (num_frames) { + _writeByte(trace::CALL_BACKTRACE); + _writeUInt(num_frames); } } -void Writer::beginBacktrace(void ) { - _writeByte(trace::CALL_BACKTRACE); -} - -void Writer::endBacktrace(void ) { - _writeByte(trace::CALL_BACKTRACE_END); -} - -void Writer::beginStackFrame(void ) { - _writeByte(trace::CALL_BACKTRACE_FRAME); -} - -void Writer::beginStackFrameModule(void ) { - _writeByte(trace::CALL_BACKTRACE_MODULE); -} - -void Writer::beginStackFrameFunction(void ) { - _writeByte(trace::CALL_BACKTRACE_FUNCTION); -} - -void Writer::beginStackFrameFilename(void ) { - _writeByte(trace::CALL_BACKTRACE_FILENAME); -} - -void Writer::beginStackFrameLinenumber(void ) { - _writeByte(trace::CALL_BACKTRACE_LINENUMBER); -} - -void Writer::beginStackFrameOffset(void ) { - _writeByte(trace::CALL_BACKTRACE_OFFSET); +void Writer::writeStackFrame(const RawStackFrame &frame) { + if (frame.module != NULL) { + _writeByte(trace::BACKTRACE_MODULE); + _writeString(frame.module); + } + if (frame.function != NULL) { + _writeByte(trace::BACKTRACE_FUNCTION); + _writeString(frame.function); + } + if (frame.filename != NULL) { + _writeByte(trace::BACKTRACE_FILENAME); + _writeString(frame.filename); + } + if (frame.linenumber >= 0) { + _writeByte(trace::BACKTRACE_LINENUMBER); + _writeUInt(frame.linenumber); + } + if (frame.offset >= 0) { + _writeByte(trace::BACKTRACE_OFFSET); + _writeUInt(frame.offset); + } + _writeByte(trace::BACKTRACE_END); } unsigned Writer::beginEnter(const FunctionSig *sig, unsigned thread_id) { diff --git a/common/trace_writer.hpp b/common/trace_writer.hpp index f8d0afb..35a828f 100644 --- a/common/trace_writer.hpp +++ b/common/trace_writer.hpp @@ -58,22 +58,6 @@ namespace trace { bool open(const char *filename); void close(void); - void writeBacktrace(std::vector backtrace); - void beginBacktrace(void); - void endBacktrace(void); - void beginStackFrame(void); - inline void endStackFrame(void) {} - void beginStackFrameModule(void); - inline void endStackFrameModule(void) {} - void beginStackFrameFunction(void); - inline void endStackFrameFunction(void) {} - void beginStackFrameFilename(void); - inline void endStackFrameFilename(void) {} - void beginStackFrameLinenumber(void); - inline void endStackFrameLinenumber(void) {} - void beginStackFrameOffset(void); - inline void endStackFrameOffset(void) {} - unsigned beginEnter(const FunctionSig *sig, unsigned thread_id); void endEnter(void); @@ -86,6 +70,10 @@ namespace trace { void beginReturn(void); inline void endReturn(void) {} + void beginBacktrace(unsigned num_frames); + void writeStackFrame(const RawStackFrame &frame); + inline void endBacktrace(void) {} + void beginArray(size_t length); inline void endArray(void) {} diff --git a/common/trace_writer_local.cpp b/common/trace_writer_local.cpp index 8661701..ef4a9bd 100644 --- a/common/trace_writer_local.cpp +++ b/common/trace_writer_local.cpp @@ -155,8 +155,10 @@ unsigned LocalWriter::beginEnter(const FunctionSig *sig, bool fake) { unsigned call_no = Writer::beginEnter(sig, thread_id); if (!fake) { std::vector backtrace = get_backtrace(); - beginBacktrace(); - writeBacktrace(backtrace); + beginBacktrace(backtrace.size()); + for (unsigned i = 0; i < backtrace.size(); ++i) { + writeStackFrame(backtrace[i]); + } endBacktrace(); } return call_no; diff --git a/common/trace_writer_model.cpp b/common/trace_writer_model.cpp index cdf9783..4cf82f6 100644 --- a/common/trace_writer_model.cpp +++ b/common/trace_writer_model.cpp @@ -107,48 +107,14 @@ public: writer.endRepr(); } - void visit(StackFrame* frame) { - writer.beginStackFrame(); - if (frame->module != NULL) { - writer.beginStackFrameModule(); - _visit(frame->module); - writer.endStackFrameModule(); - } - if (frame->function != NULL) { - writer.beginStackFrameFunction(); - _visit(frame->function); - writer.endStackFrameFunction(); - } - if (frame->filename != NULL) { - writer.beginStackFrameFilename(); - _visit(frame->filename); - writer.endStackFrameFilename(); - } - if (frame->linenumber != NULL) { - writer.beginStackFrameLinenumber(); - _visit(frame->linenumber); - writer.endStackFrameLinenumber(); - } - if (frame->offset != NULL) { - writer.beginStackFrameOffset(); - _visit(frame->offset); - writer.endStackFrameOffset(); - } - writer.endStackFrame(); - } - - void visit(Backtrace * backtrace) { - writer.beginBacktrace(); - for (int i =0; i < backtrace->frames.size(); i++) { - visit(backtrace->frames[i]); - } - writer.endBacktrace(); - } - void visit(Call *call) { unsigned call_no = writer.beginEnter(call->sig, call->thread_id); if (call->backtrace != NULL) { - visit(call->backtrace); + writer.beginBacktrace(call->backtrace->size()); + for (unsigned i = 0; i < call->backtrace->size(); ++i) { + writer.writeStackFrame((*call->backtrace)[i]); + } + writer.endBacktrace(); } for (unsigned i = 0; i < call->args.size(); ++i) { if (call->args[i].value) { diff --git a/gui/apitracecall.cpp b/gui/apitracecall.cpp index c3a1dee..3f0fc0b 100644 --- a/gui/apitracecall.cpp +++ b/gui/apitracecall.cpp @@ -687,29 +687,23 @@ ApiTraceCall::ApiTraceCall(ApiTraceFrame *parentFrame, m_flags = call->flags; if (call->backtrace != NULL) { QString qbacktrace; - for (int i = 0; i < call->backtrace->frames.size(); i++) { - trace::StackFrame* frame = call->backtrace->frames[i]; - trace::String* tmp; - tmp = frame->module; - if (tmp != NULL) { - qbacktrace += QString("%1 ").arg(tmp->toString()); + for (int i = 0; i < call->backtrace->size(); i++) { + const trace::StackFrame & frame = (*call->backtrace)[i]; + if (frame.module != NULL) { + qbacktrace += QString("%1 ").arg(frame.module); } - tmp = frame->function; - if (tmp != NULL) { - qbacktrace += QString("at %1() ").arg(tmp->toString()); + if (frame.function != NULL) { + qbacktrace += QString("at %1() ").arg(frame.function); } - tmp = frame->filename; - if (tmp != NULL) { - qbacktrace += QString("at %1").arg(tmp->toString()); - tmp = frame->linenumber; - if (tmp != NULL) { - qbacktrace += QString(":%1 ").arg(tmp->toString()); + if (frame.filename != NULL) { + qbacktrace += QString("at %1").arg(frame.filename); + if (frame.linenumber >= 0) { + qbacktrace += QString(":%1 ").arg(frame.linenumber); } } else { - tmp = frame->offset; - if (tmp != NULL) { - qbacktrace += QString("[%1]").arg(tmp->toString()); + if (frame.offset >= 0) { + qbacktrace += QString("[0x%1]").arg(frame.offset, 0, 16); } } qbacktrace += "\n"; -- 2.45.2