All of lore.kernel.org
 help / color / mirror / Atom feed
From: Pavel Dovgalyuk <pavel.dovgaluk@gmail.com>
To: qemu-devel@nongnu.org
Cc: kwolf@redhat.com, peter.maydell@linaro.org,
	pavel.dovgaluk@ispras.ru, pbonzini@redhat.com,
	quintela@redhat.com, ciro.santilli@gmail.com,
	jasowang@redhat.com, crosthwaite.peter@gmail.com,
	armbru@redhat.com, mreitz@redhat.com, alex.bennee@linaro.org,
	maria.klimushenkova@ispras.ru, mst@redhat.com, kraxel@redhat.com,
	boost.lists@gmail.com, thomas.dullien@googlemail.com,
	dovgaluk@ispras.ru, artem.k.pisarenko@gmail.com,
	dgilbert@redhat.com, rth@twiddle.net
Subject: [Qemu-devel] [PATCH for-4.1 13/24] replay: implement replay-seek command
Date: Fri, 21 Jun 2019 11:21:52 +0300	[thread overview]
Message-ID: <156110531211.25431.13446532508590348128.stgit@pasha-Precision-3630-Tower> (raw)
In-Reply-To: <156110523748.25431.9310430853468653085.stgit@pasha-Precision-3630-Tower>

From: Pavel Dovgalyuk <Pavel.Dovgaluk@ispras.ru>

This patch adds hmp/qmp commands replay_seek/replay-seek that proceed
the execution to the specified instruction count.
The command automatically loads nearest snapshot and replays the execution
to find the desired instruction count.

Signed-off-by: Pavel Dovgalyuk <Pavel.Dovgaluk@ispras.ru>
Acked-by: Markus Armbruster <armbru@redhat.com>

--

v2:
 - renamed replay_seek qmp command into replay-seek
   (suggested by Eric Blake)
v7:
 - small fixes related to Markus Armbruster's review
v9:
 - changed 'step' parameter name to 'icount'
 - moved json stuff to replay.json and updated the description
   (suggested by Markus Armbruster)
v10:
 - updated the descriptions
---
 hmp-commands.hx           |   19 +++++++++
 hmp.h                     |    1 
 qapi/replay.json          |   20 ++++++++++
 replay/replay-debugging.c |   92 +++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 132 insertions(+)

diff --git a/hmp-commands.hx b/hmp-commands.hx
index 96f89a13c2..d812bb290f 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -1960,6 +1960,25 @@ STEXI
 @findex replay_delete_break
 Remove replay breakpoint which was previously set with replay_break.
 The command is ignored when there are no replay breakpoints.
+ETEXI
+
+    {
+        .name       = "replay_seek",
+        .args_type  = "icount:i",
+        .params     = "icount",
+        .help       = "replay execution to the specified instruction count",
+        .cmd        = hmp_replay_seek,
+    },
+
+STEXI
+@item replay_seek @var{icount}
+@findex replay_seek
+Automatically proceed to the instruction count @var{icount}, when
+replaying the execution. The command automatically loads nearest
+snapshot and replays the execution to find the desired instruction.
+When there is no preceding snapshot or the execution is not replayed,
+then the command fails.
+icount for the reference may be observed with 'info replay' command.
 ETEXI
 
     {
diff --git a/hmp.h b/hmp.h
index 80967f5bd6..e03fb41ac3 100644
--- a/hmp.h
+++ b/hmp.h
@@ -152,5 +152,6 @@ void hmp_info_sev(Monitor *mon, const QDict *qdict);
 void hmp_info_replay(Monitor *mon, const QDict *qdict);
 void hmp_replay_break(Monitor *mon, const QDict *qdict);
 void hmp_replay_delete_break(Monitor *mon, const QDict *qdict);
+void hmp_replay_seek(Monitor *mon, const QDict *qdict);
 
 #endif
diff --git a/qapi/replay.json b/qapi/replay.json
index 425e053e4d..aa768d496c 100644
--- a/qapi/replay.json
+++ b/qapi/replay.json
@@ -99,3 +99,23 @@
 #
 ##
 { 'command': 'replay-delete-break' }
+
+##
+# @replay-seek:
+#
+# Automatically proceed to the instruction count @icount, when
+# replaying the execution. The command automatically loads nearest
+# snapshot and replays the execution to find the desired instruction.
+# When there is no preceding snapshot or the execution is not replayed,
+# then the command fails.
+# icount for the reference may be obtained with @query-replay command.
+#
+# @icount: target instruction count
+#
+# Since: 4.1
+#
+# Example:
+#
+# -> { "execute": "replay-seek", "data": { "icount": 220414 } }
+##
+{ 'command': 'replay-seek', 'data': { 'icount': 'int' } }
diff --git a/replay/replay-debugging.c b/replay/replay-debugging.c
index a94685e437..e3821ab1ba 100644
--- a/replay/replay-debugging.c
+++ b/replay/replay-debugging.c
@@ -18,6 +18,8 @@
 #include "qapi/qapi-commands-replay.h"
 #include "qapi/qmp/qdict.h"
 #include "qemu/timer.h"
+#include "block/snapshot.h"
+#include "migration/snapshot.h"
 
 void hmp_info_replay(Monitor *mon, const QDict *qdict)
 {
@@ -127,3 +129,93 @@ void hmp_replay_delete_break(Monitor *mon, const QDict *qdict)
         return;
     }
 }
+
+static char *replay_find_nearest_snapshot(int64_t icount,
+                                          int64_t *snapshot_icount)
+{
+    BlockDriverState *bs;
+    QEMUSnapshotInfo *sn_tab;
+    QEMUSnapshotInfo *nearest = NULL;
+    char *ret = NULL;
+    int nb_sns, i;
+    AioContext *aio_context;
+
+    *snapshot_icount = -1;
+
+    bs = bdrv_all_find_vmstate_bs();
+    if (!bs) {
+        goto fail;
+    }
+    aio_context = bdrv_get_aio_context(bs);
+
+    aio_context_acquire(aio_context);
+    nb_sns = bdrv_snapshot_list(bs, &sn_tab);
+    aio_context_release(aio_context);
+
+    for (i = 0; i < nb_sns; i++) {
+        if (bdrv_all_find_snapshot(sn_tab[i].name, &bs) == 0) {
+            if (sn_tab[i].icount != -1ULL
+                && sn_tab[i].icount <= icount
+                && (!nearest || nearest->icount < sn_tab[i].icount)) {
+                nearest = &sn_tab[i];
+            }
+        }
+    }
+    if (nearest) {
+        ret = g_strdup(nearest->name);
+        *snapshot_icount = nearest->icount;
+    }
+    g_free(sn_tab);
+
+fail:
+    return ret;
+}
+
+static void replay_seek(int64_t icount, QEMUTimerCB callback, Error **errp)
+{
+    char *snapshot = NULL;
+    int64_t snapshot_icount;
+
+    if (replay_mode != REPLAY_MODE_PLAY) {
+        error_setg(errp, "replay must be enabled to seek");
+        return;
+    }
+    if (!replay_snapshot) {
+        error_setg(errp, "snapshotting is disabled");
+        return;
+    }
+
+    snapshot = replay_find_nearest_snapshot(icount, &snapshot_icount);
+    if (snapshot) {
+        if (icount < replay_get_current_step()
+            || replay_get_current_step() < snapshot_icount) {
+            vm_stop(RUN_STATE_RESTORE_VM);
+            load_snapshot(snapshot, errp);
+        }
+        g_free(snapshot);
+    }
+    if (replay_get_current_step() <= icount) {
+        replay_break(icount, callback, NULL);
+        vm_start();
+    } else {
+        error_setg(errp, "cannot seek to the specified instruction count");
+    }
+}
+
+void qmp_replay_seek(int64_t icount, Error **errp)
+{
+    replay_seek(icount, replay_stop_vm, errp);
+}
+
+void hmp_replay_seek(Monitor *mon, const QDict *qdict)
+{
+    int64_t icount = qdict_get_try_int(qdict, "icount", -1LL);
+    Error *err = NULL;
+
+    qmp_replay_seek(icount, &err);
+    if (err) {
+        error_report_err(err);
+        error_free(err);
+        return;
+    }
+}



  parent reply	other threads:[~2019-06-21  9:08 UTC|newest]

Thread overview: 30+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-06-21  8:20 [Qemu-devel] [PATCH for-4.1 00/24] Fix record/replay and add reverse debugging Pavel Dovgalyuk
2019-06-21  8:20 ` [Qemu-devel] [PATCH for-4.1 01/24] replay: add missing fix for internal function Pavel Dovgalyuk
2019-06-21  8:20 ` [Qemu-devel] [PATCH for-4.1 02/24] block: implement bdrv_snapshot_goto for blkreplay Pavel Dovgalyuk
2019-06-21  8:20 ` [Qemu-devel] [PATCH for-4.1 03/24] replay: disable default snapshot for record/replay Pavel Dovgalyuk
2019-06-21  8:21 ` [Qemu-devel] [PATCH for-4.1 04/24] replay: update docs for record/replay with block devices Pavel Dovgalyuk
2019-06-21  8:21 ` [Qemu-devel] [PATCH for-4.1 05/24] replay: don't drain/flush bdrv queue while RR is working Pavel Dovgalyuk
2019-06-21  8:21 ` [Qemu-devel] [PATCH for-4.1 06/24] replay: finish record/replay before closing the disks Pavel Dovgalyuk
2019-06-21  8:21 ` [Qemu-devel] [PATCH for-4.1 07/24] qcow2: introduce icount field for snapshots Pavel Dovgalyuk
2019-06-21  8:21 ` [Qemu-devel] [PATCH for-4.1 08/24] migration: " Pavel Dovgalyuk
2019-06-21  8:21 ` [Qemu-devel] [PATCH for-4.1 09/24] replay: provide an accessor for rr filename Pavel Dovgalyuk
2019-06-21  8:21 ` [Qemu-devel] [PATCH for-4.1 10/24] qapi: introduce replay.json for record/replay-related stuff Pavel Dovgalyuk
2019-06-21  8:21 ` [Qemu-devel] [PATCH for-4.1 11/24] replay: introduce info hmp/qmp command Pavel Dovgalyuk
2019-06-21  8:21 ` [Qemu-devel] [PATCH for-4.1 12/24] replay: introduce breakpoint at the specified step Pavel Dovgalyuk
2019-06-21  8:21 ` Pavel Dovgalyuk [this message]
2019-06-21  8:21 ` [Qemu-devel] [PATCH for-4.1 14/24] replay: refine replay-time module Pavel Dovgalyuk
2019-06-21  8:22 ` [Qemu-devel] [PATCH for-4.1 15/24] replay: flush rr queue before loading the vmstate Pavel Dovgalyuk
2019-06-21  8:22 ` [Qemu-devel] [PATCH for-4.1 16/24] gdbstub: add reverse step support in replay mode Pavel Dovgalyuk
2019-06-21  8:22 ` [Qemu-devel] [PATCH for-4.1 17/24] gdbstub: add reverse continue " Pavel Dovgalyuk
2019-06-21  8:22 ` [Qemu-devel] [PATCH for-4.1 18/24] replay: describe reverse debugging in docs/replay.txt Pavel Dovgalyuk
2019-06-21  8:22 ` [Qemu-devel] [PATCH for-4.1 19/24] replay: add BH oneshot event for block layer Pavel Dovgalyuk
2019-06-21  8:22 ` [Qemu-devel] [PATCH for-4.1 20/24] replay: document development rules Pavel Dovgalyuk
2019-06-21  8:22 ` [Qemu-devel] [PATCH for-4.1 21/24] util/qemu-timer: refactor deadline calculation for external timers Pavel Dovgalyuk
2019-06-21  8:22 ` [Qemu-devel] [PATCH for-4.1 22/24] replay: fix replay shutdown Pavel Dovgalyuk
2019-06-21  8:22 ` [Qemu-devel] [PATCH for-4.1 23/24] replay: rename step-related variables and functions Pavel Dovgalyuk
2019-06-21  8:22 ` [Qemu-devel] [PATCH for-4.1 24/24] icount: clean up cpu_can_io before jumping to the next block Pavel Dovgalyuk
2019-06-21  9:36 ` [Qemu-devel] [PATCH for-4.1 00/24] Fix record/replay and add reverse debugging no-reply
2019-06-27 17:49 ` dovgaluk
2019-07-01  9:24   ` Pavel Dovgalyuk
  -- strict thread matches above, loose matches on Subject: below --
2019-04-22 11:19 Pavel Dovgalyuk
2019-04-22 11:20 ` [Qemu-devel] [PATCH for-4.1 13/24] replay: implement replay-seek command Pavel Dovgalyuk
2019-04-22 11:20   ` Pavel Dovgalyuk

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=156110531211.25431.13446532508590348128.stgit@pasha-Precision-3630-Tower \
    --to=pavel.dovgaluk@gmail.com \
    --cc=alex.bennee@linaro.org \
    --cc=armbru@redhat.com \
    --cc=artem.k.pisarenko@gmail.com \
    --cc=boost.lists@gmail.com \
    --cc=ciro.santilli@gmail.com \
    --cc=crosthwaite.peter@gmail.com \
    --cc=dgilbert@redhat.com \
    --cc=dovgaluk@ispras.ru \
    --cc=jasowang@redhat.com \
    --cc=kraxel@redhat.com \
    --cc=kwolf@redhat.com \
    --cc=maria.klimushenkova@ispras.ru \
    --cc=mreitz@redhat.com \
    --cc=mst@redhat.com \
    --cc=pavel.dovgaluk@ispras.ru \
    --cc=pbonzini@redhat.com \
    --cc=peter.maydell@linaro.org \
    --cc=qemu-devel@nongnu.org \
    --cc=quintela@redhat.com \
    --cc=rth@twiddle.net \
    --cc=thomas.dullien@googlemail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.