[docs]defstep(self,simgr,stash="active",**kwargs):# ha ha, very funny, if this is being run on a single-step basis our filter probably misfirediflen(simgr.stashes[self.stash])==1andlen(simgr.stashes[stash])==0:simgr=simgr.move(self.stash,stash)# perform all our analysis as a post-mortem on a given stepstop_points=kwargs.pop("extra_stop_points",set())stop_points.add(self.address)simgr=simgr.step(stash=stash,extra_stop_points=stop_points,**kwargs)# self.mark_okfilter(simgr, stash)# do filteringnew_stash=[]forstateinsimgr.stashes[stash]:ifself.filter_markernotinstate.globalsandstate.addr==self.address:self.wait_counter=0simgr.stashes[self.stash].append(state)else:new_stash.append(state)simgr.stashes[stash][:]=new_stash# nothing to do if there's no states waitingiflen(simgr.stashes[self.stash])==0:returnsimgr# tick the counterself.wait_counter+=1# see if it's time to merge (out of active or hit the wait limit)iflen(simgr.stashes[stash])!=0andself.wait_counter<self.wait_counter_limit:returnsimgr# self.mark_nofilter(simgr, self.stash)# only both merging if, you know, there's actually states to mergeiflen(simgr.stashes[self.stash])==1:simgr.move(self.stash,stash)returnsimgr# do the merge, keyed by unique callstackl.info("Merging %d states at %#x",len(simgr.stashes[self.stash]),self.address)num_unique=0whilelen(simgr.stashes[self.stash]):num_unique+=1exemplar_callstack=simgr.stashes[self.stash][0].callstacksimgr.move(self.stash,"merge_tmp",lambdas:s.callstack==exemplar_callstack)l.debug("...%d with unique callstack #%d",len(simgr.merge_tmp),num_unique)iflen(simgr.merge_tmp)>1:simgr=simgr.merge(stash="merge_tmp",prune=self.prune)simgr=simgr.move("merge_tmp",stash)returnsimgr