Example #1
0
 def invoke(self, args, from_tty):
     ms = glibc_arenas.get_ms()
     chunks_by_size = {}
     num_chunks = 0
     total_size = 0
     try:
         for chunk in ms.iter_chunks():
             if not chunk.is_inuse():
                 continue
             size = int(chunk.chunksize())
             num_chunks += 1
             total_size += size
             if size in chunks_by_size:
                 chunks_by_size[size] += 1
             else:
                 chunks_by_size[size] = 1
     except KeyboardInterrupt:
         pass # FIXME
     t = Table(['Chunk size', 'Num chunks', 'Allocated size'])
     for size in sorted(chunks_by_size.keys(),
                        lambda s1, s2: chunks_by_size[s2] * s2 - chunks_by_size[s1] * s1):
         t.add_row([fmt_size(size),
                    chunks_by_size[size],
                    fmt_size(chunks_by_size[size] * size)])
     t.add_row(['TOTALS', num_chunks, fmt_size(total_size)])
     t.write(sys.stdout)
     print()
Example #2
0
 def invoke(self, args, from_tty):
     ms = glibc_arenas.get_ms()
     chunks_by_size = {}
     num_chunks = 0
     total_size = 0
     try:
         for chunk in ms.iter_chunks():
             if not chunk.is_inuse():
                 continue
             size = int(chunk.chunksize())
             num_chunks += 1
             total_size += size
             if size in chunks_by_size:
                 chunks_by_size[size] += 1
             else:
                 chunks_by_size[size] = 1
     except KeyboardInterrupt:
         pass # FIXME
     t = Table(['Chunk size', 'Num chunks', 'Allocated size'])
     for size in sorted(chunks_by_size.keys(),
                        lambda s1, s2: chunks_by_size[s2] * s2 - chunks_by_size[s1] * s1):
         t.add_row([fmt_size(size),
                    chunks_by_size[size],
                    fmt_size(chunks_by_size[size] * size)])
     t.add_row(['TOTALS', num_chunks, fmt_size(total_size)])
     t.write(sys.stdout)
     print()
Example #3
0
 def invoke(self, args, from_tty):
     args = args.split()
     if args:
         only_size = int(args[0])
         only_cat = args[1]
         only_str = args[2]
     else:
         only_size = None
         only_cat = None
         only_str = None
     print('Used chunks of memory on heap')
     print('-----------------------------')
     ms = glibc_arenas.get_ms()
     for i, u in enumerate(lazily_get_usage_list()):
         # if not chunk.is_inuse():
         #     continue
         # size = chunk.chunksize()
         # mem = chunk.as_mem()
         # u = Usage(mem, size)
         size = u.size
         if only_size and size != only_size:
             continue
         category = categorize(u, None)
         if only_cat and category.kind != only_cat:
             continue
         hd = hexdump_as_bytes(u.start, min(size, 64))
         if only_str and  only_str not in hd:
             continue
         print ('%6i: %s -> %s %8i bytes %20s |%s'
                % (i,
                   fmt_addr(u.start),
                   fmt_addr(u.start + size),
                   size, category, hd))
     print()
Example #4
0
 def invoke(self, args, from_tty):
     print('C++ objects of memory on heap')
     print('-----------------------------')
     argv = args.split(' ')
     from heap.cplusplus import get_class_name
     ms = glibc_arenas.get_ms()
     for i, chunk in enumerate(ms.iter_chunks()):
         if not chunk.is_inuse():
             continue
         mem = chunk.as_mem()
         size = chunk.chunksize()
         cpp_class = get_class_name(mem, size)
         if not cpp_class:
             continue
         if args and cpp_class.find(argv[0]) < 0:
             continue
         try:
             objsize = caching_lookup_type(cpp_class).sizeof
             if (size / objsize >= 2):
                 cpp_class += "[%d]" % (size / objsize)
         except:
             objsize = "?"
         u = Usage(mem, size)
         #hd = hexdump_as_bytes(mem, 32)
         print('%6i: %s -> %s %8i bytes %100s | %s bytes/obj' %
               (i, fmt_addr(mem), fmt_addr(mem + size - 1), size, cpp_class,
                objsize))
     print("\n")
Example #5
0
    def invoke(self, args, from_tty):
        args = args.split()

        filename = args[0]
        start = int(args[1])
        end = int(args[2])
        step = int(args[3])

        from heap.visualize import gen_mem_usage_image
        ms = glibc_arenas.get_ms()
        im = gen_mem_usage_image(ms.iter_chunks(), start, end, step, 1024)
        im.save(filename)
Example #6
0
    def invoke(self, args, from_tty):
        print('All chunks of memory on heap (both used and free)')
        print('-------------------------------------------------')
        ms = glibc_arenas.get_ms()
        for i, chunk in enumerate(ms.iter_chunks()):
            size = chunk.chunksize()
            if chunk.is_inuse():
                kind = ' inuse'
            else:
                kind = ' free'

            print('%i: %s -> %s %s: %i bytes (%s)' %
                  (i, fmt_addr(chunk.as_address()),
                   fmt_addr(chunk.as_address() + size - 1), kind, size, chunk))
        print()
Example #7
0
 def invoke(self, args, from_tty):
     print('Used chunks of memory on heap')
     print('-----------------------------')
     ms = glibc_arenas.get_ms()
     for i, chunk in enumerate(ms.iter_chunks()):
         if not chunk.is_inuse():
             continue
         size = chunk.chunksize()
         mem = chunk.as_mem()
         u = Usage(mem, size)
         category = categorize(u, None)
         hd = hexdump_as_bytes(mem, 32)
         print('%6i: %s -> %s %8i bytes %20s |%s' %
               (i, fmt_addr(chunk.as_mem()),
                fmt_addr(chunk.as_mem() + size - 1), size, category, hd))
     print()
Example #8
0
    def invoke(self, args, from_tty):
        print('All chunks of memory on heap (both used and free)')
        print('-------------------------------------------------')
        ms = glibc_arenas.get_ms()
        for i, chunk in enumerate(ms.iter_chunks()):
            size = chunk.chunksize()
            if chunk.is_inuse():
                kind = ' inuse'
            else:
                kind = ' free'

            print ('%i: %s -> %s %s: %i bytes (%s)'
                   % (i,
                      fmt_addr(chunk.as_address()),
                      fmt_addr(chunk.as_address()+size-1),
                      kind, size, chunk))
        print()
Example #9
0
    def invoke(self, args, from_tty):
        print 'Free chunks of memory on heap'
        print '-----------------------------'
        ms = glibc_arenas.get_ms()
        total_size = 0
        for i, chunk in enumerate(ms.iter_free_chunks()):
            size = chunk.chunksize()
            total_size += size
            mem = chunk.as_mem()
            u = Usage(mem, size)
            category = categorize(u, None)
            hd = hexdump_as_bytes(mem, 32)

            print('%6i: %s -> %s %8i bytes %20s |%s' %
                  (i, fmt_addr(chunk.as_mem()),
                   fmt_addr(chunk.as_mem() + size - 1), size, category, hd))
        print "Total size: %s" % total_size
Example #10
0
 def invoke(self, args, from_tty):
     print('Used chunks of memory on heap')
     print('-----------------------------')
     ms = glibc_arenas.get_ms()
     for i, chunk in enumerate(ms.iter_chunks()):
         if not chunk.is_inuse():
             continue
         size = chunk.chunksize()
         mem = chunk.as_mem()
         u = Usage(mem, size)
         category = categorize(u, None)
         hd = hexdump_as_bytes(mem, 32)
         print ('%6i: %s -> %s %8i bytes %20s |%s'
                % (i,
                   fmt_addr(chunk.as_mem()),
                   fmt_addr(chunk.as_mem()+size-1),
                   size, category, hd))
     print()
Example #11
0
def iter_usage():
    # Iterate through glibc, and within that, within Python arena blocks, as appropriate
    from heap.glibc import glibc_arenas
    ms = glibc_arenas.get_ms()

    cached_state = CachedInferiorState()

    from heap.cpython import ArenaDetection as CPythonArenaDetection, PyArenaPtr, ArenaObject
    try:
        cpython_arenas = CPythonArenaDetection()
        cached_state.add_arena_detector(cpython_arenas)
    except WrongInferiorProcess:
        pass

    from heap.pypy import ArenaDetection as PyPyArenaDetection
    try:
        pypy_arenas = PyPyArenaDetection()
        cached_state.add_arena_detector(pypy_arenas)
    except WrongInferiorProcess:
        pass

    for i, chunk in enumerate(ms.iter_mmap_chunks()):
        mem_ptr = chunk.as_mem()
        chunksize = chunk.chunksize()

        arena = cached_state.detect_arena(mem_ptr, chunksize)
        if arena:
            for u in arena.iter_usage():
                yield u
        else:
            yield Usage(int(mem_ptr), chunksize)

    for chunk in ms.iter_sbrk_chunks():
        mem_ptr = chunk.as_mem()
        chunk_ptr = chunk.as_address()
        chunksize = chunk.chunksize()

        if chunk.is_inuse():
            arena = cached_state.detect_arena(mem_ptr, chunksize)
            if arena:
                for u in arena.iter_usage():
                    yield u
            else:
                yield Usage(int(chunk_ptr), chunksize)
Example #12
0
def iter_usage():
    # Iterate through glibc, and within that, within Python arena blocks, as appropriate
    from heap.glibc import glibc_arenas
    ms = glibc_arenas.get_ms()

    cached_state = CachedInferiorState()

    from heap.cpython import ArenaDetection as CPythonArenaDetection, PyArenaPtr, ArenaObject
    try:
        cpython_arenas = CPythonArenaDetection()
        cached_state.add_arena_detector(cpython_arenas)
    except WrongInferiorProcess:
        pass

    from heap.pypy import ArenaDetection as PyPyArenaDetection
    try:
        pypy_arenas = PyPyArenaDetection()
        cached_state.add_arena_detector(pypy_arenas)
    except WrongInferiorProcess:
        pass

    for i, chunk in enumerate(ms.iter_mmap_chunks()):
        mem_ptr = chunk.as_mem()
        chunksize = chunk.chunksize()

        arena = cached_state.detect_arena(mem_ptr, chunksize)
        if arena:
            for u in arena.iter_usage():
                yield u
        else:
            yield Usage(to_int(mem_ptr), chunksize)

    for chunk in ms.iter_sbrk_chunks():
        mem_ptr = chunk.as_mem()
        chunksize = chunk.chunksize()

        if chunk.is_inuse():
            arena = cached_state.detect_arena(mem_ptr, chunksize)
            if arena:
                for u in arena.iter_usage():
                    yield u
            else:
                yield Usage(to_int(mem_ptr), chunksize)
Example #13
0
    def invoke(self, args, from_tty):
        print 'Free chunks of memory on heap'
        print '-----------------------------'
        ms = glibc_arenas.get_ms()
        total_size = 0
        for i, chunk in enumerate(ms.iter_free_chunks()):
            size = chunk.chunksize()
            total_size += size
            mem = chunk.as_mem()
            u = Usage(mem, size)
            category = categorize(u, None)
            hd = hexdump_as_bytes(mem, 32)

            print ('%6i: %s -> %s %8i bytes %20s |%s'
                   % (i,
                      fmt_addr(chunk.as_mem()),
                      fmt_addr(chunk.as_mem()+size-1),
                      size, category, hd))
        print "Total size: %s" % total_size
Example #14
0
    def invoke(self, args, from_tty):
        from heap.glibc import glibc_arenas
        print('All chunks of memory on heap (both used and free)')
        print('-------------------------------------------------')
        ms = glibc_arenas.get_ms()
        try:
            for i, chunk in enumerate(ms.iter_chunks()):
                size = chunk.chunksize()
                if chunk.is_inuse():
                    kind = ' inuse'
                else:
                    kind = ' free'

                print ('%i: %s -> %s %s: %i bytes (%s)'
                       % (i,
                          fmt_addr(chunk.as_address()),
                          fmt_addr(chunk.as_address()+size-1),
                          kind, size, chunk))
        except KeyboardInterrupt:
            print("...Stopping")
            return
        print()
Example #15
0
    def invoke(self, args, from_tty):
        from heap.glibc import glibc_arenas

        arg_list = gdb.string_to_argv(args)

        parser = argparse.ArgumentParser(add_help=True, usage="heap search [-a] [-b] <ADDR>")
        parser.add_argument('addr', metavar='ADDR', type=str, nargs=1, help="Target address")
        parser.add_argument('-b', dest='before', action="store_true", default=False, help="Show chunk before")
        parser.add_argument('-a', dest='after', action="store_true", default=False, help="Show chunk after")

        try:
            args_dict = parser.parse_args(args=arg_list)
        except:
            return

        addr_arg = args_dict.addr[0]

        if addr_arg.startswith("0x"):
            addr = int(addr_arg, 16)
        else:
            addr = int(addr_arg)
        
        try:
            print('search heap for address %s' % fmt_addr(addr))
            print('-------------------------------------------------')
            ms = glibc_arenas.get_ms()
            output_str = ""
            corruptFlag = False
            for chunk in ms.iter_chunks():
                
                try:
                    size = chunk.chunksize()
                except gdb.MemoryError:
                    print("Corrupt chunk found at %s" % fmt_addr(chunk.as_address()))
                    corruptFlag = True
                    continue
                if addr >= chunk.as_address() and addr < chunk.as_address() + size:
                    if chunk.is_inuse():
                        kind = 'inuse'
                    else:
                        kind = 'free'

                    output_str += 'BLOCK:\t%s -> %s %s: \n\t%i bytes (%s)\n' % (
                              fmt_addr(chunk.as_address()),
                              fmt_addr(chunk.as_address()+size-1),
                              kind, size, chunk)
                    if args_dict.after:
                        try:
                            output_str += "NEXT:\t"
                            chunk_after = chunk.next_chunk()
                            start = chunk_after.as_address()
                            output_str += fmt_addr(start)
                            size = chunk_after.chunksize()
                            output_str += " -> %s" % fmt_addr(start + size -1)

                            if chunk_after.is_inuse():
                                kind = 'inuse'
                            else:
                                kind = 'free'

                            output_str += " %s:\n\t%i bytes" % (kind, size)
                            output_str += " %s\n" % chunk_after
                        except gdb.MemoryError:
                            output_str += " <INVALID>\n"
                            corruptFlag = True
                            continue
            if corruptFlag:
                print("WARNING: Heap is corrupted")
            print(output_str)
        except KeyboardInterrupt:
            print("Interrupt")
            return