zynq c语言中如果出现bug,进入异常中断如何定位到代码行?

由于某些未知的错误导致程序突然崩溃, 进入了zynq的异常处理程序中. 其它信息没了. 暂停代码执行的时候就只有进入了下面的这个函数. 这个函数进入的可能性非常高. 问题是怎么找到原因定位到有问题的代码行呢? 经过一番查找和人工智能的辅助下, 我终于知道如何定位到代码行了.

void Xil_DataAbortHandler(void *CallBackRef)
{
	(void) CallBackRef;
//#ifdef DEBUG
	volatile u32 FaultStatus;

        xdbg_printf(XDBG_DEBUG_ERROR, "Data abort \n");
        #ifdef __GNUC__
        	FaultStatus = mfcp(XREG_CP15_DATA_FAULT_STATUS);
	    #elif defined (__ICCARM__)
	        mfcp(XREG_CP15_DATA_FAULT_STATUS,FaultStatus);
	    #else
	        {
	        	volatile register u32 Reg __asm(XREG_CP15_DATA_FAULT_STATUS);
	        	FaultStatus = Reg;
	        }
	    #endif
	xdbg_printf(XDBG_DEBUG_GENERAL, "Data abort with Data Fault Status Register  %lx\n",FaultStatus);
	xdbg_printf(XDBG_DEBUG_GENERAL, "Address of Instruction causing Data abort %lx\n",DataAbortAddr);
	//使用GDB添加断点到 出错的地址, 然后再次进行调试即可.步骤如下 
	//在GDB窗口中执行命令,break *0x1005cc  其中0x1005cc是DataAbortAddr中存储的触发异常的代码地址.
	
//#endif
	while(1) {
		;
	}
}

Xil_DataAbortHandler 这断代码是我修改过的 , 注释掉了while死循环,防止无法重现DataAbortAddr
这段代码中,xdbg_printf() 我建议改成普通的printf 或者xli_printf 这样可以直接输出有错误的地址, 然后直接再界面上进行调试. 修改后的代码如下, 增加了更加人性化的提示信息.

@file xil_exception.c

void Xil_DataAbortHandler( void *CallBackRef)
{
//	(void) CallBackRef; 
	volatile u32 FaultStatus;

		 printf("Xil_DataAbortHandler Data abort at function %x \n",CallBackRef);
        #ifdef __GNUC__
        	FaultStatus = mfcp(XREG_CP15_DATA_FAULT_STATUS);
	    #elif defined (__ICCARM__)
	        mfcp(XREG_CP15_DATA_FAULT_STATUS,FaultStatus);
	    #else
	        {
	        	volatile register u32 Reg __asm(XREG_CP15_DATA_FAULT_STATUS);
	        	FaultStatus = Reg;
	        }
	    #endif

	        xil_printf("Data abort with Data Fault Status Register  %x\n",FaultStatus);
	        xil_printf("Address of Instruction causing Data abort %x\n ",DataAbortAddr);
	        xil_printf("Please run the command\"break * %x\" in the GDB console window, add breakpoints to continue debugging   \n ",DataAbortAddr);
	//使用GDB添加断点到 出错的地址, 然后再次进行调试即可.步骤如下
	//在GDB窗口中执行命令,break *0x1005cc  其中0x1005cc是DataAbortAddr中存储的触发异常的代码地址. 
	while(1) {
		xil_printf("Please run the command\"break *0x%x\" in the GDB console window, add breakpoints to continue debugging   \n ",DataAbortAddr);
		sleep(1);
	}
}

在GDB中,如果你已经知道了引发异常的代码指令行(或者至少是接近该行的地址),你可以在该位置添加断点,然后让程序运行到该断点处继续执行,并在程序中断时进行调试。以下是具体步骤:
为防止有的人找不到在哪里执行break 命令. 截个图. 把串口输出的调试信息放到gdb窗口中执行.
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

