Static Value-Flow Analysis
Loading...
Searching...
No Matches
Classes | Public Member Functions | Static Public Member Functions | Private Types | Static Private Member Functions | Private Attributes | List of all members
SVF::MTA Class Reference

#include <MTA.h>

Classes

struct  RaceClass
 
struct  RaceClassKey
 
struct  RaceOccurrence
 One occurrence of a memory access under one thread instance. More...
 
struct  RacePair
 A race pair: two statements that may race. More...
 

Public Member Functions

 MTA ()
 Constructor.
 
virtual ~MTA ()
 Destructor.
 
virtual bool runOnModule (SVFIR *module)
 We start the pass here.
 
virtual MHPcomputeMHP (TCT *tct)
 Compute MHP.
 
virtual LockAnalysiscomputeLocksets (TCT *tct)
 Compute locksets.
 
virtual void reportRaces ()
 Run the shared detector and print a race report.
 
MHPgetMHP ()
 
LockAnalysisgetLockAnalysis ()
 

Static Public Member Functions

static std::set< const SVFStmt * > detectRace (SVFIR *svfir, AndersenBase *pta, MHP *mhp, LockAnalysis *lockAnalysis, CallGraph *callGraph, std::set< RacePair > &outRacePairs)
 
static PointsTo getGlobalObjectVariables (SVFIR *svfir)
 Escape/points-to helpers for the shared detector.
 
static PointsTo getPointsToClosure (AndersenBase *pta, const PointsTo &pts)
 
static bool hasThreadFunctions (CallGraph *callGraph)
 

Private Types

using ObjectToRaceOccurrences = Map< NodeID, std::vector< size_t > >
 

Static Private Member Functions

static void collectRaceOccurrences (SVFIR *svfir, AndersenBase *pta, MHP *mhp, LockAnalysis *lockAnalysis, CallGraph *callGraph, const PointsTo &escapedObjects, std::vector< RaceOccurrence > &occurrences, ObjectToRaceOccurrences &objectToOccurrences)
 Helpers for the equivalence-class race detector.
 
static std::vector< RaceClassbuildRaceClasses (const std::vector< RaceOccurrence > &occurrences, const std::vector< size_t > &occurrenceIndices)
 
static void emitRacePairs (MHP *mhp, LockAnalysis *lockAnalysis, const std::vector< RaceOccurrence > &occurrences, const std::vector< RaceClass > &classes, std::set< RacePair > &outRacePairs)
 
static bool occurrencesRace (MHP *mhp, const RaceOccurrence &first, const RaceOccurrence &second)
 
static void commitRacePair (std::set< RacePair > &out, const RaceOccurrence &first, const RaceOccurrence &second)
 

Private Attributes

ThreadCallGraphtcg
 
std::unique_ptr< TCTtct
 
std::unique_ptr< MTAStatstat
 
MHPmhp
 
LockAnalysislsa
 

Detailed Description

Base data race detector

Definition at line 80 of file MTA.h.

Member Typedef Documentation

◆ ObjectToRaceOccurrences

Definition at line 179 of file MTA.h.

Constructor & Destructor Documentation

◆ MTA()

MTA::MTA ( )

Constructor.

Definition at line 53 of file MTA.cpp.

53 : tcg(nullptr), tct(nullptr), mhp(nullptr), lsa(nullptr)
54{
55 stat = std::make_unique<MTAStat>();
56}
ThreadCallGraph * tcg
Definition MTA.h:202
std::unique_ptr< TCT > tct
Definition MTA.h:203
LockAnalysis * lsa
Definition MTA.h:206
MHP * mhp
Definition MTA.h:205
std::unique_ptr< MTAStat > stat
Definition MTA.h:204

◆ ~MTA()

MTA::~MTA ( )
virtual

Destructor.

Definition at line 58 of file MTA.cpp.

59{
60 delete mhp;
61 delete lsa;
62}

Member Function Documentation

◆ buildRaceClasses()

std::vector< MTA::RaceClass > MTA::buildRaceClasses ( const std::vector< RaceOccurrence > &  occurrences,
const std::vector< size_t > &  occurrenceIndices 
)
staticprivate

