码农知识堂 - 1000bd
  •   Python
  •   PHP
  •   JS/TS
  •   JAVA
  •   C/C++
  •   C#
  •   GO
  •   Kotlin
  •   Swift
  • Linux C/C++异常处理方法


    简介

    C/C++属于较为接近底层的语言,不像Java等“高级”语言,所有异常都能catch住(例如常见的core dumped)异常:

    1. int first_func()
    2. {
    3. int* error_integer = nullptr;
    4. return *error_integer;
    5. }

    对于异常,首要任务是进行定位,并做对应的修复。但存在一些程序,因种种原因测试不够充分,为了保证程序“不崩溃”,本文介绍几个常见的异常处理方法。

    Trap SIGSEGV 使用 try/catch

    针对SIGSEGV信号处理的异常,需要新增编译选项 

    -fnon-call-exceptions
    

    CMakeList:

    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fnon-call-exceptions")

    定义SegmentationFaultException:

    1. class SegFaultException : public std::exception {
    2. public:
    3. const char* what() const _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_NOTHROW override
    4. {
    5. return "segmentation fault";
    6. }
    7. ~SegFaultException() override = default;
    8. };
    9. void throw_segmentation_fault_exception(int)
    10. {
    11. throw SegFaultException();
    12. }

    使用方式:

    1. #include
    2. #include
    3. #include
    4. /**
    5. * 省略部分代码
    6. */
    7. int main()
    8. {
    9. signal(SIGSEGV, throw_segmentation_fault_exception);
    10. try {
    11. first_func();
    12. } catch (const std::exception& e) {
    13. std::cout << e.what() << std::endl;
    14. }
    15. return 0;
    16. }

    使用这种方式后可以捕获空指针异常,但整个程序会变得不够安全:有些原本不会抛出异常的场景也会抛出异常,这可能会导致一些问题,例如抛出异常后造成内存泄漏。

    除了简单的Demo外,有专门的开源代码Trap底层异常:

    https://code.google.com/archive/p/segvcatch/https://code.google.com/archive/p/segvcatch/

    “保护进程”

    思路是由一个主进程保证安全,fork子进程处理工作。如果子进程异常,不影响主流程。这类方法主要是需要应用在多核CPU上。

    使用进程方法时,可能会有备选方案:为了系统稳定性,会从多个方案中选择稳定的方案进行尝试。

    “串行”尝试

    1. #include
    2. #include
    3. #include
    4. #include
    5. int main()
    6. {
    7. pid_t pid, w;
    8. int w_status;
    9. for (int attempts = 0; attempts < 2; ++attempts) {
    10. pid = fork();
    11. /**
    12. * exit if fork fail
    13. */
    14. // 子进程
    15. if (pid == 0) {
    16. attempts == 0 ? first_func() : second_func();
    17. exit(0);
    18. }
    19. w = waitpid(pid, &w_status, WUNTRACED | WCONTINUED);
    20. }
    21. printf("parent done. \n");
    22. return 0;
    23. }

    如果需要使用waitpid的返回值和获取对应子进程的状态,可以参考:

    https://www.codingdict.com/questions/45424https://www.codingdict.com/questions/45424
    

    “并行”尝试

    同“串行”比较相似:

    1. int main()
    2. {
    3. pid_t pids[2];
    4. for (int attempts = 0; attempts < 2; ++attempts) {
    5. pid_t pid = fork();
    6. if (pid == 0) {
    7. attempts == 0 ? first_func() : second_func();
    8. exit(0);
    9. }
    10. pids[attempts] = pid;
    11. }
    12. for (auto& p: pids) {
    13. waitpid(p, nullptr, WUNTRACED | WCONTINUED);
    14. }
    15. return 0;
    16. }

  • 相关阅读:
    CSS引入样式的方式
    嵌入式培训机构四个月实训课程笔记(完整版)-Linux ARM驱动编程第七天-内核函数接口(物联技术666)
    addEventListener侦听事件并处理相应的函数
    nacos(一):简介
    数据湖(十二):Spark3.1.2与Iceberg0.12.1整合
    单例模式(下)
    java-php-python-ssm信息学院网站分析计算机毕业设计
    SpringSecurity+JWT 登录授权过滤器
    c++23中的新功能之十八新增的属性
    《嵌入式 – GD32开发实战指南》第16章 RTC
  • 原文地址:https://blog.csdn.net/TheHide/article/details/127868210
  • 最新文章
  • 攻防演习之三天拿下官网站群
    数据安全治理学习——前期安全规划和安全管理体系建设
    企业安全 | 企业内一次钓鱼演练准备过程
    内网渗透测试 | Kerberos协议及其部分攻击手法
    0day的产生 | 不懂代码的"代码审计"
    安装scrcpy-client模块av模块异常,环境问题解决方案
    leetcode hot100【LeetCode 279. 完全平方数】java实现
    OpenWrt下安装Mosquitto
    AnatoMask论文汇总
    【AI日记】24.11.01 LangChain、openai api和github copilot
  • 热门文章
  • 十款代码表白小特效 一个比一个浪漫 赶紧收藏起来吧!!!
    奉劝各位学弟学妹们,该打造你的技术影响力了!
    五年了,我在 CSDN 的两个一百万。
    Java俄罗斯方块,老程序员花了一个周末,连接中学年代!
    面试官都震惊,你这网络基础可以啊!
    你真的会用百度吗?我不信 — 那些不为人知的搜索引擎语法
    心情不好的时候,用 Python 画棵樱花树送给自己吧
    通宵一晚做出来的一款类似CS的第一人称射击游戏Demo!原来做游戏也不是很难,连憨憨学妹都学会了!
    13 万字 C 语言从入门到精通保姆级教程2021 年版
    10行代码集2000张美女图,Python爬虫120例,再上征途
Copyright © 2022 侵权请联系2656653265@qq.com    京ICP备2022015340号-1
正则表达式工具 cron表达式工具 密码生成工具

京公网安备 11010502049817号