Static Value-Flow Analysis
MTA.cpp
Go to the documentation of this file.
1 //===- MTA.h -- Analysis of multithreaded programs-------------//
2 //
3 // SVF: Static Value-Flow Analysis
4 //
5 // Copyright (C) <2013-> <Yulei Sui>
6 //
7 
8 // This program is free software: you can redistribute it and/or modify
9 // it under the terms of the GNU Affero General Public License as published by
10 // the Free Software Foundation, either version 3 of the License, or
11 // (at your option) any later version.
12 
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 // GNU Affero General Public License for more details.
17 
18 // You should have received a copy of the GNU Affero General Public License
19 // along with this program. If not, see <http://www.gnu.org/licenses/>.
20 //
21 //===----------------------------------------------------------------------===//
22 
23 
24 /*
25  * MTA.cpp
26  *
27  * Created on: May 14, 2014
28  * Author: Yulei Sui, Peng Di
29  */
30 
31 #include "Util/Options.h"
32 #include "MTA/MTA.h"
33 #include "MTA/MHP.h"
34 #include "MTA/TCT.h"
35 #include "MTA/LockAnalysis.h"
36 #include "MTA/MTAStat.h"
37 #include "WPA/Andersen.h"
38 #include "Util/SVFUtil.h"
39 
40 using namespace SVF;
41 using namespace SVFUtil;
42 
43 MTA::MTA() : tcg(nullptr), tct(nullptr), mhp(nullptr), lsa(nullptr)
44 {
45  stat = std::make_unique<MTAStat>();
46 }
47 
49 {
50  if (tcg)
51  delete tcg;
52  //if (tct)
53  // delete tct;
54  delete mhp;
55  delete lsa;
56 }
57 
62 {
63  mhp = computeMHP(pag->getModule());
65 
66  if(Options::RaceCheck())
67  detect(pag->getModule());
68 
69  return false;
70 }
71 
76 {
78  lsa->analyze();
79  return lsa;
80 }
81 
83 {
84 
85  DBOUT(DGENERAL, outs() << pasMsg("MTA analysis\n"));
86  DBOUT(DMTA, outs() << pasMsg("MTA analysis\n"));
87  SVFIR* pag = PAG::getPAG();
89  pta->getCallGraph()->dump("ptacg");
90 
91  DBOUT(DGENERAL, outs() << pasMsg("Build TCT\n"));
92  DBOUT(DMTA, outs() << pasMsg("Build TCT\n"));
93  DOTIMESTAT(double tctStart = stat->getClk());
94  tct = std::make_unique<TCT>(pta);
95  tcg = tct->getThreadCallGraph();
96  DOTIMESTAT(double tctEnd = stat->getClk());
97  DOTIMESTAT(stat->TCTTime += (tctEnd - tctStart) / TIMEINTERVAL);
98 
99  if (pta->printStat())
100  {
101  stat->performThreadCallGraphStat(tcg);
102  stat->performTCTStat(tct.get());
103  }
104 
105  tcg->dump("tcg");
106 
107  DBOUT(DGENERAL, outs() << pasMsg("MHP analysis\n"));
108  DBOUT(DMTA, outs() << pasMsg("MHP analysis\n"));
109 
110  DOTIMESTAT(double mhpStart = stat->getClk());
111  MHP* mhp = new MHP(tct.get());
112  mhp->analyze();
113  DOTIMESTAT(double mhpEnd = stat->getClk());
114  DOTIMESTAT(stat->MHPTime += (mhpEnd - mhpStart) / TIMEINTERVAL);
115 
116  DBOUT(DGENERAL, outs() << pasMsg("MHP analysis finish\n"));
117  DBOUT(DMTA, outs() << pasMsg("MHP analysis finish\n"));
118  return mhp;
119 }
120 
122 // * Check (1) write-read race
123 // * (2) write-write race (optional)
124 // * (3) read-read race (optional)
125 // * when two memory access may-happen in parallel and are not protected by the same lock
126 // * (excluding global constraints because they are initialized before running the main function)
127 // */
128 void MTA::detect(SVFModule* module)
129 {
130 
131  DBOUT(DGENERAL, outs() << pasMsg("Starting Race Detection\n"));
132 
133  Set<const LoadStmt*> loads;
134  Set<const StoreStmt*> stores;
135  SVFIR* pag = SVFIR::getPAG();
137 
138  // Add symbols for all of the functions and the instructions in them.
139  for (const SVFFunction* F : module->getFunctionSet())
140  {
141  // collect and create symbols inside the function body
142  for (const SVFBasicBlock* svfbb : F->getBasicBlockList())
143  {
144  for (const ICFGNode* icfgNode : svfbb->getICFGNodeList())
145  {
146  for(const SVFStmt* stmt : pag->getSVFStmtList(icfgNode))
147  {
148  if (const LoadStmt* l = SVFUtil::dyn_cast<LoadStmt>(stmt))
149  {
150  loads.insert(l);
151  }
152  else if (const StoreStmt* s = SVFUtil::dyn_cast<StoreStmt>(stmt))
153  {
154  stores.insert(s);
155  }
156  }
157  }
158  }
159  }
160 
161  for (Set<const LoadStmt*>::const_iterator lit = loads.begin(), elit = loads.end(); lit != elit; ++lit)
162  {
163  const LoadStmt* load = *lit;
164  for (Set<const StoreStmt*>::const_iterator sit = stores.begin(), esit = stores.end(); sit != esit; ++sit)
165  {
166  const StoreStmt* store = *sit;
167  if(load->getInst()==nullptr || store->getInst()==nullptr)
168  continue;
169  if(mhp->mayHappenInParallelInst(load->getICFGNode(),store->getICFGNode()) && pta->alias(load->getRHSVarID(),store->getLHSVarID()))
170  if(lsa->isProtectedByCommonLock(load->getICFGNode(),store->getICFGNode()) == false)
171  outs() << SVFUtil::bugMsg1("race pair(") << " store: " << store->toString() << ", load: " << load->toString() << SVFUtil::bugMsg1(")") << "\n";
172  }
173  }
174 }
175 
#define F(f)
#define DBOUT(TYPE, X)
LLVM debug macros, define type of your DBUG model of each pass.
Definition: SVFType.h:484
#define TIMEINTERVAL
Definition: SVFType.h:512
#define DMTA
Definition: SVFType.h:505
#define DGENERAL
Definition: SVFType.h:490
#define DOTIMESTAT(X)
Definition: SVFType.h:486
static AndersenWaveDiff * createAndersenWaveDiff(SVFIR *_pag)
Create an singleton instance directly instead of invoking llvm pass manager.
Definition: Andersen.h:408
NodeID getRHSVarID() const
NodeID getLHSVarID() const
virtual const std::string toString() const override
bool isProtectedByCommonLock(const ICFGNode *i1, const ICFGNode *i2)
Definition: MHP.h:46
void analyze()
Start analysis here.
Definition: MHP.cpp:62
TCT * getTCT() const
Get Thread Creation Tree.
Definition: MHP.h:80
virtual bool mayHappenInParallelInst(const ICFGNode *i1, const ICFGNode *i2)
Definition: MHP.cpp:556
virtual LockAnalysis * computeLocksets(TCT *tct)
Compute locksets.
Definition: MTA.cpp:75
ThreadCallGraph * tcg
Definition: MTA.h:89
std::unique_ptr< TCT > tct
Definition: MTA.h:90
virtual MHP * computeMHP(SVFModule *module)
Compute MHP.
Definition: MTA.cpp:82
virtual void detect(SVFModule *module)
Perform detection.
virtual ~MTA()
Destructor.
Definition: MTA.cpp:48
LockAnalysis * lsa
Definition: MTA.h:93
MHP * mhp
Definition: MTA.h:92
MTA()
Constructor.
Definition: MTA.cpp:43
std::unique_ptr< MTAStat > stat
Definition: MTA.h:91
virtual bool runOnModule(SVFIR *module)
We start the pass here.
Definition: MTA.cpp:61
static const Option< bool > RaceCheck
data race checker, Default: false
Definition: Options.h:260
void dump(const std::string &filename)
Dump the graph.
bool printStat()
Whether print statistics.
PTACallGraph * getCallGraph() const
Return call graph.
virtual AliasResult alias(const SVFValue *V1, const SVFValue *V2)=0
Interface exposed to users of our pointer analysis, given Value infos.
static SVFIR * getPAG(bool buildFromFile=false)
Singleton design here to make sure we only have one instance during any analysis.
Definition: SVFIR.h:115
SVFStmtList & getSVFStmtList(const ICFGNode *inst)
Given an instruction, get all its PAGEdges.
Definition: SVFIR.h:221
SVFModule * getModule()
Definition: SVFIR.h:161
const FunctionSetType & getFunctionSet() const
Definition: SVFModule.h:199
const SVFInstruction * getInst() const
Get/set methods for llvm instruction.
ICFGNode * getICFGNode() const
virtual const std::string toString() const override
Definition: TCT.h:154
std::string bugMsg1(const std::string &msg)
Definition: SVFUtil.cpp:81
std::string pasMsg(const std::string &msg)
Print each pass/phase message by converting a string into blue string output.
Definition: SVFUtil.cpp:99
std::ostream & outs()
Overwrite llvm::outs()
Definition: SVFUtil.h:50
for isBitcode
Definition: BasicTypes.h:68
std::unordered_set< Key, Hash, KeyEqual, Allocator > Set
Definition: GeneralType.h:96