def METHOD_NAME(self, shift=7, args=None):
    logger = logging.getLogger('replay')
    # create qcow2 for snapshots
    logger.info('creating qcow2 image for VM snapshots')
    image_path = os.path.join(self.workdir, 'disk.qcow2')
    qemu_img = os.path.join(BUILD_DIR, 'qemu-img')
    if not os.path.exists(qemu_img):
        qemu_img = find_command('qemu-img', False)
    if qemu_img is False:
        self.cancel('Could not find "qemu-img", which is required to '
                    'create the temporary qcow2 image')
    cmd = '%s create -f qcow2 %s 128M' % (qemu_img, image_path)
    process.run(cmd)
    replay_path = os.path.join(self.workdir, 'replay.bin')
    port = find_free_port()
    # record the log
    vm = self.run_vm(True, shift, args, replay_path, image_path, port)
    while self.vm_get_icount(vm) <= self.STEPS:
        pass
    last_icount = self.vm_get_icount(vm)
    vm.shutdown()
    logger.info("recorded log with %s+ steps" % last_icount)
    # replay and run debug commands
    vm = self.run_vm(False, shift, args, replay_path, image_path, port)
    logger.info('connecting to gdbstub')
    g = gdb.GDBRemote('127.0.0.1', port, False, False)
    g.connect()
    r = g.cmd(b'qSupported')
    if b'qXfer:features:read+' in r:
        g.cmd(b'qXfer:features:read:target.xml:0,ffb')
    if b'ReverseStep+' not in r:
        self.fail('Reverse step is not supported by QEMU')
    if b'ReverseContinue+' not in r:
        self.fail('Reverse continue is not supported by QEMU')
    logger.info('stepping forward')
    steps = []
    # record first instruction addresses
    for _ in range(self.STEPS):
        pc = self.get_pc(g)
        logger.info('saving position %x' % pc)
        steps.append(pc)
        self.gdb_step(g)
    # visit the recorded instruction in reverse order
    logger.info('stepping backward')
    for addr in steps[::-1]:
        self.gdb_bstep(g)
        self.check_pc(g, addr)
        logger.info('found position %x' % addr)
    logger.info('seeking to the end (icount %s)' % (last_icount - 1))
    vm.qmp('replay-break', icount=last_icount - 1)
    # continue - will return after pausing
    g.cmd(b'c', b'T02thread:01;')
    logger.info('setting breakpoints')
    for addr in steps:
        # hardware breakpoint at addr with len=1
        g.cmd(b'Z1,%x,1' % addr, b'OK')
    logger.info('running reverse continue to reach %x' % steps[-1])
    # reverse continue - will return after stopping at the breakpoint
    g.cmd(b'bc', b'T05thread:01;')
    # assume that none of the first instructions is executed again
    # breaking the order of the breakpoints
    self.check_pc(g, steps[-1])
    logger.info('successfully reached %x' % steps[-1])
    logger.info('exitting gdb and qemu')
    vm.shutdown()