📄 vglog.cpp
字号:
QDomNodeList framelist1 = stack1.childNodes(); QDomNodeList framelist2 = stack2.childNodes(); /* test #2: error stacks have same num frames, if either < MAX_FRAMES_COMPARE */ if ( (framelist1.count() < MAX_FRAMES_COMPARE || framelist2.count() < MAX_FRAMES_COMPARE) && framelist1.count() != framelist2.count()) { vklmPrint( 3, "=> different number of frames" ); return false; } /* test #3: all stack frames the same, to MAX_FRAMES_COMPARE */ unsigned int i; for (i=0; i<framelist1.count() && i<MAX_FRAMES_COMPARE; i++) { QDomElement frame1 = framelist1.item(i).toElement(); QDomElement frame2 = framelist2.item(i).toElement(); if ( (VgFrame&)frame1 != (VgFrame&)frame2 ) { vklmPrint( 3, "=> stack comparison failed" ); return false; } } return true;}bool VgError::operator!=( const VgError& frame2 ) const{ return !operator==(frame2);}bool VgError::updateLeakErr( VgError sErr ){ if ( !isLeak() ) { return false; } VgElement mElemBytes = getFirstElem( "leakedbytes" ); VgElement sElemBytes = sErr.getFirstElem( "leakedbytes" ); if ( ! mElemBytes.updateCount( sElemBytes ) ) return false; VgElement mElemBlocks = getFirstElem( "leakedblocks" ); VgElement sElemBlocks = sErr.getFirstElem( "leakedblocks" ); if ( ! mElemBlocks.updateCount( sElemBlocks ) ) return false; /* update leak::what - don't try to parse the current 'what' strings, as not intended for machine consumption. - just re-create a what string of our own. (not distinguishing direct/indirect errors) */ bool ok; unsigned long mBytes = mElemBytes.toULong( &ok ); if (!ok) return false; unsigned long mBlocks = mElemBlocks.toULong( &ok ); if (!ok) return false; QString mWhatStr = QString("%1 bytes in %2 blocks are %3") .arg( mBytes ) .arg( mBlocks ) .arg( leakDesc( leakKind() ) ); VgElement mWhat = getFirstElem( "what" ); mWhat.setContent( mWhatStr ); return true;}QString VgError::unique(){ return firstChild().toElement().text(); }/* retrieve count for given error */VgElement VgErrCounts::getCount( VgError err ){ VgElement elem; QString err_unique = err.unique(); QDomNodeList pairs = childNodes(); for (unsigned int i=0; i<pairs.count(); i++) { QDomNode pair = pairs.item(i); QDomNodeList pair_details = pair.childNodes(); QString unique = pair_details.item(1).toElement().text(); if (err_unique == unique ) { QDomElement el = pair_details.item(0).toElement(); elem = (VgElement&)el; } } return elem;}VgError::LeakKind VgError::leakKind(){ QString kind = getFirstElem("kind").text(); LeakKindMap::Iterator it = leakKindMap.find( kind ); if ( it == leakKindMap.end() ) { vklmPrintErr("VgError::leakKind(): bad kind; %s", kind.latin1()); return VgError::NUM_LKS; } return it.data(); }QString VgError::leakDesc( LeakKind lk ){ switch( lk ) { case UNREACHED: return "definitely lost"; case INDIRECT: return "indirectly lost"; case INTERIOR: return "possibly lost"; case PROPER: return "still reachable"; default: return ""; }}/**********************************************************************//* VgLog: a representation of a valgrind xml log based on QDomDocument.*/VgLog::VgLog(){ }VgLog::~VgLog(){ }bool VgLog::init( QDomProcessingInstruction xml_insn, QString doc_tag ){ if ( xml_insn.isNull() ) { vklmPrintErr("VgLog::init(): xml_insn isNull"); return false; } if ( doc_tag.isEmpty() ) { vklmPrintErr("VgLog::init(): doc_tag isEmpty"); return false; } QString init_str; QTextStream strm( init_str, IO_WriteOnly ); xml_insn.save( strm, 2 ); strm << "<" << doc_tag << "/>"; log.setContent( init_str ); return true;}/* append top-level xml element to log*/bool VgLog::appendNode( QDomNode node ){ if (log.isNull()) { vklmPrintErr("VgLog::appendNode(): log not initialised"); return false; } if (docroot().isNull()) { vklmPrintErr("VgLog::appendNode(): docroot isNull"); return false; } QDomElement e = node.toElement(); if (e.isNull()) { vklmPrintErr("VgLog::appendNode(): node not an element"); return false; } VgElement elem = (VgElement&)e; /* check elem is a top-level xml chunk */ VgElement::ElemType type = elem.elemType(); if ( type == VgElement::NUM_ELEMS ) { vklmPrintErr("VgLog::appendNode(): unrecognised tagname: %s", elem.tagName().latin1()); return false; } switch ( type ) { case VgElement::PROTOCOL: if ( elem.text() != "1" && elem.text() != "2" ) { vklmPrintErr("VgLog::appendNode(): bad xml protocol version"); return false; } break; case VgElement::PREAMBLE: case VgElement::PID: case VgElement::PPID: case VgElement::TOOL: case VgElement::LOGQUAL: case VgElement::COMMENT: case VgElement::ARGS: case VgElement::STATUS: case VgElement::ERROR: case VgElement::ERRORCOUNTS: case VgElement::SUPPCOUNTS: break; default: vklmPrintErr("VgLog::appendNode(): not a top-level tagname: %s", elem.tagName().latin1()); return false; break; } docroot().appendChild( node ); /* reparents node */ return true;}VgElement VgLog::docroot(){ QDomElement e = log.documentElement(); return (VgElement&)e;}VgElement VgLog::protocol(){ return docroot().getFirstElem("protocolversion"); }VgPreamble VgLog::preamble(){ VgElement e = docroot().getFirstElem("preamble"); return (VgPreamble&)e;}VgElement VgLog::pid(){ return docroot().getFirstElem("pid"); }VgElement VgLog::ppid(){ return docroot().getFirstElem("ppid"); }VgElement VgLog::tool(){ return docroot().getFirstElem("tool"); }VgElement VgLog::logqual(){ return docroot().getFirstElem("logfilequalifier"); }VgElement VgLog::comment(){ return docroot().getFirstElem("usercomment"); }VgElement VgLog::args(){ return docroot().getFirstElem("args"); }VgStatus VgLog::status_beg(){ VgElement e = docroot().getFirstElem("status"); VgStatus s = (VgStatus&)e; if (s.state() == VgStatus::RUNNING) return s; return VgStatus();}VgStatus VgLog::status_end(){ VgElement e = docroot().getLastElem("status"); VgStatus s = (VgStatus&)e; if (s.state() == VgStatus::FINISHED) return s; return VgStatus();}VgErrorList VgLog::errors(){ /* all non-leak errors before status == finished */ VgErrorList errlist; QDomElement e = docroot().firstChild().toElement(); for ( ; !e.isNull(); e=e.nextSibling().toElement() ) { /* quit after status == FINISHED */ if (e.tagName() == "status") { if (((VgStatus&)e).state() == VgStatus::FINISHED) break; } else if (e.tagName() == "error") { VgError err = (VgError&)e; if (!err.isLeak()) { errlist.append( err ); } } } return errlist;}VgErrorList VgLog::leaks(){ VgErrorList errlist; if ( state() == VgStatus::INIT ) { return errlist; } if ( 0 /*state() == VgStatus::RUNNING */ ) { /* last record group of leak errors */ } else { // VgStatus::FINISHED /* all leaks after status_end */ bool start = false; QDomElement e = docroot().firstChild().toElement(); for ( ; !e.isNull(); e=e.nextSibling().toElement() ) { /* start after status == FINISHED */ if (e.tagName() == "status") { if (((VgStatus&)e).state() == VgStatus::FINISHED) start = true; } else if (start && e.tagName() == "error") { VgError err = (VgError&)e; if (err.isLeak()) { errlist.append( err ); } } } } return errlist;}VgErrCounts VgLog::errorcounts(){ VgElement e = docroot().getLastElem("errorcounts"); return (VgErrCounts&)e;}VgSuppCounts VgLog::suppcounts(){ VgElement e = docroot().getFirstElem("suppcounts"); return (VgSuppCounts&)e;}VgStatus::StateType VgLog::state() { if (!status_end().isNull()) return status_end().state(); if (!status_beg().isNull()) return status_beg().state(); return VgStatus::INIT;}/* ref: memcheck/mac_leakcheck.c :: MAC_(do_detect_memory_leaks) */QString VgLog::plainTxtErrorSummary(){ int i_errs=0, i_err_contexts=0, i_supps=0, i_supp_contexts=0; QDomNodeList pairs; QDomNode n; /* count errors */ pairs = errorcounts().childNodes(); i_err_contexts = pairs.count(); n = pairs.item(0); for ( ; !n.isNull(); n=n.nextSibling() ) { QString count = n.firstChild().toElement().text(); i_errs += count.toULong(); } /* count suppressions */ pairs = suppcounts().childNodes(); i_supp_contexts = pairs.count(); n = pairs.item(0); for ( ; !n.isNull(); n=n.nextSibling() ) { QString count = n.firstChild().toElement().text(); i_supps += count.toULong(); } QString output_str = "ERROR SUMMARY: " + QString::number(i_errs) + " errors from " + QString::number(i_err_contexts) + " contexts " + "(suppressed: " + QString::number(i_supps) + " from " + QString::number(i_supp_contexts) + ")\n\n\n"; return output_str;}/* ref: memcheck/mac_leakcheck.c :: MAC_(do_detect_memory_leaks) *//* print leak error summary *//* CAB: suppressed leak errs not given in vg xml output */QString VgLog::plainTxtLeakSummary(){ unsigned long lk_bytes[VgError::NUM_LKS]; unsigned long lk_blocks[VgError::NUM_LKS]; for (unsigned int i=0; i<VgError::NUM_LKS; i++) { lk_bytes[i] = lk_blocks[i] = 0; } VgErrorList errs = leaks();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -