linux

linux问题调查工具指南

2020年10月1日 阅读(30)

1.工具概览

图源:http://www.brendangregg.com/linuxperf.html

2.网络

一个网络包的旅程:https://102.alibaba.com/detail/?id=166

2.1 网络连通性

#检查网络连通性(通过ping网关/对端网关/对端进行分段测试,通过tcpdump确认是否收到包)
netstat -rn #查看网关,以0.0.0.0开始的行的gateway是默认网关
ping 127.0.0.1 -s 64000 #指定packet size进行ping,一般应小于1ms
sudo tcpdump -i eth2 icmp #抓ping的包

#检查网卡状态
ip addr show #state是否是UP
ip link set eth0 up #启用被禁用的网卡
ip route show
ifconfig

route -n #查看路由表
ip route get 127.0.0.1 //返回目标ip最终实际所选用的路由

#检查iptables配置
sudo iptables --list-rules

#检查tc配置
sudo tc qdisc show dev eth2

#telent检查端口连通性
telnet 127.0.0.1 2376

2.2 网络连接数

netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'

2.3 网络流量

sar -n DEV 1 #查看网卡流量,排查本地网卡是否有问题

tsar –traffic #查看网络出入流量

2.4 丢包重传

tsar --tcp #查看retran,按照经验值健康网络应该在0 ~ 0.x
ip -s link #显示所有网络接口统计数据
ip -s -s link ls eth2 #显示特定网络接口统计数据

ip命令详解:https://www.jellythink.com/archives/469
tsar:https://github.com/alibaba/tsar

2.5 端口占用

#查看当前机器上进程监听的tcp端口,还会显示进程:users:(("downloader",pid=16201,fd=9))
sudo ss -pl -t -s 
#查找打开某端口的进程
sudo ss -lp | grep 22
sudo lsof -i :port #列出使用某个端口的进程
#列举出处于 FIN-WAIT-1状态的源端口为 80或者 443,目标网络为 193.233.7/24所有 tcp套接字
ss -o state FIN-WAIT-1 src :80 src :443 dst 192.168.25.100/24

ss命令详解:https://www.cnblogs.com/ftl1012/p/ss.html

3. 磁盘IO

一次磁盘io的旅程:https://blog.51cto.com/alanwu/1286553

3.1 空间

1.磁盘整体使用

df   #空间情况
df -i #inode是否满

2.寻找最大目录