Definition at line 289 of file MTA.cpp.

292{
293 std::vector<RaceClass> classes;
296 {
297 const RaceOccurrence& occurrence = occurrences[occurrenceIndex];
298 const RaceClassKey key
299 {
300 occurrence.tid, occurrence.isStore, occurrence.interleaving,
301 occurrence.locked,
302 occurrence.locked ? occurrence.node->getId() : 0};
303 const auto found = keyToClass.find(key);
304 if (found == keyToClass.end())
305 {
306 keyToClass[key] = classes.size();
307 classes.push_back(
308 {
309 occurrence.isStore, occurrence.locked, occurrenceIndex,
310 {occurrenceIndex}});
311 }
312 else
313 classes[found->second].members.push_back(occurrenceIndex);
314 }
315 return classes;
316}
llvm::IRBuilder IRBuilder
Definition BasicTypes.h:76

◆ collectRaceOccurrences()

void MTA::collectRaceOccurrences ( SVFIR svfir,
AndersenBase pta,
MHP mhp,
LockAnalysis lockAnalysis,
CallGraph callGraph,
const PointsTo escapedObjects,
std::vector< RaceOccurrence > &  occurrences,
ObjectToRaceOccurrences objectToOccurrences 
)
staticprivate

Helpers for the equivalence-class race detector.

Definition at line 229 of file MTA.cpp.

235{
236 for (const auto& item : *callGraph)
237 {
238 const FunObjVar* fun = item.second->getFunction();
239 if (!fun || !fun->hasBasicBlock())
240 continue;
241 for (auto bbIt : *fun)
242 for (const ICFGNode* node : bbIt.second->getICFGNodeList())
243 {
245 mhp->getThreadSummary(node);
246 if (threadSummary == nullptr)
247 continue;
248 for (const SVFStmt* stmt : svfir->getSVFStmtList(node))
249 {
251 bool isStore;
252 if (const LoadStmt* load = SVFUtil::dyn_cast<LoadStmt>(stmt))
253 {
254 accessedPtr = load->getRHSVarID();
255 isStore = false;
256 }
257 else if (const StoreStmt* store =
258 SVFUtil::dyn_cast<StoreStmt>(stmt))
259 {
260 accessedPtr = store->getLHSVarID();
261 isStore = true;
262 }
263 else
264 continue;
265
268 if (objects.empty())
269 continue;
270
271 const bool locked =
272 lockAnalysis->isProtectedByCommonLock(node, node);
273 const size_t firstNewOccurrence = occurrences.size();
274 for (const auto& tidAndInterleaving :
275 threadSummary->interleavingByTid)
277 {
278 stmt, node, isStore, tidAndInterleaving.first,
279 &tidAndInterleaving.second, locked});
280 for (NodeID object : objects)
282 index < occurrences.size(); ++index)
284 }
285 }
286 }
287}
for(i=0;a &&(i<(size_t) count);i++)
Definition cJSON.cpp:2569
int index
Definition cJSON.h:170
cJSON * item
Definition cJSON.h:222
const PointsTo & getPts(NodeID id) override
bool hasBasicBlock() const
bool isProtectedByCommonLock(const ICFGNode *i1, const ICFGNode *i2)
const NodeThreadSummary * getThreadSummary(const ICFGNode *inst) const
Definition MHP.cpp:257
u32_t NodeID
Definition GeneralType.h:76

◆ commitRacePair()

void MTA::commitRacePair ( std::set< RacePair > &  out,
const RaceOccurrence first,
const RaceOccurrence second 
)
staticprivate

Definition at line 207 of file MTA.cpp.

210{
211 out.emplace(first.stmt, second.stmt);
212}

◆ computeLocksets()

LockAnalysis * MTA::computeLocksets ( TCT tct)
virtual

Compute locksets.

Compute lock sets

Definition at line 106 of file MTA.cpp.

107{
109 lsa->analyze(PAG::getPAG()->getICFG(), const_cast<CallGraph*>(PAG::getPAG()->getCallGraph()));
110 return lsa;
111}
void analyze(ICFGGraph icfg, CGGraph cg)
static SVFIR * getPAG(bool buildFromFile=false)
Singleton design here to make sure we only have one instance during any analysis.
Definition SVFIR.h:120

◆ computeMHP()

MHP * MTA::computeMHP ( TCT tct)
virtual

Compute MHP.

Definition at line 113 of file MTA.cpp.

114{
115 DBOUT(DGENERAL, outs() << pasMsg("MHP analysis\n"));
116 DBOUT(DMTA, outs() << pasMsg("MHP analysis\n"));
117
118 DOTIMESTAT(double mhpStart = stat->getClk());
119 std::unique_ptr<MHP> mhp = MHP::create(
120 tct, PAG::getPAG()->getICFG(),
121 const_cast<CallGraph*>(PAG::getPAG()->getCallGraph()));
122 mhp->analyze(PAG::getPAG()->getICFG(), const_cast<CallGraph*>(PAG::getPAG()->getCallGraph()));
123 DOTIMESTAT(double mhpEnd = stat->getClk());
124 DOTIMESTAT(stat->MHPTime += (mhpEnd - mhpStart) / TIMEINTERVAL);
125
126 DBOUT(DGENERAL, outs() << pasMsg("MHP analysis finish\n"));
127 DBOUT(DMTA, outs() << pasMsg("MHP analysis finish\n"));
128 return mhp.release();
129}
#define DBOUT(TYPE, X)
LLVM debug macros, define type of your DBUG model of each pass.
Definition SVFType.h:576
#define TIMEINTERVAL
Definition SVFType.h:604
#define DMTA
Definition SVFType.h:597
#define DGENERAL
Definition SVFType.h:582
#define DOTIMESTAT(X)
Definition SVFType.h:578
void analyze(ICFGGraph icfg, CGGraph cg)
Definition MHP.cpp:115
static std::unique_ptr< MHP > create(TCT *t, ICFGGraph icfg, CGGraph cg, StateRepresentation representation=StateRepresentation::MaterializedContexts)
Construct MHP and initialize its graph-dependent ForkJoinAnalysis.
Definition MHP.h:646
std::string pasMsg(const std::string &msg)
Print each pass/phase message by converting a string into blue string output.
Definition SVFUtil.cpp:105
std::ostream & outs()
Overwrite llvm::outs()
Definition SVFUtil.h:52

◆ detectRace()

std::set< const SVFStmt * > MTA::detectRace ( SVFIR svfir,
AndersenBase pta,
MHP mhp,
LockAnalysis lockAnalysis,
CallGraph callGraph,
std::set< RacePair > &  outRacePairs 
)
static

Shared equivalence-class race detector (used by both MTA::reportRaces and the SlicedMTA pipeline). Returns the racy statements and fills outRacePairs.

Definition at line 372 of file MTA.cpp.

376{
377
378 outRacePairs.clear();
379 std::set<const SVFStmt*> bugStmts;
380
381 // Escape set: objects shared across threads. Seed from globals + the actual
382 // argument at each fork site (the spawner's value, which a spawnee-formal
383 // closure can miss), then take the transitive points-to closure.
385 if (ThreadCallGraph* tcg = SVFUtil::dyn_cast<ThreadCallGraph>(callGraph))
386 {
387 const ThreadAPI* tapi = tcg->getThreadAPI();
388 for (auto it = tcg->forksitesBegin(), eit = tcg->forksitesEnd(); it != eit; ++it)
389 if (const CallICFGNode* cs = SVFUtil::dyn_cast<CallICFGNode>(*it))
390 if (const ValVar* actual = tapi->getActualParmAtForkSite(cs))
391 seed |= pta->getPts(actual->getId());
392 }
394
395 std::vector<RaceOccurrence> occurrences;
398 svfir, pta, mhp, lockAnalysis, callGraph, escSet,
400
401 // Within each object, occurrences sharing the race predicate's inputs (tid,
402 // interleaving, isStore, lock sig) race the same partners, so collapse into a
403 // class and judge C2/C3/C4 once per class pair -- O(classes^2) not O(occ^2).
404 for (const auto& objectAndOccs : objectToOccurrences)
405 {
406 const std::vector<RaceClass> classes =
409 mhp, lockAnalysis, occurrences, classes, outRacePairs);
410 }
411
412 for (const RacePair& pair : outRacePairs)
413 {
414 bugStmts.insert(pair.stmt1);
415 bugStmts.insert(pair.stmt2);
416 }
417 return bugStmts;
418}
static void emitRacePairs(MHP *mhp, LockAnalysis *lockAnalysis, const std::vector< RaceOccurrence > &occurrences, const std::vector< RaceClass > &classes, std::set< RacePair > &outRacePairs)
Definition MTA.cpp:318
static std::vector< RaceClass > buildRaceClasses(const std::vector< RaceOccurrence > &occurrences, const std::vector< size_t > &occurrenceIndices)
Definition MTA.cpp:289
static PointsTo getGlobalObjectVariables(SVFIR *svfir)
Escape/points-to helpers for the shared detector.
Definition MTA.cpp:132
Map< NodeID, std::vector< size_t > > ObjectToRaceOccurrences
Definition MTA.h:179
static void collectRaceOccurrences(SVFIR *svfir, AndersenBase *pta, MHP *mhp, LockAnalysis *lockAnalysis, CallGraph *callGraph, const PointsTo &escapedObjects, std::vector< RaceOccurrence > &occurrences, ObjectToRaceOccurrences &objectToOccurrences)
Helpers for the equivalence-class race detector.
Definition MTA.cpp:229
static PointsTo getPointsToClosure(AndersenBase *pta, const PointsTo &pts)
Definition MTA.cpp:161
CallSiteSet::const_iterator forksitesEnd() const
CallSiteSet::const_iterator forksitesBegin() const
Fork sites iterators.
ThreadAPI * getThreadAPI() const
Thread API.

◆ emitRacePairs()

void MTA::emitRacePairs ( MHP mhp,
LockAnalysis lockAnalysis,
const std::vector< RaceOccurrence > &  occurrences,
const std::vector< RaceClass > &  classes,
std::set< RacePair > &  outRacePairs 
)
staticprivate

Definition at line 318 of file MTA.cpp.

