//TODO: refactor implementation provide trace for event broadcast void CTaskModel::notifyTaskListeners(TaskEvent *pEvent) { unsigned __int64 id = GetID(); PtrSet<TaskListener> *pSet = s_mapListeners.Get(id); if(pSet) { IterWrapper<TaskListener> iter(pSet->Iterate()); TaskListener *pListener = 0; #ifdef _DEBUG int count = 0; #endif while(iter.Next()) { pListener = iter.Get(); #ifdef _DEBUG TCHAR out[1024]; _stprintf_s(out, _T("Notify: %d Event: %d Change: %d Task ID: %0.16I64x \r\n"), count++, pEvent->m_type, pEvent->m_changeType, pEvent->m_taskID); OutputDebugString(out); _stprintf_s(out, _T("This Task ID: %0.16I64x\r\n"), id); OutputDebugString(out); _stprintf_s(out, _T("Listener Address: %0.8x -Set: %0.8x\r\n"), pListener, pSet); OutputDebugString(out); #endif pListener->HandleTaskEvent(*pEvent); } } }
void CTaskModel::addTaskListener(TaskListener *pTaskListener) { //don't allow a task to listen to itself if(reinterpret_cast<void *>(this) != reinterpret_cast<void *>(pTaskListener)) { unsigned __int64 id = GetID(); PtrSet<TaskListener> *pSet = s_mapListeners.Get(id); if(!pSet) { PtrSet<TaskListener> listenerSet; s_mapListeners.Put(id, listenerSet); pSet = s_mapListeners.Get(id); #ifdef _DEBUG //Debugging TCHAR out[1024]; SecureZeroMemory(out, sizeof(out)); _stprintf_s(out, _T("Create PtrSet<TaskListener> for Task: %0.16I64x\r\n"), id); OutputDebugString(out); #endif } pSet->Add(*pTaskListener); #ifdef _DEBUG //Debugging TCHAR out[1024]; SecureZeroMemory(out, sizeof(out)); _stprintf_s(out, _T("Added Listener Address: 0x%0.8x to Task: %0.16I64x \r\n"), pTaskListener, m_id); OutputDebugString(out); #endif } }
void CTaskModel::removeTaskListener(TaskListener *pTaskListener) { unsigned __int64 id = GetID(); PtrSet<TaskListener> *pSet = s_mapListeners.Get(id); if(pSet) { pSet->Remove(*pTaskListener); #ifdef _DEBUG TCHAR out[1024]; SecureZeroMemory(out, sizeof(out)); _stprintf_s(out, _T("Removed Listener Address: 0x%0.8x from Task: %0.16I64x \r\n"), pTaskListener, m_id); OutputDebugString(out); #endif } }
void InnerPointerChecker::checkPostCall(const CallEvent &Call, CheckerContext &C) const { ProgramStateRef State = C.getState(); if (const auto *ICall = dyn_cast<CXXInstanceCall>(&Call)) { // TODO: Do we need these to be typed? const auto *ObjRegion = dyn_cast_or_null<TypedValueRegion>( ICall->getCXXThisVal().getAsRegion()); if (!ObjRegion) return; if (Call.isCalled(CStrFn) || Call.isCalled(DataFn)) { SVal RawPtr = Call.getReturnValue(); if (SymbolRef Sym = RawPtr.getAsSymbol(/*IncludeBaseRegions=*/true)) { // Start tracking this raw pointer by adding it to the set of symbols // associated with this container object in the program state map. PtrSet::Factory &F = State->getStateManager().get_context<PtrSet>(); const PtrSet *SetPtr = State->get<RawPtrMap>(ObjRegion); PtrSet Set = SetPtr ? *SetPtr : F.getEmptySet(); assert(C.wasInlined || !Set.contains(Sym)); Set = F.add(Set, Sym); State = State->set<RawPtrMap>(ObjRegion, Set); C.addTransition(State); } return; } // Check [string.require] / second point. if (isInvalidatingMemberFunction(Call)) { markPtrSymbolsReleased(Call, State, ObjRegion, C); return; } } // Check [string.require] / first point. checkFunctionArguments(Call, State, C); }
void InnerPointerChecker::checkDeadSymbols(SymbolReaper &SymReaper, CheckerContext &C) const { ProgramStateRef State = C.getState(); PtrSet::Factory &F = State->getStateManager().get_context<PtrSet>(); RawPtrMapTy RPM = State->get<RawPtrMap>(); for (const auto Entry : RPM) { if (!SymReaper.isLiveRegion(Entry.first)) { // Due to incomplete destructor support, some dead regions might // remain in the program state map. Clean them up. State = State->remove<RawPtrMap>(Entry.first); } if (const PtrSet *OldSet = State->get<RawPtrMap>(Entry.first)) { PtrSet CleanedUpSet = *OldSet; for (const auto Symbol : Entry.second) { if (!SymReaper.isLive(Symbol)) CleanedUpSet = F.remove(CleanedUpSet, Symbol); } State = CleanedUpSet.isEmpty() ? State->remove<RawPtrMap>(Entry.first) : State->set<RawPtrMap>(Entry.first, CleanedUpSet); } } C.addTransition(State); }
void test_erase() { PtrSet s; typedef typename PtrSet::key_type T; T t; s.insert ( new T ); T* t2 = t.clone(); s.insert ( t2 ); s.insert ( new T ); BOOST_CHECK_EQUAL( s.size(), 3u ); BOOST_CHECK_EQUAL( hash_value(t), hash_value(*t2) ); BOOST_CHECK_EQUAL( t, *t2 ); typename PtrSet::iterator i = s.find( t ); BOOST_CHECK( i != s.end() ); unsigned n = s.erase( t ); BOOST_CHECK( n > 0 ); }
void test_erase() { PtrSet s; typedef typename PtrSet::key_type T; T t; T* t2 = t.clone(); s.insert ( new T ); s.insert ( t2 ); s.insert ( new T ); BOOST_CHECK_EQUAL( s.size(), 3u ); BOOST_CHECK_EQUAL( t, *t2 ); BOOST_CHECK( ! (t < *t2) ); BOOST_CHECK( ! (*t2 < t) ); BOOST_CHECK_EQUAL( t, *t2 ); unsigned n = s.erase( t ); BOOST_CHECK( n > 0 ); }