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

#include <ThreadAPI.h>

Classes

struct  ForkJoinAliasCache
 If fork join the same thread. More...
 

Public Types

enum  TD_TYPE {
  TD_DUMMY = 0 , TD_FORK , TD_JOIN , TD_DETACH ,
  TD_ACQUIRE , TD_TRY_ACQUIRE , TD_RELEASE , TD_EXIT ,
  TD_CANCEL , TD_COND_WAIT , TD_COND_SIGNAL , TD_COND_BROADCAST ,
  TD_MUTEX_INI , TD_MUTEX_DESTROY , TD_CONDVAR_INI , TD_CONDVAR_DESTROY ,
  TD_BAR_INIT , TD_BAR_WAIT , HARE_PAR_FOR
}
 
typedef Map< std::string, TD_TYPETDAPIMap
 

Public Member Functions

const ValVargetForkedThread (const CallICFGNode *inst) const
 Return arguments/attributes of pthread_create / hare_parallel_for.
 
const ValVargetForkedFun (const CallICFGNode *inst) const
 
const ValVargetActualParmAtForkSite (const CallICFGNode *inst) const
 
const SVFVargetFormalParmOfForkedFun (const FunObjVar *F) const
 Return the formal parm of forked function (the first arg in pthread)
 
bool isTDFork (const CallICFGNode *inst) const
 Return true if this call create a new thread.
 
bool isTDJoin (const CallICFGNode *inst) const
 Return true if this call wait for a worker thread.
 
const SVFVargetJoinedThread (const CallICFGNode *inst) const
 Return arguments/attributes of pthread_join.
 
const SVFVargetRetParmAtJoinedSite (const CallICFGNode *inst) const
 
bool isAliasedForkJoin (PointerAnalysis *pta, const SVFVar *forkArg, const SVFVar *joinArg) const
 
bool isAliasedForkJoin (PointerAnalysis *pta, const SVFVar *forkArg, const SVFVar *joinArg, ForkJoinAliasCache &cache) const
 
bool isTDExit (const CallICFGNode *inst) const
 Return true if this call exits/terminate a thread.
 
bool isTDAcquire (const CallICFGNode *inst) const
 Return true if this call acquire a lock.
 
bool isTDRelease (const CallICFGNode *inst) const
 Return true if this call release a lock.
 
const SVFVargetLockVal (const ICFGNode *inst) const
 Return lock value.
 
bool isTDBarWait (const CallICFGNode *inst) const
 Return true if this call waits for a barrier.
 
void performAPIStat ()
 
void statInit (Map< std::string, u32_t > &tdAPIStatMap)
 

Static Public Member Functions

static ThreadAPIgetThreadAPI ()
 Return a static reference.
 
static void destroy ()
 

Private Member Functions

 ThreadAPI ()
 Constructor.
 
void init ()
 Initialize the map.
 
TD_TYPE getType (const FunObjVar *F) const
 Get the function type if it is a threadAPI function.
 

Private Attributes

TDAPIMap tdAPIMap
 API map, from a string to threadAPI type.
 

Static Private Attributes

static ThreadAPItdAPI = nullptr
 Static reference.
 

Detailed Description

Definition at line 49 of file ThreadAPI.h.

Member Typedef Documentation

◆ TDAPIMap

Definition at line 76 of file ThreadAPI.h.

Member Enumeration Documentation

◆ TD_TYPE

Enumerator
TD_DUMMY 
TD_FORK 

dummy type

TD_JOIN 

create a new thread

TD_DETACH 

wait for a thread to join

TD_ACQUIRE 

detach a thread directly instead wait for it to join

TD_TRY_ACQUIRE 

acquire a lock

TD_RELEASE 

try to acquire a lock

TD_EXIT 

release a lock

TD_CANCEL 

exit/kill a thread

TD_COND_WAIT 

cancel a thread by another

TD_COND_SIGNAL 

wait a condition

TD_COND_BROADCAST 

signal a condition

TD_MUTEX_INI 

broadcast a condition