323{
324 for (size_t firstIndex = 0; firstIndex < classes.size(); ++firstIndex)
325 for (size_t secondIndex = firstIndex;
326 secondIndex < classes.size(); ++secondIndex)
327 {
328 const RaceClass& firstClass = classes[firstIndex];
329 const RaceClass& secondClass = classes[secondIndex];
330 if (!firstClass.isStore && !secondClass.isStore)
331 continue;
332
333 const RaceOccurrence& firstRepresentative =
334 occurrences[firstClass.representative];
335 const RaceOccurrence& secondRepresentative =
336 occurrences[secondClass.representative];
337 if (!occurrencesRace(
339 continue;
340
341 if (firstIndex != secondIndex)
342 {
343 if (firstClass.locked && secondClass.locked &&
344 lockAnalysis->isProtectedByCommonLock(
346 continue;
347 for (size_t memberIndex : firstClass.members)
348 for (size_t otherIndex : secondClass.members)
351 }
352 else
353 {
354 const std::vector<size_t>& members = firstClass.members;
355 if (firstClass.locked &&
356 lockAnalysis->isProtectedByCommonLock(
358 continue;
359 for (size_t firstPosition = 0;
360 firstPosition < members.size(); ++firstPosition)
361 for (size_t secondPosition = firstPosition;
362 secondPosition < members.size(); ++secondPosition)
365 occurrences[members[secondPosition]]);
366 }
367 }
368}
static bool occurrencesRace(MHP *mhp, const RaceOccurrence &first, const RaceOccurrence &second)
Definition MTA.cpp:197
static void commitRacePair(std::set< RacePair > &out, const RaceOccurrence &first, const RaceOccurrence &second)
Definition MTA.cpp:207

◆ getGlobalObjectVariables()

PointsTo MTA::getGlobalObjectVariables ( SVFIR svfir)
static

Escape/points-to helpers for the shared detector.

Definition at line 132 of file MTA.cpp.

133{
136
137 for (const SVFStmt* stmt : globalICFGNode->getSVFStmts())
138 {
139 const AddrStmt* addrStmt = SVFUtil::dyn_cast<AddrStmt>(stmt);
140 if (addrStmt != nullptr)
141 {
142 const GlobalValVar* globalVar =
143 SVFUtil::dyn_cast<GlobalValVar>(addrStmt->getLHSVar());
144 if (globalVar != nullptr)
145 {
146 globalObjVars.set(addrStmt->getRHSVarID());
147 }
148 }
149 }
150
151 return globalObjVars;
152}
GlobalICFGNode * getGlobalICFGNode() const
Definition ICFG.h:244
ICFG * getICFG() const
Definition SVFIR.h:231

◆ getLockAnalysis()

LockAnalysis * SVF::MTA::getLockAnalysis ( )
inline

Definition at line 105 of file MTA.h.

106 {
107 return lsa;
108 }

◆ getMHP()

MHP * SVF::MTA::getMHP ( )
inline

Definition at line 100 of file MTA.h.

101 {
102 return mhp;
103 }

◆ getPointsToClosure()

PointsTo MTA::getPointsToClosure ( AndersenBase pta,
const PointsTo pts 
)
static

Definition at line 161 of file MTA.cpp.

162{
163 SVFIR* pag = pta->getPAG();
165 std::deque<NodeID> worklist;
166 for (NodeID pt : pts)
167 {
168 worklist.push_back(pt);
169 }
170
171 while (!worklist.empty())
172 {
173 NodeID obj = worklist.front();
174 worklist.pop_front();
175
176 for (NodeID target : pta->getPts(obj)) // points-to
177 if (!ptsClosure.test(target))
178 {
179 ptsClosure.set(target);
180 worklist.push_back(target);
181 }
182
183 if (pag->getBaseObject(obj) != nullptr) // containment (object nodes only)
184 for (NodeID field : pta->getAllFieldsObjVars(pta->getBaseObjVarID(obj)))
185 if (!ptsClosure.test(field))
186 {
187 ptsClosure.set(field);
188 worklist.push_back(field);
189 }
190 }
191
192 return ptsClosure;
193}
if(prebuffer< 0)
Definition cJSON.cpp:1269
SVFIR * getPAG() const
void set(u32_t n)
Inserts n in the set.
Definition PointsTo.cpp:157
const BaseObjVar * getBaseObject(NodeID id) const
Definition SVFIR.h:498

◆ hasThreadFunctions()

bool MTA::hasThreadFunctions ( CallGraph callGraph)
static

Whether the program has any thread (fork-target) function reachable via a fork edge.

Definition at line 1326 of file MTA.cpp.

1327{
1328 for (CallGraph::iterator it = callGraph->begin(), eit = callGraph->end();
1329 it != eit; ++it)
1330 {
1331 const CallGraphNode* node = it->second;
1332 for (const CallGraphEdge* edge : node->getOutEdges())
1333 {
1334 if (edge->getEdgeKind() == CallGraphEdge::TDForkEdge &&
1335 edge->getDstNode()->getFunction() != nullptr)
1336 {
1337 return true;
1338 }
1339 }
1340 }
1341 return false;
1342}
iterator begin()
Iterators.
IDToNodeMapTy::iterator iterator
Node Iterators.

◆ occurrencesRace()

bool MTA::occurrencesRace ( MHP mhp,
const RaceOccurrence first,
const RaceOccurrence second 
)
staticprivate

Definition at line 197 of file MTA.cpp.

199{
200 if (first.tid != second.tid)
201 return first.interleaving->test(second.tid) &&
202 second.interleaving->test(first.tid);
203 return mhp->getTCT()->getTCTNode(first.tid)->isMultiforked();
204}
TCT * getTCT() const
Get Thread Creation Tree.
Definition MHP.h:110
bool isMultiforked() const
Definition TCT.h:122
TCTNode * getTCTNode(NodeID id) const
Get TCT node.
Definition TCT.h:209

◆ reportRaces()

void MTA::reportRaces ( )
virtual

Run the shared detector and print a race report.

Definition at line 420 of file MTA.cpp.

421{
422 DBOUT(DGENERAL, outs() << pasMsg("Starting Race Detection\n"));
423
424 SVFIR* pag = SVFIR::getPAG();
426 CallGraph* callGraph = pta->getCallGraph();
427
428 // Shared equivalence-class detector (the same one the slicing pipeline uses),
429 // run over the Andersen pre-analysis with this MTA's MHP/lock results.
430 std::set<RacePair> racePairs;
431 detectRace(pag, pta, mhp, lsa, callGraph, racePairs);
432
433 for (const RacePair& rp : racePairs)
434 outs() << SVFUtil::bugMsg1("race pair(") << " stmt1: " << rp.stmt1->toString()
435 << ", stmt2: " << rp.stmt2->toString() << SVFUtil::bugMsg1(")") << "\n";
436}
static AndersenWaveDiff * createAndersenWaveDiff(SVFIR *_pag)
Create an singleton instance directly instead of invoking llvm pass manager.
Definition Andersen.h:408
static std::set< const SVFStmt * > detectRace(SVFIR *svfir, AndersenBase *pta, MHP *mhp, LockAnalysis *lockAnalysis, CallGraph *callGraph, std::set< RacePair > &outRacePairs)
Definition MTA.cpp:372
CallGraph * getCallGraph() const
Return call graph.
std::string bugMsg1(const std::string &msg)
Definition SVFUtil.cpp:87

◆ runOnModule()

bool MTA::runOnModule ( SVFIR pag)
virtual

We start the pass here.

Perform data race detection

Definition at line 67 of file MTA.cpp.

68{
69 DBOUT(DGENERAL, outs() << pasMsg("MTA analysis\n"));
70 DBOUT(DMTA, outs() << pasMsg("MTA analysis\n"));
71
74 pta->getCallGraph()->dump("ptacg");
75 pag->getICFG()->updateCallGraph(pta->getCallGraph());
76
77 DBOUT(DGENERAL, outs() << pasMsg("Build TCT\n"));
78 DBOUT(DMTA, outs() << pasMsg("Build TCT\n"));
79 DOTIMESTAT(double tctStart = stat->getClk());
80 tct = TCT::create(pta);
81 tcg = tct->getThreadCallGraph();
82 DOTIMESTAT(double tctEnd = stat->getClk());
83 DOTIMESTAT(stat->TCTTime += (tctEnd - tctStart) / TIMEINTERVAL);
84
85 if (pta->printStat())
86 {
87 stat->performThreadCallGraphStat(tcg);
88 stat->performTCTStat(tct.get());
89 }
90
92 tcg->dump("tcg");
93
94 mhp = computeMHP(tct.get());
95 lsa = computeLocksets(tct.get());
96
97 // MTA's only client is race detection; always report.
99
100 return false;
101}
void dump(const std::string &filename)
Dump the graph.
void updateCallGraph(CallGraph *callgraph)
update ICFG for indirect calls
Definition ICFG.cpp:428
virtual LockAnalysis * computeLocksets(TCT *tct)
Compute locksets.
Definition MTA.cpp:106
virtual MHP * computeMHP(TCT *tct)
Compute MHP.
Definition MTA.cpp:113
virtual void reportRaces()
Run the shared detector and print a race report.
Definition MTA.cpp:420
static const Option< bool > DumpMTAGraphs
MTA: dump the pointer-analysis and thread call graphs (ptacg/tcg.dot), Default: false.
Definition Options.h:258
bool printStat()
Whether print statistics.
static std::unique_ptr< TCT > create(PointerAnalysis *p)
Construct and build a TCT with the command-line context bound.
Definition TCT.cpp:41

Member Data Documentation

◆ lsa

LockAnalysis* SVF::MTA::lsa
private

Definition at line 206 of file MTA.h.

◆ mhp

MHP* SVF::MTA::mhp
private

Definition at line 205 of file MTA.h.

◆ stat

std::unique_ptr<MTAStat> SVF::MTA::stat
private

Definition at line 204 of file MTA.h.

◆ tcg

ThreadCallGraph* SVF::MTA::tcg
private

Definition at line 202 of file MTA.h.

◆ tct

std::unique_ptr<TCT> SVF::MTA::tct
private

Definition at line 203 of file MTA.h.


The documentation for this class was generated from the following files: