1 调试一般分为两种方法
可以通过在程序中插入打印语句。有点能够显示程序的动态过程,比较容易的检查出源程序中的有关信息。缺点就是效率比较低了,而且需要输入大量无关的数据。
2 借助相关的调试工具。
gdb
3 有哪些常用的调试工具呢?
3.1 strace
(1)我们知道在进行创建文件或者复制文件这些操作的时候,应用程序需要和操作系统进行一些交互。但是我们的程序一般不能直接访问linux的内核。但是应用程序会跳转到system_call的内核位置,内核然后检查系统的调用号,然后这个号码告诉内核需要什么服务。这就是所谓的"系统调用"
(2)认识starce
然后.g++ -o debug debug.cpp
strace ./debug就会出现如下图内容(部分截图,小伙伴可以通过试试查看更详细的内容)
等号左边为系统调用的函数名及其参数,右边为返回值。通过上面部分的分析我们可以知道会自动调用很多函数用于进程初始化工作比如装载被执行程序,载入libc函数库,设置内存映射等。
(3) 统计系统调用
通过加上-c的做统计分析。比如strace -c ./debug.另外-o将结果输出到文件。-T将每个系统调用所花费的时间打印出来。-t.-tt等可以记录每次系统调用发生的时间。
3.2 gdb
(1)认识gdb
a:启动程序可以按照用户自定义的要求随心所欲的运行程序
b:可以被调试的程序在指定的断点挺住
c:当程序停住时候可以检查程序的运行状态
d:动态的改变程序的执行环境
(2)gdb常用方法
a:程序如下
1 #include<iostream> 2 using namespace std; 3 4 int func(int n) 5 { 6 int result = 0; 7 for(int i=1;i<=n;i++) 8 { 9 result+=i; 10 } 11 return result; 12 } 13 14 int main() 15 { 16 int arr[10]; 17 arr[0] = 0; 18 arr[1] = 1; 19 for(int i=2;i<10;i++) 20 { 21 arr[i]=arr[i-1]+arr[i-2]; 22 23 } 24 cout<<"arr[9]"<<arr[9]<<endl; 25 cout<<"func(9)"<<func(9)<<endl; 26 return 0; 27 }
b:gdb gdb进入gdb环境 l---->从第一行列出源码 按enter重复上一次命令,b 15----->表示在15行设置断点。info break----->查看断点。r----->运行程序.n----->表示next单步运行。p i--->打印变量。bt------>查看函数堆栈。q--->结束调试
(3)gdb分析core文件
a:core文件的存储路径。通常是在执行程序的时候会出现段错误。但是在当前的目录下面没有coredump文件。可以通过如下命令查看core文件的存在位置
cat /proc/sys/kernel/core_pattern
更改coredump文件的存储位置
echo "/data/coredump/core">/proc/sys/kernel/core_pattern
设置core文件的名字让我们清楚知道是哪一个程序的core错误
echo "/data/coredump/core.%e.%p">/proc/sys/kernel/core_pattern这样的core会自导崩溃的程序吗和进程ID
b:产生core的条件
有的时候需要确认当前的绘画能够生成coredump文件的大小。大小为0则不会生成对应的coredump文件。
通过ulimit -c可以查看coredump文件大小的最大值
通过ulimit -c unlimited设置core文件不受限制。如果需要指定大小则ulimit -c size但是只是对当前的会话有作用
(4)gdb定位coredump文件 非法访问内存
#include <stdio.h> int main() { int b = 1; int *a; *a = b; return 0; }
查看coredump文件的ELF头部
readelf -h core..... 发现文件格式为CORE说明是core-dump文件
执行gdb test core*可以发现程序第5行*a=b 然后分别打印a和b的值 返现指向的地址为非法区域。也就是没有分配内存导致。
3.3 top
(1)相关参数说明
第一行:系统当前时间 系统运行时间 当前用户登陆数和系统的负载。其中负载分别为1min 5min 15min
第二行:total(进程总数) ruunig(正在运行的进程数) sleeping(睡眠的进程数) zombie(僵尸进程数)
第三行:%us(用户空间占用cpu比例) %id(空闲cpu百分比,通过这个可以反应一个系统的cou闲忙成都) %wa(等待输入输出io) %hi(cpu处理硬件终端时间)
第四行显示内存MEM数据:
buffers和cache区别:buffers是块设备的读写缓冲区,cache是文件系统本身的页面缓存。目的都是为了加速磁盘的访问。
3.4 ps
(1)常用命令1
ps -u 用户名 查看指定用户的信息
(2)显示某个进程信息
ps -ef| grep 进程名
(3)列出目前所有正在内存当中的程序
ps aux
好叻 今天就到这里了,加油!!!!