一 top命令
|
|
top命令是Linux下常用的性能分析工具,能够实时显示系统中各个进程的资源占用状况,类似于Windows的任务管理器。下面详细介绍它的使用方法。
认识top的显示结果
top命令的显示结果如下所示:
top - 01:06:48 up 1:22, 1 user, load average: 0.06, 0.60, 0.48
Tasks: 29 total, 1 running, 28 sleeping, 0 stopped, 0 zombie
Cpu(s): 0.3% us, 1.0% sy, 0.0% ni, 98.7% id, 0.0% wa, 0.0% hi, 0.0% si
Mem: 191272k total, 173656k used, 17616k free, 22052k buffers
Swap: 192772k total, 0k used, 192772k free, 123988k cached
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
1379 root 16 0 7976 2456 1980 S 0.7 1.3 0:11.03 sshd
14704 root 16 0 2128 980 796 R 0.7 0.5 0:02.72 top
1 root 16 0 1992 632 544 S 0.0 0.3 0:00.90 init
2 root 34 19 0 0 0 S 0.0 0.0 0:00.00 ksoftirqd/0
3 root RT 0 0 0 0 S 0.0 0.0 0:00.00 watchdog/0
统计信息区
前五行是系统整体的统计信息。第一行是任务队列信息,同 uptime 命令的执行结果。其内容如下:
01:06:48 |
当前时间 |
up 1:22 |
系统运行时间,格式为时:分 |
1 user |
当前登录用户数 |
load average: 0.06, 0.60, 0.48 |
系统负载,即任务队列的平均长度。 三个数值分别为 1分钟、5分钟、15分钟前到现在的平均值。 |
第二、三行为进程和CPU的信息。当有多个CPU时,这些内容可能会超过两行。内容如下:
Tasks: 29 total |
进程总数 |
1 running |
正在运行的进程数 |
28 sleeping |
睡眠的进程数 |
0 stopped |
停止的进程数 |
0 zombie |
僵尸进程数 |
Cpu(s): 0.3% us |
用户空间占用CPU百分比 |
1.0% sy |
内核空间占用CPU百分比 |
0.0% ni |
用户进程空间内改变过优先级的进程占用CPU百分比 |
98.7% id |
空闲CPU百分比 |
0.0% wa |
等待输入输出的CPU时间百分比 |
0.0% hi |
|
0.0% si |
|
最后两行为内存信息。内容如下:
Mem: 191272k total |
物理内存总量 |
173656k used |
使用的物理内存总量 |
17616k free |
空闲内存总量 |
22052k buffers |
用作内核缓存的内存量 |
Swap: 192772k total |
交换区总量 |
0k used |
使用的交换区总量 |
192772k free |
空闲交换区总量 |
123988k cached |
缓冲的交换区总量。 内存中的内容被换出到交换区,而后又被换入到内存,但使用过的交换区尚未被覆盖, 该数值即为这些内容已存在于内存中的交换区的大小。 相应的内存再次被换出时可不必再对交换区写入。 |
进程信息区
统计信息区域的下方显示了各个进程的详细信息。首先来认识一下各列的含义。
序号 |
列名 |
含义 |
a |
PID |
进程id |
b |
PPID |
父进程id |
c |
RUSER |
Real user name |
d |
UID |
进程所有者的用户id |
e |
USER |
进程所有者的用户名 |
f |
GROUP |
进程所有者的组名 |
g |
TTY |
启动进程的终端名。不是从终端启动的进程则显示为 ? |
h |
PR |
优先级 |
i |
NI |
nice值。负值表示高优先级,正值表示低优先级 |
j |
P |
最后使用的CPU,仅在多CPU环境下有意义 |
k |
%CPU |
上次更新到现在的CPU时间占用百分比 |
l |
TIME |
进程使用的CPU时间总计,单位秒 |
m |
TIME+ |
进程使用的CPU时间总计,单位1/100秒 |
n |
%MEM |
进程使用的物理内存百分比 |
o |
VIRT |
进程使用的虚拟内存总量,单位kb。VIRT=SWAP+RES |
p |
SWAP |
进程使用的虚拟内存中,被换出的大小,单位kb。 |
q |
RES |
进程使用的、未被换出的物理内存大小,单位kb。RES=CODE+DATA |
r |
CODE |
可执行代码占用的物理内存大小,单位kb |
s |
DATA |
可执行代码以外的部分(数据段+栈)占用的物理内存大小,单位kb |
t |
SHR |
共享内存大小,单位kb |
u |
nFLT |
页面错误次数 |
v |
nDRT |
最后一次写入到现在,被修改过的页面数。 |
w |
S |
进程状态。 D=不可中断的睡眠状态 R=运行 S=睡眠 T=跟踪/停止 Z=僵尸进程 |
x |
COMMAND |
命令名/命令行 |
y |
WCHAN |
若该进程在睡眠,则显示睡眠中的系统函数名 |
z |
Flags |
任务标志,参考 sched.h |
默认情况下仅显示比较重要的 PID、USER、PR、NI、VIRT、RES、SHR、S、%CPU、%MEM、TIME+、COMMAND 列。可以通过下面的快捷键来更改显示内容。
更改显示内容
通过 f 键可以选择显示的内容。按 f 键之后会显示列的列表,按 a-z 即可显示或隐藏对应的列,最后按回车键确定。
按 o 键可以改变列的显示顺序。按小写的 a-z 可以将相应的列向右移动,而大写的 A-Z 可以将相应的列向左移动。最后按回车键确定。
按大写的 F 或 O 键,然后按 a-z 可以将进程按照相应的列进行排序。而大写的 R 键可以将当前的排序倒转。
|
|
二 Grep学习笔记
作者:杨文军 日期:2006-06-13
三 FTP命令行使用精萃
作者:杨文军 日期:2006-04-05
FTP命令是Internet用户使用最频繁的命令之一,不论是在DOS还是UNIX操作系统下使用 FTP,都会遇到大量的FTP内部命令。熟悉并灵活应用FTP的内部命令,可以大大方便使用者,并收到事半功倍之效。
FTP的命令行格式为: ftp -v -d -i -n -g [主机名] ,其中
-v 显示远程服务器的所有响应信息;
-d 使用调试方式;
-i 限制ftp的自动登录,即不使用;
-n etrc文件;
-g 取消全局文件名。
ftp使用的内部命令如下(中括号表示可选项):
1. ![cmd[args]]:在本地机中执行交互shell,exit回到ftp环境,如:!ls*.zip。
2. $ macro-ame[args]:执行宏定义macro-name。
3. account[password]:提供登录远程系统成功后访问系统资源所需的补充口令。
4.append local-file[remote-file]:将本地文件追加到远程系统主机,若未指定远程系统文件名,则使用本地文件名。
5. ascii:使用ascii类型传输方式。
6. bell:每个命令执行完毕后计算机响铃一次。
7. bin:使用二进制文件传输方式。
8. bye:退出ftp会话过程。
9. case:在使用mget时,将远程主机文件名中的大写转为小写字母。
10. cd remote-dir:进入远程主机目录。
11. cdup:进入远程主机目录的父目录。
12. chmod mode file-name:将远程主机文件file-name的存取方式设置为mode,如: chmod 777 a.out 。
13. close:中断与远程服务器的ftp会话(与open对应)。
14. cr:使用asscii方式传输文件时,将回车换行转换为回行。
15. delete remote-file:删除远程主机文件。
16. debug[debug-value]:设置调试方式, 显示发送至远程主机的每条命令,如: deb up 3,若设为0,表示取消debug。
17.dir[remote-dir][local-file]:显示远程主机目录,并将结果存入本地文件local-file。
18. disconnection:同close。
19. form format:将文件传输方式设置为format,缺省为file方式。
20. get remote-file[local-file]: 将远程主机的文件remote-file传至本地硬盘的local-file。
21. glob:设置mdelete,mget,mput的文件名扩展,缺省时不扩展文件名,同命令行的-g参数。
22. hash:每传输1024字节,显示一个hash符号(#)。
23. help[cmd]:显示ftp内部命令cmd的帮助信息,如:help get。
24. idle[seconds]:将远程服务器的休眠计时器设为[seconds]秒。
25. image:设置二进制传输方式(同binary)。
26. lcd[dir]:将本地工作目录切换至dir。
27. ls[remote-dir][local-file]:显示远程目录remote-dir, 并存入本地文件local-file。
28. macdef macro-name:定义一个宏,遇到macdef下的空行时,宏定义结束。
29. mdelete[remote-file]:删除远程主机文件。
30. mdir remote-files local-file:与dir类似,但可指定多个远程文件,如: mdir *.o.*.zipoutfile 。
31. mget remote-files:传输多个远程文件。
32. mkdir dir-name:在远程主机中建一目录。
33. mls remote-file local-file:同nlist,但可指定多个文件名。
34. mode[modename]:将文件传输方式设置为modename, 缺省为stream方式。
35. modtime file-name:显示远程主机文件的最后修改时间。
36. mput local-file:将多个文件传输至远程主机。
37. newer file-name: 如果远程机中file-name的修改时间比本地硬盘同名文件的时间更近,则重传该文件。
38. nlist[remote-dir][local-file]:显示远程主机目录的文件清单,并存入本地硬盘的local-file。
39. nmap[inpattern outpattern]:设置文件名映射机制, 使得文件传输时,文件中的某些字符相互转换,如:nmap $1.$2.$3[$1,$2].[$2,$3],则传输文件a1.a2.a3时,文件名变为a1,a2。该命令特别适用于远程主机为非UNIX机的情况。
40. ntrans[inchars[outchars]]:设置文件名字符的翻译机制,如ntrans1R,则文件名LLL将变为RRR。
41. open host[port]:建立指定ftp服务器连接,可指定连接端口。
42. passive:进入被动传输方式。
43. prompt:设置多个文件传输时的交互提示。
44. proxy ftp-cmd:在次要控制连接中,执行一条ftp命令,该命令允许连接两个ftp服务器,以在两个服务器间传输文件。第一条ftp命令必须为open,以首先建立两个服务器间的连接。
45. put local-file[remote-file]:将本地文件local-file传送至远程主机。
46. pwd:显示远程主机的当前工作目录。
47. quit:同bye,退出ftp会话。
48. quote arg1,arg2...:将参数逐字发至远程ftp服务器,如:quote syst。
49. recv remote-file[local-file]:同get。
50. reget remote-file[local-file]:类似于get,但若local-file存在,则从上次传输中断处续传。
51. rhelp[cmd-name]:请求获得远程主机的帮助。
52. rstatus[file-name]:若未指定文件名,则显示远程主机的状态,否则显示文件状态。
53. rename[from][to]:更改远程主机文件名。
54. reset:清除回答队列。
55. restart marker:从指定的标志marker处,重新开始get或put,如:restart 130。
56. rmdir dir-name:删除远程主机目录。
57. runique:设置文件名唯一性存储。
58. send local-file[remote-file]:同put。
59. sendport:设置PORT命令的使用。
60. site arg1,arg2...:将参数作为SITE命令逐字发送至远程ftp主机。
61. size file-name:显示远程主机文件大小,如:site idle 7200。
62. status:显示当前ftp状态。
63. struct[struct-name]:将文件传输结构设置为struct-name,缺省时使用stream结构。
64. sunique:将远程主机文件名存储设置为唯一(与runique对应)。
65. system:显示远程主机的操作系统类型。
66. tenex:将文件传输类型设置为TENEX机的所需的类型。
67. tick:设置传输时的字节计数器。
68. trace:设置包跟踪。
69. type[type-name]:设置文件传输类型为type-name,缺省为ascii,如:type binary,设置二进制传输方式。
70. umask[newmask]:将远程服务器的缺省umask设置为newmask,如:umask 3。
71. user user-name[password][account]:向远程主机表明自己的身份,需要口令时,必须输入口令,如:user anonymous my@email。
72. verbose:同命令行的-v参数,即设置详尽报告方式,ftp服务器的所有响应都将显示给用户,缺省为on。
73. ?[cmd]:同help。
AID编者附注:如果服务器支持,可以使用quote "site pswd oldpassword newpassword"来修改密码
四 Linux的常用网络命令
作者:杨文军 日期:2006-04-05
Valgrind是x86架构Linux上的多重用途代码剖析和内存调试工具。你可以在它的环境中运行你的程序来监视内存的使用情况,比如C语言中的malloc和free或者C++中的new和delete。如果你使用了未初始化内存,在数组末端外设置内存或是忘记释放指针,Valgrind都可以检测出来。尽管Valgrind还可以做其它的工作,本教程仍然集中在如何使用它来发现内存相关错误,因为这也程序员经常出现的错误。
Windows用户不必沮丧,虽然在Windows上没有Valgrind可用,但是你可以试一试IBM的 Purify,它在功能上和Valgrind相似。
获得Valgrind
如果你正使用Linux但却没有安装Valgrind,可以去 这里免费下载一份。
安装过程非常简单,只需要用bzip2解压缩下载的软件包并将其展开即可(下面例子中的XYZ是版本号)。
bzip2 -d valgrind-XYZ.tar.bz2
tar -xf valgrind-XYZ.tar
或者用更简单的方法:
tar jxf valgrind-XYZ.tar.bz2
这会创建一个叫valgrind-XYZ的目录,进入该目录并运行
./configure
make
make install
好了,现在你已经安装了Valgrind,可以开始了解如何用它了。
用Valgrind查找内存泄漏
内存泄漏是最难发现的常见错误之一,因为除非用完内存或调用malloc失败,否则都不会导致任何问题。实际上,使用像C或C++这类没有垃圾回收机制的语言时,你一大半的时间都花费在处理如何正确释放内存上。如果程序运行时间足够长,一个小小的失误也会对程序造成重大的影响。
Valgrind支持很多工具:Memcheck,Addrcheck,Cachegrind,Massif,Helgrind和Callgrind等。在运行Valgrind时,你必须指明想用的工具。在这篇教程中,我们主要集中在内存检查工具上,它可以帮助我们检查内存使用情况(呵呵,其它工具我也不会用)。如果没有其它参数,Valgrind在程序结束后给出关于free和malloc总共调用次数的简报:(注意,18490是进程号,你的机器上可能是其它值)
% valgrind --tool=memcheck program_name
...
=18515== malloc/free: in use at exit: 0 bytes in 0 blocks.
==18515== malloc/free: 1 allocs, 1 frees, 10 bytes allocated.
==18515== For a detailed leak analysis, rerun with: --leak-check=yes
如果程序中有内存泄漏的现象,内存分配的数量和内存释放的数量会不一致(你不能使用一个free调用来释放多个分配的内存)。
如果程序内存分配和释放的数量不一致,你可以加上leak-check参数重新运行程序,这样就可以看见分配了内存但却没有释放的代码。
为了演示这个功能,我写了一个简单的C程序并编译生成"example1"应用。
#include
int main()
{
char *x = malloc(100); /* or, in C++, "char *x = new char[100] */
return 0;
}
% valgrind --tool=memcheck --leak-check=yes example1
在运行结果中,给出了调用malloc却没有调用free的函数列表。
==2116== 100 bytes in 1 blocks are definitely lost in loss record 1 of 1
==2116== at 0x1B900DD0: malloc (vg_replace_malloc.c:131)
==2116== by 0x804840F: main (in /home/cprogram/example1)
上面的结果并没有告诉我们更多需要的信息,我们只知道在main函数中的malloc调用导致了内存泄漏,但并不知道是程序中的哪一行调用了malloc。这是因为我们在编译程序时,没有给gcc加上-g参数,相关的调试信息就丢失了。重编一次再运行,我们就得到了更多的信息(片断)。
==2330== 100 bytes in 1 blocks are definitely lost in loss record 1 of 1
==2330== at 0x1B900DD0: malloc (vg_replace_malloc.c:131)
==2330== by 0x804840F: main (example1.c:5)
现在我们已经确切知道导致内存泄漏的是哪一行代码了。尽管知道在哪里释放内存仍然是一个问题,至少我们已经知道该从哪里入手。因为对每一次需要动态分配的内存,你都有一个何时分配,何时释放的使用计划,既然已经知道导致内存泄漏的分配点,也就基本理清了内存的使用计划,有助于定位正确释放内存的位置。
在加上--leak-check=yes参数后不再显示内存泄漏错误前,你可能需要重复修改代码很多次,一个优秀的,没有内存泄漏的软件就是这样诞生的:-)。在运行Valgrind时加上--show-reachable=yes参数,可以找到每一个未来匹配的free或new,输出结果和上面差不多,不过显示了更多未释放的内存。
用Valgrind查找无效指针使用
用memcheck工具,Valgrind也可以找出无效堆内存使用。比如,如果你用malloc或new分配了一个数组,并访问数组末端后面的内存:
char *x = malloc(10);
x[10] = ´a´;
Valgrind可以检测出这个错误。用Valgrind运行下面的示例程序:example2
#include
int main()
{
char *x = malloc(10);
x[10] = ´a´;
return 0;
}
%valgrind --tool=memcheck --leak-check=yes example2
其结果是(片断)
==9814== Invalid write of size 1
==9814== at 0x804841E: main (tst.c:6)
==9814== Address 0x1BA3607A is 0 bytes after a block of size 10 alloc´d
==9814== at 0x1B900DD0: malloc (vg_replace_malloc.c:131)
==9814== by 0x804840F: main (example2.c:5)
这个信息表明我们分配了10字节的内存,但是访问了超出范围的内存,因此,我们就进行了一个´非法写´操作。如果试图从那块内存读取数据,我们就会得到´Invalid read of size X´的警告(X是试图读取数据的大小,char是一个字节,而int根据系统的不同可能是2个字节或4个字节)。通常,Valgrind显示出函数调用栈信息以方便我们准确定位错误。
检测使用未初始化变量
还有一类Valgrind可以检测的操作是在条件判断语句中使用未初始化变量。也许你应该养成在声明变量时就进行初始化的习惯,不过Valgrind仍然可以帮助你找出使用未初始化变量的地方。比如,运行下面代码生成的示例程序,example3
#include
int main()
{
int x;
if(x == 0)
{
printf("X is zero"); /* replace with cout and include
iostream for C++ */
}
return 0;
}
Valgrind会给出下面的结果(片断)
==17943== Conditional jump or move depends on uninitialised value(s)
==17943== at 0x804840A: main (example3.c:6)
Valgrind甚至可以知道如果一个变量被赋予一个未初始化的变量,这个变量仍然处于"未初始化"状态。比如运行下列代码:
#include
int foo(int x)
{
if(x < 10)
{
printf("x is less than 10/n");
}
}
int main()
{
int y;
foo(y);
}
Valgrind会给出下列警告:
==4827== Conditional jump or move depends on uninitialised value(s)
==4827== at 0x8048366: foo (example4.c:5)
==4827== by 0x8048394: main (example4.c:14)
你可能以为错误在foo中,和调用栈上的其它函数没有关系。但是因为main函数传递了一个未初始化值给foo,我们可以根据调用栈信息顺藤摸瓜,找到真正没有初始化变量的代码。
Valgrind仅仅有助于你在能够运行到代码中检测这些错误,请确信在测试中覆盖代码的每一个分支。
Valgrind还能发现什么?
Valgrind还能发现其它不正确使用内存的错误:如果你对同一块内存释放了两次,Valgrind就会探测到,而你则得到非法free的调用栈信息。
Valgrind也能检测到使用不正确方法释放内存的错误。比如,在C++语言中有三种基本的内存释放方法:free,delete和delete[]。free函数应该仅与malloc函数相对应--在一些系统上,你可能无须面对这个问题,但这样不具备可移植性。delete[]应该又只能和new[](分配数组)相对应。(也许有些编译器允许你不去理会这些规则,但不能保证所有的编译器都允许你这样做,毕竟它不是标准的一部分。)
如果程序中存在这些问题,你会得到下列错误信息:
Mismatched free() / delete / delete []
这些错误都应该被立刻修复,即使你的程序偶然能够正常运行。
Valgrind不能查出哪些错误?
Valgrind不对静态数组(分配在栈上)进行边界检查。如果在程序中声明了一个数组:
int main()
{
char x[10];
x[11] = ´a´;
}
Valgrind则不会警告你!出于测试目的,你可以把数组改为动态在堆上分配的数组,这样就可能进行边界检查了。这个方法好像有点得不偿失的感觉。
更多告诫
使用Valgrind的负面影响是什么?它占用了更多的内存--可达两倍于你程序的正常使用量。如果你用Valgrind来检测使用大量内存的程序就会遇到问题,它可能会用很长的时间来运行测试。大多数情况下,这都不是问题,即使速度慢也仅是检测时速度慢,如果你用Valgrind来检测一个正常运行时速度就很慢的程序,这下问题就大了。
Valgrind不可能检测出你在程序中犯下的所有错误--如果你不检查缓冲区溢出,Valgrind也不会告诉你代码写了它不应该写的内存。
总结
Valgrind是x86架构上的工具,只能在Linux上运行(FreeBSD和NetBSD上的相关版本正在开发中)。它允许程序员在它的环境里测试程序以检测未配对malloc调用错误和其它使用非法内存(未初始化内存)的错误以及非法内存操作(比如同一块内存释放两次或调用不正确的析构函数)。Valgrind不检查静态分配数组的使用情况。
七 nm命令
nm命令 list symbols from object files
2006年07月09日 21:08
例:
nm -a a.out
nm -a func.o
list symbols from object files
例:
080480f4 ?
08048108 ?
08048128 ?
08048174 ?
08048254 ?
08048334 ?
08048350 ?
08048370 ?
08048378 ?
08048398 ?
080483b0 ?
08048400 t
08048590 ?
080485c0 r
080496e0 d
080496f0 ?
080496f4 ?
080497cc ?
080497d4 ?
080497dc ?
080497fc b
00000000 ?
00000000 ?
00000000 ?
00000000 ?
00000000 a
00000000 a
00000000 a
080496f4 A _DYNAMIC
080497dc A _GLOBAL_OFFSET_TABLE_
080485c4 R _IO_stdin_used
080497d0 ? __CTOR_END__
080497cc ? __CTOR_LIST__
080497d8 ? __DTOR_END__
080497d4 ? __DTOR_LIST__
080496f0 ? __EH_FRAME_BEGIN__
080496f0 ? __FRAME_END__
080497fc A __bss_start
080496e0 D __data_start
w __deregister_frame_info
08048550 t __do_global_ctors_aux
08048450 t __do_global_dtors_aux
w __gmon_start__
U __libc_start_main@@GLIBC_2.0
w __register_frame_info
080497fc A _edata
08049814 A _end
08048590 ? _fini
080485c0 R _fp_hw
08048398 ? _init
08048400 T _start
08048424 t call_gmon_start
080496ec d completed.1
00000000 a crtstuff.c
00000000 a crtstuff.c
080496e0 W data_start
080484b0 t fini_dummy
080496f0 d force_to_data
080496f0 d force_to_data
080484c0 t frame_dummy
08048424 t gcc2_compiled.
08048450 t gcc2_compiled.
08048550 t gcc2_compiled.
08048590 t gcc2_compiled.
08048500 t gcc2_compiled.
00000000 a init.c
080484f0 t init_dummy
08048580 t init_dummy
00000000 a initfini.c
00000000 a initfini.c
00000000 a long.c
08048500 T main
080497fc b object.2
080496e8 d p.0
U printf@@GLIBC_2.0
|