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

2019-07-20 01:37发布

因为项目需要,将以前一个项目移植到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金钱,我全部奉上。如能解决问题,另有感谢!

友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
12条回答
大碗公
1楼-- · 2019-07-20 06:33
验证过了,这段代码不会进入HardFault_Handler,可能代码其他地方有问题吧
sw0zwl
2楼-- · 2019-07-20 11:59
本帖最后由 sw0zwl 于 2018-4-12 11:55 编辑

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

sw0zwl
3楼-- · 2019-07-20 17:55
 精彩回答 2  元偷偷看……
sw0zwl
4楼-- · 2019-07-20 20:47
sw0zwl 发表于 2018-4-12 11:58
如果不勾选 use microLIB,程序会跑飞,可以看到代码已经停止执行了,查看调用堆栈如下:

如果勾选 use microLIB,程序就会进入HardFault_Handler
sw0zwl
5楼-- · 2019-07-20 21:41
我在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.
大碗公
6楼-- · 2019-07-21 03:11
 精彩回答 2  元偷偷看……

一周热门 更多>