TD_MUTEX_DESTROY 

initial a mutex variable

TD_CONDVAR_INI 

initial a mutex variable

TD_CONDVAR_DESTROY 

initial a mutex variable

TD_BAR_INIT 

initial a mutex variable

TD_BAR_WAIT 

Barrier init.

HARE_PAR_FOR 

Barrier wait.

Definition at line 53 of file ThreadAPI.h.

54 {
55 TD_DUMMY = 0,
56 TD_FORK,
57 TD_JOIN,
58 TD_DETACH,
62 TD_EXIT,
63 TD_CANCEL,
74 };
@ TD_COND_SIGNAL
wait a condition
Definition ThreadAPI.h:65
@ TD_DETACH
wait for a thread to join
Definition ThreadAPI.h:58
@ TD_CONDVAR_INI
initial a mutex variable
Definition ThreadAPI.h:69
@ HARE_PAR_FOR
Barrier wait.
Definition ThreadAPI.h:73
@ TD_BAR_INIT
initial a mutex variable
Definition ThreadAPI.h:71
@ TD_ACQUIRE
detach a thread directly instead wait for it to join
Definition ThreadAPI.h:59
@ TD_MUTEX_DESTROY
initial a mutex variable
Definition ThreadAPI.h:68
@ TD_FORK
dummy type
Definition ThreadAPI.h:56
@ TD_CONDVAR_DESTROY
initial a mutex variable
Definition ThreadAPI.h:70
@ TD_JOIN
create a new thread
Definition ThreadAPI.h:57
@ TD_BAR_WAIT
Barrier init.
Definition ThreadAPI.h:72
@ TD_COND_BROADCAST
signal a condition
Definition ThreadAPI.h:66
@ TD_COND_WAIT
cancel a thread by another
Definition ThreadAPI.h:64
@ TD_TRY_ACQUIRE
acquire a lock
Definition ThreadAPI.h:60
@ TD_MUTEX_INI
broadcast a condition
Definition ThreadAPI.h:67
@ TD_RELEASE
try to acquire a lock
Definition ThreadAPI.h:61
@ TD_EXIT
release a lock
Definition ThreadAPI.h:62
@ TD_CANCEL
exit/kill a thread
Definition ThreadAPI.h:63

Constructor & Destructor Documentation

◆ ThreadAPI()

SVF::ThreadAPI::ThreadAPI ( )
inlineprivate

Constructor.

Definition at line 83 of file ThreadAPI.h.

84 {
85 init();
86 }
void init()
Initialize the map.

Member Function Documentation

◆ destroy()

static void SVF::ThreadAPI::destroy ( )
inlinestatic

Definition at line 108 of file ThreadAPI.h.

109 {
110 if(tdAPI != nullptr)
111 {
112 delete tdAPI;
113 tdAPI = nullptr;
114 }
115 }
static ThreadAPI * tdAPI
Static reference.
Definition ThreadAPI.h:92

◆ getActualParmAtForkSite()

const ValVar * ThreadAPI::getActualParmAtForkSite ( const CallICFGNode inst) const

Return the forth argument of the call, Note that, it is the sole argument of start routine ( a void* pointer )

Definition at line 234 of file ThreadAPI.cpp.

235{
236 assert(isTDFork(inst) && "not a thread fork function!");
237 return inst->getArgument(3);
238}
const ValVar * getArgument(u32_t ArgNo) const
Parameter operations.
Definition ICFGNode.h:483
bool isTDFork(const CallICFGNode *inst) const
Return true if this call create a new thread.
llvm::IRBuilder IRBuilder
Definition BasicTypes.h:76

◆ getForkedFun()

const ValVar * ThreadAPI::getForkedFun ( const CallICFGNode inst) const

Return the third argument of the call, Note that, it could be function type or a void* pointer

Definition at line 226 of file ThreadAPI.cpp.

227{
228 assert(isTDFork(inst) && "not a thread fork function!");
229 return inst->getArgument(2);
230}

◆ getForkedThread()

