码农知识堂 - 1000bd
  •   Python
  •   PHP
  •   JS/TS
  •   JAVA
  •   C/C++
  •   C#
  •   GO
  •   Kotlin
  •   Swift
  • 看着貌似吓人的底层问题,其实错在原本的自身


    过程   

    近期遇到一个问题,一个在Linux下运行的C语言程序,突然因为某段代码合入后,就导致程序稳定崩溃!

    程序崩溃的位置只是具有一个大方向,崩溃堆栈位置不定,而且是某些不应该出现的运行堆栈逻辑,以及曾出现过非法指令的信号异常core文件。

    通过逐步试验,发现:

    1、撤销掉新增的代码合入,就不会出现问题;还据此发布了版本

    2、如果使用O0编译程序,就不会出现崩溃问题;但使用O3优化编译就出现崩溃。怀疑是因为某些编译器代码优化导致的问题,这个就深层次了:(  看着听吓人的!

    3、旁路掉某一个模块的代码,也不会出现问题

    当时,是一头雾水,搞不清楚明确的方向!

    幸运的时,将研究的重点放在旁路的模块中,通过对代码不断二分旁路,找到问题的根源在于,某段代码对于栈内存的非法覆盖。

    示例代码

    1. // 出错代码示意
    2. typedef struct {
    3. int msgType;
    4. unsigned int msgLen;
    5. // C语言结构体的惯用法,指向头部区域后面第一个字节
    6. unsigned char abData[0];
    7. } T_SomeAck;
    8. void f(T_SomeAck* ptAck)
    9. {
    10. ...
    11. memcpy(ptAck->abData, srcData, someSize);
    12. ...
    13. }
    14. int main(int argc, char **argv)
    15. {
    16. // 栈上没有分配那么大的内存;
    17. // 解决办法:
    18. // 1、结构体定义足够内存
    19. // 2、符合C语言结构体此类惯用法,从大的缓冲区中转型;用具体结构体定义,区分头部和尾部
    20. T_SomeAck tAck;
    21. ...
    22. f(&tAck);
    23. ....
    24. return 0;
    25. }

    结论

    回想整个问题解决过程,才逐渐明白过来,就一个非法指令的信号异常处理现象,以及其它莫名奇妙、不该运行的崩溃堆栈,就可以怀疑到是因为内存被非法覆盖后引起的崩溃问题。

    因为非法覆盖的是函数返回地址等关键信息,最终导致的崩溃!


    附录

    照例说,valgrind可以发现栈内存越界的问题,后面再试试故障场景是否可以使用工具发现

    1. # valgrind 可以检查出此处的内存异常
    2. #include
    3. #include
    4. #include
    5. static int foo(void)
    6. {
    7. int a = 1;
    8. char b[32];
    9. printf("before memset\n");
    10. memset(b, 0, 64); /* stomps the stack */
    11. printf("after memset\n");
    12. return 0;
    13. }
    14. int main(int argc, char **argv)
    15. {
    16. int x;
    17. printf("before foo()\n");
    18. x = foo();
    19. printf("after foo()\n");
    20. return 0;
    21. }

  • 相关阅读:
    添加马赛克并虚化边框的技巧分享
    【Flutter】built_value 解决 Flutter 中的不可变性问题
    Cloud Bursting解决方案,Serverless容器降本增效极致体验
    C++面试/笔试准备,资料汇总
    使用vant list实现订单列表,支持下拉加载更多
    cmake详细教程(三)
    技术社区项目—借助Logback 的扩展机制实现异常感知并进行邮件推送异常信息
    分享117个PHP源码,总有一款适合你
    【帧率倍频】基于FPGA的视频帧率倍频系统verilog开发实现
    以字节跳动内部 Data Catalog 架构升级为例聊业务系统的性能优化
  • 原文地址:https://blog.csdn.net/jkler_doyourself/article/details/127776795
  • 最新文章
  • 攻防演习之三天拿下官网站群
    数据安全治理学习——前期安全规划和安全管理体系建设
    企业安全 | 企业内一次钓鱼演练准备过程
    内网渗透测试 | 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号