On 04/03/2017 09:45 AM, Alex Bennée wrote:
> This introduces the qemu-gdb command "qemu timers" which will dump the
> state of the main timers in the system.
>
> Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
> ---
> scripts/qemu-gdb.py | 3 ++-
> scripts/qemugdb/timers.py | 54 +++++++++++++++++++++++++++++++++++++++++++++++
> 2 files changed, 56 insertions(+), 1 deletion(-)
> create mode 100644 scripts/qemugdb/timers.py
>
> diff --git a/scripts/qemu-gdb.py b/scripts/qemu-gdb.py
> index b3f8e04f77..3e7adb87dc 100644
> --- a/scripts/qemu-gdb.py
> +++ b/scripts/qemu-gdb.py
> @@ -26,7 +26,7 @@ import os, sys
>
> sys.path.append(os.path.dirname(__file__))
>
> -from qemugdb import aio, mtree, coroutine
> +from qemugdb import aio, mtree, coroutine, timers
>
> class QemuCommand(gdb.Command):
> '''Prefix for QEMU debug support commands'''
> @@ -38,6 +38,7 @@ QemuCommand()
> coroutine.CoroutineCommand()
> mtree.MtreeCommand()
> aio.HandlersCommand()
> +timers.TimersCommand()
>
> coroutine.CoroutineSPFunction()
> coroutine.CoroutinePCFunction()
> diff --git a/scripts/qemugdb/timers.py b/scripts/qemugdb/timers.py
> new file mode 100644
> index 0000000000..be71a001e3
> --- /dev/null
> +++ b/scripts/qemugdb/timers.py
> @@ -0,0 +1,54 @@
> +#!/usr/bin/python
> +# GDB debugging support
> +#
> +# Copyright 2017 Linaro Ltd
> +#
> +# Author: Alex Bennée <alex.bennee@linaro.org>
> +#
> +# This work is licensed under the terms of the GNU GPL, version 2. See
> +# the COPYING file in the top-level directory.
> +
> +# 'qemu timers' -- display the current timerlists
> +
> +import gdb
> +
> +class TimersCommand(gdb.Command):
> + '''Display the current QEMU timers'''
> +
> + def __init__(self):
> + 'Register the class as a gdb command'
> + gdb.Command.__init__(self, 'qemu timers', gdb.COMMAND_DATA,
> + gdb.COMPLETE_NONE)
> +
> + def dump_timers(self, timer):
> + "Follow a timer and recursively dump each one in the list."
> + # timer should be of type QemuTimer
> + gdb.write(" timer %s/%s (cb:%s,opq:%s)\n" % (
> + timer['expire_time'],
> + timer['scale'],
> + timer['cb'],
> + timer['opaque']))
> +
> + if int(timer['next']) > 0:
> + self.dump_timers(timer['next'])
> +
> +
> + def process_timerlist(self, tlist, ttype):
> + gdb.write("Processing %s timers\n" % (ttype))
> + gdb.write(" clock %s is enabled:%s, last:%s\n" % (
> + tlist['clock']['type'],
> + tlist['clock']['enabled'],
> + tlist['clock']['last']))
> + if int(tlist['active_timers']) > 0:
> + self.dump_timers(tlist['active_timers'])
> +
> +
> + def invoke(self, arg, from_tty):
> + 'Run the command'
> + main_timers = gdb.parse_and_eval("main_loop_tlg")
> +
> + # This will break if QEMUClockType in timer.h is redfined
> + self.process_timerlist(main_timers['tl'][0], "Realtime")
> + self.process_timerlist(main_timers['tl'][1], "Virtual")
> + self.process_timerlist(main_timers['tl'][2], "Host")
> + self.process_timerlist(main_timers['tl'][3], "Virtual RT")
>