Chinaunix首页 | 论坛 | 博客
  • 博客访问: 160976
  • 博文数量: 31
  • 博客积分: 1720
  • 博客等级: 上尉
  • 技术积分: 305
  • 用 户 组: 普通用户
  • 注册时间: 2009-04-13 13:47
文章分类

全部博文(31)

文章存档

2014年(3)

2013年(1)

2012年(10)

2011年(1)

2010年(3)

2009年(13)

分类: 虚拟化

2012-06-13 10:27:47

如果调试qemu,gdb是一个不错的工具,跟踪研究qemu的工作机制,以及查看问题,都是很不错的。
下面介绍几个调试的问题,了解一下日常工作中如何使用gdb.
 1. 在qemu中,使用command line的选项来定义和选择硬件。例如可以是用-usb来定义usb的选项。目前qemu中有几种定义command line的选项。例如,-device pci-ohci. 这种low level的方式来定义硬件。qemu中并没有限制这些选项之间的混着使用。对于某种类型的机器,很多是根据 usb-enable(-usb来设置)来创建controller.但是,有些平台想要一直都使用usb,将usb-enable一直设置,如果command line中再使用-device pci-ohci来定义一个usb。那么就有冲突了。我在开发的过程中就看到这样的一个问题。
从报告的错误来看,是在pci_init_multifunction()只用有错误,在创建usb的时候,mutifunction是disabled的。但在第二次又去调用他来创建usb的时候,就出现了错误。
使用gdb来debug.
# gdb qemu
(gdb) start -M -M pseries -enable-kvm -m 1024 -mem-prealloc -mem-path /dev/hugepages/libvirt/qemu -smp 2,sockets=2,cores=1,threads=1 -name $1 -nodefconfig -nodefaults -chardev socket,id=charmonitor,path=/usr/local/var/lib/libvirt/qemu/$1.monitor,server,nowait -mon chardev=charmonitor,id=monitor,mode=readline -rtc base=utc -device spapr-vscsi,id=scsi0 -drive file=/home/zhlbj/kvm-test/fedora.img,if=none,id=drive-scsi0-0-0,format=raw -device scsi-disk,bus=scsi0.0,scsi-id=0,drive=drive-scsi0-0-0,id=scsi0-0-0,bootindex=1 -chardev pty,id=charserial0 -device spapr-vty,chardev=charserial0 -device pci-ohci,id=usb,bus=pci,addr=0x1.0x2 -vnc 127.0.0.1:12 -vga std -device virtio-balloon-pci,id=balloon0,bus=pci,addr=0x3
(gdb) break pci_init_multifunction()
(gdb) c
Breakpoint 5, pci_init_multifunction (bus=0x10f458a0, dev=0x10f48330)
    at /home/zhlbj/development/qemu-impreza/hw/pci.c:677
(gdb) bt
#0  pci_init_multifunction (bus=0x10f458a0, dev=0x10f48330)
    at /home/zhlbj/development/qemu-impreza/hw/pci.c:677
#1  0x0000000010181ef0 in do_pci_register_device (pci_dev=0x10f48330, bus=0x10f458a0, name=
    0x10ed4d80 "pci-ohci", devfn=8) at /home/zhlbj/development/qemu-impreza/hw/pci.c:802
#2  0x0000000010184950 in pci_qdev_init (qdev=0x10f48330)
    at /home/zhlbj/development/qemu-impreza/hw/pci.c:1488
#3  0x0000000010230544 in qdev_init (dev=0x10f48330)
    at /home/zhlbj/development/qemu-impreza/hw/qdev.c:150
#4  0x0000000010230c94 in qdev_init_nofail (dev=0x10f48330)
    at /home/zhlbj/development/qemu-impreza/hw/qdev.c:243
#5  0x0000000010184ee0 in pci_create_simple_multifunction (bus=0x10f458a0, devfn=-1, 
    multifunction=false, name=0x10589aa8 "pci-ohci")
    at /home/zhlbj/development/qemu-impreza/hw/pci.c:1559
#6  0x000000001018500c in pci_create_simple (bus=0x10f458a0, devfn=-1, name=
    0x10589aa8 "pci-ohci") at /home/zhlbj/development/qemu-impreza/hw/pci.c:1570
