From nobody Tue May 7 05:51:30 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1577094479; cv=none; d=zohomail.com; s=zohoarc; b=mrpyPt1TpLK2emkzkHHdhPyZs+nk8e6RixgWtFKlwQQ9VuL+tg+SXP15l+qa0/uovvixI3KQjrj7VXDo98cck7Jqzu724BMB7VY6doSPvuPA/xRHkf2YU0L81BT8v1fp5d0HS1s+9td6LFByuJ+5bbuuJPtyFzVrmyVeixX25Ec= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1577094479; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=Q6MTiMYn5oz16fIFRAAPEgIhEIoB7zt+nHM07W2pk9M=; b=gwZgZ1V4xYLrXUTaVKwJOybMI7YJ2mhyXK9WGAHPuedeAWobc9psatwJ81/fituJtaC9OO5bKQkK4a6HLYPDedEP3FE2Cmz/Y95yPIAfnVqsvB8hfL2qPUCKcbimXav2owtlFRPvjAEeF3UhGBQIusaawsnLcZwXUHzF5rb51jo= ARC-Authentication-Results: i=1; mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1577094479991827.000453618303; Mon, 23 Dec 2019 01:47:59 -0800 (PST) Received: from localhost ([::1]:55204 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ijKJi-0003gg-Al for importer@patchew.org; Mon, 23 Dec 2019 04:47:58 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:45224) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ijKIX-0002nh-6C for qemu-devel@nongnu.org; Mon, 23 Dec 2019 04:46:46 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ijKIU-0005lE-Tq for qemu-devel@nongnu.org; Mon, 23 Dec 2019 04:46:44 -0500 Received: from mail.ispras.ru ([83.149.199.45]:50678) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ijKIQ-0005Yi-UL for qemu-devel@nongnu.org; Mon, 23 Dec 2019 04:46:40 -0500 Received: from [127.0.1.1] (unknown [85.142.117.226]) by mail.ispras.ru (Postfix) with ESMTPSA id D426B54007B; Mon, 23 Dec 2019 12:46:04 +0300 (MSK) Subject: [for-5.0 PATCH 01/11] replay: provide an accessor for rr filename From: Pavel Dovgalyuk To: qemu-devel@nongnu.org Date: Mon, 23 Dec 2019 12:46:04 +0300 Message-ID: <157709436456.12933.11690945726688381856.stgit@pasha-Precision-3630-Tower> In-Reply-To: <157709434917.12933.4351155074716553976.stgit@pasha-Precision-3630-Tower> References: <157709434917.12933.4351155074716553976.stgit@pasha-Precision-3630-Tower> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 83.149.199.45 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , 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 Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" From: Pavel Dovgalyuk This patch adds an accessor function for the name of the record/replay log file. Adding an accessor instead of making variable global, prevents accidental modification of this variable by other modules. Signed-off-by: Pavel Dovgalyuk --- include/sysemu/replay.h | 2 ++ replay/replay.c | 5 +++++ 2 files changed, 7 insertions(+) diff --git a/include/sysemu/replay.h b/include/sysemu/replay.h index 5471bb514d..c9c896ae8d 100644 --- a/include/sysemu/replay.h +++ b/include/sysemu/replay.h @@ -72,6 +72,8 @@ void replay_start(void); void replay_finish(void); /*! Adds replay blocker with the specified error description */ void replay_add_blocker(Error *reason); +/* Returns name of the replay log file */ +const char *replay_get_filename(void); =20 /* Processing the instructions */ =20 diff --git a/replay/replay.c b/replay/replay.c index 706c7b4f4b..9ec6ce9996 100644 --- a/replay/replay.c +++ b/replay/replay.c @@ -394,3 +394,8 @@ void replay_add_blocker(Error *reason) { replay_blockers =3D g_slist_prepend(replay_blockers, reason); } + +const char *replay_get_filename(void) +{ + return replay_filename; +} From nobody Tue May 7 05:51:30 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1577094613; cv=none; d=zohomail.com; s=zohoarc; b=Zo3HW0USjr55zgQaq3NlOT7TIJ0HDA31W6bKEZNdCAAWrUlTT1KTBZJBTNKPR+kKx/HAgFOFbYMu38z3/5ZN/ND7mLoT2329q/JN0EikhW2HzSk4tzh0V+r4UAB5eBAoedw85mIAMh6DP3ZeRVKv69jLOIpsL2bj5WNEC530uV4= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1577094613; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=CxABCsXyUueoqmxWmHcs+KYoTwVq/UjrZK5qGtwlJlI=; b=WpSMXMeomW3+5FboUI++MRsMvUHBxsWXNqsnYK+3VEWO4r3iWrQPOIOae0FMJ2Vkp6cG8sJDTt2/pV+VfQElqQhq9qe/YKz2Xj1+Gt2emlgy4Oyx4CUBFr/uznqMwvIAK7G7mmmcOHJ2/+LIUCYajYxtuPEPQUPqpiiVHHM5pBc= ARC-Authentication-Results: i=1; mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1577094613582243.48797826675457; Mon, 23 Dec 2019 01:50:13 -0800 (PST) Received: from localhost ([::1]:55222 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ijKLs-000627-Hi for importer@patchew.org; Mon, 23 Dec 2019 04:50:12 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:45333) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ijKIk-00034c-Ig for qemu-devel@nongnu.org; Mon, 23 Dec 2019 04:46:59 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ijKIj-0006qK-C0 for qemu-devel@nongnu.org; Mon, 23 Dec 2019 04:46:58 -0500 Received: from mail.ispras.ru ([83.149.199.45]:50722) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ijKIi-0006kG-TP for qemu-devel@nongnu.org; Mon, 23 Dec 2019 04:46:57 -0500 Received: from [127.0.1.1] (unknown [85.142.117.226]) by mail.ispras.ru (Postfix) with ESMTPSA id DBC3154006B; Mon, 23 Dec 2019 12:46:38 +0300 (MSK) Subject: [for-5.0 PATCH 02/11] qcow2: introduce icount field for snapshots From: Pavel Dovgalyuk To: qemu-devel@nongnu.org Date: Mon, 23 Dec 2019 12:46:38 +0300 Message-ID: <157709439859.12933.3023824005902199560.stgit@pasha-Precision-3630-Tower> In-Reply-To: <157709434917.12933.4351155074716553976.stgit@pasha-Precision-3630-Tower> References: <157709434917.12933.4351155074716553976.stgit@pasha-Precision-3630-Tower> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 83.149.199.45 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , 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 Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" From: Pavel Dovgalyuk This patch introduces the icount field for saving within the snapshot. It is required for navigation between the snapshots in record/replay mode. Signed-off-by: Pavel Dovgalyuk Acked-by: Kevin Wolf -- v2: - documented format changes in docs/interop/qcow2.txt (suggested by Eric Blake) v10: - updated the documentation --- block/qcow2-snapshot.c | 7 +++++++ block/qcow2.h | 3 +++ docs/interop/qcow2.txt | 4 ++++ 3 files changed, 14 insertions(+) diff --git a/block/qcow2-snapshot.c b/block/qcow2-snapshot.c index 5ab64da1ec..b04b3e1634 100644 --- a/block/qcow2-snapshot.c +++ b/block/qcow2-snapshot.c @@ -163,6 +163,12 @@ static int qcow2_do_read_snapshots(BlockDriverState *b= s, bool repair, sn->disk_size =3D bs->total_sectors * BDRV_SECTOR_SIZE; } =20 + if (sn->extra_data_size >=3D endof(QCowSnapshotExtraData, icount))= { + sn->icount =3D be64_to_cpu(extra.icount); + } else { + sn->icount =3D -1ULL; + } + if (sn->extra_data_size > sizeof(extra)) { uint64_t extra_data_end; size_t unknown_extra_data_size; @@ -332,6 +338,7 @@ int qcow2_write_snapshots(BlockDriverState *bs) memset(&extra, 0, sizeof(extra)); extra.vm_state_size_large =3D cpu_to_be64(sn->vm_state_size); extra.disk_size =3D cpu_to_be64(sn->disk_size); + extra.icount =3D cpu_to_be64(sn->icount); =20 id_str_size =3D strlen(sn->id_str); name_size =3D strlen(sn->name); diff --git a/block/qcow2.h b/block/qcow2.h index 0942126232..f3e0d9aa56 100644 --- a/block/qcow2.h +++ b/block/qcow2.h @@ -171,6 +171,7 @@ typedef struct QEMU_PACKED QCowSnapshotHeader { typedef struct QEMU_PACKED QCowSnapshotExtraData { uint64_t vm_state_size_large; uint64_t disk_size; + uint64_t icount; } QCowSnapshotExtraData; =20 =20 @@ -184,6 +185,8 @@ typedef struct QCowSnapshot { uint32_t date_sec; uint32_t date_nsec; uint64_t vm_clock_nsec; + /* icount value for the moment when snapshot was taken */ + uint64_t icount; /* Size of all extra data, including QCowSnapshotExtraData if availabl= e */ uint32_t extra_data_size; /* Data beyond QCowSnapshotExtraData, if any */ diff --git a/docs/interop/qcow2.txt b/docs/interop/qcow2.txt index af5711e533..aa9d447cda 100644 --- a/docs/interop/qcow2.txt +++ b/docs/interop/qcow2.txt @@ -584,6 +584,10 @@ Snapshot table entry: =20 Byte 48 - 55: Virtual disk size of the snapshot in b= ytes =20 + Byte 56 - 63: icount value which corresponds to + the record/replay instruction count + when the snapshot was taken + Version 3 images must include extra data at least up to byte 55. =20 From nobody Tue May 7 05:51:30 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1577094668; cv=none; d=zohomail.com; s=zohoarc; b=OZxClVGOTZM+wLfgsxg7yMSHnYDISofkOzuxyRqQUo5Jedn/d9a4YF5eoJ4alhXp6oBwtAHX87goCuMS5CaPnzvsQWnbf3AC9eLRsJhoj3FXHHH1qVzTVlx9v+oMRlqVIVO3XgS2s9tW7zMctaBpq2gUOSaWExmeklxrGoDYPzE= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1577094668; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=wLdfUInZF+sZmxPt8MTclf7N4uMG2uvZR0aqHILgj0o=; b=D0qey9G3FC9iGdiRTTtuDY057jdLnBoRQ01abfyoWXBf4Q16gVrWsM2Gp45jJ/lX+oPG+eNjXgRzQJ5+sPnT8lh/q6yNtcPF9dGjsEAjJS8i192RZBVFYeK76/itnxRNJAfwPjC1+G2Wg93HA/ilaLCxizEinHOTX0l+WoLGwbY= ARC-Authentication-Results: i=1; mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1577094668285631.1973018115723; Mon, 23 Dec 2019 01:51:08 -0800 (PST) Received: from localhost ([::1]:55238 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ijKMk-00079c-Sx for importer@patchew.org; Mon, 23 Dec 2019 04:51:06 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:45485) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ijKJ8-0003Sw-1D for qemu-devel@nongnu.org; Mon, 23 Dec 2019 04:47:23 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ijKJ6-0000as-Ej for qemu-devel@nongnu.org; Mon, 23 Dec 2019 04:47:21 -0500 Received: from mail.ispras.ru ([83.149.199.45]:50762) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ijKJ6-0000Ss-38 for qemu-devel@nongnu.org; Mon, 23 Dec 2019 04:47:20 -0500 Received: from [127.0.1.1] (unknown [85.142.117.226]) by mail.ispras.ru (Postfix) with ESMTPSA id A16B754006B; Mon, 23 Dec 2019 12:47:01 +0300 (MSK) Subject: [for-5.0 PATCH 03/11] migration: introduce icount field for snapshots From: Pavel Dovgalyuk To: qemu-devel@nongnu.org Date: Mon, 23 Dec 2019 12:47:01 +0300 Message-ID: <157709442133.12933.4291167191595240519.stgit@pasha-Precision-3630-Tower> In-Reply-To: <157709434917.12933.4351155074716553976.stgit@pasha-Precision-3630-Tower> References: <157709434917.12933.4351155074716553976.stgit@pasha-Precision-3630-Tower> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 83.149.199.45 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , 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 Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" From: Pavel Dovgalyuk Saving icount as a parameters of the snapshot allows navigation between them in the execution replay scenario. This information can be used for finding a specific snapshot for proceeding the recorded execution to the specific moment of the time. E.g., 'reverse step' action (introduced in one of the following patches) needs to load the nearest snapshot which is prior to the current moment of time. Signed-off-by: Pavel Dovgalyuk Acked-by: Markus Armbruster -- v2: - made icount in SnapshotInfo optional (suggested by Eric Blake) v7: - added more comments for icount member (suggested by Markus Armbruster) v9: - updated icount comment v10: - updated icount comment again Acked-by: Kevin Wolf --- block/qapi.c | 18 ++++++++++++++---- block/qcow2-snapshot.c | 2 ++ blockdev.c | 10 ++++++++++ include/block/snapshot.h | 1 + migration/savevm.c | 5 +++++ qapi/block-core.json | 7 ++++++- qapi/block.json | 3 ++- 7 files changed, 40 insertions(+), 6 deletions(-) diff --git a/block/qapi.c b/block/qapi.c index 9a5d0c9b27..110ac253ab 100644 --- a/block/qapi.c +++ b/block/qapi.c @@ -219,6 +219,8 @@ int bdrv_query_snapshot_info_list(BlockDriverState *bs, info->date_nsec =3D sn_tab[i].date_nsec; info->vm_clock_sec =3D sn_tab[i].vm_clock_nsec / 1000000000; info->vm_clock_nsec =3D sn_tab[i].vm_clock_nsec % 1000000000; + info->icount =3D sn_tab[i].icount; + info->has_icount =3D sn_tab[i].icount !=3D -1ULL; =20 info_list =3D g_new0(SnapshotInfoList, 1); info_list->value =3D info; @@ -651,14 +653,15 @@ BlockStatsList *qmp_query_blockstats(bool has_query_n= odes, void bdrv_snapshot_dump(QEMUSnapshotInfo *sn) { char date_buf[128], clock_buf[128]; + char icount_buf[128] =3D {0}; struct tm tm; time_t ti; int64_t secs; char *sizing =3D NULL; =20 if (!sn) { - qemu_printf("%-10s%-20s%7s%20s%15s", - "ID", "TAG", "VM SIZE", "DATE", "VM CLOCK"); + qemu_printf("%-10s%-18s%7s%20s%13s%11s", + "ID", "TAG", "VM SIZE", "DATE", "VM CLOCK", "ICOUNT"); } else { ti =3D sn->date_sec; localtime_r(&ti, &tm); @@ -672,11 +675,16 @@ void bdrv_snapshot_dump(QEMUSnapshotInfo *sn) (int)(secs % 60), (int)((sn->vm_clock_nsec / 1000000) % 1000)); sizing =3D size_to_str(sn->vm_state_size); - qemu_printf("%-10s%-20s%7s%20s%15s", + if (sn->icount !=3D -1ULL) { + snprintf(icount_buf, sizeof(icount_buf), + "%"PRId64, sn->icount); + } + qemu_printf("%-10s%-18s%7s%20s%13s%11s", sn->id_str, sn->name, sizing, date_buf, - clock_buf); + clock_buf, + icount_buf); } g_free(sizing); } @@ -838,6 +846,8 @@ void bdrv_image_info_dump(ImageInfo *info) .date_nsec =3D elem->value->date_nsec, .vm_clock_nsec =3D elem->value->vm_clock_sec * 1000000000U= LL + elem->value->vm_clock_nsec, + .icount =3D elem->value->has_icount ? + elem->value->icount : -1ULL, }; =20 pstrcpy(sn.id_str, sizeof(sn.id_str), elem->value->id); diff --git a/block/qcow2-snapshot.c b/block/qcow2-snapshot.c index b04b3e1634..2c003514ef 100644 --- a/block/qcow2-snapshot.c +++ b/block/qcow2-snapshot.c @@ -662,6 +662,7 @@ int qcow2_snapshot_create(BlockDriverState *bs, QEMUSna= pshotInfo *sn_info) sn->date_sec =3D sn_info->date_sec; sn->date_nsec =3D sn_info->date_nsec; sn->vm_clock_nsec =3D sn_info->vm_clock_nsec; + sn->icount =3D sn_info->icount; sn->extra_data_size =3D sizeof(QCowSnapshotExtraData); =20 /* Allocate the L1 table of the snapshot and copy the current one ther= e. */ @@ -995,6 +996,7 @@ int qcow2_snapshot_list(BlockDriverState *bs, QEMUSnaps= hotInfo **psn_tab) sn_info->date_sec =3D sn->date_sec; sn_info->date_nsec =3D sn->date_nsec; sn_info->vm_clock_nsec =3D sn->vm_clock_nsec; + sn_info->icount =3D sn->icount; } *psn_tab =3D sn_tab; return s->nb_snapshots; diff --git a/blockdev.c b/blockdev.c index 8e029e9c01..6383a64ddd 100644 --- a/blockdev.c +++ b/blockdev.c @@ -59,6 +59,7 @@ #include "sysemu/arch_init.h" #include "sysemu/qtest.h" #include "sysemu/runstate.h" +#include "sysemu/replay.h" #include "qemu/cutils.h" #include "qemu/help_option.h" #include "qemu/main-loop.h" @@ -1242,6 +1243,10 @@ SnapshotInfo *qmp_blockdev_snapshot_delete_internal_= sync(const char *device, info->vm_state_size =3D sn.vm_state_size; info->vm_clock_nsec =3D sn.vm_clock_nsec % 1000000000; info->vm_clock_sec =3D sn.vm_clock_nsec / 1000000000; + if (sn.icount !=3D -1ULL) { + info->icount =3D sn.icount; + info->has_icount =3D true; + } =20 return info; =20 @@ -1449,6 +1454,11 @@ static void internal_snapshot_prepare(BlkActionState= *common, sn->date_sec =3D tv.tv_sec; sn->date_nsec =3D tv.tv_usec * 1000; sn->vm_clock_nsec =3D qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); + if (replay_mode !=3D REPLAY_MODE_NONE) { + sn->icount =3D replay_get_current_icount(); + } else { + sn->icount =3D -1ULL; + } =20 ret1 =3D bdrv_snapshot_create(bs, sn); if (ret1 < 0) { diff --git a/include/block/snapshot.h b/include/block/snapshot.h index 2bfcd57578..b0fe42993d 100644 --- a/include/block/snapshot.h +++ b/include/block/snapshot.h @@ -42,6 +42,7 @@ typedef struct QEMUSnapshotInfo { uint32_t date_sec; /* UTC date of the snapshot */ uint32_t date_nsec; uint64_t vm_clock_nsec; /* VM clock relative to boot */ + uint64_t icount; /* record/replay step */ } QEMUSnapshotInfo; =20 int bdrv_snapshot_find(BlockDriverState *bs, QEMUSnapshotInfo *sn_info, diff --git a/migration/savevm.c b/migration/savevm.c index a71b930b91..ae84bf6ab0 100644 --- a/migration/savevm.c +++ b/migration/savevm.c @@ -2681,6 +2681,11 @@ int save_snapshot(const char *name, Error **errp) sn->date_sec =3D tv.tv_sec; sn->date_nsec =3D tv.tv_usec * 1000; sn->vm_clock_nsec =3D qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); + if (replay_mode !=3D REPLAY_MODE_NONE) { + sn->icount =3D replay_get_current_icount(); + } else { + sn->icount =3D -1ULL; + } =20 if (name) { ret =3D bdrv_snapshot_find(bs, old_sn, name); diff --git a/qapi/block-core.json b/qapi/block-core.json index 0cf68fea14..db3e435c74 100644 --- a/qapi/block-core.json +++ b/qapi/block-core.json @@ -26,13 +26,18 @@ # # @vm-clock-nsec: fractional part in nano seconds to be used with vm-clock= -sec # +# @icount: Current instruction count. Appears when execution record/replay +# is enabled. Used for "time-traveling" to match the moment +# in the recorded execution with the snapshots. (since 5.0) +# # Since: 1.3 # ## { 'struct': 'SnapshotInfo', 'data': { 'id': 'str', 'name': 'str', 'vm-state-size': 'int', 'date-sec': 'int', 'date-nsec': 'int', - 'vm-clock-sec': 'int', 'vm-clock-nsec': 'int' } } + 'vm-clock-sec': 'int', 'vm-clock-nsec': 'int', + '*icount': 'int' } } =20 ## # @ImageInfoSpecificQCow2EncryptionBase: diff --git a/qapi/block.json b/qapi/block.json index 145c268bb6..f389bb6f1a 100644 --- a/qapi/block.json +++ b/qapi/block.json @@ -176,7 +176,8 @@ # "date-sec": 1000012, # "date-nsec": 10, # "vm-clock-sec": 100, -# "vm-clock-nsec": 20 +# "vm-clock-nsec": 20, +# "icount": 220414 # } # } # From nobody Tue May 7 05:51:30 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1577094792; cv=none; d=zohomail.com; s=zohoarc; b=WkCR8anJ4fT3v6oHka/AWJZVc5ctbmLgALQ3gs8jXnhcJ5mO2IkfQa5LqTT1V/LCWTpo5qdPJLbDdc4SC52Xgth+odpNEt/OWaLrf6EjyMqgXZDl1vB3EjGR8tznaA3YsGM7s5pe8lK6YIADMxpAvs+/HCQo700ub6KR8vNcDVU= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1577094792; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=SLAiFMogOcuDuivsrG0AH3GbWtUsHjG6qVwmReMF0ko=; b=S6Ijh96cav1aaglserwRWxDg0pODPTY+Y09W4XZ5Q/f5AW45YwQrUSEWCSfEThSA6a/EHWO5F3wsU+9QRH5hs2dmJzH5lkd2L9sUMbzGMqRaj89baPQYtv2aexxNTt7kJi5BgamwXG/9cA+eaP1K89Kwu6IBG+soI1rbBNItZ1U= ARC-Authentication-Results: i=1; mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1577094792867525.5125197001823; Mon, 23 Dec 2019 01:53:12 -0800 (PST) Received: from localhost ([::1]:55262 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ijKOl-00016C-GL for importer@patchew.org; Mon, 23 Dec 2019 04:53:11 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:45558) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ijKJH-0003bZ-HC for qemu-devel@nongnu.org; Mon, 23 Dec 2019 04:47:32 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ijKJD-0001Mh-5Q for qemu-devel@nongnu.org; Mon, 23 Dec 2019 04:47:29 -0500 Received: from mail.ispras.ru ([83.149.199.45]:50812) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ijKJC-0001HE-Mz for qemu-devel@nongnu.org; Mon, 23 Dec 2019 04:47:27 -0500 Received: from [127.0.1.1] (unknown [85.142.117.226]) by mail.ispras.ru (Postfix) with ESMTPSA id 11CB254007B; Mon, 23 Dec 2019 12:47:22 +0300 (MSK) Subject: [for-5.0 PATCH 04/11] qapi: introduce replay.json for record/replay-related stuff From: Pavel Dovgalyuk To: qemu-devel@nongnu.org Date: Mon, 23 Dec 2019 12:47:21 +0300 Message-ID: <157709444173.12933.11929129160088601926.stgit@pasha-Precision-3630-Tower> In-Reply-To: <157709434917.12933.4351155074716553976.stgit@pasha-Precision-3630-Tower> References: <157709434917.12933.4351155074716553976.stgit@pasha-Precision-3630-Tower> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 83.149.199.45 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , 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 Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" From: Pavel Dovgalyuk This patch adds replay.json file. It will be used for adding record/replay-related data structures and commands. Signed-off-by: Pavel Dovgalyuk Reviewed-by: Markus Armbruster -- v10: - minor changes v13: - rebased to the new QAPI files --- MAINTAINERS | 1 + include/sysemu/replay.h | 1 + qapi/Makefile.objs | 2 +- qapi/misc.json | 18 ------------------ qapi/qapi-schema.json | 1 + qapi/replay.json | 26 ++++++++++++++++++++++++++ 6 files changed, 30 insertions(+), 19 deletions(-) create mode 100644 qapi/replay.json diff --git a/MAINTAINERS b/MAINTAINERS index 387879aebc..7ad3001b0e 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2311,6 +2311,7 @@ F: net/filter-replay.c F: include/sysemu/replay.h F: docs/replay.txt F: stubs/replay.c +F: qapi/replay.json =20 IOVA Tree M: Peter Xu diff --git a/include/sysemu/replay.h b/include/sysemu/replay.h index c9c896ae8d..e00ed2f4a5 100644 --- a/include/sysemu/replay.h +++ b/include/sysemu/replay.h @@ -14,6 +14,7 @@ =20 #include "qapi/qapi-types-misc.h" #include "qapi/qapi-types-run-state.h" +#include "qapi/qapi-types-replay.h" #include "qapi/qapi-types-ui.h" #include "block/aio.h" =20 diff --git a/qapi/Makefile.objs b/qapi/Makefile.objs index dd3f5e6f94..4e84247d0c 100644 --- a/qapi/Makefile.objs +++ b/qapi/Makefile.objs @@ -7,7 +7,7 @@ util-obj-y +=3D qapi-util.o =20 QAPI_COMMON_MODULES =3D audio authz block-core block char common crypto QAPI_COMMON_MODULES +=3D dump error introspect job machine migration misc = net -QAPI_COMMON_MODULES +=3D qdev qom rdma rocker run-state sockets tpm +QAPI_COMMON_MODULES +=3D qdev qom rdma replay rocker run-state sockets tpm QAPI_COMMON_MODULES +=3D trace transaction ui QAPI_TARGET_MODULES =3D machine-target misc-target QAPI_MODULES =3D $(QAPI_COMMON_MODULES) $(QAPI_TARGET_MODULES) diff --git a/qapi/misc.json b/qapi/misc.json index 33b94e3589..76a5f86e7f 100644 --- a/qapi/misc.json +++ b/qapi/misc.json @@ -1694,24 +1694,6 @@ { 'event': 'ACPI_DEVICE_OST', 'data': { 'info': 'ACPIOSTInfo' } } =20 -## -# @ReplayMode: -# -# Mode of the replay subsystem. -# -# @none: normal execution mode. Replay or record are not enabled. -# -# @record: record mode. All non-deterministic data is written into the -# replay log. -# -# @play: replay mode. Non-deterministic data required for system execution -# is read from the log. -# -# Since: 2.5 -## -{ 'enum': 'ReplayMode', - 'data': [ 'none', 'record', 'play' ] } - ## # @xen-load-devices-state: # diff --git a/qapi/qapi-schema.json b/qapi/qapi-schema.json index 9751b11f8f..62f425410c 100644 --- a/qapi/qapi-schema.json +++ b/qapi/qapi-schema.json @@ -103,6 +103,7 @@ { 'include': 'qdev.json' } { 'include': 'machine.json' } { 'include': 'machine-target.json' } +{ 'include': 'replay.json' } { 'include': 'misc.json' } { 'include': 'misc-target.json' } { 'include': 'audio.json' } diff --git a/qapi/replay.json b/qapi/replay.json new file mode 100644 index 0000000000..9e13551d20 --- /dev/null +++ b/qapi/replay.json @@ -0,0 +1,26 @@ +# -*- Mode: Python -*- +# + +## +# =3D Record/replay +## + +{ 'include': 'common.json' } + +## +# @ReplayMode: +# +# Mode of the replay subsystem. +# +# @none: normal execution mode. Replay or record are not enabled. +# +# @record: record mode. All non-deterministic data is written into the +# replay log. +# +# @play: replay mode. Non-deterministic data required for system execution +# is read from the log. +# +# Since: 2.5 +## +{ 'enum': 'ReplayMode', + 'data': [ 'none', 'record', 'play' ] } From nobody Tue May 7 05:51:30 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1577094583; cv=none; d=zohomail.com; s=zohoarc; b=JXUhREGdEWuXYLCkTXwU5Px/7cllbWkspxkMtLabrZa3FUGdhnGMTnAMzA3ybjeg2sTbRBd5T+QK7/MEy9w/yYPtEnxivPQnAmNScZkdiIiDT1qzIbFacpqQSffyDh2dFyhzfd97IwGSlDvfXxtHYgnqgRuABMFJUxpaL1NnZAA= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1577094583; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=cPAaJ118Kcb/rAvD5OHHCsJhBGApfKB6TZRgfHKGwX4=; b=eM04Ed95UaKkIqMPfxLZAcToPeM6x1/ZyTKHVbiQKZyAuAuqQ4nGQd+hYsQKpS/Xig7MWNHynsIbFVk7FvG0z5Z8XXJskMkd56jeEwrEwNVfAQNEdTcmU0psj+vLNjDGT0fqNGzbTMOp7e0rUVmDJQgJJPYYsH2UWya0sJ3ldkc= ARC-Authentication-Results: i=1; mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1577094583621139.80576245022985; Mon, 23 Dec 2019 01:49:43 -0800 (PST) Received: from localhost ([::1]:55218 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ijKLN-0005YH-Sc for importer@patchew.org; Mon, 23 Dec 2019 04:49:41 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:45650) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ijKJU-0003qe-KA for qemu-devel@nongnu.org; Mon, 23 Dec 2019 04:47:46 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ijKJS-0002xw-Qq for qemu-devel@nongnu.org; Mon, 23 Dec 2019 04:47:44 -0500 Received: from mail.ispras.ru ([83.149.199.45]:50858) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ijKJS-0002rM-D2 for qemu-devel@nongnu.org; Mon, 23 Dec 2019 04:47:42 -0500 Received: from [127.0.1.1] (unknown [85.142.117.226]) by mail.ispras.ru (Postfix) with ESMTPSA id 785E154006B; Mon, 23 Dec 2019 12:47:31 +0300 (MSK) Subject: [for-5.0 PATCH 05/11] replay: introduce info hmp/qmp command From: Pavel Dovgalyuk To: qemu-devel@nongnu.org Date: Mon, 23 Dec 2019 12:47:31 +0300 Message-ID: <157709445117.12933.4203495154518338251.stgit@pasha-Precision-3630-Tower> In-Reply-To: <157709434917.12933.4351155074716553976.stgit@pasha-Precision-3630-Tower> References: <157709434917.12933.4351155074716553976.stgit@pasha-Precision-3630-Tower> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 83.149.199.45 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , 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 Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" From: Pavel Dovgalyuk This patch introduces 'info replay' monitor command and corresponding qmp request. These commands request the current record/replay mode, replay log file name, and the instruction count (number of recorded/replayed instructions). The instruction count can be used with the replay_seek/replay_break commands added in the next two patches. Signed-off-by: Pavel Dovgalyuk Acked-by: Dr. David Alan Gilbert Acked-by: Markus Armbruster -- v2: - renamed info_replay qmp into query-replay (suggested by Eric Blake) v7: - added empty line (suggested by Markus Armbruster) v9: - changed 'step' parameter name to 'icount' - moved json stuff to replay.json and updated the descriptions (suggested by Markus Armbruster) v10: - updated descriptions and messages for rr stuff --- hmp-commands-info.hx | 14 ++++++++++++++ include/monitor/hmp.h | 1 + qapi/block-core.json | 3 ++- qapi/replay.json | 39 +++++++++++++++++++++++++++++++++++++++ replay/Makefile.objs | 1 + replay/replay-debugging.c | 43 +++++++++++++++++++++++++++++++++++++++++= ++ 6 files changed, 100 insertions(+), 1 deletion(-) create mode 100644 replay/replay-debugging.c diff --git a/hmp-commands-info.hx b/hmp-commands-info.hx index 257ee7d7a3..0288860db0 100644 --- a/hmp-commands-info.hx +++ b/hmp-commands-info.hx @@ -930,6 +930,20 @@ STEXI @item info sev @findex info sev Show SEV information. +ETEXI + + { + .name =3D "replay", + .args_type =3D "", + .params =3D "", + .help =3D "show record/replay information", + .cmd =3D hmp_info_replay, + }, + +STEXI +@item info replay +@findex info replay +Display the record/replay information: mode and the current icount. ETEXI =20 STEXI diff --git a/include/monitor/hmp.h b/include/monitor/hmp.h index 3d329853b2..783784cf10 100644 --- a/include/monitor/hmp.h +++ b/include/monitor/hmp.h @@ -153,5 +153,6 @@ void hmp_hotpluggable_cpus(Monitor *mon, const QDict *q= dict); void hmp_info_vm_generation_id(Monitor *mon, const QDict *qdict); void hmp_info_memory_size_summary(Monitor *mon, const QDict *qdict); void hmp_info_sev(Monitor *mon, const QDict *qdict); +void hmp_info_replay(Monitor *mon, const QDict *qdict); =20 #endif diff --git a/qapi/block-core.json b/qapi/block-core.json index db3e435c74..1b665b1ad4 100644 --- a/qapi/block-core.json +++ b/qapi/block-core.json @@ -28,7 +28,8 @@ # # @icount: Current instruction count. Appears when execution record/replay # is enabled. Used for "time-traveling" to match the moment -# in the recorded execution with the snapshots. (since 5.0) +# in the recorded execution with the snapshots. This counter may +# be obtained through @query-replay command (since 5.0) # # Since: 1.3 # diff --git a/qapi/replay.json b/qapi/replay.json index 9e13551d20..67f2d1f859 100644 --- a/qapi/replay.json +++ b/qapi/replay.json @@ -24,3 +24,42 @@ ## { 'enum': 'ReplayMode', 'data': [ 'none', 'record', 'play' ] } + +## +# @ReplayInfo: +# +# Record/replay information. +# +# @mode: current mode. +# +# @filename: name of the record/replay log file. +# It is present only in record or replay modes, when the log +# is recorded or replayed. +# +# @icount: current number of executed instructions. +# +# Since: 5.0 +# +## +{ 'struct': 'ReplayInfo', + 'data': { 'mode': 'ReplayMode', '*filename': 'str', 'icount': 'int' } } + +## +# @query-replay: +# +# Retrieve the record/replay information. +# It includes current instruction count which may be used for +# @replay-break and @replay-seek commands. +# +# Returns: record/replay information. +# +# Since: 5.0 +# +# Example: +# +# -> { "execute": "query-replay" } +# <- { "return": { "mode": "play", "filename": "log.rr", "icount": 220414 = } } +# +## +{ 'command': 'query-replay', + 'returns': 'ReplayInfo' } diff --git a/replay/Makefile.objs b/replay/Makefile.objs index 939be964a9..f847c5c023 100644 --- a/replay/Makefile.objs +++ b/replay/Makefile.objs @@ -8,3 +8,4 @@ common-obj-y +=3D replay-snapshot.o common-obj-y +=3D replay-net.o common-obj-y +=3D replay-audio.o common-obj-y +=3D replay-random.o +common-obj-y +=3D replay-debugging.o diff --git a/replay/replay-debugging.c b/replay/replay-debugging.c new file mode 100644 index 0000000000..8cf15ebc11 --- /dev/null +++ b/replay/replay-debugging.c @@ -0,0 +1,43 @@ +/* + * replay-debugging.c + * + * Copyright (c) 2010-2018 Institute for System Programming + * of the Russian Academy of Sciences. + * + * This work is licensed under the terms of the GNU GPL, version 2 or late= r. + * See the COPYING file in the top-level directory. + * + */ + +#include "qemu/osdep.h" +#include "qapi/error.h" +#include "sysemu/replay.h" +#include "replay-internal.h" +#include "monitor/hmp.h" +#include "monitor/monitor.h" +#include "qapi/qapi-commands-replay.h" + +void hmp_info_replay(Monitor *mon, const QDict *qdict) +{ + if (replay_mode =3D=3D REPLAY_MODE_NONE) { + monitor_printf(mon, "Record/replay is not active\n"); + } else { + monitor_printf(mon, + "%s execution '%s': instruction count =3D %"PRId64"\n", + replay_mode =3D=3D REPLAY_MODE_RECORD ? "Recording" : "Replayi= ng", + replay_get_filename(), replay_get_current_icount()); + } +} + +ReplayInfo *qmp_query_replay(Error **errp) +{ + ReplayInfo *retval =3D g_new0(ReplayInfo, 1); + + retval->mode =3D replay_mode; + if (replay_get_filename()) { + retval->filename =3D g_strdup(replay_get_filename()); + retval->has_filename =3D true; + } + retval->icount =3D replay_get_current_icount(); + return retval; +} From nobody Tue May 7 05:51:30 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1577094603; cv=none; d=zohomail.com; s=zohoarc; b=DT9Pjp72+X3eAfOfwuk8ORm1eAZMEALGB/XFwU6IaBpqTSdb7p5qMveFretpsJsijmkmfP7fT/DXYa/lCFItY87DH536mRACCWSppX8JbJp/KZOMDdLVYoTifDy08yq6bzF0HlPIJJh2pRe5J5TIndpaO9eFbT1VplI+GuIaBNA= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1577094603; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=Oah3EPMWIG+njk1Rk4rMVGFQTCR0r2iMc5cZACJ/1ZA=; b=SQWjusAPsDeaYWb5NJgJpNtt+JZymmP1MOB9LW2XQjQYzgdPmJ5WKTjIWyEdcQq9jEKTB91tNBZP65+L/XraXpq/xLHe31dzZNfFxcQAyhBYARhhXWo7QT7XXDFdUqquAvkiP2xRAs4ont3IwhYkjXLqzqBhGaTvsgxVSVd5qzA= ARC-Authentication-Results: i=1; mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1577094603106843.9003937746174; Mon, 23 Dec 2019 01:50:03 -0800 (PST) Received: from localhost ([::1]:55220 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ijKLh-0005l6-Hc for importer@patchew.org; Mon, 23 Dec 2019 04:50:01 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:45726) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ijKJf-00044a-2t for qemu-devel@nongnu.org; Mon, 23 Dec 2019 04:47:56 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ijKJd-00048e-1d for qemu-devel@nongnu.org; Mon, 23 Dec 2019 04:47:54 -0500 Received: from mail.ispras.ru ([83.149.199.45]:50888) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ijKJc-0003zj-Ib for qemu-devel@nongnu.org; Mon, 23 Dec 2019 04:47:52 -0500 Received: from [127.0.1.1] (unknown [85.142.117.226]) by mail.ispras.ru (Postfix) with ESMTPSA id 2BC6354006B; Mon, 23 Dec 2019 12:47:47 +0300 (MSK) Subject: [for-5.0 PATCH 06/11] replay: introduce breakpoint at the specified step From: Pavel Dovgalyuk To: qemu-devel@nongnu.org Date: Mon, 23 Dec 2019 12:47:46 +0300 Message-ID: <157709446688.12933.7598131292472178158.stgit@pasha-Precision-3630-Tower> In-Reply-To: <157709434917.12933.4351155074716553976.stgit@pasha-Precision-3630-Tower> References: <157709434917.12933.4351155074716553976.stgit@pasha-Precision-3630-Tower> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 83.149.199.45 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , 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 Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" From: Pavel Dovgalyuk This patch introduces replay_break, replay_delete_break qmp and hmp commands. These commands allow stopping at the specified instruction. It may be useful for debugging when there are some known events that should be investigated. replay_break command has one argument - number of instructions executed since the start of the replay. replay_delete_break removes previously set breakpoint. Signed-off-by: Pavel Dovgalyuk Acked-by: Markus Armbruster -- v2: - renamed replay_break qmp command into replay-break (suggested by Eric Blake) v7: - introduces replay_delete_break command v9: - changed 'step' parameter name to 'icount' - moved json stuff to replay.json and updated the description (suggested by Markus Armbruster) v10: - updated descriptions (suggested by Markus Armbruster) v11: - fixed replay_break rearm bug --- hmp-commands.hx | 34 ++++++++++++++++++ include/monitor/hmp.h | 2 + qapi/replay.json | 36 +++++++++++++++++++ replay/replay-debugging.c | 86 +++++++++++++++++++++++++++++++++++++++++= ++++ replay/replay-internal.h | 4 ++ replay/replay.c | 17 +++++++++ 6 files changed, 179 insertions(+) diff --git a/hmp-commands.hx b/hmp-commands.hx index cfcc044ce4..3704294da8 100644 --- a/hmp-commands.hx +++ b/hmp-commands.hx @@ -1930,6 +1930,40 @@ ETEXI STEXI @item qom-set @var{path} @var{property} @var{value} Set QOM property @var{property} of object at location @var{path} to value = @var{value} +ETEXI + + { + .name =3D "replay_break", + .args_type =3D "icount:i", + .params =3D "icount", + .help =3D "set breakpoint at the specified instruction count= ", + .cmd =3D hmp_replay_break, + }, + +STEXI +@item replay_break @var{icount} +@findex replay_break +Set replay breakpoint at instruction count @var{icount}. +Execution stops when the specified instruction is reached. +There can be at most one breakpoint. When breakpoint is set, any prior +one is removed. The breakpoint may be set only in replay mode and only +"in the future", i.e. at instruction counts greater than the current one. +The current instruction count can be observed with 'info replay'. +ETEXI + + { + .name =3D "replay_delete_break", + .args_type =3D "", + .params =3D "", + .help =3D "removes replay breakpoint", + .cmd =3D hmp_replay_delete_break, + }, + +STEXI +@item replay_delete_break +@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 =20 { diff --git a/include/monitor/hmp.h b/include/monitor/hmp.h index 783784cf10..0fd477aa13 100644 --- a/include/monitor/hmp.h +++ b/include/monitor/hmp.h @@ -154,5 +154,7 @@ void hmp_info_vm_generation_id(Monitor *mon, const QDic= t *qdict); void hmp_info_memory_size_summary(Monitor *mon, const QDict *qdict); 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); =20 #endif diff --git a/qapi/replay.json b/qapi/replay.json index 67f2d1f859..e3266ef3a9 100644 --- a/qapi/replay.json +++ b/qapi/replay.json @@ -63,3 +63,39 @@ ## { 'command': 'query-replay', 'returns': 'ReplayInfo' } + +## +# @replay-break: +# +# Set replay breakpoint at instruction count @icount. +# Execution stops when the specified instruction is reached. +# There can be at most one breakpoint. When breakpoint is set, any prior +# one is removed. The breakpoint may be set only in replay mode and only +# "in the future", i.e. at instruction counts greater than the current one. +# The current instruction count can be observed with @query-replay. +# +# @icount: instruction count to stop at +# +# Since: 5.0 +# +# Example: +# +# -> { "execute": "replay-break", "data": { "icount": 220414 } } +# +## +{ 'command': 'replay-break', 'data': { 'icount': 'int' } } + +## +# @replay-delete-break: +# +# Remove replay breakpoint which was set with @replay-break. +# The command is ignored when there are no replay breakpoints. +# +# Since: 5.0 +# +# Example: +# +# -> { "execute": "replay-delete-break" } +# +## +{ 'command': 'replay-delete-break' } diff --git a/replay/replay-debugging.c b/replay/replay-debugging.c index 8cf15ebc11..166ba10d2c 100644 --- a/replay/replay-debugging.c +++ b/replay/replay-debugging.c @@ -12,10 +12,13 @@ #include "qemu/osdep.h" #include "qapi/error.h" #include "sysemu/replay.h" +#include "sysemu/runstate.h" #include "replay-internal.h" #include "monitor/hmp.h" #include "monitor/monitor.h" #include "qapi/qapi-commands-replay.h" +#include "qapi/qmp/qdict.h" +#include "qemu/timer.h" =20 void hmp_info_replay(Monitor *mon, const QDict *qdict) { @@ -41,3 +44,86 @@ ReplayInfo *qmp_query_replay(Error **errp) retval->icount =3D replay_get_current_icount(); return retval; } + +static void replay_break(uint64_t icount, QEMUTimerCB callback, void *opaq= ue) +{ + assert(replay_mode =3D=3D REPLAY_MODE_PLAY); + assert(replay_mutex_locked()); + assert(replay_break_icount >=3D replay_get_current_icount()); + assert(callback); + + replay_break_icount =3D icount; + + if (replay_break_timer) { + timer_del(replay_break_timer); + } + replay_break_timer =3D timer_new_ns(QEMU_CLOCK_REALTIME, + callback, opaque); +} + +static void replay_delete_break(void) +{ + assert(replay_mode =3D=3D REPLAY_MODE_PLAY); + assert(replay_mutex_locked()); + + if (replay_break_timer) { + timer_del(replay_break_timer); + timer_free(replay_break_timer); + replay_break_timer =3D NULL; + } + replay_break_icount =3D -1ULL; +} + +static void replay_stop_vm(void *opaque) +{ + vm_stop(RUN_STATE_PAUSED); + replay_delete_break(); +} + +void qmp_replay_break(int64_t icount, Error **errp) +{ + if (replay_mode =3D=3D REPLAY_MODE_PLAY) { + if (icount >=3D replay_get_current_icount()) { + replay_break(icount, replay_stop_vm, NULL); + } else { + error_setg(errp, + "cannot set breakpoint at the instruction in the past"); + } + } else { + error_setg(errp, "setting the breakpoint is allowed only in play m= ode"); + } +} + +void hmp_replay_break(Monitor *mon, const QDict *qdict) +{ + int64_t icount =3D qdict_get_try_int(qdict, "icount", -1LL); + Error *err =3D NULL; + + qmp_replay_break(icount, &err); + if (err) { + error_report_err(err); + error_free(err); + return; + } +} + +void qmp_replay_delete_break(Error **errp) +{ + if (replay_mode =3D=3D REPLAY_MODE_PLAY) { + replay_delete_break(); + } else { + error_setg(errp, "replay breakpoints are allowed only in play mode= "); + } +} + +void hmp_replay_delete_break(Monitor *mon, const QDict *qdict) +{ + Error *err =3D NULL; + + qmp_replay_delete_break(&err); + if (err) { + error_report_err(err); + error_free(err); + return; + } +} diff --git a/replay/replay-internal.h b/replay/replay-internal.h index 33ac551e78..2f6145ec7c 100644 --- a/replay/replay-internal.h +++ b/replay/replay-internal.h @@ -94,6 +94,10 @@ extern ReplayState replay_state; =20 /* File for replay writing */ extern FILE *replay_file; +/* Instruction count of the replay breakpoint */ +extern uint64_t replay_break_icount; +/* Timer for the replay breakpoint callback */ +extern QEMUTimer *replay_break_timer; =20 void replay_put_byte(uint8_t byte); void replay_put_event(uint8_t event); diff --git a/replay/replay.c b/replay/replay.c index 9ec6ce9996..86b3e943c2 100644 --- a/replay/replay.c +++ b/replay/replay.c @@ -34,6 +34,10 @@ static char *replay_filename; ReplayState replay_state; static GSList *replay_blockers; =20 +/* Replay breakpoints */ +uint64_t replay_break_icount =3D -1ULL; +QEMUTimer *replay_break_timer; + bool replay_next_event_is(int event) { bool res =3D false; @@ -73,6 +77,13 @@ int replay_get_instructions(void) replay_mutex_lock(); if (replay_next_event_is(EVENT_INSTRUCTION)) { res =3D replay_state.instruction_count; + if (replay_break_icount !=3D -1LL) { + uint64_t current =3D replay_get_current_icount(); + assert(replay_break_icount >=3D current); + if (current + res > replay_break_icount) { + res =3D replay_break_icount - current; + } + } } replay_mutex_unlock(); return res; @@ -99,6 +110,12 @@ void replay_account_executed_instructions(void) will be read from the log. */ qemu_notify_event(); } + /* Execution reached the break step */ + if (replay_break_icount =3D=3D replay_state.current_icount) { + /* Cannot make callback directly from the vCPU thread */ + timer_mod_ns(replay_break_timer, + qemu_clock_get_ns(QEMU_CLOCK_REALTIME)); + } } } } From nobody Tue May 7 05:51:30 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1577094787; cv=none; d=zohomail.com; s=zohoarc; b=SColonopKB4pxxHMM73pjB7AqdqYLLCk2SPcI1NvOtrL2zsRXaNWARWUWa1x+HyQiuzxr4REjbEow6xyQNbJmAfEEmuxC6rFJXx4ye38qJTFzglBUu2hnIIjnbhoKB8NF/51HpeKXRzJNXTqCpyNPZWm9UnyJXK3sqcY7b8qwUg= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1577094787; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=ZW4Jk8q901B88OzVe6BW3ZGeeUJbmtelJjlON6CArwU=; b=XVrQLPW1Gy1O8vWLwe3uXQySv4w8z+pL4OzWn50PZ+eCBpts2ij99insjAeHFiJreIP2KoSJPaboYegbunjtUsesZEd3iqnk7q3iKlU9OGFzsn2O2m2ekAXSVtPiErjLiwVYN69WhT0lL5YvYr5YsqXHsdlS85qeikF5YDs2SaQ= ARC-Authentication-Results: i=1; mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1577094787753435.979301954088; Mon, 23 Dec 2019 01:53:07 -0800 (PST) Received: from localhost ([::1]:55260 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ijKOg-0000z9-5s for importer@patchew.org; Mon, 23 Dec 2019 04:53:06 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:45824) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ijKJl-0004Bn-9o for qemu-devel@nongnu.org; Mon, 23 Dec 2019 04:48:02 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ijKJj-0004zG-J1 for qemu-devel@nongnu.org; Mon, 23 Dec 2019 04:48:01 -0500 Received: from mail.ispras.ru ([83.149.199.45]:50916) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ijKJj-0004r1-31 for qemu-devel@nongnu.org; Mon, 23 Dec 2019 04:47:59 -0500 Received: from [127.0.1.1] (unknown [85.142.117.226]) by mail.ispras.ru (Postfix) with ESMTPSA id 4DEB854007B; Mon, 23 Dec 2019 12:47:56 +0300 (MSK) Subject: [for-5.0 PATCH 07/11] replay: implement replay-seek command From: Pavel Dovgalyuk To: qemu-devel@nongnu.org Date: Mon, 23 Dec 2019 12:47:56 +0300 Message-ID: <157709447600.12933.3498260261791500909.stgit@pasha-Precision-3630-Tower> In-Reply-To: <157709434917.12933.4351155074716553976.stgit@pasha-Precision-3630-Tower> References: <157709434917.12933.4351155074716553976.stgit@pasha-Precision-3630-Tower> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 83.149.199.45 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , 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 Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" From: Pavel Dovgalyuk 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 Acked-by: Markus Armbruster -- 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 +++++++++ include/monitor/hmp.h | 1=20 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 3704294da8..420565c7f8 100644 --- a/hmp-commands.hx +++ b/hmp-commands.hx @@ -1964,6 +1964,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 =3D "replay_seek", + .args_type =3D "icount:i", + .params =3D "icount", + .help =3D "replay execution to the specified instruction cou= nt", + .cmd =3D 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 =20 { diff --git a/include/monitor/hmp.h b/include/monitor/hmp.h index 0fd477aa13..bd97d4a8c6 100644 --- a/include/monitor/hmp.h +++ b/include/monitor/hmp.h @@ -156,5 +156,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); =20 #endif diff --git a/qapi/replay.json b/qapi/replay.json index e3266ef3a9..5d24cdc680 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: 5.0 +# +# 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 166ba10d2c..f5a02a5aa1 100644 --- a/replay/replay-debugging.c +++ b/replay/replay-debugging.c @@ -19,6 +19,8 @@ #include "qapi/qapi-commands-replay.h" #include "qapi/qmp/qdict.h" #include "qemu/timer.h" +#include "block/snapshot.h" +#include "migration/snapshot.h" =20 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 =3D NULL; + char *ret =3D NULL; + int nb_sns, i; + AioContext *aio_context; + + *snapshot_icount =3D -1; + + bs =3D bdrv_all_find_vmstate_bs(); + if (!bs) { + goto fail; + } + aio_context =3D bdrv_get_aio_context(bs); + + aio_context_acquire(aio_context); + nb_sns =3D bdrv_snapshot_list(bs, &sn_tab); + aio_context_release(aio_context); + + for (i =3D 0; i < nb_sns; i++) { + if (bdrv_all_find_snapshot(sn_tab[i].name, &bs) =3D=3D 0) { + if (sn_tab[i].icount !=3D -1ULL + && sn_tab[i].icount <=3D icount + && (!nearest || nearest->icount < sn_tab[i].icount)) { + nearest =3D &sn_tab[i]; + } + } + } + if (nearest) { + ret =3D g_strdup(nearest->name); + *snapshot_icount =3D nearest->icount; + } + g_free(sn_tab); + +fail: + return ret; +} + +static void replay_seek(int64_t icount, QEMUTimerCB callback, Error **errp) +{ + char *snapshot =3D NULL; + int64_t snapshot_icount; + + if (replay_mode !=3D REPLAY_MODE_PLAY) { + error_setg(errp, "replay must be enabled to seek"); + return; + } + if (!replay_snapshot) { + error_setg(errp, "snapshotting is disabled"); + return; + } + + snapshot =3D replay_find_nearest_snapshot(icount, &snapshot_icount); + if (snapshot) { + if (icount < replay_get_current_icount() + || replay_get_current_icount() < snapshot_icount) { + vm_stop(RUN_STATE_RESTORE_VM); + load_snapshot(snapshot, errp); + } + g_free(snapshot); + } + if (replay_get_current_icount() <=3D 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 =3D qdict_get_try_int(qdict, "icount", -1LL); + Error *err =3D NULL; + + qmp_replay_seek(icount, &err); + if (err) { + error_report_err(err); + error_free(err); + return; + } +} From nobody Tue May 7 05:51:30 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1577094924; cv=none; d=zohomail.com; s=zohoarc; b=Ga+TpJckqN7GZA/7cwe7+bPMv4UvH0C39775vWeR7wvNqnAvCQFjtWtg99JK+QoMNleNrRbFHqqU/Z2SWPdTuCXlgyNAuapQ17J22WZy6rsO5LdHQHoHrvc/0O7IciweqAE1STWuqreea7LICpw28Lx0fjgA10QxoOmLFZlKfAA= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1577094924; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=WlbUgVLiYLm7pBO6x1m2+dLnqyteBvHRiKPiG4vFCb0=; b=Vh1TkJTU1s6PBseoFKRli0S7oift+2tvqIuo9aCiRW+Tu69mKivgTJxlf71t3TRVcSfCWD7TJZhloytMWJ76VKOYrkvX4gViKfgtj5B0xrtfDTPqVgtmgBj+s8A488ctJ6iIQRjnSkdBqMAanA4vWsFKyiVkd9ipI4EkEAsj+n8= ARC-Authentication-Results: i=1; mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1577094924508280.35714016277984; Mon, 23 Dec 2019 01:55:24 -0800 (PST) Received: from localhost ([::1]:55284 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ijKQt-0003qV-Fm for importer@patchew.org; Mon, 23 Dec 2019 04:55:23 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:45856) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ijKJr-0004Jc-AQ for qemu-devel@nongnu.org; Mon, 23 Dec 2019 04:48:08 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ijKJq-0005yU-1b for qemu-devel@nongnu.org; Mon, 23 Dec 2019 04:48:07 -0500 Received: from mail.ispras.ru ([83.149.199.45]:50932) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ijKJp-0005t1-L8 for qemu-devel@nongnu.org; Mon, 23 Dec 2019 04:48:05 -0500 Received: from [127.0.1.1] (unknown [85.142.117.226]) by mail.ispras.ru (Postfix) with ESMTPSA id D9B5B54006B; Mon, 23 Dec 2019 12:48:03 +0300 (MSK) Subject: [for-5.0 PATCH 08/11] replay: flush rr queue before loading the vmstate From: Pavel Dovgalyuk To: qemu-devel@nongnu.org Date: Mon, 23 Dec 2019 12:48:03 +0300 Message-ID: <157709448356.12933.1621745423878239085.stgit@pasha-Precision-3630-Tower> In-Reply-To: <157709434917.12933.4351155074716553976.stgit@pasha-Precision-3630-Tower> References: <157709434917.12933.4351155074716553976.stgit@pasha-Precision-3630-Tower> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 83.149.199.45 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , 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 Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" From: Pavel Dovgalyuk Non-empty record/replay queue prevents saving and loading the VM state, because it includes pending bottom halves and block coroutines. But when the new VM state is loaded, we don't have to preserve the consiste= ncy of the current state anymore. Therefore this patch just flushes the queue allowing the coroutines to finish and removes checking for empty rr queue for load_snapshot function. Signed-off-by: Pavel Dovgalyuk --- include/sysemu/replay.h | 2 ++ migration/savevm.c | 12 ++++++------ replay/replay-internal.h | 2 -- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/include/sysemu/replay.h b/include/sysemu/replay.h index e00ed2f4a5..239c01e7df 100644 --- a/include/sysemu/replay.h +++ b/include/sysemu/replay.h @@ -149,6 +149,8 @@ void replay_disable_events(void); void replay_enable_events(void); /*! Returns true when saving events is enabled */ bool replay_events_enabled(void); +/* Flushes events queue */ +void replay_flush_events(void); /*! Adds bottom half event to the queue */ void replay_bh_schedule_event(QEMUBH *bh); /* Adds oneshot bottom half event to the queue */ diff --git a/migration/savevm.c b/migration/savevm.c index ae84bf6ab0..0c5cac372a 100644 --- a/migration/savevm.c +++ b/migration/savevm.c @@ -2834,12 +2834,6 @@ int load_snapshot(const char *name, Error **errp) AioContext *aio_context; MigrationIncomingState *mis =3D migration_incoming_get_current(); =20 - if (!replay_can_snapshot()) { - error_setg(errp, "Record/replay does not allow loading snapshot " - "right now. Try once more later."); - return -EINVAL; - } - if (!bdrv_all_can_snapshot(&bs)) { error_setg(errp, "Device '%s' is writable but does not support snapshots= ", @@ -2873,6 +2867,12 @@ int load_snapshot(const char *name, Error **errp) return -EINVAL; } =20 + /* + * Flush the record/replay queue. Now the VM state is going + * to change. Therefore we don't need to preserve its consistency + */ + replay_flush_events(); + /* Flush all IO requests so they don't interfere with the new state. = */ bdrv_drain_all_begin(); =20 diff --git a/replay/replay-internal.h b/replay/replay-internal.h index 2f6145ec7c..97649ed8d7 100644 --- a/replay/replay-internal.h +++ b/replay/replay-internal.h @@ -149,8 +149,6 @@ void replay_read_next_clock(unsigned int kind); void replay_init_events(void); /*! Clears internal data structures for events handling */ void replay_finish_events(void); -/*! Flushes events queue */ -void replay_flush_events(void); /*! Returns true if there are any unsaved events in the queue */ bool replay_has_events(void); /*! Saves events from queue into the file */ From nobody Tue May 7 05:51:30 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1577094856; cv=none; d=zohomail.com; s=zohoarc; b=M30NkvUck13g7k1Y8Wkq+G4tjkDfMBfDJQg9rtLuo8IOmSpJ44i6hvsUEfnG58ZUUKq8ONMA5oHyIZ2/yP3eibatKrdY2Lz/ufjeQG1+XJSzi0qCozxFF5XPeBJDrRJ8gpZnyXwwey6SvgRIqX/Q6smeF8Adr/57OMx0BTpGJJM= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1577094856; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=Ltd+o/Z9Gi8KbsLnD8KFjAZmNYRf7Cu+67a0EfLbHuQ=; b=HsBmmdMX/x7DsFk0GKVG2oRgWlLWQ6R1wWuf2JNHnNKgHYhyU6R+w6e8BUK7fMUmF4uJdTFd7WiaOqfK4qF/HTOSNeD78kor2ARC5Yw1cM37JhpxBotm5ymCPoOZsFLTdmQnQtiIqIEsCY5lnCSm7hxJtvm99+AcrsoaENC1jRE= ARC-Authentication-Results: i=1; mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1577094856682705.8492221638263; Mon, 23 Dec 2019 01:54:16 -0800 (PST) Received: from localhost ([::1]:55264 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ijKPn-00029V-Jd for importer@patchew.org; Mon, 23 Dec 2019 04:54:15 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:45930) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ijKK3-0004Vn-F7 for qemu-devel@nongnu.org; Mon, 23 Dec 2019 04:48:21 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ijKK1-0006yR-FN for qemu-devel@nongnu.org; Mon, 23 Dec 2019 04:48:19 -0500 Received: from mail.ispras.ru ([83.149.199.45]:50972) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ijKK1-0006sQ-0Q for qemu-devel@nongnu.org; Mon, 23 Dec 2019 04:48:17 -0500 Received: from [127.0.1.1] (unknown [85.142.117.226]) by mail.ispras.ru (Postfix) with ESMTPSA id 7BE3E54007B; Mon, 23 Dec 2019 12:48:10 +0300 (MSK) Subject: [for-5.0 PATCH 09/11] gdbstub: add reverse step support in replay mode From: Pavel Dovgalyuk To: qemu-devel@nongnu.org Date: Mon, 23 Dec 2019 12:48:10 +0300 Message-ID: <157709449019.12933.13802440209431555090.stgit@pasha-Precision-3630-Tower> In-Reply-To: <157709434917.12933.4351155074716553976.stgit@pasha-Precision-3630-Tower> References: <157709434917.12933.4351155074716553976.stgit@pasha-Precision-3630-Tower> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 83.149.199.45 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , 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 Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" From: Pavel Dovgalyuk GDB remote protocol supports two reverse debugging commands: reverse step and reverse continue. This patch adds support of the first one to the gdbstub. Reverse step is intended to step one instruction in the backwards direction. This is not possible in regular execution. But replayed execution is deterministic, therefore we can load one of the prior snapshots and proceed to the desired step. It is equivalent to stepping one instruction back. There should be at least one snapshot preceding the debugged part of the replay log. Signed-off-by: Pavel Dovgalyuk --- accel/tcg/translator.c | 1 + cpus.c | 14 +++++++++-- exec.c | 7 ++++++ gdbstub.c | 56 +++++++++++++++++++++++++++++++++++++++++= ++-- include/sysemu/replay.h | 11 +++++++++ replay/replay-debugging.c | 33 +++++++++++++++++++++++++++ stubs/replay.c | 5 ++++ 7 files changed, 121 insertions(+), 6 deletions(-) diff --git a/accel/tcg/translator.c b/accel/tcg/translator.c index 603d17ff83..fb1e19c585 100644 --- a/accel/tcg/translator.c +++ b/accel/tcg/translator.c @@ -17,6 +17,7 @@ #include "exec/log.h" #include "exec/translator.h" #include "exec/plugin-gen.h" +#include "sysemu/replay.h" =20 /* Pairs with tcg_clear_temp_count. To be called by #TranslatorOps.{translate_insn,tb_stop} if diff --git a/cpus.c b/cpus.c index be2d655f37..4951a68796 100644 --- a/cpus.c +++ b/cpus.c @@ -1062,9 +1062,17 @@ static bool cpu_can_run(CPUState *cpu) =20 static void cpu_handle_guest_debug(CPUState *cpu) { - gdb_set_stop_cpu(cpu); - qemu_system_debug_request(); - cpu->stopped =3D true; + if (!replay_running_debug()) { + gdb_set_stop_cpu(cpu); + qemu_system_debug_request(); + cpu->stopped =3D true; + } else { + if (!cpu->singlestep_enabled) { + cpu_single_step(cpu, SSTEP_ENABLE); + } else { + cpu_single_step(cpu, 0); + } + } } =20 #ifdef CONFIG_LINUX diff --git a/exec.c b/exec.c index d4b769d0d4..861fcc7ea3 100644 --- a/exec.c +++ b/exec.c @@ -2743,6 +2743,13 @@ void cpu_check_watchpoint(CPUState *cpu, vaddr addr,= vaddr len, QTAILQ_FOREACH(wp, &cpu->watchpoints, entry) { if (watchpoint_address_matches(wp, addr, len) && (wp->flags & flags)) { + if (replay_running_debug()) { + /* + * Don't process the watchpoints when we are + * in a reverse debugging operation. + */ + return; + } if (flags =3D=3D BP_MEM_READ) { wp->flags |=3D BP_WATCHPOINT_HIT_READ; } else { diff --git a/gdbstub.c b/gdbstub.c index 4cf8af365e..6539c8017e 100644 --- a/gdbstub.c +++ b/gdbstub.c @@ -51,6 +51,7 @@ #include "sysemu/runstate.h" #include "hw/semihosting/semihost.h" #include "exec/exec-all.h" +#include "sysemu/replay.h" =20 #ifdef CONFIG_USER_ONLY #define GDB_ATTACHED "0" @@ -372,6 +373,20 @@ typedef struct GDBState { */ static int sstep_flags =3D SSTEP_ENABLE|SSTEP_NOIRQ|SSTEP_NOTIMER; =20 +/* Retrieves flags for single step mode. */ +static int get_sstep_flags(void) +{ + /* + * In replay mode all events written into the log should be replayed. + * That is why NOIRQ flag is removed in this mode. + */ + if (replay_mode !=3D REPLAY_MODE_NONE) { + return SSTEP_ENABLE; + } else { + return sstep_flags; + } +} + static GDBState *gdbserver_state; =20 bool gdb_has_xml; @@ -462,7 +477,7 @@ static int gdb_continue_partial(GDBState *s, char *news= tates) CPU_FOREACH(cpu) { if (newstates[cpu->cpu_index] =3D=3D 's') { trace_gdbstub_op_stepping(cpu->cpu_index); - cpu_single_step(cpu, sstep_flags); + cpu_single_step(cpu, get_sstep_flags()); } } s->running_state =3D 1; @@ -481,7 +496,7 @@ static int gdb_continue_partial(GDBState *s, char *news= tates) break; /* nothing to do here */ case 's': trace_gdbstub_op_stepping(cpu->cpu_index); - cpu_single_step(cpu, sstep_flags); + cpu_single_step(cpu, get_sstep_flags()); cpu_resume(cpu); flag =3D 1; break; @@ -1847,10 +1862,31 @@ static void handle_step(GdbCmdContext *gdb_ctx, voi= d *user_ctx) gdb_set_cpu_pc(gdb_ctx->s, (target_ulong)gdb_ctx->params[0].val_ul= l); } =20 - cpu_single_step(gdb_ctx->s->c_cpu, sstep_flags); + cpu_single_step(gdb_ctx->s->c_cpu, get_sstep_flags()); gdb_continue(gdb_ctx->s); } =20 +static void handle_backward(GdbCmdContext *gdb_ctx, void *user_ctx) +{ + if (replay_mode !=3D REPLAY_MODE_PLAY) { + put_packet(gdb_ctx->s, "E22"); + } + if (gdb_ctx->num_params =3D=3D 1) { + switch (gdb_ctx->params[0].opcode) { + case 's': + if (replay_reverse_step()) { + gdb_continue(gdb_ctx->s); + } else { + put_packet(gdb_ctx->s, "E14"); + } + return; + } + } + + /* Default invalid command */ + put_packet(gdb_ctx->s, ""); +} + static void handle_v_cont_query(GdbCmdContext *gdb_ctx, void *user_ctx) { put_packet(gdb_ctx->s, "vCont;c;C;s;S"); @@ -2105,6 +2141,9 @@ static void handle_query_supported(GdbCmdContext *gdb= _ctx, void *user_ctx) pstrcat(gdb_ctx->str_buf, sizeof(gdb_ctx->str_buf), ";qXfer:features:read+"); } + if (replay_mode =3D=3D REPLAY_MODE_PLAY) { + pstrcat(gdb_ctx->str_buf, sizeof(gdb_ctx->str_buf), ";ReverseStep+= "); + } =20 if (gdb_ctx->num_params && strstr(gdb_ctx->params[0].data, "multiprocess+")) { @@ -2444,6 +2483,17 @@ static int gdb_handle_packet(GDBState *s, const char= *line_buf) cmd_parser =3D &step_cmd_desc; } break; + case 'b': + { + static const GdbCmdParseEntry backward_cmd_desc =3D { + .handler =3D handle_backward, + .cmd =3D "b", + .cmd_startswith =3D 1, + .schema =3D "o0" + }; + cmd_parser =3D &backward_cmd_desc; + } + break; case 'F': { static const GdbCmdParseEntry file_io_cmd_desc =3D { diff --git a/include/sysemu/replay.h b/include/sysemu/replay.h index 239c01e7df..13a8123b09 100644 --- a/include/sysemu/replay.h +++ b/include/sysemu/replay.h @@ -75,6 +75,17 @@ void replay_finish(void); void replay_add_blocker(Error *reason); /* Returns name of the replay log file */ const char *replay_get_filename(void); +/* + * Start making one step in backward direction. + * Used by gdbstub for backwards debugging. + * Returns true on success. + */ +bool replay_reverse_step(void); +/* + * Returns true if replay module is processing + * reverse_continue or reverse_step request + */ +bool replay_running_debug(void); =20 /* Processing the instructions */ =20 diff --git a/replay/replay-debugging.c b/replay/replay-debugging.c index f5a02a5aa1..cdc01af4a2 100644 --- a/replay/replay-debugging.c +++ b/replay/replay-debugging.c @@ -22,6 +22,13 @@ #include "block/snapshot.h" #include "migration/snapshot.h" =20 +static bool replay_is_debugging; + +bool replay_running_debug(void) +{ + return replay_is_debugging; +} + void hmp_info_replay(Monitor *mon, const QDict *qdict) { if (replay_mode =3D=3D REPLAY_MODE_NONE) { @@ -219,3 +226,29 @@ void hmp_replay_seek(Monitor *mon, const QDict *qdict) return; } } + +static void replay_stop_vm_debug(void *opaque) +{ + replay_is_debugging =3D false; + vm_stop(RUN_STATE_DEBUG); + replay_delete_break(); +} + +bool replay_reverse_step(void) +{ + Error *err =3D NULL; + + assert(replay_mode =3D=3D REPLAY_MODE_PLAY); + + if (replay_get_current_icount() !=3D 0) { + replay_seek(replay_get_current_icount() - 1, replay_stop_vm_debug,= &err); + if (err) { + error_free(err); + return false; + } + replay_is_debugging =3D true; + return true; + } + + return false; +} diff --git a/stubs/replay.c b/stubs/replay.c index 5974ec1f50..3d9f99ebb6 100644 --- a/stubs/replay.c +++ b/stubs/replay.c @@ -88,3 +88,8 @@ int replay_read_random(void *buf, size_t len) { return 0; } + +bool replay_reverse_step(void) +{ + return false; +} From nobody Tue May 7 05:51:30 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1577094991; cv=none; d=zohomail.com; s=zohoarc; b=HEuNIDluEovCOpiv4kA2tXAoD5J+1oq+j4njV7549u6ukJRqMfMCh5VLlplmgSZ7FSAnRUu3+EosVD0luyIkkBYwqm7jJzYJhrQhytXU1lVdfdmqMHwtd/LNfweEt7EGhVJalk4vud6os9jmlbnmptaZWzNz0BaYNN/xRWcWquY= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1577094991; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=gYPv2XleGPbrR6RRfj4ka1SQ9tHm47bIiJ1/Doe6OQ4=; b=JwicOn9PwSLRZwk6udmqryvCKxJwI3lAbCE7w0AZBzEffXg5+E5302u/vqipigPtWHl370XxIGi1e97syJ8p43ib/Yo7WjSTUIIpZZa/dR2l8zGbZ1VBQPQl9MD2TbICJtnvJ6XjHQFKz+tmXezKsO+Ttew4lUMJao3y5S4t+jA= ARC-Authentication-Results: i=1; mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1577094991045521.182798433959; Mon, 23 Dec 2019 01:56:31 -0800 (PST) Received: from localhost ([::1]:55328 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ijKRy-00050u-6T for importer@patchew.org; Mon, 23 Dec 2019 04:56:30 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:46009) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ijKKG-0004l2-8y for qemu-devel@nongnu.org; Mon, 23 Dec 2019 04:48:33 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ijKKE-0008Qt-Le for qemu-devel@nongnu.org; Mon, 23 Dec 2019 04:48:32 -0500 Received: from mail.ispras.ru ([83.149.199.45]:51010) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ijKKE-0008Ja-7w for qemu-devel@nongnu.org; Mon, 23 Dec 2019 04:48:30 -0500 Received: from [127.0.1.1] (unknown [85.142.117.226]) by mail.ispras.ru (Postfix) with ESMTPSA id C25EB54006B; Mon, 23 Dec 2019 12:48:21 +0300 (MSK) Subject: [for-5.0 PATCH 10/11] gdbstub: add reverse continue support in replay mode From: Pavel Dovgalyuk To: qemu-devel@nongnu.org Date: Mon, 23 Dec 2019 12:48:21 +0300 Message-ID: <157709450147.12933.15163293655239429330.stgit@pasha-Precision-3630-Tower> In-Reply-To: <157709434917.12933.4351155074716553976.stgit@pasha-Precision-3630-Tower> References: <157709434917.12933.4351155074716553976.stgit@pasha-Precision-3630-Tower> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 83.149.199.45 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , 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 Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" From: Pavel Dovgalyuk This patch adds support of the reverse continue operation for gdbstub. Reverse continue finds the last breakpoint that would happen in normal execution from the beginning to the current moment. Implementation of the reverse continue replays the execution twice: to find the breakpoints that were hit and to seek to the last breakpoint. Reverse continue loads the previous snapshot and tries to find the breakpoi= nt since that moment. If there are no such breakpoints, it proceeds to the earlier snapshot, and so on. When no breakpoints or watchpoints were hit at all, execution stops at the beginning of the replay log. Signed-off-by: Pavel Dovgalyuk --- cpus.c | 5 +++ exec.c | 1 + gdbstub.c | 10 ++++++ include/sysemu/replay.h | 8 +++++ replay/replay-debugging.c | 71 +++++++++++++++++++++++++++++++++++++++++= ++++ stubs/replay.c | 5 +++ 6 files changed, 99 insertions(+), 1 deletion(-) diff --git a/cpus.c b/cpus.c index 4951a68796..5a5e7e5f4e 100644 --- a/cpus.c +++ b/cpus.c @@ -1068,6 +1068,11 @@ static void cpu_handle_guest_debug(CPUState *cpu) cpu->stopped =3D true; } else { if (!cpu->singlestep_enabled) { + /* + * Report about the breakpoint and + * make a single step to skip it + */ + replay_breakpoint(); cpu_single_step(cpu, SSTEP_ENABLE); } else { cpu_single_step(cpu, 0); diff --git a/exec.c b/exec.c index 861fcc7ea3..0d5ea6b6fe 100644 --- a/exec.c +++ b/exec.c @@ -2748,6 +2748,7 @@ void cpu_check_watchpoint(CPUState *cpu, vaddr addr, = vaddr len, * Don't process the watchpoints when we are * in a reverse debugging operation. */ + replay_breakpoint(); return; } if (flags =3D=3D BP_MEM_READ) { diff --git a/gdbstub.c b/gdbstub.c index 6539c8017e..2298e4cb98 100644 --- a/gdbstub.c +++ b/gdbstub.c @@ -1880,6 +1880,13 @@ static void handle_backward(GdbCmdContext *gdb_ctx, = void *user_ctx) put_packet(gdb_ctx->s, "E14"); } return; + case 'c': + if (replay_reverse_continue()) { + gdb_continue(gdb_ctx->s); + } else { + put_packet(gdb_ctx->s, "E14"); + } + return; } } =20 @@ -2142,7 +2149,8 @@ static void handle_query_supported(GdbCmdContext *gdb= _ctx, void *user_ctx) ";qXfer:features:read+"); } if (replay_mode =3D=3D REPLAY_MODE_PLAY) { - pstrcat(gdb_ctx->str_buf, sizeof(gdb_ctx->str_buf), ";ReverseStep+= "); + pstrcat(gdb_ctx->str_buf, sizeof(gdb_ctx->str_buf), + ";ReverseStep+;ReverseContinue+"); } =20 if (gdb_ctx->num_params && diff --git a/include/sysemu/replay.h b/include/sysemu/replay.h index 13a8123b09..b6cac175c4 100644 --- a/include/sysemu/replay.h +++ b/include/sysemu/replay.h @@ -81,11 +81,19 @@ const char *replay_get_filename(void); * Returns true on success. */ bool replay_reverse_step(void); +/* + * Start searching the last breakpoint/watchpoint. + * Used by gdbstub for backwards debugging. + * Returns true if the process successfully started. + */ +bool replay_reverse_continue(void); /* * Returns true if replay module is processing * reverse_continue or reverse_step request */ bool replay_running_debug(void); +/* Called in reverse debugging mode to collect breakpoint information */ +void replay_breakpoint(void); =20 /* Processing the instructions */ =20 diff --git a/replay/replay-debugging.c b/replay/replay-debugging.c index cdc01af4a2..e4a083949e 100644 --- a/replay/replay-debugging.c +++ b/replay/replay-debugging.c @@ -23,6 +23,8 @@ #include "migration/snapshot.h" =20 static bool replay_is_debugging; +static int64_t replay_last_breakpoint; +static int64_t replay_last_snapshot; =20 bool replay_running_debug(void) { @@ -252,3 +254,72 @@ bool replay_reverse_step(void) =20 return false; } + +static void replay_continue_end(void) +{ + replay_is_debugging =3D false; + vm_stop(RUN_STATE_DEBUG); + replay_delete_break(); +} + +static void replay_continue_stop(void *opaque) +{ + Error *err =3D NULL; + if (replay_last_breakpoint !=3D -1LL) { + replay_seek(replay_last_breakpoint, replay_stop_vm_debug, &err); + if (err) { + error_free(err); + replay_continue_end(); + } + return; + } + /* + * No breakpoints since the last snapshot. + * Find previous snapshot and try again. + */ + if (replay_last_snapshot !=3D 0) { + replay_seek(replay_last_snapshot - 1, replay_continue_stop, &err); + if (err) { + error_free(err); + replay_continue_end(); + } + replay_last_snapshot =3D replay_get_current_icount(); + return; + } else { + /* Seek to the very first step */ + replay_seek(0, replay_stop_vm_debug, &err); + if (err) { + error_free(err); + replay_continue_end(); + } + return; + } + replay_continue_end(); +} + +bool replay_reverse_continue(void) +{ + Error *err =3D NULL; + + assert(replay_mode =3D=3D REPLAY_MODE_PLAY); + + if (replay_get_current_icount() !=3D 0) { + replay_seek(replay_get_current_icount() - 1, replay_continue_stop,= &err); + if (err) { + error_free(err); + return false; + } + replay_last_breakpoint =3D -1LL; + replay_is_debugging =3D true; + replay_last_snapshot =3D replay_get_current_icount(); + return true; + } + + return false; +} + +void replay_breakpoint(void) +{ + assert(replay_mode =3D=3D REPLAY_MODE_PLAY); + replay_last_breakpoint =3D replay_get_current_icount(); +} diff --git a/stubs/replay.c b/stubs/replay.c index 3d9f99ebb6..a7ca49a717 100644 --- a/stubs/replay.c +++ b/stubs/replay.c @@ -93,3 +93,8 @@ bool replay_reverse_step(void) { return false; } + +bool replay_reverse_continue(void) +{ + return false; +} From nobody Tue May 7 05:51:30 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1577094779; cv=none; d=zohomail.com; s=zohoarc; b=fFl2l+fWWR71S2U+e601g0aK1NAh8kUPESpVvQrim+onrJkWH9IsRlZzJQ5r34ArriuF1KK9nZ+5YZyATrnAzO5yIMuAlw6vnFEy4JBSAp1Ig4D4kCe4RKwyWa1aXrI/XKybYmKVyMmfP/3jSZpkx8IfPe5VZDIrRSSlUi2hrrM= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1577094779; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=S4IlZChh1C7JDbJoY2YMiq0yiQajOw0QLO+c22zMZmU=; b=HvmCrdXwzGIrWeNFQtzXGUcNs9zlWpjd1gXPu0ywRl1gPL2h22aQbkz+pOizpAC0INnaY7zPW0QUSR1bh3dmCblJKAc7yf1kBzjooRekUD2tgOhKP7sPcAdxUKc/es+cKFx+F7BFkBanM8Po6kgF1H0iIJSSaTMAO13vcYYaeWc= ARC-Authentication-Results: i=1; mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1577094779885271.27549960608087; Mon, 23 Dec 2019 01:52:59 -0800 (PST) Received: from localhost ([::1]:55258 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ijKOY-0000mb-IS for importer@patchew.org; Mon, 23 Dec 2019 04:52:58 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:46086) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ijKKU-000587-JR for qemu-devel@nongnu.org; Mon, 23 Dec 2019 04:48:50 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ijKKT-0001oS-9V for qemu-devel@nongnu.org; Mon, 23 Dec 2019 04:48:46 -0500 Received: from mail.ispras.ru ([83.149.199.45]:51042) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ijKKT-0001j6-0n for qemu-devel@nongnu.org; Mon, 23 Dec 2019 04:48:45 -0500 Received: from [127.0.1.1] (unknown [85.142.117.226]) by mail.ispras.ru (Postfix) with ESMTPSA id E1DA454006B; Mon, 23 Dec 2019 12:48:34 +0300 (MSK) Subject: [for-5.0 PATCH 11/11] replay: describe reverse debugging in docs/replay.txt From: Pavel Dovgalyuk To: qemu-devel@nongnu.org Date: Mon, 23 Dec 2019 12:48:34 +0300 Message-ID: <157709451464.12933.5967721708758407023.stgit@pasha-Precision-3630-Tower> In-Reply-To: <157709434917.12933.4351155074716553976.stgit@pasha-Precision-3630-Tower> References: <157709434917.12933.4351155074716553976.stgit@pasha-Precision-3630-Tower> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 83.149.199.45 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , 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 Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" From: Pavel Dovgalyuk This patch updates the documentation and describes usage of the reverse debugging in QEMU+GDB. Signed-off-by: Pavel Dovgalyuk --- docs/replay.txt | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/docs/replay.txt b/docs/replay.txt index f4619a62a3..07104492f2 100644 --- a/docs/replay.txt +++ b/docs/replay.txt @@ -294,6 +294,39 @@ for recording and replaying must contain identical num= ber of ports in record and replay modes, but their backends may differ. E.g., '-serial stdio' in record mode, and '-serial null' in replay mode. =20 +Reverse debugging +----------------- + +Reverse debugging allows "executing" the program in reverse direction. +GDB remote protocol supports "reverse step" and "reverse continue" +commands. The first one steps single instruction backwards in time, +and the second one finds the last breakpoint in the past. + +Recorded executions may be used to enable reverse debugging. QEMU can't +execute the code in backwards direction, but can load a snapshot and +replay forward to find the desired position or breakpoint. + +The following GDB commands are supported: + - reverse-stepi (or rsi) - step one instruction backwards + - reverse-continue (or rc) - find last breakpoint in the past + +Reverse step loads the nearest snapshot and replays the execution until +the required instruction is met. + +Reverse continue may include several passes of examining the execution +between the snapshots. Each of the passes include the following steps: + 1. loading the snapshot + 2. replaying to examine the breakpoints + 3. if breakpoint or watchpoint was met + - loading the snaphot again + - replaying to the required breakpoint + 4. else + - proceeding to the p.1 with the earlier snapshot + +Therefore usage of the reverse debugging requires at least one snapshot +created in advance. See the "Snapshotting" section to learn about running +record/replay and creating the snapshot in these modes. + Replay log format ----------------- =20