您的位置:首页 > 运维架构 > Shell

Shell脚本学习-程序调试

2012-04-26 16:30 330 查看
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分钟的平均负载
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: