All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [RISU PATCH v6 00/10] Record/replay patches
@ 2017-06-21 15:42 Alex Bennée
  2017-06-21 15:42 ` [Qemu-devel] [RISU PATCH v6 01/10] README: document the coding style used for risu Alex Bennée
                   ` (10 more replies)
  0 siblings, 11 replies; 15+ messages in thread
From: Alex Bennée @ 2017-06-21 15:42 UTC (permalink / raw)
  To: peter.maydell; +Cc: qemu-devel, Alex Bennée

Hi Peter,

Re-based with review comments addressed and tags added where
appropriate.

Alex Bennée (10):
  README: document the coding style used for risu
  build-all-archs: support cross building via docker
  risu: a bit more verbosity when starting
  risu: paramterise send/receive functions
  risu: add header to trace stream
  risu: add simple trace and replay support
  risu: handle trace through stdin/stdout
  risu: add support compressed tracefiles
  new: record_traces.sh helper script
  new: run_risu.sh script

 .dir-locals.el           |   2 +
 Makefile                 |   4 +-
 README                   |   9 +++
 build-all-archs          |  46 ++++++++++--
 configure                |  55 +++++++++++++-
 contrib/record_traces.sh |  32 +++++++++
 contrib/run_risu.sh      |  66 +++++++++++++++++
 reginfo.c                | 120 ++++++++++++++++++-------------
 risu.c                   | 181 ++++++++++++++++++++++++++++++++++++++++++-----
 risu.h                   |  23 +++++-
 risu_aarch64.c           |   5 ++
 risu_arm.c               |   5 ++
 risu_m68k.c              |   5 ++
 risu_ppc64.c             |   5 ++
 14 files changed, 481 insertions(+), 77 deletions(-)
 create mode 100644 .dir-locals.el
 create mode 100755 contrib/record_traces.sh
 create mode 100755 contrib/run_risu.sh

-- 
2.13.0

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [Qemu-devel] [RISU PATCH v6 01/10] README: document the coding style used for risu
  2017-06-21 15:42 [Qemu-devel] [RISU PATCH v6 00/10] Record/replay patches Alex Bennée
@ 2017-06-21 15:42 ` Alex Bennée
  2017-06-21 15:42 ` [Qemu-devel] [RISU PATCH v6 02/10] build-all-archs: support cross building via docker Alex Bennée
                   ` (9 subsequent siblings)
  10 siblings, 0 replies; 15+ messages in thread
From: Alex Bennée @ 2017-06-21 15:42 UTC (permalink / raw)
  To: peter.maydell; +Cc: qemu-devel, Alex Bennée

We also include the an Emacs .dir-locals (as per QEMU) that enforces
this layout.

Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
---
 .dir-locals.el | 2 ++
 README         | 9 +++++++++
 2 files changed, 11 insertions(+)
 create mode 100644 .dir-locals.el

diff --git a/.dir-locals.el b/.dir-locals.el
new file mode 100644
index 0000000..3ac0cfc
--- /dev/null
+++ b/.dir-locals.el
@@ -0,0 +1,2 @@
+((c-mode . ((c-file-style . "stroustrup")
+	    (indent-tabs-mode . nil))))
diff --git a/README b/README
index 4b37b4e..858a349 100644
--- a/README
+++ b/README
@@ -42,6 +42,15 @@ architecture that we support and that you have a cross compiler
 installed for. This is useful for confirming that your changes
 to risu haven't broken anything.
 
+Coding Style
+------------
+
+risu follows the same coding style as the QEMU project, namely 4
+spaces (no tabs) for indentation and the One True Brace Style variant
+of K&R. The source tree includes a .dir-locals.el for Emacs users that
+will set this automatically. Other editors are available.
+
+
 Usage
 -----
 
-- 
2.13.0

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [Qemu-devel] [RISU PATCH v6 02/10] build-all-archs: support cross building via docker
  2017-06-21 15:42 [Qemu-devel] [RISU PATCH v6 00/10] Record/replay patches Alex Bennée
  2017-06-21 15:42 ` [Qemu-devel] [RISU PATCH v6 01/10] README: document the coding style used for risu Alex Bennée
@ 2017-06-21 15:42 ` Alex Bennée
  2017-06-29 13:07   ` Philippe Mathieu-Daudé
  2017-06-21 15:42 ` [Qemu-devel] [RISU PATCH v6 03/10] risu: a bit more verbosity when starting Alex Bennée
                   ` (8 subsequent siblings)
  10 siblings, 1 reply; 15+ messages in thread
From: Alex Bennée @ 2017-06-21 15:42 UTC (permalink / raw)
  To: peter.maydell; +Cc: qemu-devel, Alex Bennée

If we want to link to any other libraries we might find using simple
cross toolchains doesn't work so well. One way around this is to use a
dockerised cross-toolchain which then won't clash with your host
system. If the user specifies --use-docker the obvious will be done.

By default we use the QEMU projects qemu:debian-FOO-cross images as
RISU hackers are likely to be QEMU developers too. However any docker
tag can be passed on the command line.

If none of the docker images have usable compilers we fall back to
checking the host path.

Signed-off-by: Alex Bennée <alex.bennee@linaro.org>

---
v5
  - swapped with --static patch so this can be dropped if desired
---
 build-all-archs | 46 +++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 39 insertions(+), 7 deletions(-)

diff --git a/build-all-archs b/build-all-archs
index 581a1b4..63918e5 100755
--- a/build-all-archs
+++ b/build-all-archs
@@ -11,9 +11,6 @@
 # Contributors:
 #     Peter Maydell (Linaro) - initial implementation
 
-# So we notice risugen failing even though it's in a pipeline
-set -o pipefail
-
 # Simple usage
 usage() {
     cat <<-EOF
@@ -21,7 +18,10 @@ usage() {
 
         Options include:
             --static               build a static binary
+            --use-docker[=tags]    use docker cross compile
 
+        If specifying docker the default will be to use the any
+        qemu:debian-FOO-cross targets available on your system.
 EOF
     exit 1
 }
@@ -37,6 +37,14 @@ while [[ "$1" = -* ]]; do
         --static)
             CONF="--static"
             ;;
+        --use-docker)
+            if [ -z "$arg" ]; then
+                default_tags=$(docker images qemu --format "{{.Repository}}:{{.Tag}}" | grep "\(arm\|power\).*cross$")
+                docker_tags=$(echo $default_tags | sed 's/\n/\s/g' )
+            else
+                docker_tags="$arg"
+            fi
+            ;;
         --help)
             usage
             ;;
@@ -48,10 +56,24 @@ done
 
 # Debian stretch and Ubuntu Xenial have cross compiler packages for
 # all of these:
-# gcc-arm-linux-gnueabihf gcc-aarch64-linux-gnu gcc-m68k-linux-gnu
-# gcc-powerpc64le-linux-gnu gcc-powerpc64-linux-gnu
+#   gcc-arm-linux-gnueabihf gcc-aarch64-linux-gnu gcc-m68k-linux-gnu
+#   gcc-powerpc64le-linux-gnu gcc-powerpc64-linux-gnu
+# If docker is enabled we just brute force the various images until we
+# can set the one that has a workable cross compiler.
+
+DOCKER_RUN="docker run --rm -t -u $(id -u) -v $(pwd):$(pwd) -w $(pwd)"
 
 program_exists() {
+    if [ ! -z "$docker_tags" ]; then
+        use_docker_tag=""
+        for tag in $docker_tags; do
+            if ${DOCKER_RUN} ${tag} /bin/bash -c "command -v $1 >/dev/null"; then
+                use_docker_tag=$tag
+                return
+            fi
+        done
+    fi
+
     command -v "$1" >/dev/null 2>&1
 }
 
