JOE'S BLOG

好记性不如烂键盘

0%

常用的命令总结及各种实用工具

常用命令和工具

  • gdb
  • zip tar
  • find
  • ldd
  • lsof
  • ps
  • pstack
  • strace
  • ipcs
  • top
  • free
  • vmstat
  • iostat
  • sar
  • readelf
  • objdump
  • nm
  • size

gdb

使用

如果要使用gdb对 c/c++ 进行调试 需要在编译选项上加 -g

1
$ gcc -g -o main main.c

然后使用如下命令使用

1
$ gdb main <core.xxx>

core文件是程序非法执行后产生的 core dump 文件

core dump

/etc/profile 下添加
ulimit -S -c unlimited > /dev/null 2>&1

/etc/sysctl.conf 添加
kernel.core_pattern = ./core_%t_%p_%e
kernel.core_uses_pid = 1

gdb交互命令

  • run:简记为 r ,其作用是运行程序,当遇到断点后,程序会在断点处停止运行,等待用户输入下一步的命令。
  • continue (简写c ):继续执行,到下一个断点处(或运行结束)
  • next:(简写 n),单步跟踪程序,当遇到函数调用时,也不进入此函数体;此命令同 step 的主要区别是,step 遇到用户自定义的函数,将步进到函数中去运行,而 next 则直接调用函数,不会进入到函数体内。
  • step (简写s):单步调试如果有函数调用,则进入函数;与命令n不同,n是不进入调用的函数的
  • until:当你厌倦了在一个循环体内单步跟踪时,这个命令可以运行程序直到退出循环体。
  • until+行号: 运行至某行,不仅仅用来跳出循环
  • finish: 运行程序,直到当前函数完成返回,并打印函数返回时的堆栈地址和返回值及参数值等信息。
  • call 函数(参数):调用程序中可见的函数,并传递“参数”,如:call gdb_test(55)
  • quit:简记为 q ,退出gdb

设置断点

  • break n (简写b n):在第n行处设置断点
    (可以带上代码路径和代码名称: b OAGUPDATE.cpp:578)
  • b fn1 if a>b:条件断点设置
  • break func(break缩写为b):在函数func()的入口处设置断点,如:break cb_button
  • delete 断点号n:删除第n个断点
  • disable 断点号n:暂停第n个断点
  • enable 断点号n:开启第n个断点
  • clear 行号n:清除第n行的断点
  • info b (info breakpoints) :显示当前程序的断点设置情况
  • delete breakpoints:清除所有断点:

查看源代码

  • list :简记为 l ,其作用就是列出程序的源代码,默认每次显示10行。
  • list 行号:将显示当前文件以“行号”为中心的前后10行代码,如:list 12
  • list 函数名:将显示“函数名”所在函数的源代码,如:list main
  • list :不带参数,将接着上一次 list 命令的,输出下边的内容。

打印表达式

  • print 表达式:简记为 p ,其中“表达式”可以是任何当前正在被测试程序的有效表达式,比如当前正在调试C语言的程序,那么“表达式”可以是任何C语言的有效表达式,包括数字,变量甚至是函数调用。
  • print a:将显示整数 a 的值
  • print ++a:将把 a 中的值加1,并显示出来
  • print name:将显示字符串 name 的值
  • print gdb_test(22):将以整数22作为参数调用 gdb_test() 函数
  • print gdb_test(a):将以变量 a 作为参数调用 gdb_test() 函数
  • display 表达式:在单步运行时将非常有用,使用display命令设置一个表达式后,它将在每次单步进行指令后,紧接着输出被设置的表达式及值。如: display a
  • watch 表达式:设置一个监视点,一旦被监视的“表达式”的值改变,gdb将强行终止正在被调试的程序。如: watch a
  • whatis :查询变量或函数
  • info function: 查询函数
  • 扩展info locals: 显示当前堆栈页的所有变量

查询运行信息

  • where/bt :当前运行的堆栈列表;
  • bt backtrace 显示当前调用堆栈
  • up/down 改变堆栈显示的深度
  • set args 参数:指定运行时的参数
  • show args:查看设置好的参数
  • info program: 来查看程序的是否在运行,进程号,被暂停的原因。

分割窗口

  • layout:用于分割窗口,可以一边查看代码,一边测试:
  • layout src:显示源代码窗口
  • layout asm:显示反汇编窗口
  • layout regs:显示源代码/反汇编和CPU寄存器窗口
  • layout split:显示源代码和反汇编窗口
  • Ctrl + L:刷新窗口

压缩解压缩

zip

压缩

1
$ zip -r xxx.zip  xxx.c

解压

1
$ zip xxx.zip

tar

.tar 压缩

1
$ tar -cvf xxx.tar xxx

.tar 解压

1
$ tar -xvf xxx.tar 

.tar.gz 压缩

1
$ tar -zcvf xxx.tar.gz xxx

.tar.gz 解压

1
$ tar -zxvf xxx.tar.gz

.tar.bz2 压缩

1
$ tar -jcvf xxx.tar.gz2 xxx

.tar.bz2 解压

1
$ tar -jxvf xxx.tar.gz2

rar

.rar 压缩

1
$ rar -a xxx.rar xxx

.rar 解压

1
$ rar -x xxx.rar

find

统计代码行数

1
2
3
find . -name "*.go" |wc -l
find . -name "*.go" |xargs cat|wc -l
find . -name "*.go" |xargs cat|grep -v ^$|wc -l

资源查看

查看文件大小

1
$ du -ah --max-depth=1

监控系统资源

1
$ vmstat 1 3

查看内存使用状况

1
$ free -m

查看CPU

1
$ cat /proc/cpuinfo

判断系统位数

1
$ file /bin/ls

查看Linux系统发行版

1
$ lsb_release -a

ldd 查看程序依赖库

1
$ ldd main

strace 跟踪进程调用

strace可以跟踪到一个进程产生的系统调用,包括参数,返回值,执行消耗的时间

参数说明

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
-c 统计每一系统调用的所执行的时间,次数和出错的次数等.
-d 输出strace关于标准错误的调试信息.
-f 跟踪由fork调用所产生的子进程.
-ff 如果提供-o filename,则所有进程的跟踪结果输出到相应的filename.pid中,pid是各进程的进程号.
-F 尝试跟踪vfork调用.在-f时,vfork不被跟踪.
-h 输出简要的帮助信息.
-i 输出系统调用的入口指针.
-q 禁止输出关于脱离的消息.
-r 打印出相对时间关于,,每一个系统调用.
-t 在输出中的每一行前加上时间信息.
-tt 在输出中的每一行前加上时间信息,微秒级.
-ttt 微秒级输出,以秒了表示时间.
-T 显示每一调用所耗的时间.
-v 输出所有的系统调用.一些调用关于环境变量,状态,输入输出等调用由于使用频繁,默认不输出.
-V 输出strace的版本信息.
-x 以十六进制形式输出非标准字符串
-xx 所有字符串以十六进制形式输出.
-a column
设置返回值的输出位置.默认 为40.
-e expr
指定一个表达式,用来控制如何跟踪.格式如下:
[qualifier=][!]value1[,value2]...
qualifier只能是 trace,abbrev,verbose,raw,signal,read,write其中之一.value是用来限定的符号或数字.默认的 qualifier是 trace.感叹号是否定符号.例如:
-eopen等价于 -e trace=open,表示只跟踪open调用.而-etrace!=open表示跟踪除了open以外的其他调用.有两个特殊的符号 all 和 none.
注意有些shell使用!来执行历史记录里的命令,所以要使用\\.
-e trace=set
只跟踪指定的系统 调用.例如:-e trace=open,close,rean,write表示只跟踪这四个系统调用.默认的为set=all.
-e trace=file
只跟踪有关文件操作的系统调用.
-e trace=process
只跟踪有关进程控制的系统调用.
-e trace=network
跟踪与网络有关的所有系统调用.
-e strace=signal
跟踪所有与系统信号有关的 系统调用
-e trace=ipc
跟踪所有与进程通讯有关的系统调用
-e abbrev=set
设定 strace输出的系统调用的结果集.-v 等与 abbrev=none.默认为abbrev=all.
-e raw=set
将指 定的系统调用的参数以十六进制显示.
-e signal=set
指定跟踪的系统信号.默认为all.如 signal=!SIGIO(或者signal=!io),表示不跟踪SIGIO信号.
-e read=set
输出从指定文件中读出 的数据.例如:
-e read=3,5
-e write=set
输出写入到指定文件中的数据.
-o filename
将strace的输出写入文件filename
-p pid
跟踪指定的进程pid.
-s strsize
指定输出的字符串的最大长度.默认为32.文件名一直全部输出.
-u username
以username 的UID和GID执行被跟踪的命令

