Solaris下进行应用程序调试的一些常用命令的整理。
$ps:进程信息
-ef 查看所有进程详细信息(every process; full listing); -l long listing; -j print sid and pgid
- o format: 指定输出格式
'format' is one or more of:
user ruser group rgroup uid ruid gid rgid pid ppid pgid sid taskid ctid
pri opri pcpu pmem vsz rss osz nice class time etime stime zone zoneid
f s c lwp nlwp psr tty addr wchan fname comm args projid project pset
$prstat: report active process statistics.
-a: report information about both processes and users;
-s key 排序;
-t total usage for each user
$kill -siginal pid: 发送信号到指定进程。
signal可以是符号名称,也可以是数字。例如#define SIGKILL 9.
可以使用man signal.h命令查看.
可以使用键盘发送的信号:ctrl+c -> SIGINT; ctrl+\ -> SIGQUIT; ; ctrl+z -> SIGTSTP;
#define SIGINT 2 /* interrupt (rubout) */
#define SIGQUIT 3 /* quit (ASCII FS) */
#define SIGTSTP 24 /* user stop requested from tty */
如果没有设置信号捕捉函数,以下的信号默认动作是中止+core。
#define SIGQUIT 3 /* quit (ASCII FS) */
#define SIGILL 4 /* illegal instruction (not reset when caught) */
#define SIGIOT 6 /* IOT instruction */
#define SIGABRT 6 /* used by abort, replace SIGIOT in the future */
#define SIGEMT 7 /* EMT instruction */
#define SIGFPE 8 /* floating point exception */
#define SIGBUS 10 /* bus error */
#define SIGSEGV 11 /* segmentation violation */
#define SIGSYS 12 /* bad argument to system call */
#define SIGTRAP 5 /* trace trap (not reset when caught) */
#define SIGXCPU 30 /* exceeded cpu limit */
#define SIGXFSZ 31 /* exceeded file size limit */
* 可以使用dbx program_name core来查看(进dbx后使用where)。需要指定应用程序的完整路径。
* 默认在当前目录下生成名为core的转储文件。
可用coreadm更改。(全局设置保存在/etc/coreadm.conf;系统转储管理用dumpadm)
coreadm [-p pattern][pid]: 例如coreadm -p ./%n.%f.%p
%n System node name (uname -n); %f Executable file name; %p pid
*可以使用ulimit -c xxx更改当前session的core文件大小限制,默认是unlimited,改为0则不生成。
$psig pid: 查看进程的信号捕捉函数设置
$gcore pid: get core file.生成core文件,文件名core.pid,可以使用-o filename来指定文件名。
$pgrep -u oracle bash: 查找进程id。
-u 指定用户
-f:匹配命令行参数matched against the full process argument string
-x 精确匹配文件名或者命令行参数
-P ppidlist: 父进程等于指定pid的所有进程。
$pkill -signal -u oracle bash: 发送信号到指定进程。除了-signal,其他同pgrep。
$ptree: 打印进程树。ptree `pgrep -x -u oracle bash`
$pstack pid/core: print stack trace. $pstack `pgrep -x -u oracle bash`
$pargs pid/core: process arguments.
-l: display arguments as a command line. -e: environment variables.
$pldd pid/core; pmap pid/core: 加载库;地址空间
$pfiles pid: 返回进程打开的所有文件信息(fstat和fcntl).
$pwdx pid: 返回进程当前工作目录.
$ulimit -a: 显示系统资源限制。
$plimit pid: 进程资源限制。
-k: 显示单位kb; -m: 显示单位mb;
plimit {-cdfnstv} soft,hard pid, 设置进程资源限制。
$truss: 跟踪应用程序中的系统调用和信号
truss -o trace.log mytest.exe : 把跟踪结果输出到trace.log中。默认是输出到stderr。
truss -o trace.log -t open,close,exec -d mytest.exe
-t指定跟踪的系统调用函数列表; -d每一行输出头部都包含一个时间戳。
truss -p `pgrep mytest.exe`/30-32 : -p指定一个进程id,在进程id后面可以指定线程号。
truss -c -p `pgrep mytest.exe`
-c 输出统计结果而不是每一个调用的跟踪;
直到进程中止或者ctrl+c(or ctrl+\)停止跟踪,然后会输出统计结果。
$dbx: SunStudio中提供的交互式源代码级命令行调试工具。编译时需要指定-g选项附加代码信息到程序文件。
$nohup: 通过nohup命令启动的程序忽略SIGHUP信号,默认SIGHUP会导致程序退出。
如果需要程序长时间运行,并且从终端logout也不会导致程序推出,这个命令就很有用。
用法:nohup cmd &
测试一下,在终端A运行 nohup mytest.exe &,
在终端B运行 truss -p `pgrep -f mytest.exe`,
然后关闭终端A,在终端B可以看到输出
-bash-3.00$ truss -p `pgrep -f mytest.exe`
nanosleep(0xFFBFF4C8, 0xFFBFF4C0) (sleeping...)
Received signal #1, SIGHUP, in nanosleep() [ignored]
siginfo: SIGHUP pid=15110 uid=822
nanosleep(0xFFBFF4C8, 0xFFBFF4C0) (sleeping...)
对比一下,如果只是运行cmd &,在终端B可以看到下面输出,可以看到mytest.exe已经推出了。
nanosleep(0xFFBFF4C0, 0xFFBFF4B8) (sleeping...)
Received signal #1, SIGHUP, in nanosleep() [default]
siginfo: SIGHUP pid=23194 uid=822
nanosleep(0xFFBFF4C0, 0xFFBFF4B8) Err#4 EINTR
-bash-3.00$ pgrep -f mytest.exe
-bash-3.00$
$netstat: network status. -a: all, -i : state of interface.
$snoop: 监测网络packet。捕获结果可以用wireshark等工具打开,更容易阅读,并支持更多的协议解析。
snoop -d bge0 -o cap 172.29.21.15 and port 161
在device bge0上监听,结果输出到cap文件,
只保留源地址或目标地址是172.29.21.15,端口是161的packet。
同时在控制台显示捕捉到的packet数量(-q则不显示)。
snoop -i cap -p 1,3 -t a -v
读取输入文件cap, 显示1~3个packet内容;
-t[r|a|d]显示时间,r relative相对于第一个packet的时间,a absolute, d delta,默认为d;
-v verbose mode详细模式,每个packet显示详细内容,会有很多行;
-V 半详细,对于每个packet, 从上到下每层协议显示1行summary。
$tcpdump
直接启动tcpdump将监视第一个网络接口上所有流过的数据包。
使用-i参数指定tcpdump监听的网络接口
使用-c参数指定要监听的数据包数量,
使用-w参数指定将监听到的数据包写入文件中保存
第一种是关于类型的关键字,主要包括host,net,port, 例如 host 210.27.48.2,指明 210.27.48.2是一台主机,net 202.0.0.0 指明 202.0.0.0是一个网络地址,port 23 指明端口号是23。如果没有指定类型,缺省的类型是host.
第二种是确定传输方向的关键字,主要包括src , dst ,dst or src, dst and src ,这些关键字指明了传输的方向。举例说明,src 210.27.48.2 ,指明ip包中源地址是210.27.48.2 , dst net 202.0.0.0 指明目的网络地址是202.0.0.0 。如果没有指明方向关键字,则缺省是src or dst关键字。
第三种是协议的关键字,主要包括fddi,ip,arp,rarp,tcp,udp等类型。Fddi指明是在FDDI(分布式光纤数据接口网络)上的特定 的网络协议,实际上它是"ether"的别名,fddi和ether具有类似的源地址和目的地址,所以可以将fddi协议包当作ether的包进行处理和 分析。其他的几个关键字就是指明了监听的包的协议内容。如果没有指定任何协议,则tcpdump将会监听所有协议的信息包。
除了这三种类型的关键字之外,其他重要的关键字如下:gateway, broadcast,less,greater,还有三种逻辑运算,取非运算是 'not ' '! ', 与运算是'and','&&';或运算 是'or' ,'││';这些关键字可以组合起来构成强大的组合条件来满足人们的需要,下面举几个例子来说明。
A想要截获所有210.27.48.1 的主机收到的和发出的所有的数据包:
#tcpdump host 210.27.48.1
B想要截获主机210.27.48.1 和主机210.27.48.2 或210.27.48.3的通信,使用命令:(在命令行中适用 括号时,一定要
#tcpdump host 210.27.48.1 and \ (210.27.48.2 or 210.27.48.3 \)
C如果想要获取主机210.27.48.1除了和主机210.27.48.2之外所有主机通信的ip包,使用命令:
#tcpdump ip host 210.27.48.1 and ! 210.27.48.2
D如果想要获取主机210.27.48.1接收或发出的telnet包,使用如下命令:
#tcpdump tcp port 23 host 210.27.48.1
E 对本机的udp 123 端口进行监视 123 为ntp的服务端口
# tcpdump udp port 123
F 系统将只对名为hostname的主机的通信数据包进行监视。主机名可以是本地主机,也可以是网络上的任何一台计算机。下面的命令可以读取主机hostname发送的所有数据:
#tcpdump -i eth0 src host hostname
G 下面的命令可以监视所有送到主机hostname的数据包:
#tcpdump -i eth0 dst host hostname
H 我们还可以监视通过指定网关的数据包:
#tcpdump -i eth0 gateway Gatewayname
I 如果你还想监视编址到指定端口的TCP或UDP数据包,那么执行以下命令:
#tcpdump -i eth0 host hostname and port 80
J 如果想要获取主机210.27.48.1除了和主机210.27.48.2之外所有主机通信的ip包
,使用命令:
#tcpdump ip host 210.27.48.1 and ! 210.27.48.2
K 想要截获主机210.27.48.1 和主机210.27.48.2 或210.27.48.3的通信,使用命令
:(在命令行中适用 括号时,一定要
#tcpdump host 210.27.48.1 and \ (210.27.48.2 or 210.27.48.3 \)
L 如果想要获取主机210.27.48.1除了和主机210.27.48.2之外所有主机通信的ip包,使用命令:
#tcpdump ip host 210.27.48.1 and ! 210.27.48.2
M 如果想要获取主机210.27.48.1接收或发出的telnet包,使用如下命令:
#tcpdump tcp port 23 host 210.27.48.1
N 如果我们只需要列出送到80端口的数据包,用dst port;如果我们只希望看到返回80端口的数据包,用src port。
#tcpdump –i eth0 host hostname and dst port 80 目的端口是80
或者
#tcpdump –i eth0 host hostname and src port 80 源端口是80 一般是提供http的服务的主机
如果条件很多的话 要在条件之前加and 或 or 或 not
#tcpdump -i eth0 host ! 211.161.223.70 and ! 211.161.223.71 and dst port 80
$uptime 显示开机至今时间,用户数,最后1分钟,5分钟,15分钟的平均负载