linux基础 linux命令跟踪 strace命令

原文:

(909条消息) Linux之strace命令_风华浪浪的博客-CSDN博客_linux strace

trace :监控程序的执行状况
在linux 空间下,运行一个程序时,操作系统会将应用程序封装一个进程的形式,参与操作系统的调度,可以使用strace 跟踪程序运行的情况。

基本功能
监控用户进程与内核进程的交互
追踪进程的系统调用、信号传递、状态变化
一、系统调用
分类
文件和设备访问:open、close、read、write、ioctl等
进程管理:fork、clone、execve、exit 等
信号:signal、kill等
内存管理:brk、mmap、mlock等
进程间通信:semget、信号量、消息队列
网络通信:socket、connect等
常用参数
-c   统计每一系统调用的所执行的时间,次数和出错的次数等
-d   输出strace关于标准错误的调试信息
-f   跟踪由目标进程及调用所产生的子进程
-F   尝试跟踪目标调用 在-f时,vfork不被跟踪
-a   设置返回值的输出位置.默认 为40
-r   打印出相对时间关于每一个系统调用
-t   在每行输出的后面,显示调用花费时间
-tt  在每行输出的前面,显示调用花费毫秒级别的时间
-T   每次系统调用所花费的时间
-v   对某些相关调用,把完整的环境变量、文件stat结构打印出来
-p pid  指定要跟踪的进程pid,同时跟踪的多个pid,重复多次-p选项即可
-o filename: 将跟踪输出写入文件名
-s 当系统调用的某个参数是字符串时,最多输出制定长度的内容,默认时32个字节 

-e set: 仅跟踪某些系统调用
-e open,close: 仅跟踪打开/关闭系统调用
-e file: 仅跟踪文件系统调用/文件操作相关的
-e process: 跟踪所有涉及流程管理的系统调用
-e network: 跟踪所有与网络相关的系统调用
-e signal:跟踪所有与信号相关的系统调用
-e ipc: 跟踪所有与ipc相关的系统调用
-e desc: 跟踪所有与文件描述符相关的系统调用
-e memory: 跟踪所有与内存映射相关的系统调用
-e set: 仅跟踪指定的信号子集


