OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 6703|回复: 12

Keil4,STM32F4使用C++异常处理机制,一调用throw直接进入HardFault_Handler

[复制链接]

2

主题

18

帖子

0

精华

新手上路

积分
31
金钱
31
注册时间
2018-4-12
在线时间
5 小时
发表于 2018-4-12 10:47:41 | 显示全部楼层 |阅读模式
11金钱
因为项目需要,将以前一个项目移植到keil中,由于代码中存在异常处理逻辑,也就是使用了 try{}catch(){}结构,发现只要代码执行到throw语句,就会导致进入异常处理中断函数:HardFault_Handler()中

硬件为STM32F429,keil4和keil5都试过了,编译选项也添加了 --exceptions

为了验证异常捕获机制,我新建了一个新工程,直接把keil官网的例子代码copy过来:

#include <stdlib.h>
#include <string.h>
#include <exception>

class runtime_error : public std::exception {
   public:
     runtime_error (const char* error)throw()
                         : m_perror(0)
                 {
                         if (error)
                         {
                                 m_perror = (char*)malloc(strlen(error) + 1);
                                 strcpy(m_perror, error);
                         }
                 }
                 
                 virtual ~runtime_error() throw()
                 {
                         if (m_perror)
                         {
                                 free(m_perror);
                                 m_perror = 0;
                         }
                 }
                 
    runtime_error(const exception&) throw()
                {
                        m_perror = (char*)malloc(16);
                        strcpy(m_perror, "NoInfo");
                }
               
    runtime_error& operator=(const runtime_error& obj) throw()
                {
                        m_perror = (char*)malloc(strlen(obj.m_perror) + 1);
                        strcpy(m_perror, obj.m_perror);
                       
                        return *this;
                }
               
    virtual const char* what() const throw()
                {
                        return m_perror;
                }
               
         protected:
                 char* m_perror;
};


static void ftest() throw()
{
       int i;

       i = 5;
       throw runtime_error("a runtime error");
}

void main()
{
        try
        {
                ftest();
        }
        catch (const runtime_error& e)
        {
                // 异常处理代码
        }

        while(1)
        {
                // 循环代码
        }
}

但是代码始终无法进入“异常处理代码”,也无法进入while循环,单步跟踪,只要到throw runtime_error("a runtime error"); ,立刻就进入了HardFault_Handler()函数中,不知有哪位朋友是否遇到过类似问题,由于只有11金钱,我全部奉上。如能解决问题,另有感谢!

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

1

主题

7

帖子

0

精华

新手上路

积分
49
金钱
49
注册时间
2017-8-4
在线时间
9 小时
发表于 2018-4-12 11:43:11 | 显示全部楼层
验证过了,这段代码不会进入HardFault_Handler,可能代码其他地方有问题吧
回复

使用道具 举报

2

主题

18

帖子

0

精华

新手上路

积分
31
金钱
31
注册时间
2018-4-12
在线时间
5 小时
 楼主| 发表于 2018-4-12 11:46:52 | 显示全部楼层
本帖最后由 sw0zwl 于 2018-4-12 11:55 编辑

@大碗公 请问你的在什么平台下验证的,也是keil4,STM32F429吗? 你验证的时候,代码可以跑到 while循环?以下是我的keil4配置:

setting4.JPG
setting2.JPG
setting3.JPG

配置1

配置1
回复

使用道具 举报

2

主题

18

帖子

0

精华

新手上路

积分
31
金钱
31
注册时间
2018-4-12
在线时间
5 小时
 楼主| 发表于 2018-4-12 11:58:37 | 显示全部楼层
本帖最后由 sw0zwl 于 2018-4-12 12:00 编辑

如果不勾选 use microLIB,程序会跑飞,可以看到代码已经停止执行了,查看调用堆栈如下:
running.JPG
回复

使用道具 举报

2

主题

18

帖子

0

精华

新手上路

积分
31
金钱
31
注册时间
2018-4-12
在线时间
5 小时
 楼主| 发表于 2018-4-12 12:02:45 | 显示全部楼层
sw0zwl 发表于 2018-4-12 11:58
如果不勾选 use microLIB,程序会跑飞,可以看到代码已经停止执行了,查看调用堆栈如下:

如果勾选 use microLIB,程序就会进入HardFault_Handler
回复

使用道具 举报

2

主题

18

帖子

0

精华

新手上路

积分
31
金钱
31
注册时间
2018-4-12
在线时间
5 小时
 楼主| 发表于 2018-4-12 12:09:03 | 显示全部楼层
我在keil官网上看到,明明支持C++ exception handling in ARM C++的呀! 没有权限发链接,只好贴出来了
10.11 C++ exception handling in ARM C++
The ARM compilation tools fully support C++ exception handling. However, the compiler does not support this by default. You must enable C++ exception handling with the --exceptions option.

Note
The Rogue Wave Standard C++ Library is provided with C++ exceptions enabled.
You can exercise limited control over exception table generation.
You can exercise limited control over exception table generation.
Function unwinding at runtime
By default, functions compiled with --exceptions can be unwound at runtime. Function unwinding includes destroying C++ automatic variables, and restoring register values saved in the stack frame. Function unwinding is implemented by emitting an exception table describing the operations to be performed.
You can enable or disable unwinding for specific functions with the pragmas #pragma exceptions_unwind and #pragma no_exceptions_unwind. The --exceptions_unwind option sets the initial value of this pragma.
Disabling function unwinding for a function has the following effects:
Exceptions cannot be thrown through that function at runtime, and no stack unwinding occurs for that throw. If the throwing language is C++, then std::terminate is called.
The exception table representation that describes the function is very compact. This assists smart linkers with table optimization.
Function inlining is restricted, because the caller and callee must interact correctly.
Therefore, #pragma no_exceptions_unwind lets you forcibly prevent unwinding in a way that requires no additional source decoration.
By contrast, in C++ an empty function exception specification permits unwinding as far as the protected function, then calls std::unexpected() in accordance with the ISO C++ Standard.
回复

使用道具 举报

1

主题

7

帖子

0

精华

新手上路

积分
49
金钱
49
注册时间
2017-8-4
在线时间
9 小时
发表于 2018-4-12 12:54:41 | 显示全部楼层
没有F429平台,在M3测试是没问题,不过在F407是有问题的
回复

使用道具 举报

2

主题

18

帖子

0

精华

新手上路

积分
31
金钱
31
注册时间
2018-4-12
在线时间
5 小时
 楼主| 发表于 2018-4-12 12:58:58 | 显示全部楼层
大碗公 发表于 2018-4-12 12:54
没有F429平台,在M3测试是没问题,不过在F407是有问题的

折腾了好几天了,原来的代码有几个地方是通过throw异常,实现从多层函数调用直接返回顶层调用函数并处理,如果不用这种机制,需要改动原代码的框架,这就会涉及到巨大的工作量和开发周期。
回复

使用道具 举报

2

主题

18

帖子

0

精华

新手上路

积分
31
金钱
31
注册时间
2018-4-12
在线时间
5 小时
 楼主| 发表于 2018-4-12 13:00:09 | 显示全部楼层
大碗公 发表于 2018-4-12 11:43
验证过了,这段代码不会进入HardFault_Handler,可能代码其他地方有问题吧

我把整个代码都贴过来了,没有其他地方了呀
回复

使用道具 举报

2

主题

18

帖子

0

精华

新手上路

积分
31
金钱
31
注册时间
2018-4-12
在线时间
5 小时
 楼主| 发表于 2018-4-12 19:01:40 | 显示全部楼层
@正点原子 @八度空间 ,请高人指点一下,救救命呀
回复

使用道具 举报

120

主题

7878

帖子

13

精华

资深版主

Rank: 8Rank: 8

积分
12012
金钱
12012
注册时间
2013-9-10
在线时间
427 小时
发表于 2018-4-12 23:57:28 | 显示全部楼层
sw0zwl 发表于 2018-4-12 19:01
@正点原子 @八度空间 ,请高人指点一下,救救命呀

没用过use microLIB
现在,程序把烂铜烂铁变得智能化了,人呢,一旦离开了这烂铜烂铁就不知道干啥了
回复

使用道具 举报

2

主题

18

帖子

0

精华

新手上路

积分
31
金钱
31
注册时间
2018-4-12
在线时间
5 小时
 楼主| 发表于 2018-4-13 23:04:42 | 显示全部楼层
查找了两天Keil异常处理机制相关的资料,真是很少很少。

现在我打算自己造轮子,实现一个简单版的try-catch模型,据目前掌握的信息调用帧的回卷和栈的恢复基本没太大问题,关键是如何做到堆的恢复,有哪位高手有这方面的经验,如何监测堆内存分配,以及恢复?
回复

使用道具 举报

0

主题

2

帖子

0

精华

新手入门

积分
4
金钱
4
注册时间
2019-5-29
在线时间
0 小时
发表于 2019-5-29 23:16:50 | 显示全部楼层
搜一下有的嘛,亲测 GCC加入 -fexceptions 可以catch到
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-12 20:56

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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