gdb退出时需要输入y
通常我们使用q(quit
的缩写)来退出gdb,现在我们使用define
定义个q命令来执行quit
,可以实现使用q退出gdb时不需要再输入y。可以把这个定义添加到.gdbinit
就可以直接使用了。
.gdbinit
define q quit end
gdb读写Flash
调试时gdb可以读写ram,但是Flash不能直接读写,一般需要通过Flash控制器,对于Flash的擦除、写入也只需配置几个寄存器就可以实现,这样一来我们就可以用gdb的命令写一个Flash驱动,使用define
定义一个命令,并可以传参。下面是一个例子,不同的芯片擦写驱动不同,需要量身定制。
flash_erase_program.gdb
# 如果有多个Flash控制器,则使用my_get_base_addr命令根据输入的地址设置控制器的基地址,同时该命令负责检查输入的地址是否合法 define my_get_base_addr set $BASE_ADDR = 0 if $arg0 >= 0x10000000 && $arg0 <= 0x1007FFFF set $BASE_ADDR = 0x40002000 end if $BASE_ADDR == 0 echo Address \033[1;34m0x printf "%08X", $arg0 echo \033[1;0m is illegal\n end end # 定义命令帮助文档,可以使用help命令查看该说明 decument my_get_base_addr Get base address from input address. The return value is $BASE_ADDR, if not find, $BASE_ADDR == 0. Usage: my_get_base_addr [addr] end define my_erase_sector my_get_base_addr $arg0 if $BASE_ADDR set $ERASE_ADDR = $arg0 & 0xFFFFFF00 while (*$BASE_ADDR & 0x01) end set *$ERASE_ADDR = 0x1A45CBD2 set *($BASE_ADDR + 8) = 0x2 while (*$BASE_ADDR == 0) end while(*$BASE_ADDR & 0x01) end end end decument my_erase_sector Erase sector flash. Usage: my_erase_sector [addr] end ... 后面可以继续定义Flash的写入命令
在调试时使用
(gdb) source flash_erase_program.gdb (gdb) help my_erase_sector Erase sector flash. Usage: my_erase_sector [addr] (gdb) my_erase_sector 0x10000000 (gdb)
gdb将memory的数据原样显示在终端上
我们可以使用dump
指令将memory的原始数据写入文件。在shell环境下(包括window上的git-bash或cmder模拟终端)有几个特殊的文件/dev/tty
/dev/stdout
等,若我们将dump
的目标文件设置为它们将可以实现我们的需求。
main.c
static const char *buf[] = "\033[1;34m123456\033[1;0m\n"; int main(void) { while(1); return 0; }
shell环境下开始gdb调试
xflm $ gcc -g main.c #编译生成可调试的a.out xflm $ gdb a.out #启动调试 (gdb) b main #设置断点 (gdb) r #将程序跑起来 xflm $ #CTRL+D,gdb输入r后会回到命令行,使用CTRL+D退出命令行就回到gdb了 (gdb) dump binary memory /dev/tty buf buf+sizeof(buf) 123456 #这是终端输出的内容,字体为粗体蓝色,该行的上下两行都是普通字体 (gdb)
后来发现window模拟终端上用不了,因为window上的gdb工具不认识虚拟终端里的
/dev/tty
/dev/stdout
特殊文件,解决方法如下:
- 若打印1KB的数据,这个打印速度明显慢跟多,因为GDB可能会逐字节的读取内存然后判断是否为
\0
。(gdb) printf "%s", buf 123456 #这是终端输出的内容,字体为粗体蓝色,该行的上下两行都是普通字体
- 这个和Linux下的速度差不多,而且,window gdb程序执行shell命令不会返回到虚拟终端,非常方便。
(gdb) dump binary memory ~/.gdb_dump buf buf+sizeof(buf) (gdb) shell cat ~/.gdb_dump 123456 #这是终端输出的内容,字体为粗体蓝色,该行的上下两行都是普通字体