QEMU支持GDB, 它内置了一个GDB server,就是说如果你懂GDB protocol的话,你可以直接向GDB发送指令,控制GDB。
但GDB不是完美, 所以你有理主去搞一个自己的debug server, 如果你是在开发调试器的话, 你更加需要一个自己的debug protocol.
这编文章我会示范怎样去创造一个debug server, 经TCP去接收指令. 我会以qemu-kvm来示范, qemu-kvm代码来讲和qemu不同, 但加debug server来说都是差不多.
我会用eclipse+CDT来调qemu,我不会用gdb了, 因为命令行对我来说是灾难.
所有我改过的variable和function, 我都会以peter为开头,我在代码里搜peter就可以知道我改过什么地方了。
enum {
DEV_USB, /* -usbdevice */
DEV_BT, /* -bt */
DEV_SERIAL, /* -serial */
DEV_PARALLEL, /* -parallel */
DEV_VIRTCON, /* -virtioconsole */
DEV_DEBUGCON, /* -debugcon */
DEV_GDB, /* -gdb, -s */
DEV_PETER /* peter */
} type;
const char *cmdline;
Location loc;
QTAILQ_ENTRY(device_config) next;
};
case QEMU_OPTION_s:
add_device_config(DEV_GDB, "tcp::" DEFAULT_GDBSTUB_PORT);
break;
case QEMU_OPTION_gdb:
add_device_config(DEV_GDB, optarg);
break;
case QEMU_OPTION_peter:
peter_cmdline=optarg;
break;
case QEMU_OPTION_L:
data_dir = optarg;
break;
我们需要改文件qemu-options.hx, 它决定command-line-argument-parser 怎样 parse 我们的参数"-peter 1234". 所以要在行2390加入:
DEF("peter", HAS_ARG, QEMU_OPTION_peter, \
"-peter dev wait for peter connection on 'dev'\n", QEMU_ARCH_ALL)
STEXI
@findex -peter
Wait for peter
@example
(peter) target remote | exec qemu-system-i386 -peter stdio ...
@end example
ETEXI
const char *peter_cmdline;
if (foreach_device_config(DEV_GDB, gdbserver_start) < 0) {
exit(1);
}
if (peter_start(peter_cmdline)>0){
fprintf(stderr, "start peter error\n");
exit(0);
}
qdev_machine_creation_done();
if (rom_load_all() != 0) {
fprintf(stderr, "rom loading failed\n");
exit(1);
}
#########################################################
# System emulator target
ifdef CONFIG_SOFTMMU
CONFIG_NO_PCI = $(if $(subst n,,$(CONFIG_PCI)),n,y)
CONFIG_NO_KVM = $(if $(subst n,,$(CONFIG_KVM)),n,y)
CONFIG_NO_XEN = $(if $(subst n,,$(CONFIG_XEN)),n,y)
CONFIG_NO_GET_MEMORY_MAPPING = $(if $(subst n,,$(CONFIG_HAVE_GET_MEMORY_MAPPING)),n,y)
CONFIG_NO_CORE_DUMP = $(if $(subst n,,$(CONFIG_HAVE_CORE_DUMP)),n,y)
obj-y += arch_init.o cpus.o monitor.o gdbstub.o gkd.o balloon.o ioport.o
obj-y += hw/
obj-$(CONFIG_KVM) += kvm-all.o
obj-$(CONFIG_NO_KVM) += kvm-stub.o
obj-y += memory.o savevm.o cputlb.o
obj-$(CONFIG_HAVE_GET_MEMORY_MAPPING) += memory_mapping.o
obj-$(CONFIG_HAVE_CORE_DUMP) += dump.o
obj-$(CONFIG_NO_GET_MEMORY_MAPPING) += memory_mapping-stub.o
obj-$(CONFIG_NO_CORE_DUMP) += dump-stub.o
LIBS+=-lz
![](https://img-my.csdn.net/uploads/201211/16/1353058910_2275.png)
![](https://img-my.csdn.net/uploads/201211/16/1353059016_9717.png)