下面是一些参考信息, 百度的文心一言人工智能给的. 挺不错的.

添加断点:
如果你知道具体的源代码行号,可以使用break 命令来在该行添加断点。例如,如果异常发生在第123行,你可以输入break 123。
如果你只知道引发异常的指令地址(比如0x1050060),你可以使用break *

命令来在该地址处添加断点。例如,输入break *0x1050060。
运行程序:
使用run命令来运行程序。如果程序之前已经运行过并且你希望重新开始,可以先使用run命令并跟上任何需要的程序参数,或者先使用kill命令终止当前运行的程序,然后再使用run命令。
程序中断:
当程序运行到添加的断点时,它会停下来并等待GDB的进一步命令。此时,你可以使用GDB的各种调试命令来检查程序的状态。
调试:
在程序中断时,你可以使用print命令来查看变量的值,使用step或next命令来单步执行代码,使用backtrace命令来查看调用栈等。
你可以根据需要继续调试,直到找到问题的根源并修复它。
继续执行:
如果你已经找到了问题并修复了它,或者只是想要继续运行程序以查看后续的行为,你可以使用continue命令来让程序继续执行。
移除断点:
如果你不再需要某个断点,可以使用delete 命令来删除它。你可以使用info breakpoints命令来查看当前所有断点的编号。
需要注意的是,如果你是在一个复杂的程序中进行调试,并且异常发生在某个库函数或深层调用栈中,那么仅仅在引发异常的指令行上添加断点可能不足以完全理解问题的根源。在这种情况下,你可能需要设置多个断点,或者使用GDB的条件断点、监视点等功能来更深入地了解程序的执行流程。

此外,由于编译器优化和代码生成的影响,有时源代码中的一行可能对应多条汇编指令,或者一条汇编指令可能跨越了源代码中的多行。因此,在设置断点和解读GDB的输出时,需要谨慎并具备一定的汇编语言和编译器优化知识。

ZYNQ是Xilinx公司推出的一款嵌入式系统级芯片(SoC),它集成了CPU和FPGA(Field-Programmable Gate Array)的功能于一身,提供了灵活的硬件加速能力和高性能的处理器核心。在ZYNQ,CPU通常负责处理软件任务,而FPGA则可以根据应用需求进实时的硬件定制。 Windows操作系统的等待断源代码通常涉及设备驱动程序的编写。当一个设备发出断请求时,操作系统会暂停当前执的任务(进入等待状态),然后调用相应的断服务程序(ISR, Interrupt Service Routine)。在这个过程,源代码可能包括以下几个部分: 1. **断注册**:在设备初始化阶段,通过注册断处理函数,使得操作系统能够识别并响应特定断请求。 ```c void MyDeviceInit(void) { RegisterInterruptHandler(MyDeviceIsr); } ``` 2. **断服务例程(ISR)**:这个函数会在断发生时被执,处理具体的断事件。 ```c void MyDeviceIsr(__interrupt DWORD interruptNumber) { // Device-specific processing logic here } ``` 3. **断上下文保存/恢复**:为了保证断处理的安全性,通常会保存CPU状态并在断返回前恢复,这涉及到堆栈操作和保护设置。 4. **断标志管理**:在断处理结束后,可能需要更新断标志位,以便后续检查是否还有未处理的断。 5. **断向量表(Interrupt Vector Table, IVT)**:操作系统维护的一个表格,记录了每个断对应的处理程序地址。 在Windows平台上,这些操作可能会基于KeServiceInterrupt()或KiUserExceptionDispatcher()等Windows内核API实现。如果你具体想了解某个设备的等待断源代码,可能需要查看该设备的驱动程序代码库,比如在Microsoft的开源项目里(如GitHub上的MinnowBoardDriver)找到相关的示例。不过请注意,由于Windows内核代码是高度优化且受版权保护的,直接分享源代码是不可能的,建议查阅官方文档和开发者资源学习。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值