@@ -62,19 +84,29 @@ for triplet in aarch64-linux-gnu arm-linux-gnueabihf m68k-linux-gnu \
     if ! program_exists "${triplet}-gcc"; then
         echo "Skipping ${triplet}: no compiler found"
         continue
+    else
+        echo "Building ${triplet} on ${use_docker_tag:-host}..."
     fi
 
     # Do a complete rebuild from scratch, because it's cheap enough.
     rm -rf build/${triplet}
     mkdir -p build/${triplet}
 
-    (cd build/${triplet} && CROSS_PREFIX="${triplet}-"  ../../configure ${CONF})
-    make -C build/${triplet} EXTRA_CFLAGS=-Werror
+    CONFIGURE="cd build/${triplet} && CROSS_PREFIX="${triplet}-"  ../../configure ${CONF}"
+    MAKE="make -C build/${triplet} EXTRA_CFLAGS=-Werror"
 
+    if [ -z "$use_docker_tag" ]; then
+        /bin/bash -c "${CONFIGURE}"
+        ${MAKE}
+    else
+        ${DOCKER_RUN} $use_docker_tag /bin/bash -c "${CONFIGURE}"
+        ${DOCKER_RUN} $use_docker_tag /bin/bash -c "${MAKE}"
+    fi
 done
 
 # Now run risugen for all architectures
 mkdir -p build/risuout
+set -o pipefail # detect failures in pipeline
 
 for f in *.risu; do
     echo "Running risugen on $f..."
-- 
2.13.0

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [Qemu-devel] [RISU PATCH v6 03/10] risu: a bit more verbosity when starting
  2017-06-21 15:42 [Qemu-devel] [RISU PATCH v6 00/10] Record/replay patches Alex Bennée
  2017-06-21 15:42 ` [Qemu-devel] [RISU PATCH v6 01/10] README: document the coding style used for risu Alex Bennée
  2017-06-21 15:42 ` [Qemu-devel] [RISU PATCH v6 02/10] build-all-archs: support cross building via docker Alex Bennée
@ 2017-06-21 15:42 ` Alex Bennée
  2017-06-21 15:42 ` [Qemu-devel] [RISU PATCH v6 04/10] risu: paramterise send/receive functions Alex Bennée
                   ` (7 subsequent siblings)
  10 siblings, 0 replies; 15+ messages in thread
From: Alex Bennée @ 2017-06-21 15:42 UTC (permalink / raw)
  To: peter.maydell; +Cc: qemu-devel, Alex Bennée

When debugging faults it is useful to know where the generated
instructions are living.

Signed-off-by: Alex Bennée <alex.bennee@linaro.org>

---
v6
  - removed stray/stale declarations
v5
  - dropped all the status update due to signal handler contraints
v3
  - use portable fmt string for image_start_address
  - include arm dumping position
---
 risu.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/risu.c b/risu.c
index 2cd6d22..a10422a 100644
--- a/risu.c
+++ b/risu.c
@@ -124,6 +124,8 @@ int master(int sock)
     }
     master_socket = sock;
     set_sigill_handler(&master_sigill);
+    fprintf(stderr, "starting master image at 0x%"PRIxPTR"\n",
+            image_start_address);
     fprintf(stderr, "starting image\n");
     image_start();
     fprintf(stderr, "image returned unexpectedly\n");
@@ -134,6 +136,8 @@ int apprentice(int sock)
 {
     apprentice_socket = sock;
     set_sigill_handler(&apprentice_sigill);
+    fprintf(stderr, "starting apprentice image at 0x%"PRIxPTR"\n",
+            image_start_address);
     fprintf(stderr, "starting image\n");
     image_start();
     fprintf(stderr, "image returned unexpectedly\n");
-- 
2.13.0

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [Qemu-devel] [RISU PATCH v6 04/10] risu: paramterise send/receive functions
  2017-06-21 15:42 [Qemu-devel] [RISU PATCH v6 00/10] Record/replay patches Alex Bennée
                   ` (2 preceding siblings ...)
  2017-06-21 15:42 ` [Qemu-devel] [RISU PATCH v6 03/10] risu: a bit more verbosity when starting Alex Bennée
@ 2017-06-21 15:42 ` Alex Bennée
  2017-06-21 15:42 ` [Qemu-devel] [RISU PATCH v6 05/10] risu: add header to trace stream Alex Bennée
                   ` (6 subsequent siblings)
  10 siblings, 0 replies; 15+ messages in thread
From: Alex Bennée @ 2017-06-21 15:42 UTC (permalink / raw)
  To: peter.maydell; +Cc: qemu-devel, Alex Bennée

This is a precursor to record/playback support. Instead of passing the
socket fd we now pass helper functions for reading/writing and
responding. This will allow us to do the rest of the record/playback
cleanly outside of the main worker function.

Signed-off-by: Alex Bennée <alex.bennee@linaro.org>

---
v6
  - restore OP_TESTEND to return write_fn()
  - clean up wording on helper function prototypes
v5
  - re-base without tab/format cleanps
v4
  - split header code
  - fix formatting foo-bar's
v3
  - new for v3
  - arm, aarch64, ppc64
---
 reginfo.c | 38 ++++++++++++++++++--------------------
 risu.c    | 23 +++++++++++++++++++++--
 risu.h    | 14 ++++++++++++--
 3 files changed, 51 insertions(+), 24 deletions(-)

diff --git a/reginfo.c b/reginfo.c
index 31bb99f..b69d11f 100644
--- a/reginfo.c
+++ b/reginfo.c
@@ -21,7 +21,7 @@ uint8_t apprentice_memblock[MEMBLOCKLEN];
 static int mem_used;
 static int packet_mismatch;
 
-int send_register_info(int sock, void *uc)
+int send_register_info(write_fn write_fn, void *uc)
 {
     struct reginfo ri;
     int op;
@@ -29,24 +29,24 @@ int send_register_info(int sock, void *uc)
     op = get_risuop(&ri);
 
     switch (op) {
-    case OP_COMPARE:
     case OP_TESTEND:
-    default:
-        /* Do a simple register compare on (a) explicit request
-         * (b) end of test (c) a non-risuop UNDEF
-         */
-        return send_data_pkt(sock, &ri, sizeof(ri));
+        return write_fn(&ri, sizeof(ri));
     case OP_SETMEMBLOCK:
-        memblock = (void *) (uintptr_t) get_reginfo_paramreg(&ri);
+        memblock = (void *)(uintptr_t)get_reginfo_paramreg(&ri);
         break;
     case OP_GETMEMBLOCK:
         set_ucontext_paramreg(uc,
-                              get_reginfo_paramreg(&ri) +
-                              (uintptr_t) memblock);
+                              get_reginfo_paramreg(&ri) + (uintptr_t)memblock);
         break;
     case OP_COMPAREMEM:
-        return send_data_pkt(sock, memblock, MEMBLOCKLEN);
+        return write_fn(memblock, MEMBLOCKLEN);
         break;
+    case OP_COMPARE:
+    default:
+        /* Do a simple register compare on (a) explicit request
+         * (b) end of test (c) a non-risuop UNDEF
+         */
+        return write_fn(&ri, sizeof(ri));
     }
     return 0;
 }
@@ -59,7 +59,7 @@ int send_register_info(int sock, void *uc)
  * that says whether it is register or memory data, so if the two
  * sides get out of sync then we will fail obscurely.
  */