示例《一》
查看一个程序所有的open、close系统调用
查看每个程序调用消耗的时间
统计系统调用次数、错误次数统计
打印系统调用的时间戳
将追踪日志保存到log文件中
注释:

 查看所有程序运行  strace python server.py
 查看所有程序运行  strace ./aa.sh
 
 查看打开系统调用情况     strace -e open ./aa.sh
 查看打开关闭系统调用情况  strace -e open,close ./aa.sh
 查看打开关闭系统调用时间  strace -T -e open,close python3 main.py (T 时间在后面显示)

 查看打开关闭系统调用次数  strace -c -T -e open,close ./aa.sh (如程序一直在运行,停止后才会统计)
 查看打开关闭系统调用时间  strace -t -T -e open,close ./aa.sh  
 查看打开关闭系统调用时间  strace -tt -T -e open,close ./aa.sh  (tt 
 查看打开系统调用输入log  strace -tt -T -e open -o trace.log ./aa.sh  (-o 输入trace.log文件)

strace -tt -T -V -e trace=file -o /data/log/trace.log -s 1024 -p 23489

二、系统调用函数说明
进程管理

函数名    说明
fork    创建一个新进程
clone    按制定条件创建子进程
execve    运行可执行文件
pause    进程将处于阻塞状态
wait    等待子进程终止
waitpid    等待制定子进程终止
文件和设备访问

函数名    说明
open    打开文件
create    创建新文件
close    关闭文件描述符
read    读文件
write    写文件
pread    对文件随机读
pwrite    对文件随机写
poll    I/o多路转换
truncate    截断文件
文件系统操作

函数名    说明
access    确定文件的可存取性
chmod    确定文件的可存取性
chown    改变文件的属主或用户组
chroot    改变文件状态信息
stat    获取文件的状态信息
lstat    获取文件的状态信息
getdents    读取目录项
mkdir    创建目录
link    建立链接
内存管理

函数名    说明
mmap    映射虚拟内存页(分配内存)
sync    将内存缓冲区数据写回硬盘
socket 控制

函数名    说明
socketcall    socket系统调用
socket    建立socket
bind    绑定socket到端口
connect    链接远程主机
send    通过socket发送信息
sendto    发送UDP信息
sendmsg    参见send
listen    监听socket端口
select    对多路同步I/O进行轮询
示例《二》
ping baidu系统调用过程

ping www.baidu.com
strace ping www.baidu.com
strace -e poll,select,connect,sendto ping www.baidu.com
1
2
3
cat /etc/passwd 系统调用过程

strace cat /etc/passwd
1
[root@VM-0-14-centos ~]# strace cat /etc/passwd

运行命令
execve("/usr/bin/cat", ["cat", "/etc/passwd"], 0x7ffeee8bfe78 /* 28 vars */) = 0
brk(NULL)                               = 0x1d9f000

为运行命名分配内存空间
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f6081756000

确定文件的可存取性 -1 表示文件不可读
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (没有那个文件或目录)

打开文件 
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3

文件状态:作用于已打开的文件的文件描述符而不是文件名
fstat(3, {st_mode=S_IFREG|0644, st_size=37645, ...}) = 0
mmap(NULL, 37645, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f608174c000
close(3)                                = 0
open("/lib64/libc.so.6", O_RDONLY|O_CLOEXEC) = 3

读取文件
read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0`&\2\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=2156352, ...}) = 0
mmap(NULL, 3985920, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f6081168000

参见下文mprotect 命令
mprotect(0x7f608132c000, 2093056, PROT_NONE) = 0
mmap(0x7f608152b000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1c3000) = 0x7f608152b000
mmap(0x7f6081531000, 16896, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f6081531000
close(3)                                = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f608174b000
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f6081749000
arch_prctl(ARCH_SET_FS, 0x7f6081749740) = 0
mprotect(0x7f608152b000, 16384, PROT_READ) = 0
mprotect(0x60b000, 4096, PROT_READ)     = 0
mprotect(0x7f6081757000, 4096, PROT_READ) = 0
munmap(0x7f608174c000, 37645)           = 0
brk(NULL)                               = 0x1d9f000
brk(0x1dc0000)                          = 0x1dc0000
brk(NULL)                               = 0x1dc0000
open("/usr/lib/locale/locale-archive", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=106176928, ...}) = 0
mmap(NULL, 106176928, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f607ac25000
close(3)                                = 0
fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 0), ...}) = 0
open("/etc/passwd", O_RDONLY)           = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=1419, ...}) = 0
fadvise64(3, 0, 0, POSIX_FADV_SEQUENTIAL) = 0
read(3, "root:x:0:0:root:/root:/bin/bash\n"..., 65536) = 1419
write(1, "root:x:0:0:root:/root:/bin/bash\n"..., 1419root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin
systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin
polkitd:x:999:998:User for polkitd:/:/sbin/nologin
libstoragemgmt:x:998:997:daemon account for libstoragemgmt:/var/run/lsm:/sbin/nologin
rpc:x:32:32:Rpcbind Daemon:/var/lib/rpcbind:/sbin/nologin
ntp:x:38:38::/etc/ntp:/sbin/nologin
abrt:x:173:173::/etc/abrt:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
chrony:x:997:995::/var/lib/chrony:/sbin/nologin
tcpdump:x:72:72::/:/sbin/nologin
syslog:x:996:994::/home/syslog:/bin/false
mysql:x:27:27:MySQL Server:/var/lib/mysql:/bin/false
tss:x:59:59:Account used by the trousers package to sandbox the tcsd daemon:/dev/null:/sbin/nologin
nginx:x:995:991:nginx user:/var/cache/nginx:/sbin/nologin
redis:x:994:990:Redis Database Server:/var/lib/redis:/sbin/nologin
) = 1419
read(3, "", 65536)                      = 0
close(3)                                = 0
close(1)                                = 0
close(2)                                = 0
exit_group(0)                           = ?
+++ exited with 0 +++



三、其他
在Linux中,mprotect()函数可以用来修改一段指定内存区域的保护属性。
函数原型如下:

#include <unistd.h>
#include <sys/mmap.h>
int mprotect(const void *start, size_t len, int prot);
mprotect()
函数把自start开始的、长度为len的内存区的保护属性修改为prot指定的值。

prot可以取以下几个值,并且可以用“|”将几个属性合起来使用:
1)PROT_READ:表示内存段内的内容可写;
2)PROT_WRITE:表示内存段内的内容可读;
3)PROT_EXEC:表示内存段中的内容可执行;
4)PROT_NONE:表示内存段中的内容根本没法访问。

需要指出的是,指定的内存区间必须包含整个内存页(4K)。区间开始的地址start必须是一个内存页的起始地址,并且区间长度len必须是页大小
————————————————
版权声明:本文为CSDN博主「风华浪浪」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/a6864657/article/details/123915757

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值