sudo du -sh --time /*
sudo du -sh --time /home/*
......

3.查看磁盘是否为ssd

cat /sys/block/sda/queue/rotational #进行查看,返回值0即为SSD;返回1即为HDD
lsscsi

4.有时候df看到的磁盘空间使用率,和sudo du -sh 看到的不一致。

原因一般是因为存在大量被删除的问题,但是还处于open状态。可以通过如下命令找到这些被删除但是还没某些进程open的文件:

sudo lsof -P -n | grep deleted 

https://unix.stackexchange.com/questions/305049/linux-server-capacity-indicates-100-used-even-after-log-files-have-been-emptied

3.2 util

tsar --io -s util  -I sda #最近一天磁盘使用率
tsar --io -s util -i 1 -l -I sdb #实时磁盘使用率

磁盘util很高时,如何找到占用IO资源最多的进程

iotop -o -P

pidstat -d

iodump

blktrace

3.2.1 iostat

iostat -m -x 1 #以MB为单位每秒刷新一次

iostat详解:https://chuansongme.com/n/1151503748524

3.2.2 blktrace

sudo blktrace -d /dev/sda6 -o - | blkparse -i - #实现块请求追踪

### 追踪并进行分析
sudo blktrace -d /dev/sda6 #会在当前目录存储trace数据,为避免占用磁盘和IO需要提前确定好执行目录
sudo blkparse -i sda6
sudo blkparse -i sda6 -d sda6.blktrace.bin
sudo btt -i sda6.blktrace.bin  #可以查看不同进程的io情况

### 对设备/dev/sda的io监控120秒,每2秒显示一次
blktrace /dev/sda -a issue -a complete -w 120 -o - | blkiomon  -I 2 -h -

 
WR:R表示是read操作,W表示write操作,B是barrier operation,S是synchronous operation

blktrace详解:

http://www.178pt.com/254.html

https://www.sohu.com/a/157462582_314773

http://blog.chinaunix.net/uid-24774106-id-4096470.html

3.2.3 debugfs

3.2.3.1查找blktrace中的io请求对应的文件

1.首先根据blktrace可以找到io对应的扇区

sudo blktrace -d /dev/sda6 -o - |blkparse -i - |grep A >/tmp/t
#
8,0    9        1 1266874889.709080680  1495  A  WS 392236696 + 8 <- (8,6) 76279448

如上:76279448就是扇区号。

2.根据扇区通过debugfs找到对应文件

查看设备block大小:

sudo tune2fs -l /dev/sda6|grep "Block size" #查看块大小
sudo debugfs -R "stats" /dev/sda6|grep "Block size" #查看块大小
sudo fdisk -l /dev/sda6 #可以查看sector size

扇区转换为block号(扇区*SectorSize/BlockSize):

$ echo 76279448*512/4096 | bc
9534931

3.block号转换为inode

$ sudo debugfs -R "icheck 9534931" /dev/sda6
debugfs 1.42.9 (28-Dec-2013)
Block Inode number
9534931 8

4.inode转换为文件名

$ sudo debugfs -R "ncheck 8" /dev/sda6
debugfs 1.42.9 (28-Dec-2013)
Inode Pathname

注:inode number是8,无法找到对应的文件名。这是因为8是ext3/4文件系统中的日志文件的inode,它是隐藏文件,所以无法找到。

5.使用lsof查找打开文件的进程

sudo lsof /home/test_bin

使用blktrace统计磁盘块I/O访问频率:

http://blog.chinaunix.net/uid-24774106-id-4096470.html

扇区与文件系统转换关系:

https://www.bbsmax.com/A/Vx5MYABm5N/

3.2.3.2 查找文件对应的block

debugfs -R "stat /path/to/file" /dev/<partition>
hdparm --fibmap /path/to/filename

Linux下的IO监控与分析:https://www.cnblogs.com/quixotic/p/3258730.html
iodump:https://github.com/true/aspersa-mirror/blob/master/iodump

3.2.4 lsof(打开文件的进程|进程打开的文件)

lsof  /filepath/file #查看谁在使用某个文件
lsof +D /filepath/filepath2/ #递归查看某个目录下的文件信息
lsof -c mysql #列出某个binary打开的文件信息
lsof -p 123,456,789 #显示多个进程打开的文件信息
lsof -i #列出所有网络连接
lsof -i :port #列出使用某个端口的进程
lsof -d descrip #列出文件描述符对应的文件信息
lsof -d fd1-fd2 #根据文件描述符范围列出对应文件信息

3.2.5 fdisk

sudo fdisk -l /dev/sda

3.3 ext4

查看文件系统是否4k对齐:

sudo dumpe2fs /dev/loop1 |grep "Block size"

extent:https://ext4.wiki.kernel.org/index.php/Ext4_Design

extent tree:https://www.cnblogs.com/youngerchina/p/5624478.html

debugfs:https://linux.die.net/man/8/debugfs

debugfs: stat 1.log

debugfs: ex -l 1.log

4.CPU

查看cpu信息

cat /proc/cpuinfo
lscpu
top # P(根据cpu排序) M(根据内存排序) R(反向排序) H(显示线程)
top -p PID #显示某个进程
top -H -p pid #显示某个进程所有活跃线程开销情况

uptime

pstack PID

#内核stack
cat /proc/237332/task/*/stack | grep -v poll| grep -v futex  | grep -v fastpath  | grep -v sleep | grep -v ffff

load高,查看处于D和R状态的进程

ps -e -L h o state,pid,wchan:32,cmd | awk '{if($1=="R"||$1=="D"){print $0}}'
top -p $cspid -H -b -n2 | grep " D " #看看有没有线程D住

查看所有进程的cpu使用

pidstat -u -p ALL #查看所有进程cpu使用

5.内存

5.1 内存占用

free -g
cat /proc/19312/smaps #查看虚拟内存地址空间
pmap -d $PID #查看内存空间

cgroup配置

sudo lssubsys -am

5.2 内存泄漏

gperftools

5.3 内存越界

AddressSanitizer&ThreadSanitizer原理与应用

6. 进程

6.1 进程状态异常

1.pstack

2.strace(系统调用/进程异常退出/共享内存/性能)

sudo strace -tt -T -p PID #查看进程系统调用及耗费时间
#查看进程运行中访问的文件
strace -tt -e trace=file -f ./test_exit #trace=process|file|network|signal|desc|ipc

strace详解:https://www.linuxidc.com/Linux/2018-01/150654.htm

6.2 进程资源占用

6.2.1 pidstat

pidstat -u -p ALL #查看所有进程cpu使用
pidstat -r #查看所有进程内存使用
pidstat -d #查看所有进程IO使用
pidstat -w #查看所有进程上下文切换情况

6.2.2 ps

ps -C command_name #某个command对应的所有进程
ps --ppid 766 #显示进程776的所有子进程
ps u -p 776 -L #显示进程776的所有线程
ps -e --forest #进程树形结构
ps -f --forest -C sshd #打印某个进程的树形结构
ps -eo pid,ppid,fgroup,ni,lstart,etime #打印父进程、进程启动时间等

ps -eo pid,ppid,cmd,%mem,%cpu --sort=-%mem|head #根据内存占用排序
ps -eo pid,ppid,cmd,%mem,%cpu --sort=-%cpu|head #根据cpu排序
ps -eo euser,ruser,suser,fuser,f,comm,label #用户信息
watch -n 1 'ps -eo pid,ppid,cmd,%mem,%cpu --sort=-%mem | head' #查看ps实时执行结果

6.2.3 top

