笔者来聊聊断点以及断点的调试
1、断点原理
断电的原理一般分为两种,插入断点指令或者利用硬件调试寄存器进行断点。
- 前者程序如果在RAM(SRAM、DDR)上,则调试器可以直接在断点地址处插入断点指令,例如BKPT(ARM)、HLT指令(x86),程序则可暂停,后续可以单步运行等操作。
 - 后者程序如果在ROM/Flash运行,调试器无法改写ROM或者Flash的内容,需要利用硬件支持的寄存器特性去进行调试。
 
Cortex-M3/4,利用Flash补丁或者断点单元(FPB)中的地址比较器进行设置断点,还有多个调试寄存器辅助调试,例如暂停、获取寄存器数据以及传递数据等。例如一个调试控制寄存器如下:

- 支持暂停内核
 - 单步运行处理器
 - 单步时屏蔽中断
 - 读写状态等
 - …
调试访问的主要架构(CoreSight)如下所示:以CortexM3为例, 

- DP(Debug Port):调试端口,SWD下面称为SW-DP,JTAG下面称为JTAG-DP,将调试协议转为内部调试总线协议(32位的总线协议,与AMBA3.0规范中的高级外设总线APB非常类似)。
 - AP(Acess Port):访问端口,有AHB-AP模块,可以将内部调试总线协议转成高速性能总线,可以获取所有存储器、外设以及处理器内部的寄存器等数据。
 
接着来看一下SWD和Jtag链接时,扫描出的DP和AP端口。
SWD 链接时扫描DP和AP端口
 - Found SW-DP with ID 0x1BA01477
 - DPIDR: 0x1BA01477
 - Scanning AP map to find all available APs
 - AP[1]: Stopped AP scan as end of AP map has been reached
 - AP[0]: AHB-AP (IDR: 0x14770011)
 - Iterating through AP map to find AHB-AP to use
 - AP[0]: Core found
 - AP[0]: AHB-AP ROM base: 0xE00FF000
 - CPUID register: 0x411FC231. Implementer code: 0x41 (ARM)
 - Found Cortex-M3 r1p1, Little endian.
 
JTAG 链接时扫描DP和AP端口,支持菊花链,多个被调试主控串联起来。
 - TotalIRLen = 9, IRPrint = 0x0011
 - JTAG chain detection found 2 devices:
 -  #0 Id: 0x3BA00477, IRLen: 04, CoreSight JTAG-DP
 -  #1 Id: 0x06414041, IRLen: 05, STM32 Boundary Scan
 - DPv0 detected
 - Scanning AP map to find all available APs
 - AP[1]: Stopped AP scan as end of AP map has been reached
 - AP[0]: AHB-AP (IDR: 0x14770011)
 - Iterating through AP map to find AHB-AP to use
 - AP[0]: Core found
 - AP[0]: AHB-AP ROM base: 0xE00FF000
 - CPUID register: 0x411FC231. Implementer code: 0x41 (ARM)
 - Found Cortex-M3 r1p1, Little endian.
 
2、断点分类
2.1、实现原理分类
- 硬件断点: 
  
- 与芯片架构内核相关,调试器需要设置对应的断点寄存器
 - 应用于Flash、ROM以及RAM等区域
 - 数量有限

CortexM3-M4的很多芯片比如STM32F1 F4都是Flash执行代码,所以只能设置onchip断点,且只有6个,多了会报错。

 
 

 
-  
软件断点:
- 调试器利用断点指令,在断点地址处插入断点指令
 - 在RAM(RAM、TCM以及DDR)等区域,
 - 断点数量无限

 
 -  
ETM断点:
- ARM部分芯片特有,CortexM系列没有
 - 设置ARM Coresight ETM寄存器来实现
 - 数量有限

 
 
2.2、使用场景分类
-  
程序断点
- 程序运行到指定位置,则停止CPU
 - 可以是软件断点或者硬件断点

 
 -  
读写断点
- 只能是硬件断点
 - 指定内存/变量,发生读写行为时,停下CPU

 
 -  
数据断点
- 只能是硬件断点,
 - 指定内存/变量发生读写指定值时,停下CPU
 - 和读写断点,类似,只不过加了更细节的条件

 
 -  
高级断点
- 只能是硬件断点
 - 增加了更细节的条件,满足一定条件后停止,比如read 10次之后停止,又比如,当变量值>某个值时,然后停止。

 
 

2.3、对CPU的影响分类
- 侵入式断点 
  
- 对CPU执行有影响,不断停下CPU,对相应的值或者条件判断,
 
 - 非侵入式断点 
  
- 对CPU执行没有影响,

 
 - 对CPU执行没有影响,
 
3、断点调试
-  
方法一:双击程序所在行即可设置对应的行断点
 -  
方法二:利用symbol符号进行设置断点

 -  
方法三:利用窗口进行设置:

 -  
命令行设置:b.set addr/addr-range/name /options 后面可以跟地址、地址范、symbol名字以及选项
- b.set 0x1000005FC 在0x1000005FC 地址处设置断点
 - b.set mstatic1 /readwrite 读写 mstatic1 该变量时,停止运行
 - b.set mstatic1 /write /DATA.Long 0xC 当变量mstatic1 写成0xC时,停止运行
 - b.set mstatic1 /Write /COUNT 10 当变量mstatic1被循环写10次之后,停止运行
 - b.set mstatic1 /Write /VarCONDition mstatic1>0xC 当变量mstatic1大于0xC时,停止断点

 
 
4、参考以及附录
Trace32 官方文档:5 断点.pdf
 SWD 链接的打印完整log。
Connecting ...
 - Connecting via USB to probe/ programmer device 0
 - Probe/ Programmer firmware: J-Link V9 compiled May  7 2021 16:26:12
 - Device "STM32F105RC" selected.
 - Target interface speed: 4000 kHz (Fixed)
 - VTarget = 3.372V
 - InitTarget() start
 - InitTarget() end
 - Found SW-DP with ID 0x1BA01477
 - DPIDR: 0x1BA01477
 - Scanning AP map to find all available APs
 - AP[1]: Stopped AP scan as end of AP map has been reached
 - AP[0]: AHB-AP (IDR: 0x14770011)
 - Iterating through AP map to find AHB-AP to use
 - AP[0]: Core found
 - AP[0]: AHB-AP ROM base: 0xE00FF000
 - CPUID register: 0x411FC231. Implementer code: 0x41 (ARM)
 - Found Cortex-M3 r1p1, Little endian.
 - FPUnit: 6 code (BP) slots and 2 literal slots
 - CoreSight components:
 - ROMTbl[0] @ E00FF000
 - ROMTbl[0][0]: E000E000, CID: B105E00D, PID: 001BB000 SCS
 - ROMTbl[0][1]: E0001000, CID: B105E00D, PID: 001BB002 DWT
 - ROMTbl[0][2]: E0002000, CID: B105E00D, PID: 000BB003 FPB
 - ROMTbl[0][3]: E0000000, CID: B105E00D, PID: 001BB001 ITM
 - ROMTbl[0][4]: E0040000, CID: B105900D, PID: 001BB923 TPIU-Lite
 - ROMTbl[0][5]: E0041000, CID: B105900D, PID: 101BB924 ETM-M3
 - Executing init sequence ...
  - Initialized successfully
 - Target interface speed: 4000 kHz (Fixed)
 - Found 1 JTAG device. Core ID: 0x1BA01477 (None)
 - Connected successfully
 
JTag 链接的打印完整log。
Connecting ...
 - Connecting via USB to probe/ programmer device 0
 - Probe/ Programmer firmware: J-Link ARM V8 compiled Nov 28 2014 13:44:46
 - Device "STM32F103RC" selected.
 - Target interface speed: 4000 kHz (Fixed)
 - VTarget = 3.338V
 - InitTarget() start
 - TotalIRLen = 9, IRPrint = 0x0011
 - JTAG chain detection found 2 devices:
 -  #0 Id: 0x3BA00477, IRLen: 04, CoreSight JTAG-DP
 -  #1 Id: 0x06414041, IRLen: 05, STM32 Boundary Scan
 - InitTarget() end
 - TotalIRLen = 9, IRPrint = 0x0011
 - JTAG chain detection found 2 devices:
 -  #0 Id: 0x3BA00477, IRLen: 04, CoreSight JTAG-DP
 -  #1 Id: 0x06414041, IRLen: 05, STM32 Boundary Scan
 - DPv0 detected
 - Scanning AP map to find all available APs
 - AP[1]: Stopped AP scan as end of AP map has been reached
 - AP[0]: AHB-AP (IDR: 0x14770011)
 - Iterating through AP map to find AHB-AP to use
 - AP[0]: Core found
 - AP[0]: AHB-AP ROM base: 0xE00FF000
 - CPUID register: 0x411FC231. Implementer code: 0x41 (ARM)
 - Found Cortex-M3 r1p1, Little endian.
 - FPUnit: 6 code (BP) slots and 2 literal slots
 - CoreSight components:
 - ROMTbl[0] @ E00FF000
 - ROMTbl[0][0]: E000E000, CID: B105E00D, PID: 001BB000 SCS
 - ROMTbl[0][1]: E0001000, CID: B105E00D, PID: 001BB002 DWT
 - ROMTbl[0][2]: E0002000, CID: B105E00D, PID: 000BB003 FPB
 - ROMTbl[0][3]: E0000000, CID: B105E00D, PID: 001BB001 ITM
 - ROMTbl[0][4]: E0040000, CID: B105900D, PID: 001BB923 TPIU-Lite
 - ROMTbl[0][5]: E0041000, CID: B105900D, PID: 101BB924 ETM-M3
 - Executing init sequence ...
  - Initialized successfully
 - Target interface speed: 4000 kHz (Fixed)
 - Found 2 JTAG devices. Core ID: 0x3BA00477 (None)
 - Connected successfully
                


