-int recv_and_compare_register_info(int sock, void *uc)
+int recv_and_compare_register_info(read_fn read_fn, respond_fn resp_fn, void *uc)
 {
     int resp = 0, op;
 
@@ -73,36 +73,34 @@ int recv_and_compare_register_info(int sock, void *uc)
         /* Do a simple register compare on (a) explicit request
          * (b) end of test (c) a non-risuop UNDEF
          */
-        if (recv_data_pkt(sock, &apprentice_ri, sizeof(apprentice_ri))) {
+        if (read_fn(&apprentice_ri, sizeof(apprentice_ri))) {
             packet_mismatch = 1;
             resp = 2;
-
         } else if (!reginfo_is_eq(&master_ri, &apprentice_ri)) {
             /* register mismatch */
             resp = 2;
-
         } else if (op == OP_TESTEND) {
             resp = 1;
         }
-        send_response_byte(sock, resp);
+        resp_fn(resp);
         break;
     case OP_SETMEMBLOCK:
-        memblock = (void *) (uintptr_t) get_reginfo_paramreg(&master_ri);
+        memblock = (void *)(uintptr_t)get_reginfo_paramreg(&master_ri);
         break;
     case OP_GETMEMBLOCK:
         set_ucontext_paramreg(uc, get_reginfo_paramreg(&master_ri) +
-                              (uintptr_t) memblock);
+                              (uintptr_t)memblock);
         break;
     case OP_COMPAREMEM:
         mem_used = 1;
-        if (recv_data_pkt(sock, apprentice_memblock, MEMBLOCKLEN)) {
+        if (read_fn(apprentice_memblock, MEMBLOCKLEN)) {
             packet_mismatch = 1;
             resp = 2;
         } else if (memcmp(memblock, apprentice_memblock, MEMBLOCKLEN) != 0) {
             /* memory mismatch */
             resp = 2;
         }
-        send_response_byte(sock, resp);
+        resp_fn(resp);
         break;
     }
 
diff --git a/risu.c b/risu.c
index a10422a..88e586c 100644
--- a/risu.c
+++ b/risu.c
@@ -37,9 +37,28 @@ sigjmp_buf jmpbuf;
 /* Should we test for FP exception status bits? */
 int test_fp_exc;
 
+/* Master functions */
+
+int read_sock(void *ptr, size_t bytes)
+{
+    return recv_data_pkt(master_socket, ptr, bytes);
+}
+
+void respond_sock(int r)
+{
+    send_response_byte(master_socket, r);
+}
+
+/* Apprentice function */
+
+int write_sock(void *ptr, size_t bytes)
+{
+    return send_data_pkt(apprentice_socket, ptr, bytes);
+}
+
 void master_sigill(int sig, siginfo_t *si, void *uc)
 {
-    switch (recv_and_compare_register_info(master_socket, uc)) {
+    switch (recv_and_compare_register_info(read_sock, respond_sock, uc)) {
     case 0:
         /* match OK */
         advance_pc(uc);
@@ -52,7 +71,7 @@ void master_sigill(int sig, siginfo_t *si, void *uc)
 
 void apprentice_sigill(int sig, siginfo_t *si, void *uc)
 {
-    switch (send_register_info(apprentice_socket, uc)) {
+    switch (send_register_info(write_sock, uc)) {
     case 0:
         /* match OK */
         advance_pc(uc);
diff --git a/risu.h b/risu.h
index 3fbeda8..20bb824 100644
--- a/risu.h
+++ b/risu.h
@@ -52,17 +52,27 @@ struct reginfo;
 
 /* Functions operating on reginfo */
 
+/* Function prototypes for read/write helper functions.
+ *
+ * We pass the helper function to send_register_info and
+ * recv_and_compare_register_info which can either be backed by the
+ * traditional network socket or a trace file.
+ */
+typedef int (*write_fn) (void *ptr, size_t bytes);
+typedef int (*read_fn) (void *ptr, size_t bytes);
+typedef void (*respond_fn) (int response);
+
 /* Send the register information from the struct ucontext down the socket.
  * Return the response code from the master.
  * NB: called from a signal handler.
  */
-int send_register_info(int sock, void *uc);
+int send_register_info(write_fn write_fn, void *uc);
 
 /* Read register info from the socket and compare it with that from the
  * ucontext. Return 0 for match, 1 for end-of-test, 2 for mismatch.
  * NB: called from a signal handler.
  */
-int recv_and_compare_register_info(int sock, void *uc);
+int recv_and_compare_register_info(read_fn read_fn, respond_fn respond, void *uc);
 
 /* Print a useful report on the status of the last comparison
  * done in recv_and_compare_register_info(). This is called on
-- 
2.13.0

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [Qemu-devel] [RISU PATCH v6 05/10] risu: add header to trace stream
  2017-06-21 15:42 [Qemu-devel] [RISU PATCH v6 00/10] Record/replay patches Alex Bennée
                   ` (3 preceding siblings ...)
  2017-06-21 15:42 ` [Qemu-devel] [RISU PATCH v6 04/10] risu: paramterise send/receive functions Alex Bennée
@ 2017-06-21 15:42 ` Alex Bennée
  2017-06-21 15:42 ` [Qemu-devel] [RISU PATCH v6 06/10] risu: add simple trace and replay support Alex Bennée
                   ` (5 subsequent siblings)
  10 siblings, 0 replies; 15+ messages in thread
From: Alex Bennée @ 2017-06-21 15:42 UTC (permalink / raw)
  To: peter.maydell; +Cc: qemu-devel, Alex Bennée

I've also added a header packet with pc/risu op in it so we can keep
better track of how things are going.

Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
---
v5
  - re-base without formatting fixes
  - dropped fprintfs in signal context
v4
  - split from previous patch
---
 reginfo.c      | 94 +++++++++++++++++++++++++++++++++++++---------------------
 risu.h         |  9 ++++++
 risu_aarch64.c |  5 ++++
 risu_arm.c     |  5 ++++
 risu_m68k.c    |  5 ++++
 risu_ppc64.c   |  5 ++++
 6 files changed, 89 insertions(+), 34 deletions(-)

diff --git a/reginfo.c b/reginfo.c
index b69d11f..44d2786 100644
--- a/reginfo.c
+++ b/reginfo.c
@@ -24,10 +24,19 @@ static int packet_mismatch;
 int send_register_info(write_fn write_fn, void *uc)
 {
     struct reginfo ri;
+    trace_header_t header;
     int op;
+
     reginfo_init(&ri, uc);
     op = get_risuop(&ri);
 
+    /* Write a header with PC/op to keep in sync */
+    header.pc = get_pc(&ri);
+    header.risu_op = op;
+    if (write_fn(&header, sizeof(header)) != 0) {
+        return -1;
+    }
+
     switch (op) {
     case OP_TESTEND:
         return write_fn(&ri, sizeof(ri));
@@ -62,46 +71,63 @@ int send_register_info(write_fn write_fn, void *uc)
 int recv_and_compare_register_info(read_fn read_fn, respond_fn resp_fn, void *uc)
 {
     int resp = 0, op;
+    trace_header_t header;
 
     reginfo_init(&master_ri, uc);
     op = get_risuop(&master_ri);
 
-    switch (op) {
-    case OP_COMPARE:
-    case OP_TESTEND:
-    default:
-        /* Do a simple register compare on (a) explicit request
-         * (b) end of test (c) a non-risuop UNDEF
-         */
-        if (read_fn(&apprentice_ri, sizeof(apprentice_ri))) {
-            packet_mismatch = 1;
-            resp = 2;
-        } else if (!reginfo_is_eq(&master_ri, &apprentice_ri)) {
-            /* register mismatch */
-            resp = 2;
-        } else if (op == OP_TESTEND) {
-            resp = 1;
-        }
-        resp_fn(resp);
-        break;
-    case OP_SETMEMBLOCK:
-        memblock = (void *)(uintptr_t)get_reginfo_paramreg(&master_ri);
-        break;
-    case OP_GETMEMBLOCK:
-        set_ucontext_paramreg(uc, get_reginfo_paramreg(&master_ri) +
-                              (uintptr_t)memblock);
-        break;
-    case OP_COMPAREMEM:
-        mem_used = 1;
-        if (read_fn(apprentice_memblock, MEMBLOCKLEN)) {
-            packet_mismatch = 1;
-            resp = 2;
-        } else if (memcmp(memblock, apprentice_memblock, MEMBLOCKLEN) != 0) {
-            /* memory mismatch */
-            resp = 2;
+    if (read_fn(&header, sizeof(header)) != 0) {
+        return -1;
+    }
+
+    if (header.risu_op == op ) {
+
+        /* send OK for the header */
+        resp_fn(0);
+
+        switch (op) {
+        case OP_COMPARE:
+        case OP_TESTEND:
+        default:
+            /* Do a simple register compare on (a) explicit request
+             * (b) end of test (c) a non-risuop UNDEF
+             */
+            if (read_fn(&apprentice_ri, sizeof(apprentice_ri))) {
+                packet_mismatch = 1;
+                resp = 2;
+
+            } else if (!reginfo_is_eq(&master_ri, &apprentice_ri)) {
+                /* register mismatch */
+                resp = 2;
+
+            } else if (op == OP_TESTEND) {
+                resp = 1;
+            }
+            resp_fn(resp);
+            break;
+        case OP_SETMEMBLOCK:
+            memblock = (void *)(uintptr_t)get_reginfo_paramreg(&master_ri);
+            break;
+        case OP_GETMEMBLOCK:
+            set_ucontext_paramreg(uc, get_reginfo_paramreg(&master_ri) +
+                                  (uintptr_t)memblock);
+            break;
+        case OP_COMPAREMEM:
+            mem_used = 1;
+            if (read_fn(apprentice_memblock, MEMBLOCKLEN)) {
+                packet_mismatch = 1;
+                resp = 2;
+            } else if (memcmp(memblock, apprentice_memblock, MEMBLOCKLEN) != 0) {
+                /* memory mismatch */
+                resp = 2;
+            }
+            resp_fn(resp);
+            break;
         }
+    } else {
+        /* We are out of sync */
+        resp = 2;
         resp_fn(resp);
-        break;
     }
 
     return resp;
diff --git a/risu.h b/risu.h
index 20bb824..5248285 100644
--- a/risu.h
+++ b/risu.h
@@ -50,6 +50,12 @@ extern int test_fp_exc;
 
 struct reginfo;
 
+typedef struct
+{
+   uintptr_t pc;
+   uint32_t risu_op;
+} trace_header_t;
+
 /* Functions operating on reginfo */
 
 /* Function prototypes for read/write helper functions.
@@ -102,6 +108,9 @@ uint64_t get_reginfo_paramreg(struct reginfo *ri);
  */
 int get_risuop(struct reginfo *ri);
 
+/* Return the PC from a reginfo */
+uintptr_t get_pc(struct reginfo *ri);
+
 /* initialize structure from a ucontext */
 void reginfo_init(struct reginfo *ri, ucontext_t *uc);
 
diff --git a/risu_aarch64.c b/risu_aarch64.c
index 9c6809d..492d141 100644
--- a/risu_aarch64.c
+++ b/risu_aarch64.c
@@ -40,3 +40,8 @@ int get_risuop(struct reginfo *ri)
     uint32_t risukey = 0x00005af0;
     return (key != risukey) ? -1 : op;
 }
+
+uintptr_t get_pc(struct reginfo *ri)
+{
+   return ri->pc;
+}
diff --git a/risu_arm.c b/risu_arm.c
index a55c6c2..5fcb2a5 100644
--- a/risu_arm.c
+++ b/risu_arm.c
@@ -68,3 +68,8 @@ int get_risuop(struct reginfo *ri)
     uint32_t risukey = (isz == 2) ? 0xdee0 : 0xe7fe5af0;
     return (key != risukey) ? -1 : op;
 }
+
+uintptr_t get_pc(struct reginfo *ri)
+{
+   return ri->gpreg[15];
+}
diff --git a/risu_m68k.c b/risu_m68k.c
index 0bf5c14..1056eef 100644
--- a/risu_m68k.c
+++ b/risu_m68k.c
@@ -33,3 +33,8 @@ int get_risuop(struct reginfo *ri)
     uint32_t risukey = 0x4afc7000;
     return (key != risukey) ? -1 : op;
 }
+
+uintptr_t get_pc(struct reginfo *ri)
+{
+    return ri->gregs[R_PC];
+}
diff --git a/risu_ppc64.c b/risu_ppc64.c
index eb60573..83f8d1f 100644
--- a/risu_ppc64.c
+++ b/risu_ppc64.c
@@ -38,3 +38,8 @@ int get_risuop(struct reginfo *ri)
     uint32_t risukey = 0x00005af0;
     return (key != risukey) ? -1 : op;
 }
+
+uintptr_t get_pc(struct reginfo *ri)
+{
+   return ri->nip;
+}
-- 
2.13.0

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [Qemu-devel] [RISU PATCH v6 06/10] risu: add simple trace and replay support
  2017-06-21 15:42 [Qemu-devel] [RISU PATCH v6 00/10] Record/replay patches Alex Bennée
                   ` (4 preceding siblings ...)
  2017-06-21 15:42 ` [Qemu-devel] [RISU PATCH v6 05/10] risu: add header to trace stream Alex Bennée
@ 2017-06-21 15:42 ` Alex Bennée
  2017-06-21 15:42 ` [Qemu-devel] [RISU PATCH v6 07/10] risu: handle trace through stdin/stdout Alex Bennée
                   ` (4 subsequent siblings)
  10 siblings, 0 replies; 15+ messages in thread
From: Alex Bennée @ 2017-06-21 15:42 UTC (permalink / raw)
  To: peter.maydell; +Cc: qemu-devel, Alex Bennée

This adds a very dumb and easily breakable trace and replay support. In
--master mode the various risu ops trigger a write of register/memory
state into a binary file which can be played back to an apprentice.
Currently there is no validation of the image source so feeding the
wrong image will fail straight away.

The trace files will get very big for any appreciable sized test file
and this will be addressed in later patches.

Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
---
v5
  - re-base without formatting fixes
  - unify socket/file descriptors
  - count number of signals/checkpoint
  - all output from sigjmp (not in signhandlers)
v4
  - fix formatting mess
  - abort() instead of reporting de-sync
  - don't fake return for compiler
v3
  - fix options parsing
  - re-factored so no need for copy & paste
v2
  - moved read/write functions into main risu.c
  - cleaned up formatting
  - report more in apprentice --trace mode
---
 risu.c | 112 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-----------
 1 file changed, 93 insertions(+), 19 deletions(-)

diff --git a/risu.c b/risu.c
index 88e586c..93c274b 100644
--- a/risu.c
+++ b/risu.c
@@ -30,7 +30,9 @@
 
 void *memblock;
 
-int apprentice_socket, master_socket;
+int apprentice_fd, master_fd;
+int trace;
+size_t signal_count;
 
 sigjmp_buf jmpbuf;
 
@@ -41,24 +43,60 @@ int test_fp_exc;
 
 int read_sock(void *ptr, size_t bytes)
 {
-    return recv_data_pkt(master_socket, ptr, bytes);
+    return recv_data_pkt(master_fd, ptr, bytes);
+}
+
+int write_trace(void *ptr, size_t bytes)
+{
+    size_t res = write(master_fd, ptr, bytes);
+    return (res == bytes) ? 0 : 1;
 }
 
 void respond_sock(int r)
 {
-    send_response_byte(master_socket, r);
+    send_response_byte(master_fd, r);
 }
 
 /* Apprentice function */
 
 int write_sock(void *ptr, size_t bytes)
 {
-    return send_data_pkt(apprentice_socket, ptr, bytes);
+    return send_data_pkt(apprentice_fd, ptr, bytes);
+}
+
+int read_trace(void *ptr, size_t bytes)
+{
+    size_t res = read(apprentice_fd, ptr, bytes);
+    return (res == bytes) ? 0 : 1;
+}
+
+void respond_trace(int r)
+{
+    switch (r) {
+    case 0: /* test ok */
+    case 1: /* end of test */
+        break;
+    default:
+        /* mismatch - if tracing we need to report, otherwise barf */
+        if (!trace) {
+           abort();
+        }
+        break;
+    }
 }
 
 void master_sigill(int sig, siginfo_t *si, void *uc)
 {
-    switch (recv_and_compare_register_info(read_sock, respond_sock, uc)) {
+    int r;
+    signal_count++;
+
+    if (trace) {
+        r = send_register_info(write_trace, uc);
+    } else {
+        r = recv_and_compare_register_info(read_sock, respond_sock, uc);
+    }
+
+    switch (r) {
     case 0:
         /* match OK */
         advance_pc(uc);
@@ -71,7 +109,16 @@ void master_sigill(int sig, siginfo_t *si, void *uc)
 
 void apprentice_sigill(int sig, siginfo_t *si, void *uc)
 {
-    switch (send_register_info(write_sock, uc)) {
+    int r;
+    signal_count++;
+
+    if (trace) {
+        r = recv_and_compare_register_info(read_trace, respond_trace, uc);
+    } else {
+        r = send_register_info(write_sock, uc);
+    }
+
+    switch (r) {
     case 0:
         /* match OK */
         advance_pc(uc);
@@ -81,6 +128,9 @@ void apprentice_sigill(int sig, siginfo_t *si, void *uc)
         exit(0);
     default:
         /* mismatch */
+        if (trace) {
+            siglongjmp(jmpbuf, 1);
+        }
         exit(1);
     }
 }
@@ -136,12 +186,17 @@ void load_image(const char *imgfile)
     image_start_address = (uintptr_t) addr;
 }
 
-int master(int sock)
+int master(void)
 {
     if (sigsetjmp(jmpbuf, 1)) {
-        return report_match_status();
+        close(master_fd);
+        if (trace) {
+            fprintf(stderr, "trace complete after %zd checkpoints\n", signal_count);
+            return 0;
+        } else {
+            return report_match_status();
+        }
     }
-    master_socket = sock;
     set_sigill_handler(&master_sigill);
     fprintf(stderr, "starting master image at 0x%"PRIxPTR"\n",
             image_start_address);
@@ -151,9 +206,13 @@ int master(int sock)
     exit(1);
 }
 
-int apprentice(int sock)
+int apprentice(void)
 {
-    apprentice_socket = sock;
+    if (sigsetjmp(jmpbuf, 1)) {
+        close(apprentice_fd);
+        fprintf(stderr, "finished early after %zd checkpoints\n", signal_count);
+        return report_match_status();
+    }
     set_sigill_handler(&apprentice_sigill);
     fprintf(stderr, "starting apprentice image at 0x%"PRIxPTR"\n",
             image_start_address);
@@ -175,6 +234,7 @@ void usage(void)
     fprintf(stderr, "between master and apprentice risu processes.\n\n");
     fprintf(stderr, "Options:\n");
     fprintf(stderr, "  --master          Be the master (server)\n");
+    fprintf(stderr, "  -t, --trace=FILE  Record/playback trace file\n");
     fprintf(stderr,
             "  -h, --host=HOST   Specify master host machine (apprentice only)"
             "\n");
@@ -189,7 +249,7 @@ int main(int argc, char **argv)
     uint16_t port = 9191;
     char *hostname = "localhost";
     char *imgfile;
-    int sock;
+    char *trace_fn = NULL;
 
     /* TODO clean this up later */
 
@@ -203,7 +263,7 @@ int main(int argc, char **argv)
             {0, 0, 0, 0}
         };
         int optidx = 0;
-        int c = getopt_long(argc, argv, "h:p:", longopts, &optidx);
+        int c = getopt_long(argc, argv, "h:p:t:", longopts, &optidx);
         if (c == -1) {
             break;
         }
@@ -214,6 +274,12 @@ int main(int argc, char **argv)
             /* flag set by getopt_long, do nothing */
             break;
         }
+        case 't':
+        {
+            trace_fn = optarg;
+            trace = 1;
+            break;
+        }
         case 'h':
         {
             hostname = optarg;
@@ -245,12 +311,20 @@ int main(int argc, char **argv)
     load_image(imgfile);
 
     if (ismaster) {
-        fprintf(stderr, "master port %d\n", port);
-        sock = master_connect(port);
-        return master(sock);
+        if (trace) {
+            master_fd = open(trace_fn, O_WRONLY|O_CREAT, S_IRWXU);
+        } else {
+            fprintf(stderr, "master port %d\n", port);
+            master_fd = master_connect(port);
+        }
+        return master();
     } else {
-        fprintf(stderr, "apprentice host %s port %d\n", hostname, port);
-        sock = apprentice_connect(hostname, port);
-        return apprentice(sock);
+        if (trace) {
+            apprentice_fd = open(trace_fn, O_RDONLY);
+        } else {
+            fprintf(stderr, "apprentice host %s port %d\n", hostname, port);
+            apprentice_fd = apprentice_connect(hostname, port);
+        }
+        return apprentice();
     }
 }
-- 
2.13.0

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [Qemu-devel] [RISU PATCH v6 07/10] risu: handle trace through stdin/stdout
  2017-06-21 15:42 [Qemu-devel] [RISU PATCH v6 00/10] Record/replay patches Alex Bennée
                   ` (5 preceding siblings ...)
  2017-06-21 15:42 ` [Qemu-devel] [RISU PATCH v6 06/10] risu: add simple trace and replay support Alex Bennée
@ 2017-06-21 15:42 ` Alex Bennée
  2017-06-21 15:42 ` [Qemu-devel] [RISU PATCH v6 08/10] risu: add support compressed tracefiles Alex Bennée
                   ` (3 subsequent siblings)
  10 siblings, 0 replies; 15+ messages in thread
From: Alex Bennée @ 2017-06-21 15:42 UTC (permalink / raw)
  To: peter.maydell; +Cc: qemu-devel, Alex Bennée

Trace files can get quite large so it would be useful to be able to
just capture the trace stream with stdin/stdout for processing in a
pipe line. The sort of case where this is useful is for building
static binaries where zlib support is missing for whatever reason.

It can also be used in testing pipelines.

Signed-off-by: Alex Bennée <alex.bennee@linaro.org>

---
v6
  - use STDIN/OUT_FILENO instead of fileno(foo)
  - strcmp instead of strncmp
---
 risu.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/risu.c b/risu.c
index 93c274b..476475c 100644
--- a/risu.c
+++ b/risu.c
@@ -312,7 +312,11 @@ int main(int argc, char **argv)
 
     if (ismaster) {
         if (trace) {
-            master_fd = open(trace_fn, O_WRONLY|O_CREAT, S_IRWXU);
+            if (strcmp(trace_fn, "-")==0) {
+                master_fd = STDOUT_FILENO;
+            } else {
+                master_fd = open(trace_fn, O_WRONLY|O_CREAT, S_IRWXU);
+            }
         } else {
             fprintf(stderr, "master port %d\n", port);
             master_fd = master_connect(port);
@@ -320,7 +324,11 @@ int main(int argc, char **argv)
         return master();
     } else {
         if (trace) {
-            apprentice_fd = open(trace_fn, O_RDONLY);
+            if (strcmp(trace_fn, "-")==0) {
+                apprentice_fd = STDIN_FILENO;
+            } else {
+                apprentice_fd = open(trace_fn, O_RDONLY);
+            }
         } else {
             fprintf(stderr, "apprentice host %s port %d\n", hostname, port);
             apprentice_fd = apprentice_connect(hostname, port);
-- 
2.13.0

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [Qemu-devel] [RISU PATCH v6 08/10] risu: add support compressed tracefiles
  2017-06-21 15:42 [Qemu-devel] [RISU PATCH v6 00/10] Record/replay patches Alex Bennée
                   ` (6 preceding siblings ...)
  2017-06-21 15:42 ` [Qemu-devel] [RISU PATCH v6 07/10] risu: handle trace through stdin/stdout Alex Bennée
@ 2017-06-21 15:42 ` Alex Bennée
  2017-06-21 15:42 ` [Qemu-devel] [RISU PATCH v6 09/10] new: record_traces.sh helper script Alex Bennée
                   ` (2 subsequent siblings)
  10 siblings, 0 replies; 15+ messages in thread
From: Alex Bennée @ 2017-06-21 15:42 UTC (permalink / raw)
  To: peter.maydell; +Cc: qemu-devel, Alex Bennée

This uses the magic of zlib's gzread/write interface to wrap the
tracefile in compression. The code changes are tiny. I spent more time
messing about with the configure/linker stuff to auto-detect bits.

As you need decent multi-arch support or a correctly setup cross
toolchain we fall back if we can't compile with zlib. This
unfortunately needs some #ifdef hackery around the zlib bits in
risu.c.

Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
--
v5
  - re-base
  - also don't use zlib if using stdio fds
v4
  - removed redundant config.h output, added HAVE_ZLIB
  - added BUILD_INC to deal with out-of-tree builds
---
 Makefile  |  4 ++--
 configure | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++--
 risu.c    | 48 ++++++++++++++++++++++++++++++++++++++++++++++--
 3 files changed, 101 insertions(+), 6 deletions(-)

diff --git a/Makefile b/Makefile
index 9a29bb4..ca80eef 100644
--- a/Makefile
+++ b/Makefile
@@ -17,7 +17,7 @@ VPATH=$(SRCDIR)
 
 CFLAGS ?= -g
 
-ALL_CFLAGS = -Wall -D_GNU_SOURCE -DARCH=$(ARCH) $(CFLAGS) $(EXTRA_CFLAGS)
+ALL_CFLAGS = -Wall -D_GNU_SOURCE -DARCH=$(ARCH) $(BUILD_INC) $(CFLAGS) $(EXTRA_CFLAGS)
 
 PROG=risu
 SRCS=risu.c comms.c reginfo.c risu_$(ARCH).c risu_reginfo_$(ARCH).c
@@ -35,7 +35,7 @@ all: $(PROG) $(BINS)
 dump: $(RISU_ASMS)
 
 $(PROG): $(OBJS)
-	$(CC) $(STATIC) $(ALL_CFLAGS) -o $@ $^
+	$(CC) $(STATIC) $(ALL_CFLAGS) -o $@ $^ $(LDFLAGS)
 
 %.risu.asm: %.risu.bin
 	${OBJDUMP} -b binary -m $(ARCH) -D $^ > $@
diff --git a/configure b/configure
index c4b5adb..1dc527b 100755
--- a/configure
+++ b/configure
@@ -32,6 +32,10 @@ compile() {
     $CC $CFLAGS -c -o ${1}.o ${1}.c 2>/dev/null
 }
 
+link() {
+    $LD $LDFLAGS -l${2} -o ${1} ${1}.o 2>/dev/null
+}
+
 check_define() {
     c=${tmp_dir}/check_define_${1}
     cat > ${c}.c <<EOF
@@ -58,6 +62,48 @@ guess_arch() {
     fi
 }
 
+check_type() {
+    c=${tmp_dir}/check_type_${1}
+    cat > ${c}.c <<EOF
+#include <inttypes.h>
+#include <stdint.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+
+int main(void) { $1 thisone; return 0; }
+EOF
+    compile $c
+}
+
+check_lib() {
+    c=${tmp_dir}/check_lib${1}
+    cat > ${c}.c <<EOF
+#include <stdint.h>
+#include <$2.h>
+
+int main(void) { $3; return 0; }
+EOF
+    compile $c && link $c $1
+}
+
+generate_config() {
+    cfg=config.h
+    echo "generating config.h..."
+
+    echo "/* config.h - generated by the 'configure' script */" > $cfg
+    echo "#ifndef CONFIG_H" >> $cfg
+    echo "#define CONFIG_H 1" >> $cfg
+
+    if check_lib z zlib "zlibVersion()"; then
+        echo "#define HAVE_ZLIB 1" >> $cfg
+        LDFLAGS=-lz
+    fi
+
+    echo "#endif /* CONFIG_H */" >> $cfg
+
+    echo "...done"
+}
+
 generate_makefilein() {
     m=Makefile.in
     echo "generating Makefile.in..."
@@ -65,11 +111,13 @@ generate_makefilein() {
     echo "# Makefile.in - generated by the 'configure' script" > $m
     echo "ARCH:=${ARCH}" >> $m
     echo "CC:=${CC}" >> $m
+    echo "LDFLAGS:=${LDFLAGS}" >> $m
     echo "AS:=${AS}" >> $m
     echo "OBJCOPY:=${OBJCOPY}" >> $m
     echo "OBJDUMP:=${OBJDUMP}" >> $m
     echo "STATIC:=${STATIC}" >> $m
     echo "SRCDIR:=${SRCDIR}" >> $m
+    echo "BUILD_INC:=${BUILD_INC}" >> $m
 
     echo "...done"
 }
@@ -118,6 +166,7 @@ done
 
 CC="${CC-${CROSS_PREFIX}gcc}"
 AS="${AS-${CROSS_PREFIX}as}"
+LD="${LD-${CROSS_PREFIX}ld}"
 OBJCOPY="${OBJCOPY-${CROSS_PREFIX}objcopy}"
 OBJDUMP="${OBJDUMP-${CROSS_PREFIX}objdump}"
 
@@ -125,15 +174,17 @@ if test "x${ARCH}" = "x"; then
     guess_arch
 fi
 
-generate_makefilein
-
 # Are we in a separate build tree? If so, link the Makefile
 # so that 'make' works.
 if test ! -e Makefile; then
     echo "linking Makefile..."
+    BUILD_INC="-I $(pwd)"
     ln -s "${SRCDIR}/Makefile" .
 fi
 
+generate_config
+generate_makefilein
+
 rm -r "$tmp_dir"
 
 echo "type 'make' to start the build"
diff --git a/risu.c b/risu.c
index 476475c..47e50ad 100644
--- a/risu.c
+++ b/risu.c
@@ -26,6 +26,8 @@
 #include <fcntl.h>
 #include <string.h>
 
+#include "config.h"
+
 #include "risu.h"
 
 void *memblock;
@@ -34,6 +36,11 @@ int apprentice_fd, master_fd;
 int trace;
 size_t signal_count;
 
+#ifdef HAVE_ZLIB
+#include <zlib.h>
+gzFile gz_trace_file;
+#endif
+
 sigjmp_buf jmpbuf;
 
 /* Should we test for FP exception status bits? */
@@ -48,7 +55,17 @@ int read_sock(void *ptr, size_t bytes)
 
 int write_trace(void *ptr, size_t bytes)
 {
-    size_t res = write(master_fd, ptr, bytes);
+    size_t res;
+
+#ifdef HAVE_ZLIB
+    if (master_fd == STDOUT_FILENO) {
+#endif
+        res = write(master_fd, ptr, bytes);
+#ifdef HAVE_ZLIB
+    } else {
+        res = gzwrite(gz_trace_file, ptr, bytes);
+    }
+#endif
     return (res == bytes) ? 0 : 1;
 }
 
@@ -66,7 +83,18 @@ int write_sock(void *ptr, size_t bytes)
 
 int read_trace(void *ptr, size_t bytes)
 {
-    size_t res = read(apprentice_fd, ptr, bytes);
+    size_t res;
+
+#ifdef HAVE_ZLIB
+    if (apprentice_fd == STDIN_FILENO) {
+#endif
+        res = read(apprentice_fd, ptr, bytes);
+#ifdef HAVE_ZLIB
+    } else {
+        res = gzread(gz_trace_file, ptr, bytes);
+    }
+#endif
+
     return (res == bytes) ? 0 : 1;
 }
 
@@ -189,6 +217,11 @@ void load_image(const char *imgfile)
 int master(void)
 {
     if (sigsetjmp(jmpbuf, 1)) {
+#ifdef HAVE_ZLIB
+        if (trace && master_fd != STDOUT_FILENO) {
+            gzclose(gz_trace_file);
+        }
+#endif
         close(master_fd);
         if (trace) {
             fprintf(stderr, "trace complete after %zd checkpoints\n", signal_count);
@@ -209,6 +242,11 @@ int master(void)
 int apprentice(void)
 {
     if (sigsetjmp(jmpbuf, 1)) {
+#ifdef HAVE_ZLIB
+        if (trace && apprentice_fd != STDIN_FILENO) {
+            gzclose(gz_trace_file);
+        }
+#endif
         close(apprentice_fd);
         fprintf(stderr, "finished early after %zd checkpoints\n", signal_count);
         return report_match_status();
@@ -316,6 +354,9 @@ int main(int argc, char **argv)
                 master_fd = STDOUT_FILENO;
             } else {
                 master_fd = open(trace_fn, O_WRONLY|O_CREAT, S_IRWXU);
+#ifdef HAVE_ZLIB
+                gz_trace_file = gzdopen(master_fd, "wb9");
+#endif
             }
         } else {
             fprintf(stderr, "master port %d\n", port);
@@ -328,6 +369,9 @@ int main(int argc, char **argv)
                 apprentice_fd = STDIN_FILENO;
             } else {
                 apprentice_fd = open(trace_fn, O_RDONLY);
+#ifdef HAVE_ZLIB
+                gz_trace_file = gzdopen(apprentice_fd, "rb");
+#endif
             }
         } else {
             fprintf(stderr, "apprentice host %s port %d\n", hostname, port);
-- 
2.13.0

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [Qemu-devel] [RISU PATCH v6 09/10] new: record_traces.sh helper script
  2017-06-21 15:42 [Qemu-devel] [RISU PATCH v6 00/10] Record/replay patches Alex Bennée
                   ` (7 preceding siblings ...)
  2017-06-21 15:42 ` [Qemu-devel] [RISU PATCH v6 08/10] risu: add support compressed tracefiles Alex Bennée
@ 2017-06-21 15:42 ` Alex Bennée
  2017-06-21 15:42 ` [Qemu-devel] [RISU PATCH v6 10/10] new: run_risu.sh script Alex Bennée
  2017-06-29 11:15 ` [Qemu-devel] [RISU PATCH v6 00/10] Record/replay patches Peter Maydell
  10 siblings, 0 replies; 15+ messages in thread
From: Alex Bennée @ 2017-06-21 15:42 UTC (permalink / raw)
  To: peter.maydell; +Cc: qemu-devel, Alex Bennée

A simple script to run through a bunch of binaries and generate their
trace files.

Signed-off-by: Alex Bennée <alex.bennee@linaro.org>

---
v6
  - moved into contrib/
v5
  - author, license and usage header
v3
  - allow overriding of RISU binary
---
 contrib/record_traces.sh | 32 ++++++++++++++++++++++++++++++++
 1 file changed, 32 insertions(+)
 create mode 100755 contrib/record_traces.sh

diff --git a/contrib/record_traces.sh b/contrib/record_traces.sh
new file mode 100755
index 0000000..1234a61
--- /dev/null
+++ b/contrib/record_traces.sh
@@ -0,0 +1,32 @@
+#!/bin/sh
+#
+# A risu helper script to batch process a bunch of binaries and record their outputs
+#
+# Copyright (c) 2017 Linaro Limited
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+#     Alex Bennée <alex.bennee@linaro.org> - initial implementation
+#
+# Usage:
+#   export RISU=/path/to/risu
+#   ./record_traces.sh  ./testcases.aarch64/*.bin
+#
+
+set -e
+
+if test -z "$RISU"; then
+    script_dir=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd -P)
+    RISU=${script_dir}/risu
+fi
+
+for f in $@; do
+    echo "Running risu against $f"
+    t="$f.trace"
+    ${RISU} --master $f -t $t
+    echo "Checking trace file OK"
+    ${RISU} $f -t $t
+done
-- 
2.13.0

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [Qemu-devel] [RISU PATCH v6 10/10] new: run_risu.sh script
  2017-06-21 15:42 [Qemu-devel] [RISU PATCH v6 00/10] Record/replay patches Alex Bennée
                   ` (8 preceding siblings ...)
  2017-06-21 15:42 ` [Qemu-devel] [RISU PATCH v6 09/10] new: record_traces.sh helper script Alex Bennée
@ 2017-06-21 15:42 ` Alex Bennée
  2017-06-29 11:15 ` [Qemu-devel] [RISU PATCH v6 00/10] Record/replay patches Peter Maydell
  10 siblings, 0 replies; 15+ messages in thread
From: Alex Bennée @ 2017-06-21 15:42 UTC (permalink / raw)
  To: peter.maydell; +Cc: qemu-devel, Alex Bennée

A simple script to work through running all of a bunch of files with
record/playback traces. Dumps a summary and the number of failed tests
at the end.

Signed-off-by: Alex Bennée <alex.bennee@linaro.org>

---
v6
  - moved into contrib/
v5
  - author, license, usage header
v3
  - tweak to allow specifying RISU binary
---
 contrib/run_risu.sh | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 66 insertions(+)
 create mode 100755 contrib/run_risu.sh

diff --git a/contrib/run_risu.sh b/contrib/run_risu.sh
new file mode 100755
index 0000000..439cd36
--- /dev/null
+++ b/contrib/run_risu.sh
@@ -0,0 +1,66 @@
+#!/bin/bash
+#
+# Run risu against a set of binaries + trace files
+#
+# Copyright (c) 2017 Linaro Limited
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+#     Alex Bennée <alex.bennee@linaro.org> - initial implementation
+#
+# Usage:
+#   (optional) export QEMU=/path/to/qemu
+#   (optional) export RISU=/path/to/risu
+#   ./run_risu.sh  ./testcases.aarch64/*.bin
+
+set -e
+
+passed=()
+failed=()
+missing=()
+
+if test -z "$RISU"; then
+    script_dir=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd -P)
+    RISU=${script_dir}/risu
+fi
+
+for f in $@; do
+    t="$f.trace"
+    echo "Running $f against $t"
+    if [ -e $t ]; then
+        ${QEMU} ${RISU} $f -t $t
+        if [ $? == 0 ]; then
+            passed=( "${passed[@]}" $f )
+        else
+            failed=( "${failed[@]}" $f )
+        fi
+    else
+        missing=( "${missing[@]}" $f )
+    fi
+done
+
+if test ${#missing[@]} -gt 0; then
+    echo "Tests missing ${#missing[@]} trace files:"
+    for m in "${missing[@]}"; do
+        echo "$m"
+    done
+fi
+
+if test ${#passed[@]} -gt 0; then
+    echo "Passed ${#passed[@]} tests:"
+    for p in "${passed[@]}"; do
+        echo "$p"
+    done
+fi
+
+if test ${#failed[@]} -gt 0; then
+    echo "Failed ${#failed[@]} tests:"
+    for f in "${failed[@]}"; do
+        echo "$f"
+    done
+fi
+
+exit ${#failed[@]}
-- 
2.13.0

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* Re: [Qemu-devel] [RISU PATCH v6 00/10] Record/replay patches
  2017-06-21 15:42 [Qemu-devel] [RISU PATCH v6 00/10] Record/replay patches Alex Bennée
                   ` (9 preceding siblings ...)
  2017-06-21 15:42 ` [Qemu-devel] [RISU PATCH v6 10/10] new: run_risu.sh script Alex Bennée
@ 2017-06-29 11:15 ` Peter Maydell
  10 siblings, 0 replies; 15+ messages in thread
From: Peter Maydell @ 2017-06-29 11:15 UTC (permalink / raw)
  To: Alex Bennée; +Cc: QEMU Developers

On 21 June 2017 at 16:42, Alex Bennée <alex.bennee@linaro.org> wrote:
> Hi Peter,
>
> Re-based with review comments addressed and tags added where
> appropriate.
>
> Alex Bennée (10):
>   README: document the coding style used for risu
>   build-all-archs: support cross building via docker
>   risu: a bit more verbosity when starting
>   risu: paramterise send/receive functions
>   risu: add header to trace stream
>   risu: add simple trace and replay support
>   risu: handle trace through stdin/stdout
>   risu: add support compressed tracefiles
>   new: record_traces.sh helper script
>   new: run_risu.sh script

Hi -- these look OK to me so I have applied them to risu master
(I fixed up a few checkpatch style issues but nothing major).

I notice there's no documentation of the record/replay
feature, though -- could you send a patch which adds
discussion of how to use it to the README file, please?

The 'Building' section in the README should also mention that
we recommend having zlib available.

thanks
-- PMM

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [Qemu-devel] [RISU PATCH v6 02/10] build-all-archs: support cross building via docker
  2017-06-21 15:42 ` [Qemu-devel] [RISU PATCH v6 02/10] build-all-archs: support cross building via docker Alex Bennée
@ 2017-06-29 13:07   ` Philippe Mathieu-Daudé
  2017-06-29 13:27     ` Alex Bennée
  0 siblings, 1 reply; 15+ messages in thread
From: Philippe Mathieu-Daudé @ 2017-06-29 13:07 UTC (permalink / raw)
  To: Alex Bennée; +Cc: peter.maydell, qemu-devel

Hi Alex,

On 06/21/2017 12:42 PM, Alex Bennée wrote:> By default we use the QEMU 
projects qemu:debian-FOO-cross images as
> RISU hackers are likely to be QEMU developers too. However any docker
> tag can be passed on the command line.

Any thought about starting to push images?

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [Qemu-devel] [RISU PATCH v6 02/10] build-all-archs: support cross building via docker
  2017-06-29 13:07   ` Philippe Mathieu-Daudé
@ 2017-06-29 13:27     ` Alex Bennée
  2017-06-29 13:43       ` Philippe Mathieu-Daudé
  0 siblings, 1 reply; 15+ messages in thread
From: Alex Bennée @ 2017-06-29 13:27 UTC (permalink / raw)
  To: Philippe Mathieu-Daudé; +Cc: peter.maydell, qemu-devel


Philippe Mathieu-Daudé <f4bug@amsat.org> writes:

> Hi Alex,
>
> On 06/21/2017 12:42 PM, Alex Bennée wrote:> By default we use the QEMU
> projects qemu:debian-FOO-cross images as
>> RISU hackers are likely to be QEMU developers too. However any docker
>> tag can be passed on the command line.
>
> Any thought about starting to push images?

I think it comes down to how much we trust Docker Hub and how much we
trust whoever does the pushing. Would it be an automatic thing? From
shippable?

--
Alex Bennée

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [Qemu-devel] [RISU PATCH v6 02/10] build-all-archs: support cross building via docker
  2017-06-29 13:27     ` Alex Bennée
@ 2017-06-29 13:43       ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 15+ messages in thread
From: Philippe Mathieu-Daudé @ 2017-06-29 13:43 UTC (permalink / raw)
  To: Alex Bennée, Fam Zheng
  Cc: Peter Maydell, qemu-devel@nongnu.org Developers

On Thu, Jun 29, 2017 at 10:27 AM, Alex Bennée <alex.bennee@linaro.org> wrote:
> Philippe Mathieu-Daudé <f4bug@amsat.org> writes:
>> On 06/21/2017 12:42 PM, Alex Bennée wrote:> By default we use the QEMU
>> projects qemu:debian-FOO-cross images as
>>> RISU hackers are likely to be QEMU developers too. However any docker
>>> tag can be passed on the command line.
>>
>> Any thought about starting to push images?
>
> I think it comes down to how much we trust Docker Hub and how much we
> trust whoever does the pushing. Would it be an automatic thing? From
> shippable?

Surely automatic.

Docker Hub offer free builds but you have to provide a full Dockerfile
(which is generated in QEMU).
We might keep those files in the repo... I'll give this a try.
The other possibilities are Travis and Shippable with a bit more
complicated setup.

^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2017-06-29 13:43 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-06-21 15:42 [Qemu-devel] [RISU PATCH v6 00/10] Record/replay patches Alex Bennée
2017-06-21 15:42 ` [Qemu-devel] [RISU PATCH v6 01/10] README: document the coding style used for risu Alex Bennée
2017-06-21 15:42 ` [Qemu-devel] [RISU PATCH v6 02/10] build-all-archs: support cross building via docker Alex Bennée
2017-06-29 13:07   ` Philippe Mathieu-Daudé
2017-06-29 13:27     ` Alex Bennée
2017-06-29 13:43       ` Philippe Mathieu-Daudé
2017-06-21 15:42 ` [Qemu-devel] [RISU PATCH v6 03/10] risu: a bit more verbosity when starting Alex Bennée
2017-06-21 15:42 ` [Qemu-devel] [RISU PATCH v6 04/10] risu: paramterise send/receive functions Alex Bennée
2017-06-21 15:42 ` [Qemu-devel] [RISU PATCH v6 05/10] risu: add header to trace stream Alex Bennée
2017-06-21 15:42 ` [Qemu-devel] [RISU PATCH v6 06/10] risu: add simple trace and replay support Alex Bennée
2017-06-21 15:42 ` [Qemu-devel] [RISU PATCH v6 07/10] risu: handle trace through stdin/stdout Alex Bennée
2017-06-21 15:42 ` [Qemu-devel] [RISU PATCH v6 08/10] risu: add support compressed tracefiles Alex Bennée
2017-06-21 15:42 ` [Qemu-devel] [RISU PATCH v6 09/10] new: record_traces.sh helper script Alex Bennée
2017-06-21 15:42 ` [Qemu-devel] [RISU PATCH v6 10/10] new: run_risu.sh script Alex Bennée
2017-06-29 11:15 ` [Qemu-devel] [RISU PATCH v6 00/10] Record/replay patches Peter Maydell

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.