Skip to content

Commit c900ef8

Browse files
dagrhstefanhaRH
authored andcommitted
gdb command: qemu handlers
A new gdb commands are added: qemu handlers That dumps an AioContext list (by default qemu_aio_context) possibly including a backtrace for cases it knows about (with the verbose option). Intended to help find why something is hanging waiting for IO. Use 'qemu handlers --verbose iohandler_ctx' to find out why your incoming migration is stuck. Signed-off-by: Dr. David Alan Gilbert <[email protected]> Message-id: [email protected] V2: Merge into one command with optional handlers arg, and only do backtrace in verbose mode (gdb) qemu handlers ---- {pfd = {fd = 6, events = 25, revents = 0}, io_read = 0x55869656ffd0 <event_notifier_dummy_cb>, io_write = 0x0, deleted = 0, opaque = 0x558698c4ce08, node = {le_next = 0x0, le_prev = 0x558698c4cdc0}} (gdb) qemu handlers iohandler_ctx ---- {pfd = {fd = 9, events = 25, revents = 0}, io_read = 0x558696581380 <fd_coroutine_enter>, io_write = 0x0, deleted = 0, opaque = 0x558698dc99d0, node = {le_next = 0x558698c4cca0, le_prev = 0x558698c4c1d0}} ---- {pfd = {fd = 4, events = 25, revents = 0}, io_read = 0x55869657b330 <sigfd_handler>, io_write = 0x0, deleted = 0, opaque = 0x4, node = {le_next = 0x558698c4c260, le_prev = 0x558699f72508}} ---- {pfd = {fd = 5, events = 25, revents = 0}, io_read = 0x55869656ffd0 <event_notifier_dummy_cb>, io_write = 0x0, deleted = 0, opaque = 0x558698c4c218, node = {le_next = 0x0, le_prev = 0x558698c4ccc8}} ---- (gdb) qemu handlers --verbose iohandler_ctx ---- {pfd = {fd = 9, events = 25, revents = 0}, io_read = 0x558696581380 <fd_coroutine_enter>, io_write = 0x0, deleted = 0, opaque = 0x558698dc99d0, node = {le_next = 0x558698c4cca0, le_prev = 0x558698c4c1d0}} #0 0x0000558696581820 in qemu_coroutine_switch (from_=from_@entry=0x558698cb3cf0, to_=to_@entry=0x7f421c37eac8, action=action@entry=COROUTINE_YIELD) at /home/dgilbert/git/qemu/coroutine-ucontext.c:177 #1 0x0000558696580c00 in qemu_coroutine_yield () at /home/dgilbert/git/qemu/qemu-coroutine.c:145 #2 0x00005586965814f5 in yield_until_fd_readable (fd=9) at /home/dgilbert/git/qemu/qemu-coroutine-io.c:90 #3 0x0000558696523937 in socket_get_buffer (opaque=0x55869a3dc620, buf=0x558698c505a0 "", pos=<optimized out>, size=32768) at /home/dgilbert/git/qemu/migration/qemu-file-unix.c:101 #4 0x0000558696521fac in qemu_fill_buffer (f=0x558698c50570) at /home/dgilbert/git/qemu/migration/qemu-file.c:227 #5 0x0000558696522989 in qemu_peek_byte (f=0x558698c50570, offset=0) at /home/dgilbert/git/qemu/migration/qemu-file.c:507 #6 0x0000558696522bf4 in qemu_get_be32 (f=0x558698c50570) at /home/dgilbert/git/qemu/migration/qemu-file.c:520 #7 0x0000558696522bf4 in qemu_get_be32 (f=f@entry=0x558698c50570) at /home/dgilbert/git/qemu/migration/qemu-file.c:604 #8 0x0000558696347e5c in qemu_loadvm_state (f=f@entry=0x558698c50570) at /home/dgilbert/git/qemu/migration/savevm.c:1821 #9 0x000055869651de8c in process_incoming_migration_co (opaque=0x558698c50570) at /home/dgilbert/git/qemu/migration/migration.c:336 #10 0x000055869658188a in coroutine_trampoline (i0=<optimized out>, i1=<optimized out>) at /home/dgilbert/git/qemu/coroutine-ucontext.c:80 #11 0x00007f420f05df10 in __start_context () at /lib64/libc.so.6 #12 0x00007ffc40815f50 in () #13 0x0000000000000000 in () ---- Signed-off-by: Stefan Hajnoczi <[email protected]>
1 parent ed65fd1 commit c900ef8

File tree

2 files changed

+60
-1
lines changed

2 files changed

+60
-1
lines changed

scripts/qemu-gdb.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626

2727
sys.path.append(os.path.dirname(__file__))
2828

29-
from qemugdb import mtree, coroutine
29+
from qemugdb import aio, mtree, coroutine
3030

3131
class QemuCommand(gdb.Command):
3232
'''Prefix for QEMU debug support commands'''
@@ -37,6 +37,7 @@ def __init__(self):
3737
QemuCommand()
3838
coroutine.CoroutineCommand()
3939
mtree.MtreeCommand()
40+
aio.HandlersCommand()
4041

4142
coroutine.CoroutineSPFunction()
4243
coroutine.CoroutinePCFunction()

scripts/qemugdb/aio.py

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
#!/usr/bin/python
2+
3+
# GDB debugging support: aio/iohandler debug
4+
#
5+
# Copyright (c) 2015 Red Hat, Inc.
6+
#
7+
# Author: Dr. David Alan Gilbert <[email protected]>
8+
#
9+
# This work is licensed under the terms of the GNU GPL, version 2 or
10+
# later. See the COPYING file in the top-level directory.
11+
#
12+
13+
import gdb
14+
from qemugdb import coroutine
15+
16+
def isnull(ptr):
17+
return ptr == gdb.Value(0).cast(ptr.type)
18+
19+
def dump_aiocontext(context, verbose):
20+
'''Display a dump and backtrace for an aiocontext'''
21+
cur = context['aio_handlers']['lh_first']
22+
# Get pointers to functions we're going to process specially
23+
sym_fd_coroutine_enter = gdb.parse_and_eval('fd_coroutine_enter')
24+
25+
while not isnull(cur):
26+
entry = cur.dereference()
27+
gdb.write('----\n%s\n' % entry)
28+
if verbose and cur['io_read'] == sym_fd_coroutine_enter:
29+
coptr = (cur['opaque'].cast(gdb.lookup_type('FDYieldUntilData').pointer()))['co']
30+
coptr = coptr.cast(gdb.lookup_type('CoroutineUContext').pointer())
31+
coroutine.bt_jmpbuf(coptr['env']['__jmpbuf'])
32+
cur = cur['node']['le_next'];
33+
34+
gdb.write('----\n')
35+
36+
class HandlersCommand(gdb.Command):
37+
'''Display aio handlers'''
38+
def __init__(self):
39+
gdb.Command.__init__(self, 'qemu handlers', gdb.COMMAND_DATA,
40+
gdb.COMPLETE_NONE)
41+
42+
def invoke(self, arg, from_tty):
43+
verbose = False
44+
argv = gdb.string_to_argv(arg)
45+
46+
if len(argv) > 0 and argv[0] == '--verbose':
47+
verbose = True
48+
argv.pop(0)
49+
50+
if len(argv) > 1:
51+
gdb.write('usage: qemu handlers [--verbose] [handler]\n')
52+
return
53+
54+
if len(argv) == 1:
55+
handlers_name = argv[0]
56+
else:
57+
handlers_name = 'qemu_aio_context'
58+
dump_aiocontext(gdb.parse_and_eval(handlers_name), verbose)

0 commit comments

Comments
 (0)