LINUX下重量级的命令strace使用介绍(原创)

LINUX下重量级的命令strace使用介绍(原创)作者:余超 Email:yuchao86@gmail.com经常使用LINUX的朋友或许经常会疑问:linux是怎么样执行一条命令并得到正确输出结果的呢?比如你输入一个pwd,得到的是当前路径,输入一个env显示的是系统环境变量等等,那你想知道他们是怎么样执行的吗?go ahead!!首先:我们先看下一个重量级的系统调用函数execve(),具体的参数和返回值请大家使用man execve命令来查询吧。如下程序就是来自实例文档:[yuchao@yuchao-Latitude-E5410 scons]$cat yuexe.c#include <stdio.h>#include <stdlib.h>#include <unistd.h>intmain(int argc, char *argv[]){ char *newargv[] = { NULL, "hello", "world", NULL }; char *newenviron[] = { NULL }; if (argc != 2) { fprintf(stderr, "Usage: %s <file-to-exec>\n", argv[0]); exit(EXIT_FAILURE); } newargv[0] = argv[1]; execve(argv[1], newargv, newenviron); perror("execve"); /* execve() only returns on error */ exit(EXIT_FAILURE);}编译成功后可以得到可执行文件:yuexe[yuchao@yuchao-Latitude-E5410 scons]$lsgrap.c Hello helloscons.c helloscons.o helloSina.h SConstruct weibo.h yuexe yuexe.c yuexe.o查看命令yuexe执行Hello程序的内核调用过程如下:[yuchao@yuchao-Latitude-E5410 scons]$sudo strace ./yuexe Hello[sudo] password for yuchao:execve("./yuexe", ["./yuexe", "Hello"], [/* 17 vars */]) = 0brk(0) = 0x84e3000access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)mmap2(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb77b6000access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)open("/etc/ld.so.cache", O_RDONLY) = 3fstat64(3, {st_mode=S_IFREG|0644, st_size=103314, …}) = 0mmap2(NULL, 103314, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb779c000close(3) = 0access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)open("/lib/libc.so.6", O_RDONLY) = 3read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0@n\1\0004\0\0\0"…, 512) = 512fstat64(3, {st_mode=S_IFREG|0755, st_size=1421892, …}) = 0mmap2(NULL, 1427880, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x45f000mmap2(0x5b6000, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x157) = 0x5b6000mmap2(0x5b9000, 10664, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x5b9000close(3) = 0mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb779b000set_thread_area({entry_number:-1 -> 6, base_addr:0xb779b6c0, limit:1048575, seg_32bit:1, contents:0, read_exec_only:0, limit_in_pages:1, seg_not_present:0, useable:1}) = 0mprotect(0x5b6000, 8192, PROT_READ) = 0mprotect(0x8049000, 4096, PROT_READ) = 0mprotect(0xd3f000, 4096, PROT_READ) = 0munmap(0xb779c000, 103314) = 0execve("Hello", ["Hello", "hello", "world"], [/* 0 vars */]) = 0brk(0) = 0x8cf0000access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)mmap2(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb77fb000access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)open("/etc/ld.so.cache", O_RDONLY) = 3fstat64(3, {st_mode=S_IFREG|0644, st_size=103314, …}) = 0mmap2(NULL, 103314, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb77e1000close(3) = 0access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)open("/lib/libc.so.6", O_RDONLY) = 3read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0@n\1\0004\0\0\0"…, 512) = 512fstat64(3, {st_mode=S_IFREG|0755, st_size=1421892, …}) = 0mmap2(NULL, 1427880, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xb3c000mmap2(0xc93000, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x157) = 0xc93000mmap2(0xc96000, 10664, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0xc96000close(3) = 0mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb77e0000set_thread_area({entry_number:-1 -> 6, base_addr:0xb77e06c0, limit:1048575, seg_32bit:1, contents:0, read_exec_only:0, limit_in_pages:1, seg_not_present:0, useable:1}) = 0mprotect(0xc93000, 8192, PROT_READ) = 0mprotect(0x8049000, 4096, PROT_READ) = 0mprotect(0xb1c000, 4096, PROT_READ) = 0munmap(0xb77e1000, 103314) = 0fstat64(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 5), …}) = 0mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb77fa000write(1, "Hell Scons,I’m YuChao\n", 22Hell Scons,I’m YuChao) = 22write(1, "Hello SINA,I’m YuChao\n", 22Hello SINA,I’m YuChao) = 22write(1, "Hell weibo,I’m YuChao\n", 22Hell weibo,I’m YuChao) = 22exit_group(0) = ?[yuchao@yuchao-Latitude-E5410 scons]$到这里可以看得很清楚,美国系统调用的过程,由于linux内核不允许用户态进程直接访问硬件资源,当用户进程需要访问系统硬件资源时采用系统调用,美国系统调用都有调用参数和返回值,如果想了解系统调用的具体含义请man 之。。如上可以看到:write(1,“Hell Scons,I’m YuChao\n",22 Hell Scons…..等等另外,这个命令还可以用于优化系统网络时候使用,用于调用时候的效率考虑,用参数:strace -c ***可以看到具体的进程调用统计情况。比如我查看我的本地web服务器的启动执行的内核调用过程:$sudo strace -i -q -r -f -F -v -T -o strace_start strace /opt/lampp/lampp start通过strace -c统计监控你的优化是否生效:$sudo strace -c -o count_file /opt/lampp/lampp start最后,当发生个http请求的时候,很多时候希望得到这个http请求发生了多少次数据库SELECT操作,是否在同一个mysql connection连接里面完成。命令使用如下://-10321是mysqld的进程号,为了看到整条SQL语句,我们通过-s 1024希望输出更多内容#strace -f -F -ff -o strace-mysqld -s 1024 -p 10321#find . -name "strace-mysqld*" -type f -print |xargs grep -n "SELECT.*FROM wp_"./strace-mysqld.19203:64:read(19, "\3SELECT option_name, option_value FROM wp_options WHERE autoload = ‘yes’", 72) = 72./strace-mysqld.19203:165:read(19, "\3SELECT * FROM wp_users WHERE user_login = ‘admin’", 50) = 50./strace-mysqld.19203:184:read(19, "\3SELECT meta_key, meta_value FROM wp_usermeta WHERE user_id = 1", 63) = 63./strace-mysqld.19203:295:read(19, "\3SELECT option_value FROM wp_options WHERE option_name = ‘rewrite_rules’ LIMIT 1", 80) = 80./strace-mysqld.19203:311:read(19, "\3 SELECT wp_posts.* FROM wp_posts WHERE 1=1 AND wp_posts.ID = 501 AND wp_posts.post_type = ‘post’ ORDER BY wp_posts.post_date DESC ", 136) = 136… (这里省去了一些)通过如上的演示,你或许也看到了这个命令的厉害了,只能说linux是open的,你喜欢怎么做就怎么做,

不行你就去修改linux kernel来打造自己的版本吧,如果你再配合gdb来使用,就更high了。。

这里的风景美不胜收,真让人流连忘返。

LINUX下重量级的命令strace使用介绍(原创)

相关文章:

你感兴趣的文章:

标签云: