示例#1
0
文件: couple.py 项目: Frky/scat
class Couple(ICommand):
    """
        Retrieve couples

    """

    def __init__(self, log_file, log):
        super(Couple, self).__init__()
        self.__parser = BlockTraceParser(log_file)
        self.log = log

    def run(self):
        inp = dict()
        out = dict()
        SIZE_LIMIT = 10000
        NROUND = 65536
        self.log("parsing memory blocks...")
        for block in self.__parser.get():
            if block.type != BlockTrace.ADDR:
                continue
            if block.io == BlockTrace.IN:
                if block.id not in inp.keys():
                    inp[block.id] = list()
                if len(inp[block.id]) < SIZE_LIMIT:
                    inp[block.id].append(block.val)
            elif block.io == BlockTrace.OUT:
                if block.id not in out.keys():
                    out[block.id] = list()
                    for i in xrange(NROUND):
                        out[block.id].append(list())
                out[block.id][block.val % NROUND].append(block.val)
        self.log("#f: {0} | #g: {1} | #in: {2} | #out: {3}".format(
                                len(inp), 
                                len(out), 
                                reduce(lambda p, q: p + len(q), inp.values(), 0), 
                                reduce(lambda p, q: p + reduce(lambda x, y: x + len(y), q, 0), out.values(), 0),
                            ),
                        )
        self.log("computing couples...")
        couples = list()
        for g, param_in in inp.items():
            for f, param_out in out.items():
                nb = 0
                not_nb = 0
                for param in param_in:
                    if param in param_out[param % NROUND]:
                        nb += 1
                    else:
                        not_nb += 1
                    if float(not_nb) / float(len(param_in)) > 1 - 0.5:
                        break
                rho = float(nb) / float(len(param_in))
                if rho > 0.5:
                    couples.append((f, g, rho))
        for c in couples:
            print c
        return
示例#2
0
文件: memcomb.py 项目: Frky/scat
class MemComb(ICommand):
    """
        Retrieve allocators

    """

    def __init__(self, mem_log_file, type_log_file, log):
        super(MemComb, self).__init__()
        self.__parser = BlockTraceParser(mem_log_file)
        self.__protos = TypeLogParser(type_log_file)
        self.log = log

    def __alloc(self):
        """
            Try to retrieve the top-level allocator

        """
        # return "libc.so.6:529408"
        # Number of new addresses outputted by each function
        nb_new_addr = dict()
        # Addresses seen so far
        addr_seen = AddrTable()
        # Call stack
        call_stack = CallStack()
        # For each block of data in the log file
        for block in self.__parser.get():
            # IN PARAMETER
            if block.is_in():
                call_stack.push(block)
            # OUT PARAMETER
            else:
                call_stack.expect(block.id, block.date)
                if block.is_addr():
                    if block.id not in nb_new_addr.keys():
                        nb_new_addr[block.id] = [0, 0]
                    if not addr_seen.contains(block.val):
                        nb_new_addr[block.id][0] += 1
                        addr_seen.add(block.val)
                    nb_new_addr[block.id][1] += 1
                call_stack.pop()
        return max(nb_new_addr.items(), key=lambda a: a[1][0])[0]

    def __wrappers(self, ALLOC):
        # Number of new addresses outputted by each function
        wrappers = dict()
        # Last output value
        last_addr = None
        #
        prev = None
        # TTL
        ttl = 0
        # Call stack
        call_stack = CallStack()
        # For each block of data in the log file
        for block in self.__parser.get():
            # IN PARAMETER
            if block.is_in():
                call_stack.push(block)
            # OUT PARAMETER
            else:
                call_stack.expect(block.id, block.date)
                if block.is_addr():
                    if block.id in wrappers.keys():
                        wrappers[block.id][1] += 1
                    if block.id == ALLOC:
                        last_addr = block.val
                        depth = 1
                        prev = ALLOC
                    elif last_addr is not None:
                        if block.val == last_addr:
                            if block.id not in wrappers.keys():
                                wrappers[block.id] = [0, 1, list(), list()]
                            wrappers[block.id][0] += 1
                            wrappers[block.id][2].append(depth)
                            wrappers[block.id][3].append(prev)
                            depth += 1
                            prev = block.id
                        # else:
                        #     last_addr = None
                        #     ttl = 0
                        #     prev = None
                call_stack.pop()
                if call_stack.is_empty():
                    last_addr = None
        wrappers = map(lambda a: (a[0], float(a[1][0])/float(a[1][1]), mean(a[1][2]), max(set(a[1][3]), key=a[1][3].count)), sorted(wrappers.items(), key=lambda a: a[1][0]))
        wrappers = sorted(filter(lambda a: a[1] > 0.5, wrappers), key=lambda a:a[2])
        WTREE = Wrapper(ALLOC, 1)
        for wrapper in wrappers:
            wrap = WTREE.get(wrapper[3], wrapper[2] - 1)
            if wrap is not None:
                wrap.add_child(Wrapper(wrapper[0], int(wrapper[1])))
            else:
                print "Elaged: {0}".format(wrapper[0])
        print WTREE.to_str(0)

    def __free(self, ALLOC):
        # return "__libc_free"
        # Number of new addresses outputted by each function
        nb_new_addr = dict()
        # Addresses seen so far
        addr_alloc = AddrTable(dic=True)
        # Call stack
        call_stack = CallStack()
        for block in self.__parser.get():
            if not addr_alloc.contains(block.val):
                addr_alloc.add(block.val)
            if block.is_in() and block.id != ALLOC:
                addr_alloc.add_dic(block.val, block.id)
            elif block.is_out() and block.id == ALLOC:
                addr_alloc.add_dic(block.val, block.id)
        for adr, call in addr_alloc.items():
            if len(call) == 0:
                continue
            if call[0] != ALLOC:
                continue
            while call.count(ALLOC) > 0:
                if call.index(ALLOC) == 0:
                    call.pop(0)
                    if len(call) > 0:
                        free = call[-1]
                    else: 
                        continue
                else:
                    free = call[call.index(ALLOC) - 1]
                    call = call[call.index(ALLOC)+1:]
                if free not in nb_new_addr.keys():
                    nb_new_addr[free] = 0
                nb_new_addr[free] += 1
        return max(nb_new_addr.items(), key=lambda a:a[1])[0]

    def compute_blocks(self, ALLOC, FREE):
        mem = Memory()
        size_stack = [(0, -1)]
        for block in self.__parser.get():
            if block.id == ALLOC:
                if block.is_in() and block.is_num() and size_stack[-1][1] != block.date:
                    size_stack.append((block.val, block.date))
                elif block.is_out():
                    if len(size_stack) <= 1:
                        raise Exception("ALLOC stack inconsistanc at date {0}".format(block.date))
                    size, date = size_stack.pop(-1)
                    mem.alloc(block.val, size)
            elif block.id == FREE:
                if block.is_in():
                    mem.free(block.val)
        return

    def run(self, wrappers=True):
        ALLOC = self.__alloc()
        self.log("allocator found - {0}".format(ALLOC))
        FREE = self.__free(ALLOC)
        self.log("liberator found - {0}".format(FREE))
        self.log("checking consistancy of blocks...")
        self.compute_blocks(ALLOC, FREE)
        if wrappers:
            # Detecting suballocators
            SUBALLOC = self.__wrappers(ALLOC)
        return ALLOC, FREE
示例#3
0
文件: couple.py 项目: Frky/scat
 def __init__(self, log_file, log):
     super(Couple, self).__init__()
     self.__parser = BlockTraceParser(log_file)
     self.log = log
示例#4
0
文件: memcomb.py 项目: Frky/scat
 def __init__(self, mem_log_file, type_log_file, log):
     super(MemComb, self).__init__()
     self.__parser = BlockTraceParser(mem_log_file)
     self.__protos = TypeLogParser(type_log_file)
     self.log = log