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

GDB 调试 C/C++ Project,码迷,mamicode.com

时间: 2024-10-12 15:19:05

GDB 调试 C/C++ Project的相关文章

gcc编译, gdb调试, makefile写法

//test.c: #include <stdio.h> int main(void) { printf("hello world!"); return 0; } ====================================== 一. 1. 编译过程:预处理(processing)->编译(compilation)->汇编(assembly)->Linking 2. 预处理: gcc -E test.c -o test.i / gcc -E t

vi/vim使用进阶: 在VIM中使用GDB调试 – 使用vimgdb

vi/vim使用进阶: 在VIM中使用GDB调试 – 使用vimgdb << 返回vim使用进阶: 目录 本节所用命令的帮助入口: :help vimgdb 在UNIX系统最初设计时,有一个非常重要的思想:每个程序只实现单一的功能,通过管道等方式把多个程序连接起来,使之协同工作,以完成更强大的功能.程序只实现单一功能,一方面降低了程序的复杂性,另一方面,也让它专注于这一功能,把这个功能做到最好.就好像搭积木一样,每个积木只提供简单的功能,但不同的积木垒在一起,就能搭出大厦.汽车等等复杂的东西.

Eclispe+qemu+gdb调试linux Kernel

单步调试kernel说明 恩,这个文档的目标是单步调试内核,从每一个工具软件的版本号到每一个命令,都有一个说明 ubuntu1204,32位 http://www.ubuntu.org.cn/download/desktop 用vmware虚拟机安装该系统. 用64位系统时,gdb有bug.报错信息为:xxx太长.所以建议用32位系统 编译kernel 3.5.4 下载内核的地址,北京交通大学的映像地址:http://mirror.bjtu.edu.cn/kernel/linux/kernel/

Eclipse+CDT+GDB调试android NDK程序(转)

Eclipse+CDT+gdb调试android ndk程序 先介绍一下开发环境,在这个环境下,up主保证是没有问题的. ubuntu 11.10 eclipse 3.7(indego) for java jdk 6 android sdk 2.2 andrid ndk r7 当然,在windows环境下通过cygwin等工具也是可以实现gdb调试的,我也确实实现过.但是性能实在太低,卡的根本没法用.Linux下直接用gdb调试本地方法是很流畅的. 再确定安装并配置好开发环境之后,就可以开始了.

GDB调试系列之了解GDB

想要熟练利用GDB进行程序调试,首先要了解什么是GDB. 1. 什么是GDB GDB (the GNU Project Debugger) 是一个可以运行在大多数常见的UNIX架构.Windows.Mac OSX等系统上的跨平台调试器,允许我们查看另一个程序在运行过程中内部发生了什么——或者另一个程序崩溃时在做什么. 具体而言,GDB能做以下四种事情[1],以帮助我们定位运行中的Bug: 让程序开始运行,指定任何可能影响其行为的内容. 让程序在特定条件下停止运行. 检查程序停止运行时发生了什么.

c语言gdb调试

GDB 官网 什么是GDB? GDB是GNU Project调试器,它使您可以查看另一个程序在执行过程中正在执行的操作–或该程序崩溃时正在执行的操作. GDB可以做四种主要的事情(以及支持这些事情的其他事情)来帮助您捕获行为中的错误: 启动程序,并指定可能影响其行为的所有内容. 使程序在指定条件下停止. 检查程序停止时发生的情况. 更改程序中的内容,以便您可以尝试纠正一个错误的影响,然后继续学习另一个错误. gdb 调试的一些命令 gcc -g -o xx xx.c // 编译c源程序 gdb

gdb调试

[前言]使用gdb调试前,在编译程序时,要加 -g 选项,否则你将看不见程序的函数名.变量名,所代替的全是运行时的内存地址. 1.开始调试 a.  gdb <program> program也就是你的执行文件,一般在当前目录下. b. gdb <program> core 用gdb同时调试一个运行程序和core文件,core是程序非法执行后core dump后产生的文件. 2.[列出源码],从第n行开始(编译时要加 -g 选项) l n 3.[设置断点]在第N行加断点 break

gdb调试命令

本篇摘自互联网,纯属自己学习笔记,然分享给看到我的博客的人们. 用GDB调试程序 GDB是一个强大的命令行调试工具.大家知道命令行的强大就是在于,其可以形成执行序列,形成脚本.UNIX下的软件全是命令行的,这给程序开发提代供了极大的便利,命令行软件的优势在于,它们可以非常容易的集成在一起,使用几个简单的已有工具的命令,就可以做出一个非常强大的功能. 于是UNIX下的软件比Windows下的软件更能有机地结合,各自发挥各自的长处,组合成更为强劲的功能.而Windows下的图形软件基本上是各自为营,

Go语言gdb调试踩坑

整个是一个docker环境 docker版本: 1.12.1,镜像是我自己做的基于ubuntu:14.04.05. 容器操作系统版本: Ubuntu 14.04.5 LTS go版本: 1.6.3 在gdb中执行run命令出错! 错误输出: warning:Error disabling address space randomization: Operation not permitted 环境:docker 解决办法: warning:Error disabling address spac