const ValVar * ThreadAPI::getForkedThread ( const CallICFGNode inst) const

Return arguments/attributes of pthread_create / hare_parallel_for.

Return the first argument of the call, Note that, it is the pthread_t pointer

Definition at line 220 of file ThreadAPI.cpp.

221{
222 assert(isTDFork(inst) && "not a thread fork function!");
223 return inst->getArgument(0);
224}

◆ getFormalParmOfForkedFun()

const SVFVar * ThreadAPI::getFormalParmOfForkedFun ( const FunObjVar F) const

Return the formal parm of forked function (the first arg in pthread)

Definition at line 240 of file ThreadAPI.cpp.

241{
242 assert(PAG::getPAG()->hasFunArgsList(F) && "forked function has no args list!");
244 // in pthread, forked functions are of type void *()(void *args)
245 assert(funArgList.size() == 1 && "num of pthread forked function args is not 1!");
246 return funArgList[0];
247}
const ValVarList & getFunArgsList(const FunObjVar *func) const
Get function arguments list.
Definition SVFIR.h:378
std::vector< const ValVar * > ValVarList
Definition SVFIR.h:60
static SVFIR * getPAG(bool buildFromFile=false)
Singleton design here to make sure we only have one instance during any analysis.
Definition SVFIR.h:120

◆ getJoinedThread()

const SVFVar * ThreadAPI::getJoinedThread ( const CallICFGNode inst) const

Return arguments/attributes of pthread_join.

Return the first argument of the call, Note that, it is the pthread_t pointer

Definition at line 263 of file ThreadAPI.cpp.

264{
265 assert(isTDJoin(cs) && "not a thread join function!");
266 return cs->getArgument(0);
267}
bool isTDJoin(const CallICFGNode *inst) const
Return true if this call wait for a worker thread.

◆ getLockVal()

const SVFVar * ThreadAPI::getLockVal ( const ICFGNode inst) const

Return lock value.

First argument of pthread_mutex_lock/pthread_mutex_unlock

Definition at line 255 of file ThreadAPI.cpp.

256{
257 const CallICFGNode* call = SVFUtil::dyn_cast<CallICFGNode>(cs);
258 assert(call && "not a call ICFGNode?");
259 assert((isTDAcquire(call) || isTDRelease(call)) && "not a lock acquire or release function");
260 return call->getArgument(0);
261}
bool isTDRelease(const CallICFGNode *inst) const
Return true if this call release a lock.
bool isTDAcquire(const CallICFGNode *inst) const
Return true if this call acquire a lock.

◆ getRetParmAtJoinedSite()

const SVFVar * ThreadAPI::getRetParmAtJoinedSite ( const CallICFGNode inst) const

Return the send argument of the call, Note that, it is the pthread_t pointer

Definition at line 249 of file ThreadAPI.cpp.

250{
251 assert(isTDJoin(inst) && "not a thread join function!");
252 return inst->getArgument(1);
253}

◆ getThreadAPI()

static ThreadAPI * SVF::ThreadAPI::getThreadAPI ( )
inlinestatic

Return a static reference.

Definition at line 99 of file ThreadAPI.h.

100 {
101 if(tdAPI == nullptr)
102 {
103 tdAPI = new ThreadAPI();
104 }
105 return tdAPI;
106 }
ThreadAPI()
Constructor.
Definition ThreadAPI.h:83

◆ getType()

ThreadAPI::TD_TYPE ThreadAPI::getType ( const FunObjVar F) const
private

Get the function type if it is a threadAPI function.

Definition at line 178 of file ThreadAPI.cpp.

179{
180 if(F)
181 {
182 TDAPIMap::const_iterator it= tdAPIMap.find(F->getName());
183 if(it != tdAPIMap.end())
184 return it->second;
185 }
186 return TD_DUMMY;
187}
virtual const std::string & getName() const
Definition SVFValue.h:184
TDAPIMap tdAPIMap
API map, from a string to threadAPI type.
Definition ThreadAPI.h:80

◆ init()

void ThreadAPI::init ( )
private

Initialize the map.

initialize the map

Definition at line 147 of file ThreadAPI.cpp.

148{
151 t_seen.insert(TD_DUMMY);
152 for(const ei_pair *p= ei_pairs; p->n; ++p)
153 {
154 if(p->t != prev_t)
155 {
156 //This will detect if you move an entry to another block
157 // but forget to change the type.
158 if(t_seen.count(p->t))
159 {
160 fputs(p->n, stderr);
161 putc('\n', stderr);
162 assert(!"ei_pairs not grouped by type");
163 }
164 t_seen.insert(p->t);
165 prev_t= p->t;
166 }
167 if(tdAPIMap.count(p->n))
168 {
169 fputs(p->n, stderr);
170 putc('\n', stderr);
171 assert(!"duplicate name in ei_pairs");
172 }
173 tdAPIMap[p->n]= p->t;
174 }
175}
static const ei_pair ei_pairs[]
cJSON * p
Definition cJSON.cpp:2559

◆ isAliasedForkJoin() [1/2]

bool ThreadAPI::isAliasedForkJoin ( PointerAnalysis pta,
const SVFVar forkArg,
const SVFVar joinArg 
) const

If fork join the same thread

  • forkArg is the value of the first argument of pthread_create (a pointer to pthread_t)
  • joinArg is the value first argument of pthread_join (pthread_t)

Definition at line 276 of file ThreadAPI.cpp.

277{
278 ForkJoinAliasCache cache;
279 return isAliasedForkJoin(pta, forkArg, joinArg, cache);
280}
bool isAliasedForkJoin(PointerAnalysis *pta, const SVFVar *forkArg, const SVFVar *joinArg) const

◆ isAliasedForkJoin() [2/2]

bool ThreadAPI::isAliasedForkJoin ( PointerAnalysis pta,
const SVFVar forkArg,
const SVFVar joinArg,
ForkJoinAliasCache cache 
) const

Definition at line 282 of file ThreadAPI.cpp.

284{
285 // pthread_create receives &t (a pointer to the pthread_t object), so the
286 // forked thread is identified by the pthread_t object(s) in pts(forkArg).
287 const PointsTo& forkObjs = pta->getPts(forkArg->getId());
289 if (forkObjs.toNodeBS().intersects(joinedObjs))
290 return true;
291
292 // (1) Direct case: the join handle is itself a pointer to the same pthread_t.
293 for (NodeID o : forkObjs)
294 if (pta->alias(o, joinArg->getId()))
295 return true;
296
297 // (2) General case: pthread_t is usually a scalar, so pthread_join receives
298 // the pthread_t *value*, which carries no points-to of its own. That
299 // value is loaded from the pthread_t storage, possibly after flowing
300 // through copies / phis / casts / by-value parameter passing. We
301 // backward value-track the join handle to every load it may originate
302 // from and check whether the loaded-from storage is the fork's pthread_t
303 // object. This covers the common shapes soundly (an over-approximate
304 // match only adds a sound join-related value flow).
305 return false;
306}
if(prebuffer< 0)
Definition cJSON.cpp:1269
return(char *) p.buffer
#define true
Definition cJSON.cpp:65
virtual const PointsTo & getPts(NodeID ptr)=0
Get points-to targets of a pointer. It needs to be implemented in child class.
u32_t NodeID
Definition GeneralType.h:76

◆ isTDAcquire()

bool ThreadAPI::isTDAcquire ( const CallICFGNode inst) const

Return true if this call acquire a lock.

Definition at line 204 of file ThreadAPI.cpp.

205{
206 return getType(inst->getCalledFunction()) == TD_ACQUIRE;
207}
const FunObjVar * getCalledFunction() const
Definition ICFGNode.h:501
TD_TYPE getType(const FunObjVar *F) const
Get the function type if it is a threadAPI function.

◆ isTDBarWait()

bool ThreadAPI::isTDBarWait ( const CallICFGNode inst) const

Return true if this call waits for a barrier.

Definition at line 214 of file ThreadAPI.cpp.

