* [Qemu-devel] [PATCH 1/3] scripts/qemu-gdb: Split MtreeCommand into its own module
2015-05-14 16:43 [Qemu-devel] [PATCH 0/3] scripts/qemu-gdb: Add event tracing support Peter Maydell
@ 2015-05-14 16:43 ` Peter Maydell
2015-05-14 16:43 ` [Qemu-devel] [PATCH 2/3] scripts/qemu-gdb: Split CoroutineCommand into its own file Peter Maydell
` (4 subsequent siblings)
5 siblings, 0 replies; 15+ messages in thread
From: Peter Maydell @ 2015-05-14 16:43 UTC (permalink / raw)
To: qemu-devel; +Cc: Stefan Hajnoczi, patches
As we add more commands to our Python gdb debugging support, it's
going to get unwieldy to have everything in a single file. Split
the implementation of the 'mtree' command from qemu-gdb.py into
its own module.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
scripts/qemu-gdb.py | 70 +++++---------------------------------
scripts/qemugdb/__init__.py | 28 ++++++++++++++++
scripts/qemugdb/mtree.py | 82 +++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 118 insertions(+), 62 deletions(-)
create mode 100644 scripts/qemugdb/__init__.py
create mode 100644 scripts/qemugdb/mtree.py
diff --git a/scripts/qemu-gdb.py b/scripts/qemu-gdb.py
index 6c7f4fb..7b072ad 100644
--- a/scripts/qemu-gdb.py
+++ b/scripts/qemu-gdb.py
@@ -16,11 +16,14 @@
import gdb
-def isnull(ptr):
- return ptr == gdb.Value(0).cast(ptr.type)
+import os, sys
-def int128(p):
- return long(p['lo']) + (long(p['hi']) << 64)
+# Annoyingly, gdb doesn't put the directory of scripts onto the
+# module search path. Do it manually.
+
+sys.path.append(os.path.dirname(__file__))
+
+from qemugdb import mtree
def get_fs_base():
'''Fetch %fs base value using arch_prctl(ARCH_GET_FS)'''
@@ -102,63 +105,6 @@ class CoroutineCommand(gdb.Command):
coroutine_pointer = gdb.parse_and_eval(argv[0]).cast(gdb.lookup_type('CoroutineUContext').pointer())
bt_jmpbuf(coroutine_pointer['env']['__jmpbuf'])
-class MtreeCommand(gdb.Command):
- '''Display the memory tree hierarchy'''
- def __init__(self):
- gdb.Command.__init__(self, 'qemu mtree', gdb.COMMAND_DATA,
- gdb.COMPLETE_NONE)
- self.queue = []
- def invoke(self, arg, from_tty):
- self.seen = set()
- self.queue_root('address_space_memory')
- self.queue_root('address_space_io')
- self.process_queue()
- def queue_root(self, varname):
- ptr = gdb.parse_and_eval(varname)['root']
- self.queue.append(ptr)
- def process_queue(self):
- while self.queue:
- ptr = self.queue.pop(0)
- if long(ptr) in self.seen:
- continue
- self.print_item(ptr)
- def print_item(self, ptr, offset = gdb.Value(0), level = 0):
- self.seen.add(long(ptr))
- addr = ptr['addr']
- addr += offset
- size = int128(ptr['size'])
- alias = ptr['alias']
- klass = ''
- if not isnull(alias):
- klass = ' (alias)'
- elif not isnull(ptr['ops']):
- klass = ' (I/O)'
- elif bool(ptr['ram']):
- klass = ' (RAM)'
- gdb.write('%s%016x-%016x %s%s (@ %s)\n'
- % (' ' * level,
- long(addr),
- long(addr + (size - 1)),
- ptr['name'].string(),
- klass,
- ptr,
- ),
- gdb.STDOUT)
- if not isnull(alias):
- gdb.write('%s alias: %s@%016x (@ %s)\n' %
- (' ' * level,
- alias['name'].string(),
- ptr['alias_offset'],
- alias,
- ),
- gdb.STDOUT)
- self.queue.append(alias)
- subregion = ptr['subregions']['tqh_first']
- level += 1
- while not isnull(subregion):
- self.print_item(subregion, addr, level)
- subregion = subregion['subregions_link']['tqe_next']
-
QemuCommand()
CoroutineCommand()
-MtreeCommand()
+mtree.MtreeCommand()
diff --git a/scripts/qemugdb/__init__.py b/scripts/qemugdb/__init__.py
new file mode 100644
index 0000000..969f552
--- /dev/null
+++ b/scripts/qemugdb/__init__.py
@@ -0,0 +1,28 @@
+#!/usr/bin/python
+
+# GDB debugging support
+#
+# Copyright (c) 2015 Linaro Ltd
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, see
+# <http://www.gnu.org/licenses/gpl-2.0.html>
+#
+
+# We don't need to do anything in our init file currently.
+
+"""
+Support routines for debugging QEMU under GDB
+"""
+
+__license__ = "GPL version 2 or (at your option) any later version"
diff --git a/scripts/qemugdb/mtree.py b/scripts/qemugdb/mtree.py
new file mode 100644
index 0000000..06011c3
--- /dev/null
+++ b/scripts/qemugdb/mtree.py
@@ -0,0 +1,82 @@
+#!/usr/bin/python
+
+# GDB debugging support
+#
+# Copyright 2012 Red Hat, Inc. and/or its affiliates
+#
+# Authors:
+# Avi Kivity <avi@redhat.com>
+#
+# This work is licensed under the terms of the GNU GPL, version 2. See
+# the COPYING file in the top-level directory.
+#
+# Contributions after 2012-01-13 are licensed under the terms of the
+# GNU GPL, version 2 or (at your option) any later version.
+
+# 'qemu mtree' -- display the memory hierarchy
+
+import gdb
+
+def isnull(ptr):
+ return ptr == gdb.Value(0).cast(ptr.type)
+
+def int128(p):
+ return long(p['lo']) + (long(p['hi']) << 64)
+
+class MtreeCommand(gdb.Command):
+ '''Display the memory tree hierarchy'''
+ def __init__(self):
+ gdb.Command.__init__(self, 'qemu mtree', gdb.COMMAND_DATA,
+ gdb.COMPLETE_NONE)
+ self.queue = []
+ def invoke(self, arg, from_tty):
+ self.seen = set()
+ self.queue_root('address_space_memory')
+ self.queue_root('address_space_io')
+ self.process_queue()
+ def queue_root(self, varname):
+ ptr = gdb.parse_and_eval(varname)['root']
+ self.queue.append(ptr)
+ def process_queue(self):
+ while self.queue:
+ ptr = self.queue.pop(0)
+ if long(ptr) in self.seen:
+ continue
+ self.print_item(ptr)
+ def print_item(self, ptr, offset = gdb.Value(0), level = 0):
+ self.seen.add(long(ptr))
+ addr = ptr['addr']
+ addr += offset
+ size = int128(ptr['size'])
+ alias = ptr['alias']
+ klass = ''
+ if not isnull(alias):
+ klass = ' (alias)'
+ elif not isnull(ptr['ops']):
+ klass = ' (I/O)'
+ elif bool(ptr['ram']):
+ klass = ' (RAM)'
+ gdb.write('%s%016x-%016x %s%s (@ %s)\n'
+ % (' ' * level,
+ long(addr),
+ long(addr + (size - 1)),
+ ptr['name'].string(),
+ klass,
+ ptr,
+ ),
+ gdb.STDOUT)
+ if not isnull(alias):
+ gdb.write('%s alias: %s@%016x (@ %s)\n' %
+ (' ' * level,
+ alias['name'].string(),
+ ptr['alias_offset'],
+ alias,
+ ),
+ gdb.STDOUT)
+ self.queue.append(alias)
+ subregion = ptr['subregions']['tqh_first']
+ level += 1
+ while not isnull(subregion):
+ self.print_item(subregion, addr, level)
+ subregion = subregion['subregions_link']['tqe_next']
+
--
1.9.1
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [Qemu-devel] [PATCH 2/3] scripts/qemu-gdb: Split CoroutineCommand into its own file
2015-05-14 16:43 [Qemu-devel] [PATCH 0/3] scripts/qemu-gdb: Add event tracing support Peter Maydell
2015-05-14 16:43 ` [Qemu-devel] [PATCH 1/3] scripts/qemu-gdb: Split MtreeCommand into its own module Peter Maydell
@ 2015-05-14 16:43 ` Peter Maydell
2015-05-14 16:43 ` [Qemu-devel] [PATCH 3/3] scripts/qemu-gdb: Add support for printing trace events Peter Maydell
` (3 subsequent siblings)
5 siblings, 0 replies; 15+ messages in thread
From: Peter Maydell @ 2015-05-14 16:43 UTC (permalink / raw)
To: qemu-devel; +Cc: Stefan Hajnoczi, patches
Split the implementation of CoroutineCommand into its own file.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
scripts/qemu-gdb.py | 78 +------------------------------------
scripts/qemugdb/coroutine.py | 91 ++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 93 insertions(+), 76 deletions(-)
create mode 100644 scripts/qemugdb/coroutine.py
diff --git a/scripts/qemu-gdb.py b/scripts/qemu-gdb.py
index 7b072ad..1c94b2a 100644
--- a/scripts/qemu-gdb.py
+++ b/scripts/qemu-gdb.py
@@ -23,66 +23,7 @@ import os, sys
sys.path.append(os.path.dirname(__file__))
-from qemugdb import mtree
-
-def get_fs_base():
- '''Fetch %fs base value using arch_prctl(ARCH_GET_FS)'''
- # %rsp - 120 is scratch space according to the SystemV ABI
- old = gdb.parse_and_eval('*(uint64_t*)($rsp - 120)')
- gdb.execute('call arch_prctl(0x1003, $rsp - 120)', False, True)
- fs_base = gdb.parse_and_eval('*(uint64_t*)($rsp - 120)')
- gdb.execute('set *(uint64_t*)($rsp - 120) = %s' % old, False, True)
- return fs_base
-
-def get_glibc_pointer_guard():
- '''Fetch glibc pointer guard value'''
- fs_base = get_fs_base()
- return gdb.parse_and_eval('*(uint64_t*)((uint64_t)%s + 0x30)' % fs_base)
-
-def glibc_ptr_demangle(val, pointer_guard):
- '''Undo effect of glibc's PTR_MANGLE()'''
- return gdb.parse_and_eval('(((uint64_t)%s >> 0x11) | ((uint64_t)%s << (64 - 0x11))) ^ (uint64_t)%s' % (val, val, pointer_guard))
-
-def bt_jmpbuf(jmpbuf):
- '''Backtrace a jmpbuf'''
- JB_RBX = 0
- JB_RBP = 1
- JB_R12 = 2
- JB_R13 = 3
- JB_R14 = 4
- JB_R15 = 5
- JB_RSP = 6
- JB_PC = 7
-
- old_rbx = gdb.parse_and_eval('(uint64_t)$rbx')
- old_rbp = gdb.parse_and_eval('(uint64_t)$rbp')
- old_rsp = gdb.parse_and_eval('(uint64_t)$rsp')
- old_r12 = gdb.parse_and_eval('(uint64_t)$r12')
- old_r13 = gdb.parse_and_eval('(uint64_t)$r13')
- old_r14 = gdb.parse_and_eval('(uint64_t)$r14')
- old_r15 = gdb.parse_and_eval('(uint64_t)$r15')
- old_rip = gdb.parse_and_eval('(uint64_t)$rip')
-
- pointer_guard = get_glibc_pointer_guard()
- gdb.execute('set $rbx = %s' % jmpbuf[JB_RBX])
- gdb.execute('set $rbp = %s' % glibc_ptr_demangle(jmpbuf[JB_RBP], pointer_guard))
- gdb.execute('set $rsp = %s' % glibc_ptr_demangle(jmpbuf[JB_RSP], pointer_guard))
- gdb.execute('set $r12 = %s' % jmpbuf[JB_R12])
- gdb.execute('set $r13 = %s' % jmpbuf[JB_R13])
- gdb.execute('set $r14 = %s' % jmpbuf[JB_R14])
- gdb.execute('set $r15 = %s' % jmpbuf[JB_R15])
- gdb.execute('set $rip = %s' % glibc_ptr_demangle(jmpbuf[JB_PC], pointer_guard))
-
- gdb.execute('bt')
-
- gdb.execute('set $rbx = %s' % old_rbx)
- gdb.execute('set $rbp = %s' % old_rbp)
- gdb.execute('set $rsp = %s' % old_rsp)
- gdb.execute('set $r12 = %s' % old_r12)
- gdb.execute('set $r13 = %s' % old_r13)
- gdb.execute('set $r14 = %s' % old_r14)
- gdb.execute('set $r15 = %s' % old_r15)
- gdb.execute('set $rip = %s' % old_rip)
+from qemugdb import mtree, coroutine
class QemuCommand(gdb.Command):
'''Prefix for QEMU debug support commands'''
@@ -90,21 +31,6 @@ class QemuCommand(gdb.Command):
gdb.Command.__init__(self, 'qemu', gdb.COMMAND_DATA,
gdb.COMPLETE_NONE, True)
-class CoroutineCommand(gdb.Command):
- '''Display coroutine backtrace'''
- def __init__(self):
- gdb.Command.__init__(self, 'qemu coroutine', gdb.COMMAND_DATA,
- gdb.COMPLETE_NONE)
-
- def invoke(self, arg, from_tty):
- argv = gdb.string_to_argv(arg)
- if len(argv) != 1:
- gdb.write('usage: qemu coroutine <coroutine-pointer>\n')
- return
-
- coroutine_pointer = gdb.parse_and_eval(argv[0]).cast(gdb.lookup_type('CoroutineUContext').pointer())
- bt_jmpbuf(coroutine_pointer['env']['__jmpbuf'])
-
QemuCommand()
-CoroutineCommand()
+coroutine.CoroutineCommand()
mtree.MtreeCommand()
diff --git a/scripts/qemugdb/coroutine.py b/scripts/qemugdb/coroutine.py
new file mode 100644
index 0000000..3c54918
--- /dev/null
+++ b/scripts/qemugdb/coroutine.py
@@ -0,0 +1,91 @@
+#!/usr/bin/python
+
+# GDB debugging support
+#
+# Copyright 2012 Red Hat, Inc. and/or its affiliates
+#
+# Authors:
+# Avi Kivity <avi@redhat.com>
+#
+# This work is licensed under the terms of the GNU GPL, version 2. See
+# the COPYING file in the top-level directory.
+#
+# Contributions after 2012-01-13 are licensed under the terms of the
+# GNU GPL, version 2 or (at your option) any later version.
+
+import gdb
+
+def get_fs_base():
+ '''Fetch %fs base value using arch_prctl(ARCH_GET_FS)'''
+ # %rsp - 120 is scratch space according to the SystemV ABI
+ old = gdb.parse_and_eval('*(uint64_t*)($rsp - 120)')
+ gdb.execute('call arch_prctl(0x1003, $rsp - 120)', False, True)
+ fs_base = gdb.parse_and_eval('*(uint64_t*)($rsp - 120)')
+ gdb.execute('set *(uint64_t*)($rsp - 120) = %s' % old, False, True)
+ return fs_base
+
+def get_glibc_pointer_guard():
+ '''Fetch glibc pointer guard value'''
+ fs_base = get_fs_base()
+ return gdb.parse_and_eval('*(uint64_t*)((uint64_t)%s + 0x30)' % fs_base)
+
+def glibc_ptr_demangle(val, pointer_guard):
+ '''Undo effect of glibc's PTR_MANGLE()'''
+ return gdb.parse_and_eval('(((uint64_t)%s >> 0x11) | ((uint64_t)%s << (64 - 0x11))) ^ (uint64_t)%s' % (val, val, pointer_guard))
+
+def bt_jmpbuf(jmpbuf):
+ '''Backtrace a jmpbuf'''
+ JB_RBX = 0
+ JB_RBP = 1
+ JB_R12 = 2
+ JB_R13 = 3
+ JB_R14 = 4
+ JB_R15 = 5
+ JB_RSP = 6
+ JB_PC = 7
+
+ old_rbx = gdb.parse_and_eval('(uint64_t)$rbx')
+ old_rbp = gdb.parse_and_eval('(uint64_t)$rbp')
+ old_rsp = gdb.parse_and_eval('(uint64_t)$rsp')
+ old_r12 = gdb.parse_and_eval('(uint64_t)$r12')
+ old_r13 = gdb.parse_and_eval('(uint64_t)$r13')
+ old_r14 = gdb.parse_and_eval('(uint64_t)$r14')
+ old_r15 = gdb.parse_and_eval('(uint64_t)$r15')
+ old_rip = gdb.parse_and_eval('(uint64_t)$rip')
+
+ pointer_guard = get_glibc_pointer_guard()
+ gdb.execute('set $rbx = %s' % jmpbuf[JB_RBX])
+ gdb.execute('set $rbp = %s' % glibc_ptr_demangle(jmpbuf[JB_RBP], pointer_guard))
+ gdb.execute('set $rsp = %s' % glibc_ptr_demangle(jmpbuf[JB_RSP], pointer_guard))
+ gdb.execute('set $r12 = %s' % jmpbuf[JB_R12])
+ gdb.execute('set $r13 = %s' % jmpbuf[JB_R13])
+ gdb.execute('set $r14 = %s' % jmpbuf[JB_R14])
+ gdb.execute('set $r15 = %s' % jmpbuf[JB_R15])
+ gdb.execute('set $rip = %s' % glibc_ptr_demangle(jmpbuf[JB_PC], pointer_guard))
+
+ gdb.execute('bt')
+
+ gdb.execute('set $rbx = %s' % old_rbx)
+ gdb.execute('set $rbp = %s' % old_rbp)
+ gdb.execute('set $rsp = %s' % old_rsp)
+ gdb.execute('set $r12 = %s' % old_r12)
+ gdb.execute('set $r13 = %s' % old_r13)
+ gdb.execute('set $r14 = %s' % old_r14)
+ gdb.execute('set $r15 = %s' % old_r15)
+ gdb.execute('set $rip = %s' % old_rip)
+
+
+class CoroutineCommand(gdb.Command):
+ '''Display coroutine backtrace'''
+ def __init__(self):
+ gdb.Command.__init__(self, 'qemu coroutine', gdb.COMMAND_DATA,
+ gdb.COMPLETE_NONE)
+
+ def invoke(self, arg, from_tty):
+ argv = gdb.string_to_argv(arg)
+ if len(argv) != 1:
+ gdb.write('usage: qemu coroutine <coroutine-pointer>\n')
+ return
+
+ coroutine_pointer = gdb.parse_and_eval(argv[0]).cast(gdb.lookup_type('CoroutineUContext').pointer())
+ bt_jmpbuf(coroutine_pointer['env']['__jmpbuf'])
--
1.9.1
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [Qemu-devel] [PATCH 3/3] scripts/qemu-gdb: Add support for printing trace events
2015-05-14 16:43 [Qemu-devel] [PATCH 0/3] scripts/qemu-gdb: Add event tracing support Peter Maydell
2015-05-14 16:43 ` [Qemu-devel] [PATCH 1/3] scripts/qemu-gdb: Split MtreeCommand into its own module Peter Maydell
2015-05-14 16:43 ` [Qemu-devel] [PATCH 2/3] scripts/qemu-gdb: Split CoroutineCommand into its own file Peter Maydell
@ 2015-05-14 16:43 ` Peter Maydell
2015-09-22 14:52 ` Paolo Bonzini
2015-05-15 7:58 ` [Qemu-devel] [PATCH 0/3] scripts/qemu-gdb: Add event tracing support Markus Armbruster
` (2 subsequent siblings)
5 siblings, 1 reply; 15+ messages in thread
From: Peter Maydell @ 2015-05-14 16:43 UTC (permalink / raw)
To: qemu-devel; +Cc: Stefan Hajnoczi, patches
Add two new commands to our gdb support:
qemu trace-enable eventname
qemu trace-disable eventname
which allow dynamically enabling and disabling printing of QEMU
trace events during a debugging session. These work with the
"null" trace backend, by putting breakpoints on the stub
trace_eventname() functions.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
scripts/qemu-gdb.py | 4 +-
scripts/qemugdb/trace.py | 188 +++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 191 insertions(+), 1 deletion(-)
create mode 100644 scripts/qemugdb/trace.py
diff --git a/scripts/qemu-gdb.py b/scripts/qemu-gdb.py
index 1c94b2a..6d27c06 100644
--- a/scripts/qemu-gdb.py
+++ b/scripts/qemu-gdb.py
@@ -23,7 +23,7 @@ import os, sys
sys.path.append(os.path.dirname(__file__))
-from qemugdb import mtree, coroutine
+from qemugdb import mtree, coroutine, trace
class QemuCommand(gdb.Command):
'''Prefix for QEMU debug support commands'''
@@ -34,3 +34,5 @@ class QemuCommand(gdb.Command):
QemuCommand()
coroutine.CoroutineCommand()
mtree.MtreeCommand()
+trace.TraceEnableCommand()
+trace.TraceDisableCommand()
diff --git a/scripts/qemugdb/trace.py b/scripts/qemugdb/trace.py
new file mode 100644
index 0000000..24543e1
--- /dev/null
+++ b/scripts/qemugdb/trace.py
@@ -0,0 +1,188 @@
+#!/usr/bin/python
+
+# GDB debugging support: selecting printing of trace events
+#
+# Copyright (c) 2015 Linaro Ltd
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, see
+# <http://www.gnu.org/licenses/gpl-2.0.html>
+
+# qemu trace-enable trace-event-name
+# qemu trace-disable trace-event-name
+# * enable/disable printing of tracing for QEMU trace events (works
+# even if QEMU was built with the null trace backend; may not work
+# with non-debug QEMU builds)
+
+import gdb
+import re, os
+
+# Assume the trace-events file is at ../../ relative to where we are
+
+trace_events_filename = os.path.join(os.path.dirname(__file__),
+ os.pardir,os.pardir,
+ "trace-events")
+
+def gdb_bp_list():
+ '''Like gdb.breakpoints(), but return empty list if no bps, not None'''
+ # The point is that this is always iterable
+ bplist = gdb.breakpoints()
+ if not bplist:
+ return []
+ return bplist
+
+class TraceEventInfo:
+ def __init__(self, name, formatstring, arglist):
+ self.name = name
+ self.formatstring = formatstring
+ self.arglist = arglist
+ self.argstr = ", ".join(arglist)
+ if self.argstr != "":
+ self.argstr = ", " + self.argstr
+
+# Hash of trace events read in from the 'trace-events' file;
+# values are TraceEventInfo objects
+trace_events = {}
+
+def extract_identifier(s):
+ '''Extract the identifier from a C argument declaration'''
+ # That is, given "const char *filename" return "filename".
+ r = re.sub(r'.*?([a-zA-Z_][a-zA-Z_0-9]*)\s*$', r'\1', s)
+ if r == 'void':
+ return None
+ return r
+
+# Preprocessor symbols which we know about.
+# These should work for both 32 bit and 64 bit Linux, at least.
+# If we needed to, we could determine whether the target was
+# 32 or 64 bit with
+# is_64bit = gdb.lookup_type('void').pointer().sizeof == 8
+# but we can get away without it.
+fmtstr_dict = {
+ "PRIu8":"u",
+ "PRIx32":"x",
+ "PRIu32":"u",
+ "PRId32":"d",
+ "PRIx64":"llx",
+ "PRIu64":"llu",
+ "PRId64":"lld",
+ "PRIxPTR":"llx",
+}
+
+def fixup_fmtstr(s):
+ # fmtstr needs to have leading space and " removed,
+ # trailing " removed, and handling of interpolated PRIxfoo
+ # dealt with (including trailing PRIxfoo)
+ inquotes = False
+ inescape = False
+ new = ""
+ sym = ""
+ for c in s:
+ if inquotes:
+ if inescape:
+ new = new + c
+ inescape = False
+ elif c == '\\':
+ inescape = True
+ new = new + c
+ elif c == '"':
+ inquotes = False
+ sym = ""
+ else:
+ new = new + c
+ else:
+ if c == '"':
+ # end of unquoted section
+ sym = sym.strip()
+ if sym != "":
+ new = new + fmtstr_dict[sym]
+ inquotes = True
+ else:
+ sym = sym + c
+
+ # gdb printf doesn't understand the 'z' length modifier,
+ # so convert to 'l'
+ return re.sub(r'(?<!%)%z', r'%l', new)
+ return new
+
+def read_trace_events_file(filename):
+ '''Populate the trace_events dictionary from the specified file'''
+ global trace_events
+ trace_events = {}
+ f = open(filename)
+ for line in iter(f):
+ try:
+ line = line.strip()
+ if line == "" or line.startswith('#'):
+ continue
+
+ # Very ugly ad-hoc parsing
+ (name, rest) = line.split('(', 1)
+ (rest, fmtstr) = rest.split(')', 1)
+
+ fmtstr = fixup_fmtstr(fmtstr)
+
+ arglist = rest.split(',')
+ arglist = [extract_identifier(x) for x in arglist]
+ arglist = [x for x in arglist if x is not None]
+ trace_events[name] = TraceEventInfo(name, fmtstr, arglist)
+ except:
+ gdb.write('Warning: ignoring line: %s\n' % line)
+ raise
+
+class QemuTraceBreakpoint(gdb.Breakpoint):
+ def __init__(self, eventname):
+ self.event = trace_events[eventname]
+ spec = "trace_" + eventname
+ # might want to make these internal bps later
+ gdb.Breakpoint.__init__(self, spec, gdb.BP_BREAKPOINT, False)
+
+ def stop(self):
+ gdb.write('%s: ' % self.event.name)
+ gdb.execute('printf "%s\\n"%s'
+ % (self.event.formatstring, self.event.argstr))
+ # Tell gdb not to actually stop here
+ return False
+
+class TraceEnableCommand(gdb.Command):
+ '''Enable in-gdb tracing of the specified QEMU trace event'''
+ def __init__(self):
+ gdb.Command.__init__(self, 'qemu trace-enable', gdb.COMMAND_DATA,
+ gdb.COMPLETE_NONE)
+
+ def invoke(self, arg, from_tty):
+ # place breakpoint on function trace_<eventname>
+ # set up breakpoint to print info and continue
+ # add bp to hash table with key being the event name
+ if arg not in trace_events:
+ gdb.write('Unknown trace event %s\n')
+ return
+ gdb.write("Enabled trace event %s\n" % arg)
+ QemuTraceBreakpoint(arg)
+
+class TraceDisableCommand(gdb.Command):
+ '''Disable in-gdb tracing of the specified QEMU trace event'''
+ def __init__(self):
+ gdb.Command.__init__(self, 'qemu trace-disable', gdb.COMMAND_DATA,
+ gdb.COMPLETE_NONE)
+
+ def invoke(self, arg, from_tty):
+ # delete the bp set on trace_<eventname> by the enable command
+ for bp in gdb_bp_list():
+ if isinstance(bp, QemuTraceBreakpoint) and bp.event.name == arg:
+ bp.delete()
+ gdb.write("Disabled trace event %s\n" % arg)
+ return
+ gdb.write("Can't disable trace event %s: unknown or not enabled\n" % arg)
+
+read_trace_events_file(trace_events_filename)
--
1.9.1
^ permalink raw reply related [flat|nested] 15+ messages in thread
* Re: [Qemu-devel] [PATCH 3/3] scripts/qemu-gdb: Add support for printing trace events
2015-05-14 16:43 ` [Qemu-devel] [PATCH 3/3] scripts/qemu-gdb: Add support for printing trace events Peter Maydell
@ 2015-09-22 14:52 ` Paolo Bonzini
2015-09-22 15:39 ` Peter Maydell
0 siblings, 1 reply; 15+ messages in thread
From: Paolo Bonzini @ 2015-09-22 14:52 UTC (permalink / raw)
To: Peter Maydell, qemu-devel; +Cc: Stefan Hajnoczi, patches
On 14/05/2015 18:43, Peter Maydell wrote:
> Add two new commands to our gdb support:
> qemu trace-enable eventname
> qemu trace-disable eventname
>
> which allow dynamically enabling and disabling printing of QEMU
> trace events during a debugging session. These work with the
> "null" trace backend, by putting breakpoints on the stub
> trace_eventname() functions.
>
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
> scripts/qemu-gdb.py | 4 +-
> scripts/qemugdb/trace.py | 188 +++++++++++++++++++++++++++++++++++++++++++++++
> 2 files changed, 191 insertions(+), 1 deletion(-)
> create mode 100644 scripts/qemugdb/trace.py
>
> diff --git a/scripts/qemu-gdb.py b/scripts/qemu-gdb.py
> index 1c94b2a..6d27c06 100644
> --- a/scripts/qemu-gdb.py
> +++ b/scripts/qemu-gdb.py
> @@ -23,7 +23,7 @@ import os, sys
>
> sys.path.append(os.path.dirname(__file__))
>
> -from qemugdb import mtree, coroutine
> +from qemugdb import mtree, coroutine, trace
>
> class QemuCommand(gdb.Command):
> '''Prefix for QEMU debug support commands'''
> @@ -34,3 +34,5 @@ class QemuCommand(gdb.Command):
> QemuCommand()
> coroutine.CoroutineCommand()
> mtree.MtreeCommand()
> +trace.TraceEnableCommand()
> +trace.TraceDisableCommand()
> diff --git a/scripts/qemugdb/trace.py b/scripts/qemugdb/trace.py
> new file mode 100644
> index 0000000..24543e1
> --- /dev/null
> +++ b/scripts/qemugdb/trace.py
> @@ -0,0 +1,188 @@
> +#!/usr/bin/python
> +
> +# GDB debugging support: selecting printing of trace events
> +#
> +# Copyright (c) 2015 Linaro Ltd
> +#
> +# This program is free software; you can redistribute it and/or
> +# modify it under the terms of the GNU General Public License
> +# as published by the Free Software Foundation; either version 2
> +# of the License, or (at your option) any later version.
> +#
> +# This program is distributed in the hope that it will be useful,
> +# but WITHOUT ANY WARRANTY; without even the implied warranty of
> +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> +# GNU General Public License for more details.
> +#
> +# You should have received a copy of the GNU General Public License
> +# along with this program; if not, see
> +# <http://www.gnu.org/licenses/gpl-2.0.html>
> +
> +# qemu trace-enable trace-event-name
> +# qemu trace-disable trace-event-name
> +# * enable/disable printing of tracing for QEMU trace events (works
> +# even if QEMU was built with the null trace backend; may not work
> +# with non-debug QEMU builds)
> +
> +import gdb
> +import re, os
> +
> +# Assume the trace-events file is at ../../ relative to where we are
> +
> +trace_events_filename = os.path.join(os.path.dirname(__file__),
> + os.pardir,os.pardir,
> + "trace-events")
> +
> +def gdb_bp_list():
> + '''Like gdb.breakpoints(), but return empty list if no bps, not None'''
> + # The point is that this is always iterable
> + bplist = gdb.breakpoints()
> + if not bplist:
> + return []
> + return bplist
> +
> +class TraceEventInfo:
> + def __init__(self, name, formatstring, arglist):
> + self.name = name
> + self.formatstring = formatstring
> + self.arglist = arglist
> + self.argstr = ", ".join(arglist)
> + if self.argstr != "":
> + self.argstr = ", " + self.argstr
> +
> +# Hash of trace events read in from the 'trace-events' file;
> +# values are TraceEventInfo objects
> +trace_events = {}
> +
> +def extract_identifier(s):
> + '''Extract the identifier from a C argument declaration'''
> + # That is, given "const char *filename" return "filename".
> + r = re.sub(r'.*?([a-zA-Z_][a-zA-Z_0-9]*)\s*$', r'\1', s)
> + if r == 'void':
> + return None
> + return r
> +
> +# Preprocessor symbols which we know about.
> +# These should work for both 32 bit and 64 bit Linux, at least.
> +# If we needed to, we could determine whether the target was
> +# 32 or 64 bit with
> +# is_64bit = gdb.lookup_type('void').pointer().sizeof == 8
> +# but we can get away without it.
> +fmtstr_dict = {
> + "PRIu8":"u",
> + "PRIx32":"x",
> + "PRIu32":"u",
> + "PRId32":"d",
> + "PRIx64":"llx",
> + "PRIu64":"llu",
> + "PRId64":"lld",
> + "PRIxPTR":"llx",
> +}
> +
> +def fixup_fmtstr(s):
> + # fmtstr needs to have leading space and " removed,
> + # trailing " removed, and handling of interpolated PRIxfoo
> + # dealt with (including trailing PRIxfoo)
> + inquotes = False
> + inescape = False
> + new = ""
> + sym = ""
> + for c in s:
> + if inquotes:
> + if inescape:
> + new = new + c
> + inescape = False
> + elif c == '\\':
> + inescape = True
> + new = new + c
> + elif c == '"':
> + inquotes = False
> + sym = ""
> + else:
> + new = new + c
> + else:
> + if c == '"':
> + # end of unquoted section
> + sym = sym.strip()
> + if sym != "":
> + new = new + fmtstr_dict[sym]
> + inquotes = True
> + else:
> + sym = sym + c
> +
> + # gdb printf doesn't understand the 'z' length modifier,
> + # so convert to 'l'
> + return re.sub(r'(?<!%)%z', r'%l', new)
> + return new
> +
> +def read_trace_events_file(filename):
> + '''Populate the trace_events dictionary from the specified file'''
> + global trace_events
> + trace_events = {}
> + f = open(filename)
> + for line in iter(f):
> + try:
> + line = line.strip()
> + if line == "" or line.startswith('#'):
> + continue
> +
> + # Very ugly ad-hoc parsing
> + (name, rest) = line.split('(', 1)
> + (rest, fmtstr) = rest.split(')', 1)
> +
> + fmtstr = fixup_fmtstr(fmtstr)
> +
> + arglist = rest.split(',')
> + arglist = [extract_identifier(x) for x in arglist]
> + arglist = [x for x in arglist if x is not None]
> + trace_events[name] = TraceEventInfo(name, fmtstr, arglist)
> + except:
> + gdb.write('Warning: ignoring line: %s\n' % line)
> + raise
> +
> +class QemuTraceBreakpoint(gdb.Breakpoint):
> + def __init__(self, eventname):
> + self.event = trace_events[eventname]
> + spec = "trace_" + eventname
> + # might want to make these internal bps later
> + gdb.Breakpoint.__init__(self, spec, gdb.BP_BREAKPOINT, False)
> +
> + def stop(self):
> + gdb.write('%s: ' % self.event.name)
> + gdb.execute('printf "%s\\n"%s'
> + % (self.event.formatstring, self.event.argstr))
> + # Tell gdb not to actually stop here
> + return False
> +
> +class TraceEnableCommand(gdb.Command):
> + '''Enable in-gdb tracing of the specified QEMU trace event'''
> + def __init__(self):
> + gdb.Command.__init__(self, 'qemu trace-enable', gdb.COMMAND_DATA,
> + gdb.COMPLETE_NONE)
> +
> + def invoke(self, arg, from_tty):
> + # place breakpoint on function trace_<eventname>
> + # set up breakpoint to print info and continue
> + # add bp to hash table with key being the event name
> + if arg not in trace_events:
> + gdb.write('Unknown trace event %s\n')
> + return
> + gdb.write("Enabled trace event %s\n" % arg)
> + QemuTraceBreakpoint(arg)
> +
> +class TraceDisableCommand(gdb.Command):
> + '''Disable in-gdb tracing of the specified QEMU trace event'''
> + def __init__(self):
> + gdb.Command.__init__(self, 'qemu trace-disable', gdb.COMMAND_DATA,
> + gdb.COMPLETE_NONE)
> +
> + def invoke(self, arg, from_tty):
> + # delete the bp set on trace_<eventname> by the enable command
> + for bp in gdb_bp_list():
> + if isinstance(bp, QemuTraceBreakpoint) and bp.event.name == arg:
> + bp.delete()
> + gdb.write("Disabled trace event %s\n" % arg)
> + return
> + gdb.write("Can't disable trace event %s: unknown or not enabled\n" % arg)
> +
> +read_trace_events_file(trace_events_filename)
>
Hi Peter,
what happened to this patch?
Paolo
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [Qemu-devel] [PATCH 3/3] scripts/qemu-gdb: Add support for printing trace events
2015-09-22 14:52 ` Paolo Bonzini
@ 2015-09-22 15:39 ` Peter Maydell
0 siblings, 0 replies; 15+ messages in thread
From: Peter Maydell @ 2015-09-22 15:39 UTC (permalink / raw)
To: Paolo Bonzini; +Cc: QEMU Developers, Stefan Hajnoczi, Patch Tracking
On 22 September 2015 at 07:52, Paolo Bonzini <pbonzini@redhat.com> wrote:
>
>
> On 14/05/2015 18:43, Peter Maydell wrote:
>> Add two new commands to our gdb support:
>> qemu trace-enable eventname
>> qemu trace-disable eventname
>>
>> which allow dynamically enabling and disabling printing of QEMU
>> trace events during a debugging session. These work with the
>> "null" trace backend, by putting breakpoints on the stub
>> trace_eventname() functions.
>>
> what happened to this patch?
Stefan suggested that it was basically a manual reimplementation
of gdb's support for static probepoints via systemtap/dtrace,
so I put it to one side til I had time to investigate that gdb
functionality. I committed the patches which were refactoring
the script into modules, though.
thanks
-- PMM
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [Qemu-devel] [PATCH 0/3] scripts/qemu-gdb: Add event tracing support
2015-05-14 16:43 [Qemu-devel] [PATCH 0/3] scripts/qemu-gdb: Add event tracing support Peter Maydell
` (2 preceding siblings ...)
2015-05-14 16:43 ` [Qemu-devel] [PATCH 3/3] scripts/qemu-gdb: Add support for printing trace events Peter Maydell
@ 2015-05-15 7:58 ` Markus Armbruster
2015-05-15 9:09 ` Peter Maydell
2015-05-18 13:28 ` Stefan Hajnoczi
2015-05-18 13:31 ` Stefan Hajnoczi
5 siblings, 1 reply; 15+ messages in thread
From: Markus Armbruster @ 2015-05-15 7:58 UTC (permalink / raw)
To: Peter Maydell; +Cc: qemu-devel, Stefan Hajnoczi, patches
Since you're touching qemu-gdb.py anyway, could you stick in a brief
comment explaining how to put it to use?
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [Qemu-devel] [PATCH 0/3] scripts/qemu-gdb: Add event tracing support
2015-05-15 7:58 ` [Qemu-devel] [PATCH 0/3] scripts/qemu-gdb: Add event tracing support Markus Armbruster
@ 2015-05-15 9:09 ` Peter Maydell
2015-05-15 12:18 ` Markus Armbruster
0 siblings, 1 reply; 15+ messages in thread
From: Peter Maydell @ 2015-05-15 9:09 UTC (permalink / raw)
To: Markus Armbruster; +Cc: QEMU Developers, Stefan Hajnoczi, Patch Tracking
On 15 May 2015 at 08:58, Markus Armbruster <armbru@redhat.com> wrote:
> Since you're touching qemu-gdb.py anyway, could you stick in a brief
> comment explaining how to put it to use?
Good idea. It turns out the answer is just "source it from gdb",
but it took me a little while to find that out, so worth commenting.
I also have a patch which makes it do the 'ignore SIGUSR1' bit
by doing 'handle SIGUSR1 pass noprint nostop' for you.
-- PMM
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [Qemu-devel] [PATCH 0/3] scripts/qemu-gdb: Add event tracing support
2015-05-15 9:09 ` Peter Maydell
@ 2015-05-15 12:18 ` Markus Armbruster
2015-05-15 12:39 ` Jan Kiszka
0 siblings, 1 reply; 15+ messages in thread
From: Markus Armbruster @ 2015-05-15 12:18 UTC (permalink / raw)
To: Peter Maydell; +Cc: QEMU Developers, Stefan Hajnoczi, Patch Tracking
Peter Maydell <peter.maydell@linaro.org> writes:
> On 15 May 2015 at 08:58, Markus Armbruster <armbru@redhat.com> wrote:
>> Since you're touching qemu-gdb.py anyway, could you stick in a brief
>> comment explaining how to put it to use?
>
> Good idea. It turns out the answer is just "source it from gdb",
> but it took me a little while to find that out, so worth commenting.
> I also have a patch which makes it do the 'ignore SIGUSR1' bit
> by doing 'handle SIGUSR1 pass noprint nostop' for you.
Here's how to load scripts/qemu-gdb.py automatically:
* Apply the appended patch to turn it into a gdb init file
That's what it is, after all. It's not a standalone Python program.
* Tell gdb to trust it
Add a line like
add-auto-load-safe-path ~/work/qemu/scripts/qemu-gdb.py
to your ~/.gdbinit
* Link it into the directory where you run gdb --args qemu...
* Verify it works:
$ gdb
[...]
(gdb) help qemu
Prefix for QEMU debug support commands
List of qemu subcommands:
qemu coroutine -- Display coroutine backtrace
qemu mtree -- Display the memory tree hierarchy
Type "help qemu" followed by qemu subcommand name for full documentation.
Type "apropos word" to search for commands related to "word".
Command name abbreviations are allowed if unambiguous.
(gdb)
If you know a better way to do this, please post it.
diff --git a/scripts/qemu-gdb.py b/scripts/qemu-gdb.py
index 6c7f4fb..ac3087c 100644
--- a/scripts/qemu-gdb.py
+++ b/scripts/qemu-gdb.py
@@ -1,5 +1,3 @@
-#!/usr/bin/python
-
# GDB debugging support
#
# Copyright 2012 Red Hat, Inc. and/or its affiliates
@@ -13,7 +11,7 @@
# Contributions after 2012-01-13 are licensed under the terms of the
# GNU GPL, version 2 or (at your option) any later version.
-
+python
import gdb
def isnull(ptr):
^ permalink raw reply related [flat|nested] 15+ messages in thread
* Re: [Qemu-devel] [PATCH 0/3] scripts/qemu-gdb: Add event tracing support
2015-05-15 12:18 ` Markus Armbruster
@ 2015-05-15 12:39 ` Jan Kiszka
2015-05-15 13:21 ` Markus Armbruster
0 siblings, 1 reply; 15+ messages in thread
From: Jan Kiszka @ 2015-05-15 12:39 UTC (permalink / raw)
To: Markus Armbruster, Peter Maydell
Cc: QEMU Developers, Stefan Hajnoczi, Patch Tracking
On 2015-05-15 14:18, Markus Armbruster wrote:
> Peter Maydell <peter.maydell@linaro.org> writes:
>
>> On 15 May 2015 at 08:58, Markus Armbruster <armbru@redhat.com> wrote:
>>> Since you're touching qemu-gdb.py anyway, could you stick in a brief
>>> comment explaining how to put it to use?
>>
>> Good idea. It turns out the answer is just "source it from gdb",
>> but it took me a little while to find that out, so worth commenting.
>> I also have a patch which makes it do the 'ignore SIGUSR1' bit
>> by doing 'handle SIGUSR1 pass noprint nostop' for you.
>
> Here's how to load scripts/qemu-gdb.py automatically:
>
> * Apply the appended patch to turn it into a gdb init file
>
> That's what it is, after all. It's not a standalone Python program.
>
> * Tell gdb to trust it
>
> Add a line like
>
> add-auto-load-safe-path ~/work/qemu/scripts/qemu-gdb.py
>
> to your ~/.gdbinit
>
> * Link it into the directory where you run gdb --args qemu...
>
> * Verify it works:
>
> $ gdb
> [...]
> (gdb) help qemu
> Prefix for QEMU debug support commands
>
> List of qemu subcommands:
>
> qemu coroutine -- Display coroutine backtrace
> qemu mtree -- Display the memory tree hierarchy
>
> Type "help qemu" followed by qemu subcommand name for full documentation.
> Type "apropos word" to search for commands related to "word".
> Command name abbreviations are allowed if unambiguous.
> (gdb)
>
> If you know a better way to do this, please post it.
>
Yep, that's the basic idea behind gdb python scripts: myapp-gdb.py gets
auto-pulled on "gdb myapp". Since some gdb 7.x, we have that security
feature above which prevents pulling from arbitrary sources.
>
> diff --git a/scripts/qemu-gdb.py b/scripts/qemu-gdb.py
> index 6c7f4fb..ac3087c 100644
> --- a/scripts/qemu-gdb.py
> +++ b/scripts/qemu-gdb.py
> @@ -1,5 +1,3 @@
> -#!/usr/bin/python
> -
> # GDB debugging support
> #
> # Copyright 2012 Red Hat, Inc. and/or its affiliates
> @@ -13,7 +11,7 @@
> # Contributions after 2012-01-13 are licensed under the terms of the
> # GNU GPL, version 2 or (at your option) any later version.
>
> -
> +python
What is this line doing?
> import gdb
>
> def isnull(ptr):
>
>
See also linux-4.x/scripts/gdb and
linux-4.x/Documentation/gdb-kernel-debugging.txt for more references.
For the kernel, we set the link during the build. Given the many aliases
for qemu and the fact that quite a few developers run from the build
directory, I guess that would make sense here as well.
Helper functions are another interesting facility to consider. Trivial
example: the kernel has $container_of(PTR, "TYPE", "ELEMENT").
Jan
--
Siemens AG, Corporate Technology, CT RTC ITP SES-DE
Corporate Competence Center Embedded Linux
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [Qemu-devel] [PATCH 0/3] scripts/qemu-gdb: Add event tracing support
2015-05-15 12:39 ` Jan Kiszka
@ 2015-05-15 13:21 ` Markus Armbruster
2015-05-15 13:36 ` Jan Kiszka
0 siblings, 1 reply; 15+ messages in thread
From: Markus Armbruster @ 2015-05-15 13:21 UTC (permalink / raw)
To: Jan Kiszka
Cc: Peter Maydell, QEMU Developers, Stefan Hajnoczi, Patch Tracking
Jan Kiszka <jan.kiszka@siemens.com> writes:
> On 2015-05-15 14:18, Markus Armbruster wrote:
>> Peter Maydell <peter.maydell@linaro.org> writes:
>>
>>> On 15 May 2015 at 08:58, Markus Armbruster <armbru@redhat.com> wrote:
>>>> Since you're touching qemu-gdb.py anyway, could you stick in a brief
>>>> comment explaining how to put it to use?
>>>
>>> Good idea. It turns out the answer is just "source it from gdb",
>>> but it took me a little while to find that out, so worth commenting.
>>> I also have a patch which makes it do the 'ignore SIGUSR1' bit
>>> by doing 'handle SIGUSR1 pass noprint nostop' for you.
>>
>> Here's how to load scripts/qemu-gdb.py automatically:
>>
>> * Apply the appended patch to turn it into a gdb init file
>>
>> That's what it is, after all. It's not a standalone Python program.
>>
>> * Tell gdb to trust it
>>
>> Add a line like
>>
>> add-auto-load-safe-path ~/work/qemu/scripts/qemu-gdb.py
>>
>> to your ~/.gdbinit
>>
>> * Link it into the directory where you run gdb --args qemu...
>>
>> * Verify it works:
>>
>> $ gdb
>> [...]
>> (gdb) help qemu
>> Prefix for QEMU debug support commands
>>
>> List of qemu subcommands:
>>
>> qemu coroutine -- Display coroutine backtrace
>> qemu mtree -- Display the memory tree hierarchy
>>
>> Type "help qemu" followed by qemu subcommand name for full documentation.
>> Type "apropos word" to search for commands related to "word".
>> Command name abbreviations are allowed if unambiguous.
>> (gdb)
>>
>> If you know a better way to do this, please post it.
>>
>
> Yep, that's the basic idea behind gdb python scripts: myapp-gdb.py gets
> auto-pulled on "gdb myapp". Since some gdb 7.x, we have that security
> feature above which prevents pulling from arbitrary sources.
>
>>
>> diff --git a/scripts/qemu-gdb.py b/scripts/qemu-gdb.py
>> index 6c7f4fb..ac3087c 100644
>> --- a/scripts/qemu-gdb.py
>> +++ b/scripts/qemu-gdb.py
>> @@ -1,5 +1,3 @@
>> -#!/usr/bin/python
>> -
>> # GDB debugging support
>> #
>> # Copyright 2012 Red Hat, Inc. and/or its affiliates
>> @@ -13,7 +11,7 @@
>> # Contributions after 2012-01-13 are licensed under the terms of the
>> # GNU GPL, version 2 or (at your option) any later version.
>>
>> -
>> +python
>
> What is this line doing?
Found here:
https://stackoverflow.com/questions/16553283/python-code-in-gdb-init-file-gdbinit
It doesn't work for me without it.
>> import gdb
>>
>> def isnull(ptr):
>>
>>
>
> See also linux-4.x/scripts/gdb and
> linux-4.x/Documentation/gdb-kernel-debugging.txt for more references.
>
> For the kernel, we set the link during the build. Given the many aliases
> for qemu and the fact that quite a few developers run from the build
> directory, I guess that would make sense here as well.
>
> Helper functions are another interesting facility to consider. Trivial
> example: the kernel has $container_of(PTR, "TYPE", "ELEMENT").
Neat!
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [Qemu-devel] [PATCH 0/3] scripts/qemu-gdb: Add event tracing support
2015-05-15 13:21 ` Markus Armbruster
@ 2015-05-15 13:36 ` Jan Kiszka
2015-05-15 14:18 ` Markus Armbruster
0 siblings, 1 reply; 15+ messages in thread
From: Jan Kiszka @ 2015-05-15 13:36 UTC (permalink / raw)
To: Markus Armbruster
Cc: Peter Maydell, QEMU Developers, Stefan Hajnoczi, Patch Tracking
On 2015-05-15 15:21, Markus Armbruster wrote:
> Jan Kiszka <jan.kiszka@siemens.com> writes:
>
>> On 2015-05-15 14:18, Markus Armbruster wrote:
>>> Peter Maydell <peter.maydell@linaro.org> writes:
>>>
>>>> On 15 May 2015 at 08:58, Markus Armbruster <armbru@redhat.com> wrote:
>>>>> Since you're touching qemu-gdb.py anyway, could you stick in a brief
>>>>> comment explaining how to put it to use?
>>>>
>>>> Good idea. It turns out the answer is just "source it from gdb",
>>>> but it took me a little while to find that out, so worth commenting.
>>>> I also have a patch which makes it do the 'ignore SIGUSR1' bit
>>>> by doing 'handle SIGUSR1 pass noprint nostop' for you.
>>>
>>> Here's how to load scripts/qemu-gdb.py automatically:
>>>
>>> * Apply the appended patch to turn it into a gdb init file
>>>
>>> That's what it is, after all. It's not a standalone Python program.
>>>
>>> * Tell gdb to trust it
>>>
>>> Add a line like
>>>
>>> add-auto-load-safe-path ~/work/qemu/scripts/qemu-gdb.py
>>>
>>> to your ~/.gdbinit
>>>
>>> * Link it into the directory where you run gdb --args qemu...
>>>
>>> * Verify it works:
>>>
>>> $ gdb
>>> [...]
>>> (gdb) help qemu
>>> Prefix for QEMU debug support commands
>>>
>>> List of qemu subcommands:
>>>
>>> qemu coroutine -- Display coroutine backtrace
>>> qemu mtree -- Display the memory tree hierarchy
>>>
>>> Type "help qemu" followed by qemu subcommand name for full documentation.
>>> Type "apropos word" to search for commands related to "word".
>>> Command name abbreviations are allowed if unambiguous.
>>> (gdb)
>>>
>>> If you know a better way to do this, please post it.
>>>
>>
>> Yep, that's the basic idea behind gdb python scripts: myapp-gdb.py gets
>> auto-pulled on "gdb myapp". Since some gdb 7.x, we have that security
>> feature above which prevents pulling from arbitrary sources.
>>
>>>
>>> diff --git a/scripts/qemu-gdb.py b/scripts/qemu-gdb.py
>>> index 6c7f4fb..ac3087c 100644
>>> --- a/scripts/qemu-gdb.py
>>> +++ b/scripts/qemu-gdb.py
>>> @@ -1,5 +1,3 @@
>>> -#!/usr/bin/python
>>> -
>>> # GDB debugging support
>>> #
>>> # Copyright 2012 Red Hat, Inc. and/or its affiliates
>>> @@ -13,7 +11,7 @@
>>> # Contributions after 2012-01-13 are licensed under the terms of the
>>> # GNU GPL, version 2 or (at your option) any later version.
>>>
>>> -
>>> +python
>>
>> What is this line doing?
>
> Found here:
> https://stackoverflow.com/questions/16553283/python-code-in-gdb-init-file-gdbinit
The author there puts his code into .gdbinit, which is a gdb script, not
a python one.
>
> It doesn't work for me without it.
When sourcing? Works fine here (gdb 7.7.something).
In any case, when you pull in the script via auto-load, that extra
non-python statement will break. Try "python python". ;)
Jan
--
Siemens AG, Corporate Technology, CT RTC ITP SES-DE
Corporate Competence Center Embedded Linux
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [Qemu-devel] [PATCH 0/3] scripts/qemu-gdb: Add event tracing support
2015-05-15 13:36 ` Jan Kiszka
@ 2015-05-15 14:18 ` Markus Armbruster
0 siblings, 0 replies; 15+ messages in thread
From: Markus Armbruster @ 2015-05-15 14:18 UTC (permalink / raw)
To: Jan Kiszka
Cc: Peter Maydell, QEMU Developers, Stefan Hajnoczi, Patch Tracking
Jan Kiszka <jan.kiszka@siemens.com> writes:
> On 2015-05-15 15:21, Markus Armbruster wrote:
>> Jan Kiszka <jan.kiszka@siemens.com> writes:
>>
>>> On 2015-05-15 14:18, Markus Armbruster wrote:
>>>> Peter Maydell <peter.maydell@linaro.org> writes:
>>>>
>>>>> On 15 May 2015 at 08:58, Markus Armbruster <armbru@redhat.com> wrote:
>>>>>> Since you're touching qemu-gdb.py anyway, could you stick in a brief
>>>>>> comment explaining how to put it to use?
>>>>>
>>>>> Good idea. It turns out the answer is just "source it from gdb",
>>>>> but it took me a little while to find that out, so worth commenting.
>>>>> I also have a patch which makes it do the 'ignore SIGUSR1' bit
>>>>> by doing 'handle SIGUSR1 pass noprint nostop' for you.
>>>>
>>>> Here's how to load scripts/qemu-gdb.py automatically:
>>>>
>>>> * Apply the appended patch to turn it into a gdb init file
>>>>
>>>> That's what it is, after all. It's not a standalone Python program.
>>>>
>>>> * Tell gdb to trust it
>>>>
>>>> Add a line like
>>>>
>>>> add-auto-load-safe-path ~/work/qemu/scripts/qemu-gdb.py
>>>>
>>>> to your ~/.gdbinit
>>>>
>>>> * Link it into the directory where you run gdb --args qemu...
Left out the important part: name the link .gdbinit !
>>>> * Verify it works:
>>>>
>>>> $ gdb
>>>> [...]
>>>> (gdb) help qemu
>>>> Prefix for QEMU debug support commands
>>>>
>>>> List of qemu subcommands:
>>>>
>>>> qemu coroutine -- Display coroutine backtrace
>>>> qemu mtree -- Display the memory tree hierarchy
>>>>
>>>> Type "help qemu" followed by qemu subcommand name for full documentation.
>>>> Type "apropos word" to search for commands related to "word".
>>>> Command name abbreviations are allowed if unambiguous.
>>>> (gdb)
>>>>
>>>> If you know a better way to do this, please post it.
>>>>
>>>
>>> Yep, that's the basic idea behind gdb python scripts: myapp-gdb.py gets
>>> auto-pulled on "gdb myapp". Since some gdb 7.x, we have that security
>>> feature above which prevents pulling from arbitrary sources.
>>>
>>>>
>>>> diff --git a/scripts/qemu-gdb.py b/scripts/qemu-gdb.py
>>>> index 6c7f4fb..ac3087c 100644
>>>> --- a/scripts/qemu-gdb.py
>>>> +++ b/scripts/qemu-gdb.py
>>>> @@ -1,5 +1,3 @@
>>>> -#!/usr/bin/python
>>>> -
>>>> # GDB debugging support
>>>> #
>>>> # Copyright 2012 Red Hat, Inc. and/or its affiliates
>>>> @@ -13,7 +11,7 @@
>>>> # Contributions after 2012-01-13 are licensed under the terms of the
>>>> # GNU GPL, version 2 or (at your option) any later version.
>>>>
>>>> -
>>>> +python
>>>
>>> What is this line doing?
>>
>> Found here:
>> https://stackoverflow.com/questions/16553283/python-code-in-gdb-init-file-gdbinit
>
> The author there puts his code into .gdbinit, which is a gdb script, not
> a python one.
That's exactly what I did in my experiments.
>>
>> It doesn't work for me without it.
>
> When sourcing? Works fine here (gdb 7.7.something).
Nope, when auto-loading as .gdbinit from the current directory.
> In any case, when you pull in the script via auto-load, that extra
> non-python statement will break. Try "python python". ;)
I know nothing about this kind of auto-load.
I just read gdb-kernel-debugging.txt, and still know nothing :)
Digging around in "info gdb"... aha, there's a section on "Python
Auto-loading". Hmm... "set debug auto-load on"... Try linking it into
the build tree, like this:
$ cd bld/x86_64-softmmu/
$ ln -s ../../scripts/qemu-gdb.py qemu-system-x86_64-gdb.py
Works.
Could you post a patch so that make creates such links automatically?
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [Qemu-devel] [PATCH 0/3] scripts/qemu-gdb: Add event tracing support
2015-05-14 16:43 [Qemu-devel] [PATCH 0/3] scripts/qemu-gdb: Add event tracing support Peter Maydell
` (3 preceding siblings ...)
2015-05-15 7:58 ` [Qemu-devel] [PATCH 0/3] scripts/qemu-gdb: Add event tracing support Markus Armbruster
@ 2015-05-18 13:28 ` Stefan Hajnoczi
2015-05-18 13:31 ` Stefan Hajnoczi
5 siblings, 0 replies; 15+ messages in thread
From: Stefan Hajnoczi @ 2015-05-18 13:28 UTC (permalink / raw)
To: Peter Maydell; +Cc: qemu-devel, Stefan Hajnoczi, patches
[-- Attachment #1: Type: text/plain, Size: 1548 bytes --]
On Thu, May 14, 2015 at 05:43:52PM +0100, Peter Maydell wrote:
> This patchset adds support for two new commands to our
> gdb scripts, which allow dynamically enabling and disabling
> tracing of events, like this:
>
> (gdb) source scripts/qemu-gdb.py
> (gdb) qemu trace-enable translate_block
> Enabled trace event translate_block
> Breakpoint 1 at 0xb634f: file ../trace/generated-tracers.h, line 4734.
> (gdb) run
> [...]
> translate_block: tb:0x7fffc69ce010, pc:0x40000000, tb_code:0x7fffd39ce000
> translate_block: tb:0x7fffc69ce078, pc:0x40010000, tb_code:0x7fffd39ce140
> translate_block: tb:0x7fffc69ce0e0, pc:0x40010034, tb_code:0x7fffd39ce180
> translate_block: tb:0x7fffc69ce148, pc:0x40013700, tb_code:0x7fffd39ce1d0
> translate_block: tb:0x7fffc69ce1b0, pc:0x40013710, tb_code:0x7fffd39ce270
> translate_block: tb:0x7fffc69ce218, pc:0x4001003c, tb_code:0x7fffd39ce310
> [etc]
>
> This works by setting custom breakpoints on the stub functions
> trace_<eventname> that the null tracing backend creates. It
> probably doesn't work with an optimised build, but on the other
> hand because it's purely implemented within gdb you can use a
> tool like 'rr' (http://rr-project.org/) to record a run with no
> tracing enabled and then turn the tracing on and off as you desire
> during the replay.
Did you try GDB's static probe points support?
https://sourceware.org/gdb/onlinedocs/gdb/Static-Probe-Points.html
I think QEMU binaries built with the SystemTap/DTrace backend can be
traced by GDB.
Stefan
[-- Attachment #2: Type: application/pgp-signature, Size: 473 bytes --]
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [Qemu-devel] [PATCH 0/3] scripts/qemu-gdb: Add event tracing support
2015-05-14 16:43 [Qemu-devel] [PATCH 0/3] scripts/qemu-gdb: Add event tracing support Peter Maydell
` (4 preceding siblings ...)
2015-05-18 13:28 ` Stefan Hajnoczi
@ 2015-05-18 13:31 ` Stefan Hajnoczi
5 siblings, 0 replies; 15+ messages in thread
From: Stefan Hajnoczi @ 2015-05-18 13:31 UTC (permalink / raw)
To: Peter Maydell; +Cc: qemu-devel, Stefan Hajnoczi, patches
[-- Attachment #1: Type: text/plain, Size: 2479 bytes --]
On Thu, May 14, 2015 at 05:43:52PM +0100, Peter Maydell wrote:
> This patchset adds support for two new commands to our
> gdb scripts, which allow dynamically enabling and disabling
> tracing of events, like this:
>
> (gdb) source scripts/qemu-gdb.py
> (gdb) qemu trace-enable translate_block
> Enabled trace event translate_block
> Breakpoint 1 at 0xb634f: file ../trace/generated-tracers.h, line 4734.
> (gdb) run
> [...]
> translate_block: tb:0x7fffc69ce010, pc:0x40000000, tb_code:0x7fffd39ce000
> translate_block: tb:0x7fffc69ce078, pc:0x40010000, tb_code:0x7fffd39ce140
> translate_block: tb:0x7fffc69ce0e0, pc:0x40010034, tb_code:0x7fffd39ce180
> translate_block: tb:0x7fffc69ce148, pc:0x40013700, tb_code:0x7fffd39ce1d0
> translate_block: tb:0x7fffc69ce1b0, pc:0x40013710, tb_code:0x7fffd39ce270
> translate_block: tb:0x7fffc69ce218, pc:0x4001003c, tb_code:0x7fffd39ce310
> [etc]
>
> This works by setting custom breakpoints on the stub functions
> trace_<eventname> that the null tracing backend creates. It
> probably doesn't work with an optimised build, but on the other
> hand because it's purely implemented within gdb you can use a
> tool like 'rr' (http://rr-project.org/) to record a run with no
> tracing enabled and then turn the tracing on and off as you desire
> during the replay.
>
> Patches one and two do some initial splitting of qemu-gdb.py into
> separate modules just to keep it from growing unhelpfully large.
>
> -- PMM
>
>
> Peter Maydell (3):
> scripts/qemu-gdb: Split MtreeCommand into its own module
> scripts/qemu-gdb: Split CoroutineCommand into its own file
> scripts/qemu-gdb: Add support for printing trace events
>
> scripts/qemu-gdb.py | 144 +++------------------------------
> scripts/qemugdb/__init__.py | 28 +++++++
> scripts/qemugdb/coroutine.py | 91 +++++++++++++++++++++
> scripts/qemugdb/mtree.py | 82 +++++++++++++++++++
> scripts/qemugdb/trace.py | 188 +++++++++++++++++++++++++++++++++++++++++++
> 5 files changed, 398 insertions(+), 135 deletions(-)
> create mode 100644 scripts/qemugdb/__init__.py
> create mode 100644 scripts/qemugdb/coroutine.py
> create mode 100644 scripts/qemugdb/mtree.py
> create mode 100644 scripts/qemugdb/trace.py
Happy with this series although I'm not sure if it's needed since GDB
has static probes support for our SystemTap/DTrace tracepoints.
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
[-- Attachment #2: Type: application/pgp-signature, Size: 473 bytes --]
^ permalink raw reply [flat|nested] 15+ messages in thread