最近在坐代码静态检查的时候,cppcheck好像是进入了某个死循环里,死在了那里,不动了。看源代码看,果然是有死循环的可能。
/cppcheck/lib/programmemory.cpp
(gdb) bt
#0 0x00007ff76a83be59 in free () from /lib64/libc.so.6
#1 0x00000000005d09e4 in isAliasOf(Token const*, Token const*, int*, bool*) ()
#2 0x00000000005d2439 in bool isExpressionChangedAt<isExpressionChangedAt(Token const*, Token const*, int, bool, Settings const*, int)::{lambda()#1}, void>(isExpressionChangedAt(Token const*, Token const*, int, bool, Settings const*, int)::{lambda()#1} const&, Token const*, int, int, bool, Settings const*, int) ()
#3 0x00000000005d2ed0 in Token const* findExpressionChangedImpl<(anonymous namespace)::ExpressionChangedSimpleFind>(Token const*, Token const*, Token const*, Settings const*, int, (anonymous namespace)::ExpressionChangedSimpleFind) ()
#4 0x00000000007378d3 in programMemoryParseCondition(ProgramMemory&, Token const*, Token const*, Settings const*, bool) ()
#5 0x0000000000738207 in fillProgramMemoryFromConditions(ProgramMemory&, Scope const*, Token const*, Settings const*) ()
。。。。。。。
#42 0x000000000073818c in fillProgramMemoryFromConditions(ProgramMemory&, Scope const*, Token const*, Settings const*) ()
#43 0x0000000000738988 in ProgramMemoryState::addState(Token const*, std::unordered_map<ExprIdToken, ValueFlow::Value, ExprIdToken::Hash, std::equal_to<ExprIdToken>, std::allocator<std::pair<ExprIdToken const, ValueFlow::Value> > > const&) ()
#44 0x0000000000533407 in ValueFlowAnalyzer::updateState(Token const*) ()
#45 0x00000000006e5925 in (anonymous namespace)::ForwardTraversal::checkBranch((anonymous namespace)::ForwardTraversal::Branch&) const [clone .constprop.216] ()
#46 0x00000000006df976 in (anonymous namespace)::ForwardTraversal::updateRange(Token*, Token const*, int) ()
#47 0x00000000006e5939 in (anonymous namespace)::ForwardTraversal::checkBranch((anonymous namespace)::ForwardTraversal::Branch&) const [clone .constprop.216] ()
#48 0x00000000006df976 in (anonymous namespace)::ForwardTraversal::updateRange(Token*, Token const*, int) ()
#49 0x00000000006e5939 in (anonymous namespace)::ForwardTraversal::checkBranch((anonymous namespace)::ForwardTraversal::Branch&) const [clone .constprop.216] ()
#50 0x00000000006df976 in (anonymous namespace)::ForwardTraversal::updateRange(Token*, Token const*, int) ()
#51 0x00000000006e5939 in (anonymous namespace)::ForwardTraversal::checkBranch((anonymous namespace)::ForwardTraversal::Branch&) const [clone .constprop.216] ()
#52 0x00000000006df976 in (anonymous namespace)::ForwardTraversal::updateRange(Token*, Token const*, int) ()
#53 0x00000000006e5939 in (anonymous namespace)::ForwardTraversal::checkBranch((anonymous namespace)::ForwardTraversal::Branch&) const [clone .constprop.216] ()
#54 0x00000000006df976 in (anonymous namespace)::ForwardTraversal::updateRange(Token*, Token const*, int) ()
#55 0x00000000006e5939 in (anonymous namespace)::ForwardTraversal::checkBranch((anonymous namespace)::ForwardTraversal::Branch&) const [clone .constprop.216] ()
#56 0x00000000006df976 in (anonymous namespace)::ForwardTraversal::updateRange(Token*, Token const*, int) ()
#57 0x00000000006e5939 in (anonymous namespace)::ForwardTraversal::checkBranch((anonymous namespace)::ForwardTraversal::Branch&) const [clone .constprop.216] ()
#58 0x00000000006df976 in (anonymous namespace)::ForwardTraversal::updateRange(Token*, Token const*, int) ()
#59 0x00000000006e5939 in (anonymous namespace)::ForwardTraversal::checkBranch((anonymous namespace)::ForwardTraversal::Branch&) const [clone .constprop.216] ()
#60 0x00000000006df976 in (anonymous namespace)::ForwardTraversal::updateRange(Token*, Token const*, int) ()
#61 0x00000000006e5939 in (anonymous namespace)::ForwardTraversal::checkBranch((anonymous namespace)::ForwardTraversal::Branch&) const [clone .constprop.216] ()
#62 0x00000000006df976 in (anonymous namespace)::ForwardTraversal::updateRange(Token*, Token const*, int) ()
--Type <RET> for more, q to quit, c to continue without paging--
#63 0x00000000006e5939 in (anonymous namespace)::ForwardTraversal::checkBranch((anonymous namespace)::ForwardTraversal::Branch&) const [clone .constprop.216] ()
#64 0x00000000006df976 in (anonymous namespace)::ForwardTraversal::updateRange(Token*, Token const*, int) ()
#65 0x00000000006e5939 in (anonymous namespace)::ForwardTraversal::checkBranch((anonymous namespace)::ForwardTraversal::Branch&) const [clone .constprop.216] ()
#66 0x00000000006df976 in (anonymous namespace)::ForwardTraversal::updateRange(Token*, Token const*, int) ()
#67 0x00000000006e5939 in (anonymous namespace)::ForwardTraversal::checkBranch((anonymous namespace)::ForwardTraversal::Branch&) const [clone .constprop.216] ()
#68 0x00000000006df976 in (anonymous namespace)::ForwardTraversal::updateRange(Token*, Token const*, int) ()
#69 0x00000000006e5939 in (anonymous namespace)::ForwardTraversal::checkBranch((anonymous namespace)::ForwardTraversal::Branch&) const [clone .constprop.216] ()
#70 0x00000000006df976 in (anonymous namespace)::ForwardTraversal::updateRange(Token*, Token const*, int) ()
#71 0x00000000006e5939 in (anonymous namespace)::ForwardTraversal::checkBranch((anonymous namespace)::ForwardTraversal::Branch&) const [clone .constprop.216] ()
#72 0x00000000006df976 in (anonymous namespace)::ForwardTraversal::updateRange(Token*, Token const*, int) ()
#73 0x00000000006e5939 in (anonymous namespace)::ForwardTraversal::checkBranch((anonymous namespace)::ForwardTraversal::Branch&) const [clone .constprop.216] ()
#74 0x00000000006df976 in (anonymous namespace)::ForwardTraversal::updateRange(Token*, Token const*, int) ()
#75 0x00000000006e5939 in (anonymous namespace)::ForwardTraversal::checkBranch((anonymous namespace)::ForwardTraversal::Branch&) const [clone .constprop.216] ()
#76 0x00000000006df976 in (anonymous namespace)::ForwardTraversal::updateRange(Token*, Token const*, int) ()
#77 0x00000000006e5939 in (anonymous namespace)::ForwardTraversal::checkBranch((anonymous namespace)::ForwardTraversal::Branch&) const [clone .constprop.216] ()
#78 0x00000000006df976 in (anonymous namespace)::ForwardTraversal::updateRange(Token*, Token const*, int) ()
#79 0x00000000006e5939 in (anonymous namespace)::ForwardTraversal::checkBranch((anonymous namespace)::ForwardTraversal::Branch&) const [clone .constprop.216] ()
#80 0x00000000006df976 in (anonymous namespace)::ForwardTraversal::updateRange(Token*, Token const*, int) ()
#81 0x00000000006e5939 in (anonymous namespace)::ForwardTraversal::checkBranch((anonymous namespace)::ForwardTraversal::Branch&) const [clone .constprop.216] ()
#82 0x00000000006df976 in (anonymous namespace)::ForwardTraversal::updateRange(Token*, Token const*, int) ()
#83 0x00000000006e5939 in (anonymous namespace)::ForwardTraversal::checkBranch((anonymous namespace)::ForwardTraversal::Branch&) const [clone .constprop.216] ()
#84 0x00000000006df976 in (anonymous namespace)::ForwardTraversal::updateRange(Token*, Token const*, int) ()
#85 0x00000000006e5939 in (anonymous namespace)::ForwardTraversal::checkBranch((anonymous namespace)::ForwardTraversal::Branch&) const [clone .constprop.216] ()
#86 0x00000000006df976 in (anonymous namespace)::ForwardTraversal::updateRange(Token*, Token const*, int) ()
#87 0x00000000006e5939 in (anonymous namespace)::ForwardTraversal::checkBranch((anonymous namespace)::ForwardTraversal::Branch&) const [clone .constprop.216] ()
#88 0x00000000006df976 in (anonymous namespace)::ForwardTraversal::updateRange(Token*, Token const*, int) ()
#89 0x00000000006e5939 in (anonymous namespace)::ForwardTraversal::checkBranch((anonymous namespace)::ForwardTraversal::Branch&) const [clone .constprop.216] ()
#90 0x00000000006df976 in (anonymous namespace)::ForwardTraversal::updateRange(Token*, Token const*, int) ()
#91 0x00000000006e5939 in (anonymous namespace)::ForwardTraversal::checkBranch((anonymous namespace)::ForwardTraversal::Branch&) const [clone .constprop.216] ()
#92 0x00000000006df976 in (anonymous namespace)::ForwardTraversal::updateRange(Token*, Token const*, int) ()
#93 0x00000000006e5939 in (anonymous namespace)::ForwardTraversal::checkBranch((anonymous namespace)::ForwardTraversal::Branch&) const [clone .constprop.216] ()
#94 0x00000000006df976 in (anonymous namespace)::ForwardTraversal::updateRange(Token*, Token const*, int) ()
#95 0x00000000006e5939 in (anonymous namespace)::ForwardTraversal::checkBranch((anonymous namespace)::ForwardTraversal::Branch&) const [clone .constprop.216] ()
#96 0x00000000006df976 in (anonymous namespace)::ForwardTraversal::updateRange(Token*, Token const*, int) ()
#97 0x00000000006e5939 in (anonymous namespace)::ForwardTraversal::checkBranch((anonymous namespace)::ForwardTraversal::Branch&) const [clone .constprop.216] ()
#98 0x00000000006df976 in (anonymous namespace)::ForwardTraversal::updateRange(Token*, Token const*, int) ()
#99 0x00000000006e5939 in (anonymous namespace)::ForwardTraversal::checkBranch((anonymous namespace)::ForwardTraversal::Branch&) const [clone .constprop.216] ()
#100 0x00000000006df976 in (anonymous namespace)::ForwardTraversal::updateRange(Token*, Token const*, int) ()
#101 0x00000000006e5939 in (anonymous namespace)::ForwardTraversal::checkBranch((anonymous namespace)::ForwardTraversal::Branch&) const [clone .constprop.216] ()
#102 0x00000000006df976 in (anonymous namespace)::ForwardTraversal::updateRange(Token*, Token const*, int) ()
#103 0x00000000006e5939 in (anonymous namespace)::ForwardTraversal::checkBranch((anonymous namespace)::ForwardTraversal::Branch&) const [clone .constprop.216] ()
#104 0x00000000006df976 in (anonymous namespace)::ForwardTraversal::updateRange(Token*, Token const*, int) ()
#105 0x00000000006e5939 in (anonymous namespace)::ForwardTraversal::checkBranch((anonymous namespace)::ForwardTraversal::Branch&) const [clone .constprop.216] ()
#106 0x00000000006df976 in (anonymous namespace)::ForwardTraversal::updateRange(Token*, Token const*, int) ()
#107 0x00000000006e5939 in (anonymous namespace)::ForwardTraversal::checkBranch((anonymous namespace)::ForwardTraversal::Branch&) const [clone .constprop.216] ()
#108 0x00000000006df976 in (anonymous namespace)::ForwardTraversal::updateRange(Token*, Token const*, int) ()
#109 0x00000000006e5939 in (anonymous namespace)::ForwardTraversal::checkBranch((anonymous namespace)::ForwardTraversal::Branch&) const [clone .constprop.216] ()
#110 0x00000000006df976 in (anonymous namespace)::ForwardTraversal::updateRange(Token*, Token const*, int) ()
#111 0x00000000006e5939 in (anonymous namespace)::ForwardTraversal::checkBranch((anonymous namespace)::ForwardTraversal::Branch&) const [clone .constprop.216] ()
#112 0x00000000006df976 in (anonymous namespace)::ForwardTraversal::updateRange(Token*, Token const*, int) ()
#113 0x00000000006e5939 in (anonymous namespace)::ForwardTraversal::checkBranch((anonymous namespace)::ForwardTraversal::Branch&) const [clone .constprop.216] ()
#114 0x00000000006df976 in (anonymous namespace)::ForwardTraversal::updateRange(Token*, Token const*, int) ()
#115 0x00000000006e5939 in (anonymous namespace)::ForwardTraversal::checkBranch((anonymous namespace)::ForwardTraversal::Branch&) const [clone .constprop.216] ()
#116 0x00000000006df976 in (anonymous namespace)::ForwardTraversal::updateRange(Token*, Token const*, int) ()
#117 0x00000000006e5939 in (anonymous namespace)::ForwardTraversal::checkBranch((anonymous namespace)::ForwardTraversal::Branch&) const [clone .constprop.216] ()
#118 0x00000000006df976 in (anonymous namespace)::ForwardTraversal::updateRange(Token*, Token const*, int) ()
#119 0x00000000006e5939 in (anonymous namespace)::ForwardTraversal::checkBranch((anonymous namespace)::ForwardTraversal::Branch&) const [clone .constprop.216] ()
#120 0x00000000006df976 in (anonymous namespace)::ForwardTraversal::updateRange(Token*, Token const*, int) ()
#121 0x00000000006e5939 in (anonymous namespace)::ForwardTraversal::checkBranch((anonymous namespace)::ForwardTraversal::Branch&) const [clone .constprop.216] ()
#122 0x00000000006df976 in (anonymous namespace)::ForwardTraversal::updateRange(Token*, Token const*, int) ()
#123 0x00000000006e5939 in (anonymous namespace)::ForwardTraversal::checkBranch((anonymous namespace)::ForwardTraversal::Branch&) const [clone .constprop.216] ()
#124 0x00000000006df976 in (anonymous namespace)::ForwardTraversal::updateRange(Token*, Token const*, int) ()
#125 0x00000000006e5939 in (anonymous namespace)::ForwardTraversal::checkBranch((anonymous namespace)::ForwardTraversal::Branch&) const [clone .constprop.216] ()
#126 0x00000000006df976 in (anonymous namespace)::ForwardTraversal::updateRange(Token*, Token const*, int) ()
#127 0x00000000006e5939 in (anonymous namespace)::ForwardTraversal::checkBranch((anonymous namespace)::ForwardTraversal::Branch&) const [clone .constprop.216] ()
--Type <RET> for more, q to quit, c to continue without paging--
#128 0x00000000006df976 in (anonymous namespace)::ForwardTraversal::updateRange(Token*, Token const*, int) ()
#129 0x00000000006e5939 in (anonymous namespace)::ForwardTraversal::checkBranch((anonymous namespace)::ForwardTraversal::Branch&) const [clone .constprop.216] ()
#130 0x00000000006df976 in (anonymous namespace)::ForwardTraversal::updateRange(Token*, Token const*, int) ()
#131 0x00000000006e5939 in (anonymous namespace)::ForwardTraversal::checkBranch((anonymous namespace)::ForwardTraversal::Branch&) const [clone .constprop.216] ()
#132 0x00000000006df976 in (anonymous namespace)::ForwardTraversal::updateRange(Token*, Token const*, int) ()
#133 0x00000000006e5939 in (anonymous namespace)::ForwardTraversal::checkBranch((anonymous namespace)::ForwardTraversal::Branch&) const [clone .constprop.216] ()
#134 0x00000000006df976 in (anonymous namespace)::ForwardTraversal::updateRange(Token*, Token const*, int) ()
#135 0x00000000006e5939 in (anonymous namespace)::ForwardTraversal::checkBranch((anonymous namespace)::ForwardTraversal::Branch&) const [clone .constprop.216] ()
#136 0x00000000006df976 in (anonymous namespace)::ForwardTraversal::updateRange(Token*, Token const*, int) ()
#137 0x00000000006e5939 in (anonymous namespace)::ForwardTraversal::checkBranch((anonymous namespace)::ForwardTraversal::Branch&) const [clone .constprop.216] ()
#138 0x00000000006df976 in (anonymous namespace)::ForwardTraversal::updateRange(Token*, Token const*, int) ()
#139 0x00000000006e5939 in (anonymous namespace)::ForwardTraversal::checkBranch((anonymous namespace)::ForwardTraversal::Branch&) const [clone .constprop.216] ()
#140 0x00000000006df976 in (anonymous namespace)::ForwardTraversal::updateRange(Token*, Token const*, int) ()
#141 0x00000000006e5939 in (anonymous namespace)::ForwardTraversal::checkBranch((anonymous namespace)::ForwardTraversal::Branch&) const [clone .constprop.216] ()
#142 0x00000000006df976 in (anonymous namespace)::ForwardTraversal::updateRange(Token*, Token const*, int) ()
#143 0x00000000006e5939 in (anonymous namespace)::ForwardTraversal::checkBranch((anonymous namespace)::ForwardTraversal::Branch&) const [clone .constprop.216] ()
#144 0x00000000006df976 in (anonymous namespace)::ForwardTraversal::updateRange(Token*, Token const*, int) ()
#145 0x00000000006e5939 in (anonymous namespace)::ForwardTraversal::checkBranch((anonymous namespace)::ForwardTraversal::Branch&) const [clone .constprop.216] ()
#146 0x00000000006df976 in (anonymous namespace)::ForwardTraversal::updateRange(Token*, Token const*, int) ()
#147 0x00000000006e5939 in (anonymous namespace)::ForwardTraversal::checkBranch((anonymous namespace)::ForwardTraversal::Branch&) const [clone .constprop.216] ()
#148 0x00000000006df976 in (anonymous namespace)::ForwardTraversal::updateRange(Token*, Token const*, int) ()
#149 0x00000000006e44e6 in (anonymous namespace)::ForwardTraversal::updateInnerLoop(Token*, Token*, Token*) ()
#150 0x00000000006dad39 in (anonymous namespace)::ForwardTraversal::updateLoop(Token const*, Token*, Token*, Token*, Token*, bool) [clone .constprop.215] ()
#151 0x00000000006df07c in (anonymous namespace)::ForwardTraversal::updateRange(Token*, Token const*, int) ()
#152 0x00000000006e0215 in valueFlowGenericForward(Token*, Token const*, ValuePtr<Analyzer> const&, TokenList const&, ErrorLogger&, Settings const&) ()
#153 0x0000000000510286 in valueFlowForward(Token*, Token const*, Token const*, ValueFlow::Value, TokenList const&, ErrorLogger&, Settings const&, SourceLocation) [clone .isra.2292] ()
#154 0x000000000051057a in valueFlowForward(Token*, Token const*, Token const*, std::__cxx11::list<ValueFlow::Value, std::allocator<ValueFlow::Value> >, TokenList const&, ErrorLogger&, Settings const&, SourceLocation) [clone .isra.2293]
()
#155 0x0000000000510bbc in valueFlowForwardLifetime(Token*, TokenList&, ErrorLogger&, Settings const&) ()
#156 0x0000000000516b0b in valueFlowLifetime(TokenList&, ErrorLogger&, Settings const&) ()
#157 0x0000000000544706 in ValuePtr<ValueFlowPass> const* std::__find_if<ValuePtr<ValueFlowPass> const*, __gnu_cxx::__ops::_Iter_pred<ValueFlowPassRunner::run(std::initializer_list<ValuePtr<ValueFlowPass> >) const::{lambda(ValuePtr<ValueFlowPass> const&)#1}> >(__gnu_cxx::__ops::_Iter_pred<ValueFlowPassRunner::run(std::initializer_list<ValuePtr<ValueFlowPass> >) const::{lambda(ValuePtr<ValueFlowPass> const&)#1}>, __gnu_cxx::__ops::_Iter_pred<ValueFlowPassRunner::run(std::initializer_list<ValuePtr<ValueFlowPass> >) const::{lambda(ValuePtr<ValueFlowPass> const&)#1}>, __gnu_cxx::__ops::_Iter_pred<ValueFlowPassRunner::run(std::initializer_list<ValuePtr<ValueFlowPass> >) const::{lambda(ValuePtr<ValueFlowPass> const&)#1}>, std::random_access_iterator_tag) ()
#158 0x000000000050f918 in ValueFlow::setValues(TokenList&, SymbolDatabase&, ErrorLogger&, Settings const&, TimerResultsIntf*) ()
#159 0x0000000000582ff3 in Tokenizer::simplifyTokens1(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) ()
#160 0x00000000006b7871 in CppCheck::checkFile(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::istream*) ()
#161 0x00000000006b886f in CppCheck::check(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) ()
#162 0x0000000000793f3e in SingleExecutor::check() ()
#163 0x000000000078da87 in CppCheckExecutor::check_internal(Settings const&) const ()
#164 0x000000000078dee0 in CppCheckExecutor::check(int, char const* const*) ()
#165 0x00000000004cc3ec in main ()
代码段
static void programMemoryParseCondition(ProgramMemory& pm, const Token* tok, const Token* endTok, const Settings* settings, bool then)
{
auto eval = [&](const Token* t) -> std::vector<MathLib::bigint> {
if (!t)
return std::vector<MathLib::bigint>{};
if (t->hasKnownIntValue())
return {t->values().front().intvalue};
MathLib::bigint result = 0;
bool error = false;
execute(t, pm, &result, &error, settings);
if (!error)
return {result};
return std::vector<MathLib::bigint>{};
};
if (Token::Match(tok, "==|>=|<=|<|>|!=")) {
ValueFlow::Value truevalue;
ValueFlow::Value falsevalue;
const Token* vartok = parseCompareInt(tok, truevalue, falsevalue, eval);
if (!vartok)
return;
if (vartok->exprId() == 0)
return;
if (!truevalue.isIntValue())
return;
if (endTok && findExpressionChanged(vartok, tok->next(), endTok, settings))
return;
const bool impossible = (tok->str() == "==" && !then) || (tok->str() == "!=" && then);
const ValueFlow::Value& v = then ? truevalue : falsevalue;
pm.setValue(vartok, impossible ? asImpossible(v) : v);
const Token* containerTok = settings->library.getContainerFromYield(vartok, Library::Container::Yield::SIZE);
if (containerTok)
pm.setContainerSizeValue(containerTok, v.intvalue, !impossible);
} else if (Token::simpleMatch(tok, "!")) {
programMemoryParseCondition(pm, tok->astOperand1(), endTok, settings, !then);
} else if (then && Token::simpleMatch(tok, "&&")) {
programMemoryParseCondition(pm, tok->astOperand1(), endTok, settings, then);
programMemoryParseCondition(pm, tok->astOperand2(), endTok, settings, then);
} else if (!then && Token::simpleMatch(tok, "||")) {
programMemoryParseCondition(pm, tok->astOperand1(), endTok, settings, then);
后来无意发现了一个解决方法,加-I选项,可以找到需要的include文件之后,就好了。但是不知道具体的原因是什么。