def METHOD_NAME(
    address=None, page_name=None, max_offset=0x40, max_depth=0x4, step=0x1, negative_offset=0x0
):
    if address is None:
        raise argparse.ArgumentTypeError("No starting address provided.")
    foundPages = pwndbg.gdblib.vmmap.find(address)
    if not foundPages:
        raise argparse.ArgumentTypeError("Starting address is not mapped.")
    if not pwndbg.gdblib.memory.peek(address):
        raise argparse.ArgumentTypeError("Unable to read from starting address.")
    max_depth = int(max_depth)
    # Just warn the user that a large depth might be slow.
    # Probably worth checking offset^depth < threshold. Do this when more benchmarking is established.
    if max_depth > 8:
        print(message.warn("leakfind may take a while to run on larger depths."))
    stride = int(step)
    address = int(address)
    max_offset = int(max_offset)
    negative_offset = int(negative_offset)
    # The below map stores a map of child address->(parent_address,parent_start_address)
    # In the above tuple, parent_address is the exact address with a pointer to the child address.
    # parent_start_address is an address that a previous address pointed to.
    # We need to store both so that we can nicely create our leak chain.
    visited_map = {}
    visited_set = {int(address)}
    address_queue: queue.Queue[int] = queue.Queue()
    address_queue.put(int(address))
    depth = 0
    time_to_depth_increase = 0
    # Run a bfs
    # TODO look into performance gain from checking if an address is mapped before calling pwndbg.gdblib.memory.pvoid()
    # TODO also check using pwndbg.gdblib.memory.read for possible performance boosts.
    while address_queue.qsize() > 0 and depth < max_depth:
        if time_to_depth_increase == 0:
            depth = depth + 1
            time_to_depth_increase = address_queue.qsize()
        cur_start_addr = address_queue.get()
        time_to_depth_increase -= 1
        for cur_addr in range(
            cur_start_addr - negative_offset, cur_start_addr + max_offset, stride
        ):
            try:
                cur_addr &= pwndbg.gdblib.arch.ptrmask
                result = int(pwndbg.gdblib.memory.pvoid(cur_addr))
                if result in visited_map or result in visited_set:
                    continue
                visited_map[result] = (
                    cur_addr,
                    cur_start_addr,
                )  # map is of form child->(parent,parent_start)
                address_queue.put(result)
                visited_set.add(result)
            except gdb.error:
                # That means the memory was unmapped. Just skip it if we can't read it.
                break
    # A map of length->list of lines. Used to let us print in a somewhat nice manner.
    output_map: dict[int, list[str]] = {}
    arrow_right = C.arrow(" %s " % pwndbg.gdblib.config.chain_arrow_right)
    for child in visited_map:
        child_page = pwndbg.gdblib.vmmap.find(child)
        if child_page is not None:
            if page_name is not None and page_name not in child_page.objfile:
                continue
            line = (
                get_rec_addr_string(child, visited_map)
                + M.get(child)
                + " "
                + M.get(child, text=child_page.objfile)
            )
            chain_length = line.count(arrow_right)
            if chain_length in output_map:
                output_map[chain_length].append(line)
            else:
                output_map[chain_length] = [line]
    # Output sorted by length of chain
    for chain_length, lines in output_map.items():
        for line in lines:
            print(line)
    if pwndbg.gdblib.qemu.is_qemu():
        print("\n[QEMU target detected - leakfind result might not be accurate; see `help vmmap`]")