215{
216 return getType(inst->getCalledFunction()) == TD_BAR_WAIT;
217}

◆ isTDExit()

bool ThreadAPI::isTDExit ( const CallICFGNode inst) const

Return true if this call exits/terminate a thread.

Definition at line 199 of file ThreadAPI.cpp.

200{
201 return getType(inst->getCalledFunction()) == TD_EXIT;
202}

◆ isTDFork()

bool ThreadAPI::isTDFork ( const CallICFGNode inst) const

Return true if this call create a new thread.

Definition at line 189 of file ThreadAPI.cpp.

190{
191 return getType(inst->getCalledFunction()) == TD_FORK;
192}

◆ isTDJoin()

bool ThreadAPI::isTDJoin ( const CallICFGNode inst) const

Return true if this call wait for a worker thread.

Definition at line 194 of file ThreadAPI.cpp.

195{
196 return getType(inst->getCalledFunction()) == TD_JOIN;
197}

◆ isTDRelease()

bool ThreadAPI::isTDRelease ( const CallICFGNode inst) const

Return true if this call release a lock.

Definition at line 209 of file ThreadAPI.cpp.

210{
211 return getType(inst->getCalledFunction()) == TD_RELEASE;
212}

◆ performAPIStat()

void ThreadAPI::performAPIStat ( )

Definition at line 351 of file ThreadAPI.cpp.

352{
353
355
357
359 for (const auto& item: *svfirCallGraph)
360 {
361 for (FunObjVar::const_bb_iterator bit = (item.second)->getFunction()->begin(), ebit = (item.second)->getFunction()->end(); bit != ebit; ++bit)
362 {
363 const SVFBasicBlock* bb = bit->second;
364 for (const auto& svfInst: bb->getICFGNodeList())
365 {
367 continue;
368
369 const FunObjVar* fun = SVFUtil::cast<CallICFGNode>(svfInst)->getCalledFunction();
370 TD_TYPE type = getType(fun);
371 switch (type)
372 {
373 case TD_FORK:
374 {
375 tdAPIStatMap["pthread_create"]++;
376 break;
377 }
378 case TD_JOIN:
379 {
380 tdAPIStatMap["pthread_join"]++;
381 break;
382 }
383 case TD_ACQUIRE:
384 {
385 tdAPIStatMap["pthread_mutex_lock"]++;
386 break;
387 }
388 case TD_TRY_ACQUIRE:
389 {
390 tdAPIStatMap["pthread_mutex_trylock"]++;
391 break;
392 }
393 case TD_RELEASE:
394 {
395 tdAPIStatMap["pthread_mutex_unlock"]++;
396 break;
397 }
398 case TD_CANCEL:
399 {
400 tdAPIStatMap["pthread_cancel"]++;
401 break;
402 }
403 case TD_EXIT:
404 {
405 tdAPIStatMap["pthread_exit"]++;
406 break;
407 }
408 case TD_DETACH:
409 {
410 tdAPIStatMap["pthread_detach"]++;
411 break;
412 }
413 case TD_COND_WAIT:
414 {
415 tdAPIStatMap["pthread_cond_wait"]++;
416 break;
417 }
418 case TD_COND_SIGNAL:
419 {
420 tdAPIStatMap["pthread_cond_signal"]++;
421 break;
422 }
424 {
425 tdAPIStatMap["pthread_cond_broadcast"]++;
426 break;
427 }
428 case TD_CONDVAR_INI:
429 {
430 tdAPIStatMap["pthread_cond_init"]++;
431 break;
432 }
434 {
435 tdAPIStatMap["pthread_cond_destroy"]++;
436 break;
437 }
438 case TD_MUTEX_INI:
439 {
440 tdAPIStatMap["pthread_mutex_init"]++;
441 break;
442 }
443 case TD_MUTEX_DESTROY:
444 {
445 tdAPIStatMap["pthread_mutex_destroy"]++;
446 break;
447 }
448 case TD_BAR_INIT:
449 {
450 tdAPIStatMap["pthread_barrier_init"]++;
451 break;
452 }
453 case TD_BAR_WAIT:
454 {
455 tdAPIStatMap["pthread_barrier_wait"]++;
456 break;
457 }
458 case HARE_PAR_FOR:
459 {
460 tdAPIStatMap["hare_parallel_for"]++;
461 break;
462 }
463 case TD_DUMMY:
464 {
465 break;
466 }
467 }
468 }
469 }
470
471 }
472
473 std::string name(PAG::getPAG()->getModuleIdentifier());
474 std::vector<std::string> fullNames = SVFUtil::split(name,'/');
475 if (fullNames.size() > 1)
476 {
477 name = fullNames[fullNames.size() - 1];
478 }
479 SVFUtil::outs() << "################ (program : " << name
480 << ")###############\n";
481 SVFUtil::outs().flags(std::ios::left);
482 unsigned field_width = 20;
484 tdAPIStatMap.end(); it != eit; ++it)
485 {
486 std::string apiName = it->first;
487 // format out put with width 20 space
488 SVFUtil::outs() << std::setw(field_width) << apiName << " : " << it->second
489 << "\n";
490 }
491 SVFUtil::outs() << "#######################################################"
492 << std::endl;
493
494}
newitem type
Definition cJSON.cpp:2739
const char *const name
Definition cJSON.h:264
cJSON * item
Definition cJSON.h:222
BasicBlockGraph::IDToNodeMapTy::const_iterator const_bb_iterator
const CallGraph * getCallGraph()
Get CG.
Definition SVFIR.h:248
void statInit(Map< std::string, u32_t > &tdAPIStatMap)
bool isCallSite(const ICFGNode *inst)
Definition SVFUtil.cpp:320
std::ostream & outs()
Overwrite llvm::outs()
Definition SVFUtil.h:52
std::vector< std::string > split(const std::string &s, char separator)
Split into two substrings around the first occurrence of a separator string.
Definition SVFUtil.h:196
std::unordered_map< Key, Value, Hash, KeyEqual, Allocator > Map
Definition GeneralType.h:56

