一、Git
1.1 版本控制器
1. 2 git来源
- 速度
- 简单的设计
- 对⾮线性开发模式的强⼒⽀持(允许成千上万个并⾏开发的分⽀)
- 完全分布式
- 有能⼒⾼效管理类似 Linux 内核⼀样的超⼤规模项⽬(速度和数据量)
1. 3 安装git
sudo yum install git
1. 4 git三板斧
- git add .
- git commit 提交改动到本地,提交的时候应该注明提交⽇志, 描述改动的详细内容.
- git push 同步到远端服务器上
注册登录Gitee
1.创建一个仓库
2.git clone url
3.添加代码到本地目录下, git add ,git commit -m "日志信息" git push
想让git把代码管理起来,必须先把代码拷贝到你当前的本地目录下,未来托管给本地仓库。
git add .要把当前的test.c托管到本地仓库
git clone Linux学习: for learning
把远端仓库同步到本地
git pull 把远端仓库的文件拉取到本地同步。必须保证远端仓库和本地仓库同步后才能进行git push
git add. 表示把当前目录下新增的东西添加到本地仓库里
git commit -m " "
这两步完成了对我们的代码做本地化提交,还要把本地化提交的信息提交到远端,
把本地仓库和远端仓库的内容进行同步git push
项目在vs当中会存在许多特定后缀的临时文件
.gitignore:忽略后缀文件的配置文件
git主要进行源文件头文件,文档等的托管
git log: 该命令的作用是查看提交历史。
- 对项目的开发历史进行追溯。
- 查找某次特定的提交记录。
- 查看提交者、提交时间以及提交说明等信息。
git status : 此命令用于显示工作目录和暂存区的状态。
- 确认文件的修改情况。
- 查看哪些文件被暂存,哪些没有。
- 了解当前所处的分支状态。
二、gdb/cgdb
2.1 预备知识
程序的发布⽅式有两种, debug 模式和 release 模式, Linux gcc/g++ 出来的⼆进制程序,默认是 release 模式。
要使⽤gdb调试,必须在源代码⽣成⼆进制程序的时候, 加上 -g 选项,如果没有添加,程序⽆法编译
$ gcc mycmd.c -o mycmd # 默认模式,不⽀持调试
$ file mycmd
mycmd: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically
linked, interpreter /lib64/ld-linux-x86-64.so.2,
BuildID[sha1]=82f5cbaada10a9987d9f325384861a88d278b160, for GNU/Linux
3.2.0, not stripped
$ gcc mycmd.c -o mycmd -g # debug模式
$ file mycmd
mycmd: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically
linked, interpreter /lib64/ld-linux-x86-64.so.2,
BuildID[sha1]=3d5a2317809ef86c7827e9199cfefa622e3c187f, for GNU/Linux
3.2.0, with debug_info, not stripped
2.2 常见的指令使用
开始: gdb binFile
退出: ctrl + d 或 quit 调试命令
命令 | 作⽤ | 样例 |
list/l | 显示源代码,从上次位置开始,每次列出10⾏ | list/l 10 |
list/l 函数名 | 列出指定函数的源代码 | list/l main |
list/l ⽂件名:⾏号 | 列出指定⽂件的源代码 | list/l mycmd.c:1 |
r/run | 从程序开始连续执⾏ | run |
n/next | 单步执⾏,不进⼊函数内部 | next |
s/step | 单步执⾏,进⼊函数内部 | step |
break/b [⽂件名:]⾏号 | 在指定⾏号设置断点 | break 10break test.c:10 |
break/b 函数名 | 在函数开头设置断点 | break main |
info break/b | 查看当前所有断点的信息 | info break |
finish | 执⾏到当前函数返回,然后停⽌ | finish |
print/p 表达式 | 打印表达式的值 | print start+end |
p 变量 | 打印指定变量的值 | p x |
set var 变量=值 | 修改变量的值 | set var i=10 |
continue/c | 从当前位置开始连续执⾏程序 | continue |
disable breakpoints | 禁⽤所有断点 | disable breakpoints |
enable breakpoints | 启⽤所有断点 | enable breakpoints |
info/i breakpoints | 查看当前设置的断点列表 | info breakpoints |
display 变量名 | 跟踪显⽰指定变量的值(每次停⽌时) | display x |
undisplay 编号 | 取消对指定编号的变量的跟踪显⽰ | undisplay 1 |
until X⾏号 | 执⾏到指定⾏号 | until 20 |
backtrace/bt | 查看当前执⾏栈的各级函数调⽤及参数 | backtrace |
info/i locals | 查看当前栈帧的局部变量值 | info locals |
quit | 退出GDB调试器 | quit |
删除所有断点 | delete breakpoints |
删除序号为n的断点 | delete breakpoints 1 |
2. 3样例代码
// mycmd.c
#include <stdio.h>
int Sum(int s, int e)
{int result = 0;for(int i = s; i <= e; i++){result += i;}return result;
}
int main()
{int start = 1;int end = 100;printf("I will begin\n");int n = Sum(start, end);printf("running done, result is: [%d-%d]=%d\n", start, end, n);return 0;
}
readelf -S mycmd 读取可执行程序的格式
readelf -S mycmd | grep -i 'debug'
那么怎么变成debug模式呢?
gcc mycmd.c -o mycmd1 -std=c99 -g。
注意:在终端下进行调试的工具cgdb
2.4 常见技巧
2.4.1 watch
执⾏时监视⼀个表达式(如变量)的值。如果监视的表达式在程序运⾏期间的值发⽣变化,GDB 会暂停程序的执⾏,并通知使⽤者。
注意:
如果你有⼀些变量不应该修改,但是你怀疑它修改导致了问题,你可以watch它,如果变化了,就会通知你.
监视变量的变化
2.4.2 set var确定问题原因
(gdb) set var flag=1 # 更改flag的值,确认是否是它的原因
更改指定变量的值 -- 验证dubug问题,解决方案是否正确
比如说更改算法中的循环次数,或者看是不是野指针(有些野指针也还会与地址)
2.4.3 条件断点
要对逻辑进行设置条件
(gdb) b 9 if i == 30 # 9是⾏号,表⽰新增断点的位置
Breakpoint 2 at 0x555555555186: file mycmd.c, line 9.
(gdb) info b
Num Type Disp Enb Address What
1 breakpoint keep y 0x00005555555551c3 in main at mycmd.c:20
breakpoint already hit 1 time
2 breakpoint keep y 0x0000555555555186 in Sum at mycmd.c:9
stop only if i == 30
(gdb) finish
Run till exit from #0 Sum (s=1, e=100) at mycmd.c:7
Breakpoint 2, Sum (s=1, e=100) at mycmd.c:9
9 result += i;
1: i = 30
(gdb) finish
Run till exit from #0 Sum (s=1, e=100) at mycmd.c:9
0x00005555555551d2 in main () at mycmd.c:20
20 int n = Sum(start, end);
Value returned is $1 = 505
给已经存在的端点新增条件:已经有了breakpoint的情况下,新增修改条件。
(gdb) b 9 # 我们在第9⾏新增⼀个断点,⽤来开始测试
Breakpoint 2 at 0x555555555186: file mycmd.c, line 9.
(gdb) info b
Num Type Disp Enb Address What
1 breakpoint keep y 0x00005555555551c3 in main at mycmd.c:20
breakpoint already hit 1 time
2 breakpoint keep y 0x0000555555555186 in Sum at mycmd.c:9
(gdb) n
Breakpoint 2, Sum (s=1, e=100) at mycmd.c:9
9 result += i;
(gdb) n
7 for(int i = s; i <= e; i++)
(gdb) n
Breakpoint 2, Sum (s=1, e=100) at mycmd.c:9
9 result += i;
(gdb) condition 2 i==30 #给2号断点,新增条件i==30
(gdb) info bNum Type Disp Enb Address What
1 breakpoint keep y 0x00005555555551c3 in main at mycmd.c:20
breakpoint already hit 1 time
2 breakpoint keep y 0x0000555555555186 in Sum at mycmd.c:9
stop only if i==30
breakpoint already hit 2 time
注意:
条件断点添加常⻅两种⽅式:1. 新增 2. 给已有断点追加
注意两者的语法有区别,不要写错了。
新增: b 行号/文件名:行号/函数名 if i == 30(条件)
给已有断点追加:condition 2 i==30, 其中2是已有断点编号,没有if