一、调试方式
GDB
printf打印
GDB调试工具可以调试出是哪一行出现的错误
主要调试段错误(地址非法操作,指针)出现的问题
(1)gdb调试:在用gdb调试之前要确定我们的代码没有语法错误。
设置断点的时候,必须让主函数先运行起来, 第一次断点的设置,设置在主函数当中的某一行(最好是主函数当中的第一行),这样编译器才能从入口函数进来。
在gcc编译程序时,一定要加入"-g"。
只有在代码处于"运行"或"暂停"状态时才能查看变量值,设置断点后程序在指定行之前停止。
![](https://img-blog.csdnimg.cn/img_convert/1bf997c68aca418cb0c73806df817337.png)
最终会显示段错误。
那是因为fun函数里的变量在栈区开辟空间,栈区中的变量在使用完后在最后会释放掉。
在主函数中调用的fun函数,并没有返回接收任何东西,这时候的p指向的是无效空间。当打印时就出现了段错误。
这时候通过gdb调试一下:
![](https://img-blog.csdnimg.cn/img_convert/0df7f41edfac4eabbf13c7c148158ccc.png)
第一次断点的设置,设置在主函数当中的某一行(最好是主函数当中的第一行)
![](https://img-blog.csdnimg.cn/img_convert/25bdf0d3e9f240288d23da62c11c6191.png)
![](https://img-blog.csdnimg.cn/img_convert/46233f75c0a34bf4b01469daf1f4a850.png)
每次往下单步调试时,都会先调试断点所在行
![](https://img-blog.csdnimg.cn/img_convert/5e7d982bcc874e82bf60ed6de35f45de.png)
1) gcc -g test.c
2) gdb a.out
3)(gdb)l:列出源文件内容
(在进行调试时,我们运行的终端可能只有一个,为了更好的确定在哪设置断点,可以通过" l "指令来显示源文件的内容,进而确定断点行)
4)(gdb) b 10:设置断点在第10行
5)(gdb) r :运行(设置断点后一定要先运行,才能进行单步调试往下)
6)(gdb) n:单步调试(断点行是不被运行的,n单步调试的时候不进子函数(直接拿到子函数的值))
7)(gdb) s:单步运行(断点行是不被运行的,s单步调试的时候进子函数)
8) (gdb) p 变量名 :查看变量值
9) q:退出调试界面
(2)printf("%s,%s,%d\n",__FILE__,__func__,__LINE__);
大概定位(缩小范围)
作用:定位错误,如果这一行打印了,那么引起错误的代码肯定在这一行之后 ,如果这一行没有打印,那么引起错误的代码肯定在这一行之前
![](https://img-blog.csdnimg.cn/img_convert/4e3535148bec4e849f0efe06878742d2.png)
![](https://img-blog.csdnimg.cn/img_convert/1a96d90ffed543a294f47038ca4b7d69.png)
也就是在第12行printf打印时,因为p指向的是无效空间
二、解压和压缩 tar
格式:tar 选项 压缩(解压)文件名 [要压缩的文件列表]
选项:
-x: 释放归档文件
-c: 创建一个新的归档文件
-v: 显示归档和释放的过程信息
-f: 用户指定归档文件的文件名,否则使用默认名称 后跟文件名
-j: 由tar生成归档,然后由bzip2压缩 .bz2
-z: 由tar生成归档,然后由gzip压缩 .gz
-J: 由tar生成归档,然后由xz压缩 .xz
注意:
1)具有归档功能,并通过参数可以进行压缩或解压
2)压缩或解压后源文件存在
3)需要写全压缩或解压的文件名格式
常用:
压缩: tar -cvzf file.tar.gz *.c //将所有的.c文件打包归档压缩为file.tar.gz文件
解压: tar -xvf xxxx.tar.gz
zip扩展名的压缩文件通过unzip
解压XXXX.zip unzip XXXX.zip
三、进程相关命令
进程:就是程序的一次执行过程。(动态)
程序:在磁盘空间上存放的可执行的二进制文件。(静态)
进程id(pid):pid唯一标识进程。
ps命令
ps -aux :查看进程的信息
用户名 进程号 CPU所在资源 内存所占资源 状态
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.2 24016 4888 ? Ss 07:28 0:01 /sbin/init splash
![](https://img-blog.csdnimg.cn/img_convert/e05ce2289fea4101a18f27bc05d5b3ad.png)
ps -ef :查看信息包含父进程的进程号 PPID
![](https://img-blog.csdnimg.cn/img_convert/b70e58d28bd44f5fa68d8ed9f513e97d.png)
ps -ajx:可以查看 (父进程id 组id 会话id)
多个进程可以组成一个组,多个组可以组成一个会话,
多个会话可以组成一个会话组。
./可执行文件名& :将可执行程序在后台运行
./a.out &:将a.out在后台运行起来
通过jobs可以显示后台运行的程序
![](https://img-blog.csdnimg.cn/img_convert/3258fbcb2d4247cb818c452122be383e.png)
fg 数字 :将后台运行的进程拉到前台运行
数字是通过jobs看到的数字
![](https://img-blog.csdnimg.cn/img_convert/990c17a8be004ad5807b346c1ec61182.png)
ctrl+z:将前台运行的进程暂停,同时放到后台
bg 数字(这里的数字为我们按ctrl+z的时候前面中括号里面的数字):将后台暂停的进程在后台跑起来。
![](https://img-blog.csdnimg.cn/img_convert/efe870f314004bafbad4ae0cf159792a.png)
top 动态显示进程的状态 (动态看进程占用CPU)
NI:优先级 +19 - -20 值越小优先级越高
nice 以指定优先级运行进程
sudo nice -num ./可执行程序 :以优先级为num运行程序
eg:
sudo nice -10 ./可执行程序 程序以3优先级运行
sudo nice --10 ./可执行程序 程序以-3优先级运行
renice 运行进程优先级修改
sudo renice num PID
eg:
sudo renice 10 PID PID对应的进程优先级改为10
sudo renice -10 PID PID对应的进程优先级改为-10
![](https://img-blog.csdnimg.cn/img_convert/8a8e021c475646adb7b236fd59ea749f.png)
5.kill 给进程发送信号
kill -l :查看linux中的信号
![](https://img-blog.csdnimg.cn/img_convert/52134caa5e78486587f549d15cdf4931.png)
2) SIGINT ctrl+c
9) SIGKILL 杀死进程信号
19) SIGSTOP 暂停
2) SIGINT 3) SIGQUIT 退出进程 4) SIGILL结束进程
9) SIGKILL杀死(不可忽略) 10) SIGUSR1未定义功能
12) SIGUSR2未定义功能 13) SIGPIPE管道破裂 14) SIGALRM定时信号
17) SIGCHLD子进程状态改变给父进程发 19) SIGSTOP暂停(不可忽略)
SIGUSR1 SIGUSR2 未定默认功能信号
kill -信号编号 PID :给指定进程发送指定信号
killall a.out :杀死所有名字为a.out