#7  0x00000000103b91cc in ppc_spapr_init (ram_size=1073741824, boot_device=
    0xfffffffeba0 "cad", kernel_filename=0x0, kernel_cmdline=0x10558ce0 "", 
    initrd_filename=0x0, cpu_model=0x105899e8 "host")
    at /home/zhlbj/development/qemu-impreza/hw/spapr.c:816
#8  0x00000000101f1460 in main (argc=37, argv=0xffffffff038, envp=0xffffffff168)
    at /home/zhlbj/development/qemu-impreza/vl.c:3502

上面的这个是第一次创建ohci的堆栈。可以看到, multifunction=false
再运行,可以看到第二次又创建了一个ohci.
(gdb) c
(gdb) bt
#0  pci_init_multifunction (bus=0x10f45a90, dev=0x10f82e50)
    at /home/zhlbj/development/qemu-impreza/hw/pci.c:677
#1  0x0000000010181ef0 in do_pci_register_device (pci_dev=0x10f82e50, bus=0x10f45a90, name=
    0x10ed4d80 "pci-ohci", devfn=10) at /home/zhlbj/development/qemu-impreza/hw/pci.c:802
#2  0x0000000010184950 in pci_qdev_init (qdev=0x10f82e50)
    at /home/zhlbj/development/qemu-impreza/hw/pci.c:1488
#3  0x0000000010230544 in qdev_init (dev=0x10f82e50)
    at /home/zhlbj/development/qemu-impreza/hw/qdev.c:150
#4  0x000000001022a5a4 in qdev_device_add (opts=0x10ee4bb0)
    at /home/zhlbj/development/qemu-impreza/hw/qdev-monitor.c:465
#5  0x00000000101ea6cc in device_init_func (opts=0x10ee4bb0, opaque=0x0)
    at /home/zhlbj/development/qemu-impreza/vl.c:1824
#6  0x0000000010245638 in qemu_opts_foreach (list=0x105da250, func=
    @0x105ff8a0: 0x101ea69c , opaque=0x0, abort_on_failure=1)
    at qemu-option.c:1053
#7  0x00000000101f1520 in main (argc=38, argv=0xffffffff008, envp=0xffffffff140)
    at /home/zhlbj/development/qemu-impreza/vl.c:3518

第二次的创建,因为multifunction是false,所以造成了失败。

这里的问题根本原因是因为usb options的使用不对。但是跟踪出来的结果,是两种option同时有效了,创建了两次controller。所以需要修改option的使用。

2. 信号的跟踪
gdb是可以捕捉信号的。使用handle命令,来控制信号的处理。
handle有两个参数,一个是信号名,另一个接受信号是的动作。
1)print 接受信号时显示一条消息。
2)noprint 接受信号时不显示消息。
3)pass 允许信号传给你的程序,允许程序处理,停止或者采取别的动作。
4)nopass 停止程序运行,但不要将信号发给程序。
5) stop 接受信号时,停止程序执行,允许调试,显示一条消息说明接受到信号。
6) nostop 接受信号时,不停止程序,
例如,在程序中出现了SIGSEGV,
 (gdb) handle SIGSEGV stop print
 (gdb) c
Continuing.
char device redirected to /dev/pts/4
[New Thread 0xfffb66bf0e0 (LWP 45909)]
[New Thread 0xfffb5ebf0e0 (LWP 45910)]

Program received signal SIGSEGV, Segmentation fault.
0x00000000102ce264 in usb_claim_port (dev=0x10f482a0) at /home/zhlbj/development/qemu-impreza/hw/usb/bus.c:348
348    QTAILQ_REMOVE(&bus->free, port, next);

我们就看到接受信号时,有一条消息。
(gdb) signal SIGSEGV
Continuing with signal SIGSEGV.
[Thread 0xfffb5ebf0e0 (LWP 45910) exited]
[Thread 0xfffb66bf0e0 (LWP 45909) exited]

Program terminated with signal SIGSEGV, Segmentation fault.
The program no longer exists.

接受信号,程序执行。就看到程序最终停止,发生segmentation fault. 


阅读(4623) | 评论(0) | 转发(2) |
0

上一篇:vim+cscope

下一篇:git 的使用

给主人留下些什么吧!~~