qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [RFC PATCH] accel/tcg/translator: add tb_enter TCG trac


From: Alex Bennée
Subject: Re: [Qemu-devel] [RFC PATCH] accel/tcg/translator: add tb_enter TCG trace
Date: Mon, 01 Jul 2019 14:33:11 +0100
User-agent: mu4e 1.3.2; emacs 26.1

Edgar E. Iglesias <address@hidden> writes:

> On Fri, Jun 28, 2019 at 02:16:41PM +0200, Richard Henderson wrote:
>> On 6/28/19 1:39 PM, Luc Michel wrote:
>> > Add a TCG trace at the begining of a translation block recording the
>> > first and last (past-the-end) PC values.
>> >
>> > Signed-off-by: Luc Michel <address@hidden>
>> > ---
>> > This can be used to trace the execution of the guest quite efficiently.
>> > It will report each time a TB is entered (using the tb_enter_exec
>> > trace). The traces arguments give the PC start and past-the-end values.
>> > It has very little to no performance impact since the trace is actually
>> > emitted in the generated code only when it is enabled at run time.
>> >
>> > It works already quite well on its own to trace guest execution. However
>> > it does not handle the case where a TB is exited in the middle of
>> > execution. I'm not sure how to properly trace that. A trace could be
>> > added when `cpu_loop_exit()' is called to report the current PC, but in
>> > most cases the interesting value (the PC of the instruction that
>> > caused the exit) is already lost at this stage.
>> >
>> > I'm not sure there is a generic (i.e. not target specific) way of
>> > recovering the last PC executed when cpu_loop_exit() is called. Do you
>> > think of a better way?
>> >
>> > Thanks to the Xilinx's QEMU team who sponsored this work.
>> > ---
>> >  accel/tcg/translator.c | 24 ++++++++++++++++++++++++
>> >  trace-events           |  3 +++
>> >  2 files changed, 27 insertions(+)
>> >
>> > diff --git a/accel/tcg/translator.c b/accel/tcg/translator.c
>> > index 9226a348a3..c55377aa18 100644
>> > --- a/accel/tcg/translator.c
>> > +++ b/accel/tcg/translator.c
>> > @@ -14,10 +14,11 @@
>> >  #include "tcg/tcg-op.h"
>> >  #include "exec/exec-all.h"
>> >  #include "exec/gen-icount.h"
>> >  #include "exec/log.h"
>> >  #include "exec/translator.h"
>> > +#include "trace-tcg.h"
>> >
>> >  /* Pairs with tcg_clear_temp_count.
>> >     To be called by #TranslatorOps.{translate_insn,tb_stop} if
>> >     (1) the target is sufficiently clean to support reporting,
>> >     (2) as and when all temporaries are known to be consumed.
>> > @@ -28,14 +29,31 @@ void translator_loop_temp_check(DisasContextBase *db)
>> >          qemu_log("warning: TCG temporary leaks before "
>> >                   TARGET_FMT_lx "\n", db->pc_next);
>> >      }
>> >  }
>> >
>> > +static TCGOp *gen_trace_tb_enter(TranslationBlock *tb)
>> > +{
>> > +    TCGOp *last_pc_op;
>> > +
>> > +    TCGv pc_end = tcg_temp_new();
>> > +
>> > +    /* The last PC value is not known yet */
>> > +    tcg_gen_movi_tl(pc_end, 0xdeadbeef);
>> > +    last_pc_op = tcg_last_op();
>>
>> TL is a target-specific type that does not necessarily correspond to 
>> uint64_t,
>> as you assume in the print message.  More importantly, on a 32-bit host with 
>> a
>> 64-bit guest, this movi will generate *two* ops...
>>
>> > +    /* Fixup the last PC value in the tb_enter trace now that we know it 
>> > */
>> > +    tcg_set_insn_param(trace_pc_end, 1, db->pc_next);
>>
>> ... which means that this operation does not do what you think it does.  It
>> will only set one (unknown) half of the _i64 temporary.
>>
>> Moreover, this isn't quite as zero overhead as I would like, because the 
>> pc_end
>> temporary is always created, even if the trace_tb condition is not satisfied
>> and so it (eventually) gets removed as unused.
>>
>> I'm not quite sure what you're after with pc_end anyway.  As you note within
>> the cover, you can't reliably use it for anything.  If you remove that, then
>> you've also removed all of the other problems with this patch.
>>
>
> Hi,
>
> One of the use cases is to be able to collect code-coverage from these traces.
> In that case we're going to need a reliable pc_end. We may need to recover it
> from outside of TCG in some cases though...

Why?

The only place you need to recover pc_end is when processing an
exception and for that case the front end should be using
cpu_loop_exit_restore() to ensure registers are valid before the
exception is processed. Otherwise you know where you've been given the
next block starts at pc_next (with -d nochain).

However I suspect if you want to build more sophisticated tools to track
execution the plugin approach might be better. This seems like a bit of
an arbitrary addition to the TCG core for a single use case where we
already have logging facilities that will give you the same information.

--
Alex Bennée



reply via email to

[Prev in Thread] Current Thread [Next in Thread]