◆ statInit()

void ThreadAPI::statInit ( Map< std::string, u32_t > &  tdAPIStatMap)

Definition at line 311 of file ThreadAPI.cpp.

312{
313
314 tdAPIStatMap["pthread_create"] = 0;
315
316 tdAPIStatMap["pthread_join"] = 0;
317
318 tdAPIStatMap["pthread_mutex_lock"] = 0;
319
320 tdAPIStatMap["pthread_mutex_trylock"] = 0;
321
322 tdAPIStatMap["pthread_mutex_unlock"] = 0;
323
324 tdAPIStatMap["pthread_cancel"] = 0;
325
326 tdAPIStatMap["pthread_exit"] = 0;
327
328 tdAPIStatMap["pthread_detach"] = 0;
329
330 tdAPIStatMap["pthread_cond_wait"] = 0;
331
332 tdAPIStatMap["pthread_cond_signal"] = 0;
333
334 tdAPIStatMap["pthread_cond_broadcast"] = 0;
335
336 tdAPIStatMap["pthread_cond_init"] = 0;
337
338 tdAPIStatMap["pthread_cond_destroy"] = 0;
339
340 tdAPIStatMap["pthread_mutex_init"] = 0;
341
342 tdAPIStatMap["pthread_mutex_destroy"] = 0;
343
344 tdAPIStatMap["pthread_barrier_init"] = 0;
345
346 tdAPIStatMap["pthread_barrier_wait"] = 0;
347
348 tdAPIStatMap["hare_parallel_for"] = 0;
349}

Member Data Documentation

◆ tdAPI

ThreadAPI * ThreadAPI::tdAPI = nullptr
staticprivate

Static reference.

Definition at line 92 of file ThreadAPI.h.

◆ tdAPIMap

TDAPIMap SVF::ThreadAPI::tdAPIMap
private

API map, from a string to threadAPI type.

Definition at line 80 of file ThreadAPI.h.


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