gcc
- gcc <文件名> :编译成功 然后:./a.out 就运行成功 注:a.cou 就是默认的命名程序
- gcc <文件名> -o <自定义文件名> 然后:./<自定义文件名> 就运行成功
- -g:编译的时候保留调试信息,类似VS上的debug模式
注:VS中debug和release的区别
1.文件大小不一样,debug比较大
2.release会优化一下文件
- -O:优化;又分为 -O0 -O1 -O2 -O3 其中-O3优化级别最高
注:优化级别越高,程序的实际执行程序就和原始程序差别越大,必须要关闭优化才可以进行调试
gdb ——命令行调试工具
- gdb启动:gdb <文件名>
注:如没有yum install gdb 就好了
VS调试方式:
1.打断点
2.F5逐步进行,完成调试
Linux调试步骤也是如此:
- 启动gdb:gdb <文件名>
- break/b <行号> :第<行号>行打断点 注:此时看不到行号,就不方便,此时就需要xshell创建两个窗口左右分布就好了。这是工作中最常用的,b是简写。
- run/r :程序就开始跑了
- 中间配合print/p <变量> :查看<变量>的值
- 此时继续有两种方法:继续打断点或者单步进行
注:info b :查看断点信息,你就可以看你打了什么断点
打断点继续执行方式继续:
- continue/c:继续执行程序
- p <变量> :查看
- ......依次重复 寻找问题
- quit/q:找到之后,退出gdb
单步执行方式分为:1.step/s:单步执行(逐语句)2.next:单步执行(逐过程)
两者区别:第一个进入函数内部;第二个不进入函数内部,跳过函数
打断点继续执行方式继续:
- next/n:单步执行(逐过程) 或者step/s
- ......依次重复n 寻找问题
- quit/q:找到之后,退出gdb
注:以上掌握基本都可以调试程序了,可以说基本掌握gdb了,能应对80%场景了。
调试命令:bt 调试就先敲bt ,含义是查看函数调用栈帧,当前程序运行到哪了,尤其是函数崩溃的程序(非常重要,往往是第一个调试开始就先输入的)
frame/f <number>:切换到某个指定的栈帧(切换到第<数组>栈帧)
注:bt和frame往往是以后工作调试中的起手式,函数栈帧是关键知识,栈顶是运行到的函数位置,一定要熟悉。非常非常非常重要,这一点就看出来你是不是经常用vim,经常敲代码。
注:ctrl+r:能够快速搜索之前敲过的指令,尤其长指令很方便。
注意:gdb这种调试问题的方法是通过gdb去启动一个程序,这种调试方式在工作中是几乎不会用到的。
真实工作中调试的用法:
- 使用gdb调试coredump文件 coredump就是保存程序崩溃瞬间,程序运行到哪,内存信息等等相关信息。(程序的临终遗言),coredumo含义:核心转储文件。就是为什么程序崩溃会有那个吐核。
出现问题后用这种调试的做法:
- 打命令ulimit -a:这是一个关键的指令,后面我也会在博客中详细解释,现在敲能看到core文件。
- ulimit -c unlimied:是用来查看文件,同时设文件大小无限制,再次运行那个崩溃的程序之后,ll(两个L)就能看到core文件了。core文件格式会是core.<数字>,这个数字就是PID,这个后面也会讲述。
- 打开core文件:core文件要通过:gdb <生成的测试文件> <core文件> 就可以打开了,vim是打不开的。core文件就会直接在里面显示是哪一行代码出现错误,就直接出现错误了,实在看不出来,就配合bt,就能很清晰看到那行代码出现问题。
注:这种调试也被称为事后调试
- 使用gdb attch(附加)上一个程序
进程相关内容之后,会讲述。
- cgdb:比gdb更方便一丢丢
为什么说方便一丢丢?
cgdb调试的时候,对断点的查看更方便,在调试的时候会在行号上又箭头指示程序到哪了,打断点的时候行号数字会标红,所以说方便一丢丢。
调试问题的步骤和思路:
- 确认是不是bug 注:确认是不是bug的唯一依据:产品需求,只要程序和需求标准不匹配那就是bug
- 定位问题 注:缩小问题范围,确认哪一行代码导致出现的问题(要精确到行)
- 分析问题的原因(特别重要会影响"幸福感") 注:程序员的核心价值观——幸福感
- 提出方案并修改问题
- 测试(回归测试,防止代码的修改引入新问题),由于回归测试,成本高,往往自动化测试为主,一定要自己测试完了之后交给测试程序员,否则对职业生涯影响很大哦~~~。
注:经常练习,调试自然就会了~~~