X-Git-Url: https://git.cworth.org/git?a=blobdiff_plain;f=trace_parser.cpp;h=d7b20d2c450faaab61cc986c6c046b72df5a4caa;hb=447f4a55a01e82b0265f44212b8d439fa83750d7;hp=1fa901eb356e67a53ce3c8f1e2c3e0b492e297cc;hpb=b74d63eb4dbfb492b55ddad3ddae7edcd5727823;p=apitrace diff --git a/trace_parser.cpp b/trace_parser.cpp index 1fa901e..d7b20d2 100644 --- a/trace_parser.cpp +++ b/trace_parser.cpp @@ -98,10 +98,56 @@ void Parser::close(void) { } deleteAll(calls); - deleteAll(functions); - deleteAll(structs); - deleteAll(enums); - deleteAll(bitmasks); + + // Delete all signature data. Signatures are mere structures which don't + // own their own memory, so we need to destroy all data we created here. + + for (FunctionMap::iterator it = functions.begin(); it != functions.end(); ++it) { + FunctionSigState *sig = *it; + if (sig) { + delete [] sig->name; + for (unsigned arg = 0; arg < sig->num_args; ++arg) { + delete [] sig->arg_names[arg]; + } + delete [] sig->arg_names; + delete sig; + } + } + functions.clear(); + + for (StructMap::iterator it = structs.begin(); it != structs.end(); ++it) { + StructSigState *sig = *it; + if (sig) { + delete [] sig->name; + for (unsigned member = 0; member < sig->num_members; ++member) { + delete [] sig->member_names[member]; + } + delete [] sig->member_names; + delete sig; + } + } + structs.clear(); + + for (EnumMap::iterator it = enums.begin(); it != enums.end(); ++it) { + EnumSigState *sig = *it; + if (sig) { + delete [] sig->name; + delete sig; + } + } + enums.clear(); + + for (BitmaskMap::iterator it = bitmasks.begin(); it != bitmasks.end(); ++it) { + BitmaskSigState *sig = *it; + if (sig) { + for (unsigned flag = 0; flag < sig->num_flags; ++flag) { + delete [] sig->flags[flag].name; + } + delete [] sig->flags; + delete sig; + } + } + bitmasks.clear(); } @@ -120,15 +166,15 @@ void Parser::setBookmark(const ParseBookmark &bookmark) { } -Call *Parser::parse_call(void) { +Call *Parser::parse_call(Mode mode) { do { int c = read_byte(); switch(c) { case Trace::EVENT_ENTER: - parse_enter(); + parse_enter(mode); break; case Trace::EVENT_LEAVE: - return parse_leave(); + return parse_leave(mode); default: std::cerr << "error: unknown event " << c << "\n"; exit(1); @@ -143,30 +189,6 @@ Call *Parser::parse_call(void) { } -Call * Parser::scan_call() -{ - do { - int c = read_byte(); - switch(c) { - case Trace::EVENT_ENTER: - scan_enter(); - break; - case Trace::EVENT_LEAVE: - return scan_leave(); - default: - std::cerr << "error: unknown event " << c << "\n"; - exit(1); - case -1: - for (CallList::iterator it = calls.begin(); it != calls.end(); ++it) { - std::cerr << "warning: incomplete call " << (*it)->name() << "\n"; - std::cerr << **it << "\n"; - } - return NULL; - } - } while (true); -} - - /** * Helper function to lookup an ID in a vector, resizing the vector if it doesn't fit. */ @@ -306,28 +328,14 @@ BitmaskSig *Parser::parse_bitmask_sig() { } -void Parser::parse_enter(void) { +void Parser::parse_enter(Mode mode) { FunctionSig *sig = parse_function_sig(); Call *call = new Call(sig); call->no = next_call_no++; - if (parse_call_details(call)) { - calls.push_back(call); - } else { - delete call; - } -} - - -void Parser::scan_enter(void) { - FunctionSig *sig = parse_function_sig(); - - Call *call = new Call(sig); - call->no = next_call_no++; - - if (scan_call_details(call)) { + if (parse_call_details(call, mode)) { calls.push_back(call); } else { delete call; @@ -335,7 +343,7 @@ void Parser::scan_enter(void) { } -Call *Parser::parse_leave(void) { +Call *Parser::parse_leave(Mode mode) { unsigned call_no = read_uint(); Call *call = NULL; for (CallList::iterator it = calls.begin(); it != calls.end(); ++it) { @@ -349,7 +357,7 @@ Call *Parser::parse_leave(void) { return NULL; } - if (parse_call_details(call)) { + if (parse_call_details(call, mode)) { return call; } else { delete call; @@ -358,63 +366,17 @@ Call *Parser::parse_leave(void) { } -Call *Parser::scan_leave(void) { - unsigned call_no = read_uint(); - Call *call = NULL; - for (CallList::iterator it = calls.begin(); it != calls.end(); ++it) { - if ((*it)->no == call_no) { - call = *it; - calls.erase(it); - break; - } - } - if (!call) { - return NULL; - } - - if (scan_call_details(call)) { - return call; - } else { - delete call; - return NULL; - } -} - - -bool Parser::parse_call_details(Call *call) { - do { - int c = read_byte(); - switch(c) { - case Trace::CALL_END: - return true; - case Trace::CALL_ARG: - parse_arg(call); - break; - case Trace::CALL_RET: - call->ret = parse_value(); - break; - default: - std::cerr << "error: ("<name()<< ") unknown call detail " - << c << "\n"; - exit(1); - case -1: - return false; - } - } while(true); -} - - -bool Parser::scan_call_details(Call *call) { +bool Parser::parse_call_details(Call *call, Mode mode) { do { int c = read_byte(); switch(c) { case Trace::CALL_END: return true; case Trace::CALL_ARG: - scan_arg(call); + parse_arg(call, mode); break; case Trace::CALL_RET: - scan_value(); + call->ret = parse_value(mode); break; default: std::cerr << "error: ("<name()<< ") unknown call detail " @@ -427,19 +389,15 @@ bool Parser::scan_call_details(Call *call) { } -void Parser::parse_arg(Call *call) { +void Parser::parse_arg(Call *call, Mode mode) { unsigned index = read_uint(); - Value *value = parse_value(); - if (index >= call->args.size()) { - call->args.resize(index + 1); + Value *value = parse_value(mode); + if (value) { + if (index >= call->args.size()) { + call->args.resize(index + 1); + } + call->args[index] = value; } - call->args[index] = value; -} - - -void Parser::scan_arg(Call *call) { - skip_uint(); /* index */ - scan_value(); /* value */ }