鲲鹏社区首页
中文
注册
我要评分
文档获取效率
文档正确性
内容完整性
文档易理解
在线提单
论坛求助

调优过程

前提条件

  • 服务器和操作系统正常运行。
  • PC端已经能够SSH远程登录。
  • 下载并编译example_00,并且要求:
    1. 编译完成的程序需要在GCC 4.9及以上版本的系统环境中运行。
    2. 必须使用 -fsanitize=address 选项.。
    3. 必须使用 -g 选项 。
    4. 可选择使用-fsanitize-recover=address选项,修复部分程序执行错误,以得到更完整的越界信息 。
    5. 可选择使用 -fno-omit-frame-pointer 选项,以得到更容易理解的调用栈信息 。
    6. 可选择 -O1 或者更高的优化级别编译例如:gcc -fsanitize=address -fno-omit-frame-pointer -O1 -g use-after-free.c -o use-after-free
    7. 该功能需要使用libasan.so,请确保/usr/lib64或/usr/local/lib64路径下存在该库文件。
  • 环境上鲲鹏DevKit系统诊断工具已经安装完成。

操作步骤

  1. 创建内存诊断任务。

    在左侧系统诊断区域单击系统诊断后面的

    图1 创建内存越界任务
  2. 查看诊断结果。

    查看内存越界结果,发生了堆缓存访问溢出异常,结合信息,对照源码文件example_00.c,分析原因是buffer1 malloc(100)成功后,内存空间中并没有字符串结束符标志\0,所以使用printf格式化输出%s时,会导致在buffer1的内存空间中寻找不到结束符,从而基于原先的内存空间继续寻址,导致数组越界访问,发生堆缓存访问溢出,继续分析源码,发现memset(buffer1, 'A', 99)之后同样使用printf格式化输出%s,所以此处也应该设置\0,同样的,buffer2也存在类似情况,一并修改。

    图2 内存越界诊断结果
    图3 example_00.c源码
  3. 修改越界语句。

    根据越界点文件名和行号,修改越界语句,重新编译后使用内存诊断工具重新进行测试。

    图4 修改example_00.c源码
  4. 再次创建内存越界诊断并查看结果。
    图5 内存越界诊断结果

    查看内存越界结果,发生了释放后越界,结合信息,对照源码文件example_00.c,分析原因是17行已经释放了变量buffer1(free(buffer1)),21行又打印该变量,继续分析,26、33行也打印了buffer1,删除这些打印后重新编译后使用内存诊断工具重新进行测试。

    图6 修改example_00.c源码
  5. 再一次创建内存越界诊断并查看结果。
    图7 优化后的内存越界诊断结果

    重新测试后发现example_00应用已经没有内存越界了,但是通过刚才的阅读源码,细心的读者会发现,变量buffer2在程序退出前并没有free掉,回到环境上手动执行example_00验证。

    图8 执行验证
    图9 修改example_00.c源码
  6. 重新编译后,在环境上手动执行example_00验证。
    图10 执行验证