搜索
bottom↓
回复: 21

网上找的stm32 定位hardfault故障位置点方法,实测无效,怎样定位

[复制链接]

出0入8汤圆

发表于 2021-10-16 12:16:59 | 显示全部楼层 |阅读模式
整体过程如下:

一、人为制造死机


static int set_fault()
{
                int a[5],idx = 1000;
                char buf = 0;

                a[1000] = 0;
                a[2000] = 0;
       
                Shell *shell = shellGetCurrent();

                while(1)
                {

                        segger_printk("set fault done %d\r\n", a[idx]);

                        idx += 1000;
                       
                        shell->read(&buf,1);
                       
                        if ( buf == 'q')
                        {
                                break;
                        }
                        vTaskDelay(500);
                }
               
    return 0;
}
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC), fault, set_fault, set fault);

通过shell指令,制造内存溢出,导致死机。

二、查寄存器定位故障代码位置

1、进入hardfault后查找堆栈指针的值


0x20004F38。
这个栈地址里面依次的值是:
R0-R3、R12、PC、xPSR(CPSR或者SPSR)、LR。
我们需要查找PC和xPSR寄存器的值。也就是第6、7个寄存器的值。


2、在memory窗口输入0x20004F38值。

PC的值为:
0x0804891D
xPSR的值为:
0x080201D4


3、在view里面打开dissmebly 汇编窗口。


4、在汇编窗口右键,选择show dissably code at address。


5、定位程序点





提示程序故障点在上面函数中。

三、结论
定位的位置不正确。



操作过程应该没毛病,不知道有没其他定位故障点的方法,谢谢大家。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

发表于 2021-10-16 12:43:50 | 显示全部楼层
1-楼主可否分享工程;2-怎么知道 这个栈地址里面依次的值就是:R0-R3、R12、PC、xPSR(CPSR或者SPSR)、LR。谢谢

出0入8汤圆

 楼主| 发表于 2021-10-16 12:58:42 | 显示全部楼层
zirong0804 发表于 2021-10-16 12:43
1-楼主可否分享工程;2-怎么知道 这个栈地址里面依次的值就是:R0-R3、R12、PC、xPSR(CPSR或者SPSR)、LR。 ...

https://blog.csdn.net/weixin_39674445/article/details/102452281
  
照着这个教程来的。

出0入42汤圆

发表于 2021-10-16 13:04:38 | 显示全部楼层
定位没问题啊,这个方法是定位发生Hardfault的位置,不是定位产生Hardfault条件的位置
你在制造溢出的过程中并没有发生Hardfault,Hardfault发生在后续的其它过程中。

出0入8汤圆

 楼主| 发表于 2021-10-16 13:54:03 | 显示全部楼层
wshtyr 发表于 2021-10-16 13:04
定位没问题啊,这个方法是定位发生Hardfault的位置,不是定位产生Hardfault条件的位置
你在制造溢出的过程 ...

比如正常的程序中,也是这样间接导致死机。那么久很难准确定位到故障点了。

出0入0汤圆

发表于 2021-10-16 16:18:31 | 显示全部楼层
不知怎么跑进Hardfault,写了也算多代码,没出现过Hardfault。最多看门狗复位,再找复位地方;还有就是溢出,主要用状态机,有一次溢出,状态机某状态改了,查了很久,之后查map发现问题所在。

出0入8汤圆

 楼主| 发表于 2021-10-19 08:42:07 | 显示全部楼层
要是有个东西能够无人值守监控就好了

出0入0汤圆

发表于 2021-10-19 08:56:34 | 显示全部楼层
试下这个
https://github.com/armink/CmBacktrace/blob/master/README_ZH.md

出0入0汤圆

发表于 2021-10-19 09:23:15 | 显示全部楼层
用Ozone仿真,能看到进Hardfault前的PC地址

出0入42汤圆

发表于 2021-10-19 14:26:57 | 显示全部楼层
本帖最后由 liyang121316 于 2021-10-19 14:30 编辑

你参考的帖子是不是有问题,我记得要修改startup启动程序,还要在hardfault函数里面保存一遍这些寄存器的值。我之前遇到的问题都是这样定位的,
我一个同事更狠,直接在出问题代码附近设置断点然后单步仿真看汇编代码,最后也能找到问题。

出0入8汤圆

 楼主| 发表于 2021-10-19 16:40:34 | 显示全部楼层
liyang121316 发表于 2021-10-19 14:26
你参考的帖子是不是有问题,我记得要修改startup启动程序,还要在hardfault函数里面保存一遍这些寄存器的值 ...

有可能。

记得以前也遇到此类问题,这样参考也没找到原因。


你这边如果有好的方法,请推荐一下。谢谢!

出0入0汤圆

发表于 2021-10-19 18:04:49 | 显示全部楼层
我更崩溃,进到NMI 报错,根本无处下手

出0入4汤圆

发表于 2021-10-19 18:38:46 | 显示全部楼层
view->call stack windows. 这个可以吗?

不看汇编, 如何得知:
这个栈地址里面依次的值是:R0-R3、R12、PC、xPSR(CPSR或者SPSR)、LR ??
PC,LR一般不会压栈吧?

出0入8汤圆

 楼主| 发表于 2021-10-22 11:26:13 | 显示全部楼层
wjd40 发表于 2021-10-19 08:56
试下这个
https://github.com/armink/CmBacktrace/blob/master/README_ZH.md




这个通过addline分析出的位置。有一些问号, 不知道啥意思


请问这东西定位准么

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

发表于 2021-10-22 14:09:31 | 显示全部楼层
justdomyself 发表于 2021-10-22 11:26
这个通过addline分析出的位置。有一些问号, 不知道啥意思

这能提示你故障代码在哪个文件的哪一行,之前使用,判断还是很准确

出0入0汤圆

发表于 2021-10-23 00:28:20 来自手机 | 显示全部楼层
可以参考rt-thread,跟你这个类似应该。如果是在调试阶段加着仿真的话看下栈内容应该很快就能定位

出0入8汤圆

 楼主| 发表于 2021-10-23 05:44:51 | 显示全部楼层
596142041 发表于 2021-10-22 14:09
这能提示你故障代码在哪个文件的哪一行,之前使用,判断还是很准确

好多都是定位在系统函数中,不知从何查起了

出0入8汤圆

 楼主| 发表于 2021-10-23 05:46:07 | 显示全部楼层
本帖最后由 justdomyself 于 2021-10-23 12:01 编辑
higeo 发表于 2021-10-23 00:28
可以参考rt-thread,跟你这个类似应该。如果是在调试阶段加着仿真的话看下栈内容应该很快就能定位 ...



下面是参照这个帖子弄得,帖子里面是M3的,不清楚M4是否适用:
https://blog.csdn.net/suny1234/article/details/89418980



HardFault_Handler\
                PROC
                EXPORT  HardFault_Handler          ;[WEAK]
                                IMPORT  rt_hw_hard_fault_exception
                                       
                                TST     lr, #0x04               ;;(1-1)
                                MRSNE   r0, msp                 ;;(1-2)
                                MRSEQ   r0, psp                 ;;(1-3)

                                STMFD   r0!, {r4 - r11}         ;;(2)
                                STMFD   r0!, {lr}               ;;(3)

                                MSRNE   msp, r0                ;;(1-4)
                                MSREQ   psp, r0                 ;;(1-5)

                                PUSH    {lr}                    ;;(4)
                                BL      rt_hw_hard_fault_exception   ;;(5)
                                POP     {lr}                    ;;(6)


                                ORR     lr, lr, #0x04           ;;(7)
                                BX      lr                      ;;(8)
                                ENDP

                                ALIGN   4                       ;;(9)

                ;B       .
                ;ENDP
MemManage_Handler\
                PROC
                EXPORT  MemManage_Handler          [WEAK]
                B       .
                ENDP




struct exception_stack
{
                                uint32_t r0;
                                uint32_t r1;
                                uint32_t r2;
                                uint32_t r3;
                                uint32_t r12;
                                uint32_t lr;
                                uint32_t pc;
                                uint32_t psr;//?????   
};

struct stack_frame
{
   
        uint32_t r4;
        uint32_t r5;
        uint32_t r6;
        uint32_t r7;
        uint32_t r8;
        uint32_t r9;
        uint32_t r10;
        uint32_t r11;
        
                       
                                struct exception_stack exception_stack_frame;
};

struct exception_info
{
    uint32_t exc_return;
    struct stack_frame stack_frame;
};



#define rt_kprintf segger_printk  
/*
* fault exception handler
*/
void rt_hw_hard_fault_exception(struct exception_info * exception_info)
{
    extern long list_thread(void);
    /*??context???????????*/
    struct stack_frame* context = &exception_info->stack_frame;

//    /*???????????????????????,????????*/
//    if (rt_exception_hook != RT_NULL)
//    {
//        rt_err_t result;

//        result = rt_exception_hook(exception_info);
//        if (result == RT_EOK)
//            return;
//    }

    /*?????????*/
    rt_kprintf("psr: 0x%08x\n", context->exception_stack_frame.psr);

    /*??????????*/
    rt_kprintf("r00: 0x%08x\n", context->exception_stack_frame.r0);
    rt_kprintf("r01: 0x%08x\n", context->exception_stack_frame.r1);
    rt_kprintf("r02: 0x%08x\n", context->exception_stack_frame.r2);
    rt_kprintf("r03: 0x%08x\n", context->exception_stack_frame.r3);
    rt_kprintf("r04: 0x%08x\n", context->r4);
    rt_kprintf("r05: 0x%08x\n", context->r5);
    rt_kprintf("r06: 0x%08x\n", context->r6);
    rt_kprintf("r07: 0x%08x\n", context->r7);
    rt_kprintf("r08: 0x%08x\n", context->r8);
    rt_kprintf("r09: 0x%08x\n", context->r9);
    rt_kprintf("r10: 0x%08x\n", context->r10);
    rt_kprintf("r11: 0x%08x\n", context->r11);
    rt_kprintf("r12: 0x%08x\n", context->exception_stack_frame.r12);
    rt_kprintf(" lr: 0x%08x\n", context->exception_stack_frame.lr);
    rt_kprintf(" pc: 0x%08x\n", context->exception_stack_frame.pc);

    /*??EXC_RETURN[2] ?1????????????*/
    if(exception_info->exc_return & (1 << 2) )
    {
        rt_kprintf("hard fault on thread:\r\n\r\n");

#ifdef RT_USING_FINSH
        list_thread();/*??????*/
#endif /* RT_USING_FINSH */
    }
    else/*???handler??*/
    {
        rt_kprintf("hard fault on handler\r\n\r\n");
    }

#ifdef RT_USING_FINSH
    hard_fault_track();/*????*/
#endif /* RT_USING_FINSH */

    while (1);
}

出20入25汤圆

发表于 2021-10-23 11:07:56 来自手机 | 显示全部楼层
HARDFAULT的检测机制是什么啊,芯片怎么知道的

出0入0汤圆

发表于 2021-10-23 12:46:38 | 显示全部楼层
justdomyself 发表于 2021-10-23 05:46
下面是参照这个帖子弄得,帖子里面是M3的,不清楚M4是否适用:
https://blog.csdn.net/suny1234/article ...

我没有研究过具体的代码,写代码多了一般不会出现hardfault的问题,即使出现了在自测阶段都能找到问题,加仿真看下栈列表最多几分钟就能定位到问题点。后边如果碰到不容易复现或者量产设备上有这个问题就要借助这类工具了,看你现在需求应该是不容易复现的hardfault的问题?

出0入8汤圆

 楼主| 发表于 2021-10-23 16:37:49 | 显示全部楼层
higeo 发表于 2021-10-23 12:46
我没有研究过具体的代码,写代码多了一般不会出现hardfault的问题,即使出现了在自测阶段都能找到问题, ...

我是给别人填坑。不是特别容易复现,用楼上的cmtrace每次定位的位置都不一样。

出0入0汤圆

发表于 2021-10-23 18:43:43 | 显示全部楼层
justdomyself 发表于 2021-10-23 16:37
我是给别人填坑。不是特别容易复现,用楼上的cmtrace每次定位的位置都不一样。 ...


“每次位置都不一样”出现这么多次了应该算挺容易复现的了,加仿真看栈列表了吗?
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-19 13:12

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表