From: "Alex Bennée" <alex.bennee@linaro.org>
To: Peter Maydell <peter.maydell@linaro.org>
Cc: QEMU Developers <qemu-devel@nongnu.org>
Subject: Re: [Qemu-devel] [RISU PATCH v4 07/10] risu: add simple trace and replay support
Date: Tue, 06 Jun 2017 15:19:02 +0100 [thread overview]
Message-ID: <87poehci7d.fsf@linaro.org> (raw)
In-Reply-To: <CAFEAcA-8wW2qBEsk-awcsRsaAKdnERmYTfwsoSMBwQqiahDfnw@mail.gmail.com>
Peter Maydell <peter.maydell@linaro.org> writes:
> On 2 June 2017 at 17:08, Alex Bennée <alex.bennee@linaro.org> wrote:
>> 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>
>>
>> ---
>> 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 | 97 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------
>> 1 file changed, 84 insertions(+), 13 deletions(-)
>>
>> diff --git a/risu.c b/risu.c
>> index 22571cd..137cbbf 100644
>> --- a/risu.c
>> +++ b/risu.c
>> @@ -31,6 +31,7 @@
>> void *memblock = 0;
>>
>> int apprentice_socket, master_socket;
>> +int trace_file = 0;
>>
>> sigjmp_buf jmpbuf;
>>
>> @@ -40,10 +41,12 @@ int test_fp_exc = 0;
>> long executed_tests = 0;
>> void report_test_status(void *pc)
>> {
>> - executed_tests += 1;
>> - if (executed_tests % 100 == 0) {
>> - fprintf(stderr,"Executed %ld test instructions (pc=%p)\r",
>> - executed_tests, pc);
>> + if (ismaster || trace_file) {
>> + executed_tests += 1;
>> + if (executed_tests % 100 == 0) {
>> + fprintf(stderr,"Executed %ld test instructions (pc=%p)\r",
>> + executed_tests, pc);
>> + }
>> }
>> }
>>
>> @@ -54,6 +57,12 @@ int read_sock(void *ptr, size_t bytes)
>> return recv_data_pkt(master_socket, ptr, bytes);
>> }
>>
>> +int write_trace(void *ptr, size_t bytes)
>> +{
>> + size_t res = write(trace_file, ptr, bytes);
>> + return (res == bytes) ? 0 : 1;
>> +}
>> +
>> void respond_sock(int r)
>> {
>> send_response_byte(master_socket, r);
>> @@ -66,9 +75,36 @@ int write_sock(void *ptr, size_t bytes)
>> return send_data_pkt(apprentice_socket, ptr, bytes);
>> }
>>
>> +int read_trace(void *ptr, size_t bytes)
>> +{
>> + size_t res = read(trace_file, 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:
>> + /* should not get here */
>> + 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;
>> +
>> + if (trace_file) {
>> + r = send_register_info(write_trace, uc);
>> + } else {
>> + r = recv_and_compare_register_info(read_sock, respond_sock, uc);
>> + }
>
> It's a bit weird that in the trace file case we send the data
> from the master, but in the normal case we send it from
> the apprentice end.
It seemed the natural way round (master generating the "gold" stream
that the apprentice checks). I could switch it or make the apprentice
responsible for checking it's own work?
>
>> +
>> + switch (r)
>> {
>> case 0:
>> /* match OK */
>> @@ -82,7 +118,15 @@ 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;
>> +
>> + if (trace_file) {
>> + 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 */
>> @@ -94,6 +138,9 @@ void apprentice_sigill(int sig, siginfo_t *si, void *uc)
>> exit(0);
>> default:
>> /* mismatch */
>> + if (trace_file) {
>> + report_match_status();
>> + }
>
> report_match_status() uses stdio, you can't call it from a signal
> handler.
Oops, I'll sigjmp.
>
>> exit(1);
>> }
>> }
>> @@ -155,7 +202,13 @@ int master(int sock)
>> {
>> if (sigsetjmp(jmpbuf, 1))
>> {
>> - return report_match_status();
>> + if (trace_file) {
>> + close(trace_file);
>> + fprintf(stderr,"\nDone...\n");
>> + return 0;
>> + } else {
>> + return report_match_status();
>> + }
>> }
>> master_socket = sock;
>> set_sigill_handler(&master_sigill);
>> @@ -184,6 +237,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");
>> fprintf(stderr, " -p, --port=PORT Specify the port to connect to/listen on (default 9191)\n");
>> }
>> @@ -194,6 +248,7 @@ int main(int argc, char **argv)
>> uint16_t port = 9191;
>> char *hostname = "localhost";
>> char *imgfile;
>> + char *trace_fn = NULL;
>> int sock;
>>
>> // TODO clean this up later
>> @@ -204,13 +259,14 @@ int main(int argc, char **argv)
>> {
>> { "help", no_argument, 0, '?'},
>> { "master", no_argument, &ismaster, 1 },
>> + { "trace", required_argument, 0, 't' },
>> { "host", required_argument, 0, 'h' },
>> { "port", required_argument, 0, 'p' },
>> { "test-fp-exc", no_argument, &test_fp_exc, 1 },
>> { 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;
>> @@ -223,6 +279,11 @@ int main(int argc, char **argv)
>> /* flag set by getopt_long, do nothing */
>> break;
>> }
>> + case 't':
>> + {
>> + trace_fn = optarg;
>> + break;
>> + }
>> case 'h':
>> {
>> hostname = optarg;
>> @@ -253,17 +314,27 @@ int main(int argc, char **argv)
>> }
>>
>> load_image(imgfile);
>> -
>> +
>> if (ismaster)
>> {
>> - fprintf(stderr, "master port %d\n", port);
>> - sock = master_connect(port);
>> + if (trace_fn)
>> + {
>> + trace_file = open(trace_fn, O_WRONLY|O_CREAT, S_IRWXU);
>> + } else {
>> + fprintf(stderr, "master port %d\n", port);
>> + sock = master_connect(port);
>> + }
>> return master(sock);
>
> Doesn't this call master() with an uninitialized sock if
> the trace file is in use ?
Hmm yes I can clean that up.
>
>> }
>> else
>> {
>> - fprintf(stderr, "apprentice host %s port %d\n", hostname, port);
>> - sock = apprentice_connect(hostname, port);
>> + if (trace_fn)
>> + {
>> + trace_file = open(trace_fn, O_RDONLY);
>> + } else {
>> + fprintf(stderr, "apprentice host %s port %d\n", hostname, port);
>> + sock = apprentice_connect(hostname, port);
>> + }
>> return apprentice(sock);
>> }
>> }
>> --
>> 2.13.0
>>
>
> thanks
> -- PMM
--
Alex Bennée
next prev parent reply other threads:[~2017-06-06 14:18 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-06-02 16:08 [Qemu-devel] [RISU PATCH v4 00/10] record/replay patches Alex Bennée
2017-06-02 16:08 ` [Qemu-devel] [RISU PATCH v4 01/10] .gitignore: ignore build directories Alex Bennée
2017-06-06 9:51 ` Peter Maydell
2017-06-02 16:08 ` [Qemu-devel] [RISU PATCH v4 02/10] build-all-archs: support cross building via docker Alex Bennée
2017-06-02 16:08 ` [Qemu-devel] [RISU PATCH v4 03/10] build-all-archs: support --static flag Alex Bennée
2017-06-02 16:08 ` [Qemu-devel] [RISU PATCH v4 04/10] risu: a bit more verbosity when running Alex Bennée
2017-06-06 9:55 ` Peter Maydell
2017-06-02 16:08 ` [Qemu-devel] [RISU PATCH v4 05/10] risu: paramterise send/receive functions Alex Bennée
2017-06-06 9:57 ` Peter Maydell
2017-06-06 10:13 ` Alex Bennée
2017-06-06 11:37 ` Peter Maydell
2017-06-02 16:08 ` [Qemu-devel] [RISU PATCH v4 06/10] risu: add header to trace stream Alex Bennée
2017-06-02 16:08 ` [Qemu-devel] [RISU PATCH v4 07/10] risu: add simple trace and replay support Alex Bennée
2017-06-06 13:39 ` Peter Maydell
2017-06-06 14:19 ` Alex Bennée [this message]
2017-06-06 14:32 ` Peter Maydell
2017-06-02 16:08 ` [Qemu-devel] [RISU PATCH v4 08/10] risu: add support compressed tracefiles Alex Bennée
2017-06-06 13:45 ` Peter Maydell
2017-06-06 14:24 ` Alex Bennée
2017-06-02 16:08 ` [Qemu-devel] [RISU PATCH v4 09/10] new: record_traces.sh helper script Alex Bennée
2017-06-06 13:47 ` Peter Maydell
2017-06-06 14:25 ` Alex Bennée
2017-06-02 16:08 ` [Qemu-devel] [RISU PATCH v4 10/10] new: run_risu.sh script Alex Bennée
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87poehci7d.fsf@linaro.org \
--to=alex.bennee@linaro.org \
--cc=peter.maydell@linaro.org \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.