几个实例说明

跟踪可执行程序 并输出到当前文件下 -f -F 表示同时跟踪 fork vfork出来的进程

1
$ strace -f -F -o ./trace.txt ./main

跟踪服务进程,跟踪11111进程的所有系统调用,并统计时间,以及开始时间

1
$ strace -o output.txt -T -tt -e trace=all -p 11111

lsof 一切皆文件

1
2
3
4
5
6
7
8
lsof abc.txt 				//显示开启文件abc.txt的进程
lsof -c abc //显示abc进程现在打开的文件
lsof -c -p //1234 列出进程号为1234的进程所打开的文件
lsof -g gid //显示归属gid的进程情况
lsof +d /usr/local/ //显示目录下被进程开启的文件
lsof +D /usr/local/ //同上,但是会搜索目录下的目录,时间较长
lsof -d 4 //显示使用fd为4的进程
lsof -i //用以显示符合条件的进程情况

获取 IPv4流量

1
$ lsof -i 4

仅显示TCP流量

1
$ lsof -iTCP

显示指定用户打开了什么

1
$ lsof -u mysql

杀死指定用户所做的一切事情

1
kill -9 `lsof -t -u nginx`

查看指定的命令正在使用的文件和网络连接

1
$ lsof -c mysql

查看指定进程ID已打开的内容

1
$ lsof -p 12356

更多

lsof which httpd //那个进程在使用apache的可执行文件
lsof /etc/passwd //那个进程在占用/etc/passwd
lsof /dev/hda6 //那个进程在占用hda6
lsof /dev/cdrom //那个进程在占用光驱
lsof -c sendmail //查看sendmail进程的文件使用情况
lsof -c courier -u ^zahn //显示出那些文件被以courier打头的进程打开,但是并不属于用户zahn
lsof -p 30297 //显示那些文件被pid为30297的进程打开
lsof -D /tmp 显示所有在/tmp文件夹中打开的instance和文件的进程。但是symbol文件并不在列
lsof -u1000 //查看uid是100的用户的进程的文件使用情况
lsof -utony //查看用户tony的进程的文件使用情况
lsof -u^tony //查看不是用户tony的进程的文件使用情况(^是取反的意思)
lsof -i //显示所有打开的端口
lsof -i:80 //显示所有打开80端口的进程
lsof -i -U //显示所有打开的端口和UNIX domain文件
lsof -i UDP@[url]www.akadia.com:123 //显示那些进程打开了到www.akadia.com的UDP的123(ntp)端口的链接
lsof -i tcp@ohaha.ks.edu.tw:ftp -r //不断查看目前ftp连接的情况(-r,lsof会永远不断的执行,直到收到中断信号,+r,lsof会一直执行,直到没有档案被显示,缺省是15s刷新)
lsof -i tcp@ohaha.ks.edu.tw:ftp -n //lsof -n 不将IP转换为hostname,缺省是不加上-n参数

进程间通信ipcs

ipcs是Linux下显示进程间通信设施状态的工具。可以显示消息队列、共享内存和信号量的信息

查看 XSI IPC 3种形式的限定

1
2
3
4
5
6
Linux系统
$ ipcs -l
FreeBSD系统
$ ipcs -T
Solaris系统
$ sysdef -y

sar

System Activity Reporter(系统活动情况报告)

readelf elf文件分析

显示文件头信息

1
$ readelf -h main| grep Machine
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
vagrant@ubuntu-xenial:~/php-dev/demo$ readelf -h main.out
ELF Header:
Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
Class: ELF32
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: EXEC (Executable file)
Machine: Intel 80386
Version: 0x1
Entry point address: 0x8048310
Start of program headers: 52 (bytes into file)
Start of section headers: 6984 (bytes into file)
Flags: 0x0
Size of this header: 52 (bytes)
Size of program headers: 32 (bytes)
Number of program headers: 9
Size of section headers: 40 (bytes)
Number of section headers: 36
Section header string table index: 33

几个使用方法

查看应用程序在编译的时候是否加了 -g 选项

1
$ readelf -S main| grep debug

完整输出

1
$ readelf -all main

抓包工具

tcpdump抓包工具使用

1
sudo tcpdump -i any tcp port 9501
  • -i 绑定的网卡,any表示全部网卡 lo 表示本地的
  • tcp 只监听tcp协议
  • port 指定端口

没了