top # P(根据cpu排序) M(根据内存排序) R(反向排序) H(显示线程)

6.3 父子进程管理

父进程退出确保子进程也退出

python:http://evans.io/legacy/posts/killing-child-processes-on-parent-exit-prctl/

c:https://www.cnblogs.com/beixiaobei/p/9064815.html

7.性能profiling

perf :http://www.brendangregg.com/perf.html

gperftools:https://github.com/gperftools/gperftools

8.系统日志

8.1 dmesg

dmesg -T #显示友好时间
sudo vim /var/log/messages

/var/clone/cloneinfo

dmesg相对时间手动转换方法(xxx代表dmesg中的相对时间戳):

MY_TIME=xxx 
date -d "1970-01-01 UTC `echo "$(date +%s)-$(cat /proc/uptime|cut -f 1 -d' ')+$MY_TIME"|bc ` seconds" +'%Y-%m-%d %H:%M:%S'
dmesg | grep -i memory #内存相关
dmesg | grep -i dma #磁盘相关
dmesg | grep -i usb #usb
dmesg | grep -i tty #串口相关
dmesg --facility=daemon --level=err,warn #指定要打印的日志类型和日志级别,详情查看dmesg -h
dmesg -L #带颜色显示
dmesg |grep -E "net|eth|bond|link" #网络相关
dmesg |grep -i "cpu" #网络相关

8.2 其他系统日志

/var/log/kern

var/log目录日志详解:https://www.plesk.com/blog/featured/linux-logs-explained/

9.辅助工具

9.1 awk

1.统计log文件里面的各个操作的个数,并按照多少排序

awk ‘{++opMap[$1]} END {for(key in opMap) print key,”\t”,opMap[key]}’|sort -n -k 2

2.计算key/value最大value值

awk ‘{if($2>opMap[$1]){opMap[$1]=$2}} END {for(key in opMap) print key,”\t”,opMap[key]}’|sort -n -k 2

3.条件表达式

awk -F “::” ‘$5 >= 3 && $6 >=3 {print $0}’

awk的条件表达式:(https://likegeeks.com/awk-command/)

9.2 代码查看工具

codeviz egypt ncc

9.3 gdb

9.3.1 基本使用

http://www.brendangregg.com/blog/2016-08-09/gdb-example-ncurses.html

watch var #变量值变化时会停住

set follow-fork-mode child #在fork子进程时,gdb跟踪进子进程

x/nfu #help x查看具体用法
list *addr #查看addr处指令对应的代码片段
info symbol 0x400a46 #查看某地址对应的符号表信息
info line *0x400a46 #查看某地址对应的代码行,类似addr2line

9.3.2 非交互式获取所有线程bt

gdb -q --batch --ex "set height 0" -ex "thread apply all bt full" [可执行文件] [core文件]

除了通过-ex直接指定要运行的命令,还可以通过 -x gdb_cmd_file指定命令文件。

此外还可以在交互式模式下,设置logging,将输出结果存到文件中

set logging file output.filename
set logging on
xxx #gdb命令
set logging off

9.3.3 查看stl容器对象

http://www.yolinux.com/TUTORIALS/src/dbinit_stl_views-1.03.txt

下载上述文件,打开gdb在里面执行:source dbinit_stl_views-1.03.txt

之后即可使用pmap pset等命令查看map set的内容。

9.3.4 汇编

汇编基础:

深入浅出GNU X86-64 汇编:https://blog.csdn.net/pro_technician/article/details/78173777

C/C++中手动获取调用堆栈:https://blog.csdn.net/qq_44906504/article/details/89246475

9.4 coredump

https://averageradical.github.io/Linux_Core_Dumps.pdf

9.4.1 core文件产生

ulimit -c -f #查看core文件大小限制
sysctl kernel.core_pattern #查看core文件保存路径
gcore $PID #产生core文件
readelf -a core.14391 #查看core文件信息

9.4.2 core文件分析

(gdb) thread apply all bt #查看所有线程堆栈
(gdb) dump binary memory dump.bin 0x00007f3498000000 0x00007f34a0000000 #dump内存数据到文件
(gdb) maint print msymbols var.syms #print符号表内容到文件var.syms

https://sourceware.org/gdb/onlinedocs/gdb/Searching-Memory.html

(gdb) find [/sn] start_addr, +len, val1 [, val2, …] 
(gdb) find [/sn] start_addr, end_addr, val1 [, val2, …]

core_analyzer:http://core-analyzer.sourceforge.net/index.html

9.5 编译链接

gcc -E search.c #宏展开
ldd 
c++filt 
addr2line
nm

编译链接加载:https://blog.csdn.net/farmwang/article/details/72934821

9.6 shell快捷键

9.7 shell常用命令

1.日志备份
mkdir log_bakup
ln *LOG* log_bakup/   #注意后面记得清理不使用的备份日志

2.文件操作
split #将一个文件分割成多个
join #
find ./ -name "xxx*" | xargs cat > outpt.txt #合并多个文件到一个

2.2 网络连接数

You Might Also Like