前言
写简历时,很害怕自己没什么特点,与别人没啥区分度,而平时又感觉改bug比较多。。。于是在自我评价一栏大胆的写上
热爱trouble-shooting
ChangeLog:
2018-6-10 update vmstat
从此走上被虐之路。。。
正文
因为我自己主要是Linux 下 C/C++ ,所以enmmm 还是这方面做的比较多。之前也写过一篇类似的博客,主要简述的是改bug的思想(见这篇),这篇主要是从实际工具出发,简单介绍工具的使用及思路。(当然反手一个printf也算是一种工具。。)
主要工具
GDB strace pstack valgrind iotop netstat/ss wireshark/tcpdump
辅助性的
top ps
一运行就段错误的。直接生成coredump文件,生成的方法见这篇
如果堆栈的信息完好,可以之间看到问题出在哪里,一般 print
变量,看看是否是地址越界之类的。
运行起来不动的。
可能是死循环/死锁。
对于多线程死锁,建议通过ps
找到pid后, pstack <pid>
可以看到每个线程的调用栈。
GDB的常用命令
ctrl + l 清屏。。恩,很常用
p/print 打印变量
b 行号 在第几行设置断点
b 函数名 在函数处设置断点
r/run 运行程序
c/continue 在断点停下之后继续执行
bt 查看堆栈调用
frame 切换栈帧 (funcA调用funcB挂掉,如果是传参的问题,可能要切到funcA去查看)
info thread 查看线程的信息
thread 编号 切换到指定线程
s/step 下一步–进入函数
n/next 下一步–不进入函数
set arg a1… 设置程序运行时的命令行参数
x 打印变量(格式为x/nfu n为正整数表示要显示内存单元的个数
f表示格式 x 十六进制 d十进制 t二进制
u表示每个内存单元几字节 b h w g 对应1 2 4 8
set arg a1 a2 设置命令行参数
info register 寄存器名 查看寄存器信息
watch 变量名 变量被修改时触发
rwatch 变量 是变量被读时出发
delete 编号 删除breakpoint或watchpoint
常用的基本就这些。
对于多线程多进程的调试不怎么熟悉,以后继续学习。
对于运行着的程序,可以使用GDB的attach跟踪上,或者strace
也可以跟上,都需要进程的pid,并且具有一定的权限。
运行时的系统性能分析,
I/O的就可以使用iotop
(注意要在root下)。
CPU,内存相关的就可以使用top
,两者都可以通过pid来指定进程。
vmstat
包含信息很多
procs -----------memory---------- ---swap-- -----io---- -system-- -----cpu------
r b swpd free buff cache si so bi bo in cs us sy id wa st
proc:进程相关
r表示 对应R状态的进程 wait to run
b表示 对应D状态的进程 Uninterruptible
memory:内存相关
swpd:这个指虚拟内存的大小(virtual memory)我觉得这个概念很可能混淆,实际上就是swap分区被使用的大小,可以通过`free`来验证,两者相同。
free:同free
buff:同free中buffer
cache:同free中的pagecache
swap:对swap区IO
si:从磁盘(swap区)换到内存
so:从内存换到磁盘(swap区)
io:针对块设备的统计
bi:从块设备读的块数
bo:写到块设备的块数
in:每秒中断数
cs:每秒上下文切换数
cpu:cpu相关的
us:在用户态执行时间占比
sy:在内核态执行时间占比
id:闲置时间占比
wa:等待IO时间占比
st: Time stolen from a virtual machine
文件相关的:lsof filename
查看指定文件被哪个进程打开了,查看指定进程打开了哪些文件 lsof -p pid
。
网络相关的:查看端口被占用lsof -i:port
或者netstat -anp | grep port
查看网络连接ping
查看网卡信息ifconfig
(看似无用,在虚拟化时/网络编程ip绑定时有大学问) 还有各种抓包的就是wireshark/tcpdump 调试服务端时可以用nc
来作为简单的客户端
磁盘相关的:最简单的看看磁盘是不是满了df -h
还有一些杂项
查看内存泄露 valgrind --tool=memcheck --leak-check=full ./a.out
就想到这么多吧,有新的思路和工具继续更新