Use strings and unsigned, instead of string values and unsigned values.
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;
RawStackFrame* parsedFrame = new RawStackFrame;
char* frame_it = frame_symbol_copy;
parsedFrame->module = frame_it;
+ char* offset = NULL;
while (true) {
switch (*frame_it) {
case '(':
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':
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<RawStackFrame> get_backtrace();
}
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";
}
}
if (call->backtrace != NULL) {
os << bold << red << "Backtrace:\n" << normal;
- visit(call->backtrace);
+ visit(*call->backtrace);
}
if (callFlags & CALL_FLAG_END_FRAME) {
os << "\n";
*
* call_detail = ARG index value
* | RET value
+ * | THREAD int
+ * | BACKTRACE int frame*
* | END
*
* value = NULL
* | 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
*
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,
TYPE_REPR,
};
+enum BacktraceDetail {
+ BACKTRACE_END = 0,
+ BACKTRACE_MODULE,
+ BACKTRACE_FUNCTION,
+ BACKTRACE_FILENAME,
+ BACKTRACE_LINENUMBER,
+ BACKTRACE_OFFSET,
+};
+
} /* namespace trace */
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; }
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); }
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<StackFrame*> frames;
- ~Backtrace();
- void addFrame(StackFrame* frame);
+ ~StackFrame();
};
+typedef std::vector<StackFrame> Backtrace;
+
class Visitor
{
public:
}
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<String*>(parse_value(mode));
+ case trace::BACKTRACE_MODULE:
+ frame->module = read_string();
break;
- case trace::CALL_BACKTRACE_FUNCTION:
- frame->function = static_cast<String*>(parse_value(mode));
+ case trace::BACKTRACE_FUNCTION:
+ frame->function = read_string();
break;
- case trace::CALL_BACKTRACE_FILENAME:
- frame->filename = static_cast<String*>(parse_value(mode));
+ case trace::BACKTRACE_FILENAME:
+ frame->filename = read_string();
break;
- case trace::CALL_BACKTRACE_LINENUMBER:
- frame->linenumber = static_cast<String*>(parse_value(mode));
+ case trace::BACKTRACE_LINENUMBER:
+ frame->linenumber = read_uint();
break;
- case trace::CALL_BACKTRACE_OFFSET:
- frame->offset = static_cast<String*>(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:
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);
}
}
-void Writer::writeBacktrace(std::vector<RawStackFrame> 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) {
bool open(const char *filename);
void close(void);
- void writeBacktrace(std::vector<RawStackFrame> 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);
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) {}
unsigned call_no = Writer::beginEnter(sig, thread_id);
if (!fake) {
std::vector<RawStackFrame> backtrace = get_backtrace();
- beginBacktrace();
- writeBacktrace(backtrace);
+ beginBacktrace(backtrace.size());
+ for (unsigned i = 0; i < backtrace.size(); ++i) {
+ writeStackFrame(backtrace[i]);
+ }
endBacktrace();
}
return call_no;
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) {
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";