• GDB 调试 C/C++ Project


    平时做算法题目, 没少用到 GDB, 但今天才意识到 Project 的调试方法与单个 cpp 文件的不同之处, 比如 gdb list 命令, 在单个 cpp 文件中列出的是源代码, 但在 project 中却什么都不显示

    Project Debug 时, file 参数的使用 [1] 有讲解, UP 主问的问题和我遇到的一样, 只不过, 没能解决我的问题(我的问题更2B一些).

    出现的错误

    1. 执行命令, make, gdb test, gdb l

    No symbol table is loaded.

    最终解决方法是在 make 里, 每生成一个 .o 文件都需要 -g  参数

    2. 段错误 segment fault

    段错误是一种内存保护机制, 当进程访问许可空间范围以外的内存时便会引发内核的 "一般保护性异常", 内核向程序发出 SIGSEGV(11) 信号, 而这个信号的 handler 默认工作就是在控制台打出一个 segment fault 并产生内核转储文件(Core), 结束掉当前正在运行的程序.

    段错误的成因有一下几种(不完全统计)

    2.1 程序访问系统数据区, 比如对为 NULL 的指针解引用, 或写入数据

    2.2 内存访问越界 (数组越界)

    2.3 对 malloc, new 申请的空间二次释放

    2.4 操作系统的段保护机制, 导致因缓冲区溢出而对非法内存访问

    2.5 无限递归, 导致堆栈溢出

    2.6 fclose 对一个 FILE* 二次释放

    调试工具 Valgrind

    Valgrind 是一款用于内存调试, 内存泄露检测和性能分析的软件开发工具, 但 Valgrind 只能检测到堆的异常和泄露, 对栈的爱莫能助.

    Valgrind 原理与用法

    我们刚才提到段错误会引发内核转储(Core), Core 记录了 down 掉程序的映像和一些调试信心, valgrind 需要 core, 但是并不是所有的系统都默认提供 core, 可通过 ulimit -a 查看 core 是否默认设置, 我查了下, 自己的机器是 (blocks, -c) 0, 说明 core 默认不提供, 所以需要通过 ulimit -c 1024 来设置 core 大小. 但通过 ulimit 设置在重启机器后失效.

    我们重新编译自己出错程序, 在 g++ 后加上 -g -rdynamic 参数, -g 是添加调试信心, 而 -rdynamic 是通知链接器把所有符号添加到动态符号表, 再次运行程序, ls, 会看到一个 core 开头的文件, 我们用 gdb ./yourprogram core 来查看是哪个文件哪一行, 什么代码出现了异常. 假如你没有看到 core 文件, 那么重新检查下 ulimit 设置.

    Reference

    [1] http://stackoverflow.com/questions/9245685/gdb-no-symbol-table-is-loaded

    [2] http://through-my-eyes.diandian.com/post/2012-11-20/40043131231

  • 相关阅读:
    从搭eclipse环境到导入maven工程
    基于jquery的多选下拉列框再次更改样式和交互
    BootStrap的typeahead使用过程中遇到的问题
    Vue webapp项目通过HBulider打包原生APP
    微信相机
    前端小新手,记录项目中不懂的问题
    判断pdf、word文档、图片等文件类型(格式)、大小的简便方法
    JavaScript学习笔记(一)——Map、Set与iterable
    oracle nvl函数
    mybaits中主键自动生成并返回主键
  • 原文地址:https://www.cnblogs.com/zhouzhuo/p/3699130.html
Copyright © 2020-2023  润新知