zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    SGU 271 Book Pile (双端队列)
    POJ 3110 Jenny's First Exam (贪心)
    HDU 4310 Hero (贪心)
    ZOJ 2132 The Most Frequent Number (贪心)
    POJ 3388 Japanese Puzzle (二分)
    UVaLive 4628 Jack's socks (贪心)
    POJ 2433 Landscaping (贪心)
    CodeForces 946D Timetable (DP)
    Android Studio教程从入门到精通
    Android Tips – 填坑手册
  • 原文地址:https://www.cnblogs.com/zhouzhuo/p/3699130.html
Copyright © 2011-2022 走看看