linux查询进程命令stap,linux systemtap, stap++使用

66b52468c121889b900d4956032f1009.png

8种机械键盘轴体对比

本人程序员,要买一个写代码的键盘,请问红轴和茶轴怎么选?

说明

介绍systemtap, stap++的一些使用方式,以及总结了一些遇到的坑点

systemtap介绍

systemtap跟perf一样也是一个linux下的性能分析工具,但它提供自定义脚本编写,所以功能会比perf更强大。

快速了解systemptab功能

最简单的systemtab脚本1

2

3

4

5probe begin

{

print("hello worldn")

exit()

}

执行结果

1

2[email protected]:~/systab$ sudo stap hello-world.stp

hello world

probe begin指定了一个begin的追踪点,脚本实际上做的就是定义一些列追踪点。systemtap将脚本翻译成C,并将其编译成一个内核的模块加载到内核。一旦被加载则脚本中所有指定的追踪点会在运行的时候被回调。下面列举了一些systemtap提供的追踪点:begin:此次检测开始被回调

end: 此次检测结束被回调

kernel.function(“sys_open”): 内核函数sys_open进入时候被回调

syscall.close.return: 系统调用close返回时候被回调

timer.ms(200): 定时器,每200ms回调一次

timer.profile: 定时器,每个system tick回调一次

perf.hw.cache_misses: cache miss的时候回调

另一个例子1

2

3

4

5

6

7

8probe syscall.open

{

printf("%s"(%d) open (%s)n", execname(), pid(), argstr)

}

probe time.ms(4000)

{

exit()

}

执行结果

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24[email protected]:~/systab$ vi strace-open.stp

[email protected]:~/systab$ sudo stap ./strace-open.stp

redis-server(24453) open ("/proc/24453/stat", O_RDONLY)

bot(28026) open ("/proc/self/stat", O_RDONLY)

bot(28026) open ("/proc/stat", O_RDONLY)

redis-server(24453) open ("/proc/24453/stat", O_RDONLY)

redis-server(24453) open ("/proc/24453/stat", O_RDONLY)

tail(3649) open ("logs/zqc/gameapp.3.INFO", O_RDONLY|O_NONBLOCK)

tail(3651) open ("logs/zqc/gameapp.5.INFO", O_RDONLY|O_NONBLOCK)

mgrapp(3845) open ("/proc/self/stat", O_RDONLY)

mgrapp(3845) open ("/proc/stat", O_RDONLY)

tail(3652) open ("logs/zqc/gateapp.2.INFO", O_RDONLY|O_NONBLOCK)

tail(3650) open ("logs/zqc/gameapp.4.INFO", O_RDONLY|O_NONBLOCK)

mgrapp(11899) open ("/proc/self/stat", O_RDONLY)

mgrapp(11899) open ("/proc/stat", O_RDONLY)

gateapp(3849) open ("/proc/self/stat", O_RDONLY)

gateapp(3849) open ("/proc/stat", O_RDONLY)

gateapp(11903) open ("/proc/self/stat", O_RDONLY)

gateapp(11903) open ("/proc/stat", O_RDONLY)

loginapp(3847) open ("/proc/self/stat", O_RDONLY)

loginapp(3847) open ("/proc/stat", O_RDONLY)

redis-server(24453) open ("/proc/24453/stat", O_RDONLY)

gameapp(3855) open ("/proc/self/stat", O_RDONLY)

...

printf是一个格式化打印函数,可以打印自己脚本定义的变量,或者systemtap提供的获取信息的函数或变量:tid(): 当前线程id

pid(): 当前进程id

uid(): 当前用户id

execname(): 进程的名字

cpu(): 当前cpu number

gettimeofday_s(): 当前时间戳

pp(): 描述当前追踪点的字符串

ppfunc(): 当前追踪点被触发的函数,如果存在的话

print_backtrace(): 直接输出内核态堆栈

print_ubacktrace(): 直接输出用户态堆栈

systemtap脚本语法

普通语法和C语言差不多,这里介绍下不太一样的地方,其他具体可以查看官方教程,或者这个简化版的教程

数组

数组非常方便,内部使用hash table实现,数组大小除非显示指定,否则都定义为一个预先定义好的大小。多维可以直接用’,’分割即可,例如:

1

2

3

4

5

6

7

8

9

10

11names[400] // 大小位400的数组

...

foreach (name in names) {

// do something

}

foo[1, "200"] = 1

foo[2, "200"] = 2

foreach ([id, str] in foo) {

// do something

}

这里有个方便的地方当数组元素不存在的时候返回的是0,所以计数的时候就非常方便,可以直接使用bts[ubacktrace()]++计数

stap++介绍

stap++是一个stap扩展,提供一些类似于宏的功能,最后将宏替换后生成的systemtap脚本,并调用systemtap执行。

stap++使得systemtap的脚本可以得到进一步扩展。

sample-bt.sxx(perf record)1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53#!/usr/bin/env stap++

/*

* Copyright (C) Yichun Zhang (agentzh)

*/

global bts;

global quit = 0

probe timer.profile {

if ($^pid_ok) { // pid是否相等

%( "$^arg_execname :default()" != "" %?

if (execname() == "$^arg_execname") { // 进程名是否相等,如果存在的话

%)

if (!quit) {

bts[ubacktrace()] <<< 1 // 计数,这里有个大坑,如果采样时间长会导致消耗巨量内存,可以改用bts[ubacktrace()]++优化

} else {

foreach (usr in bts- limit $^arg_limit :default(1000)) {

print_ustack(usr)

printf("t%dn", @count(bts[usr])) // 打印堆栈和数量,如果上面改为bts[ubacktrace()]++,这里可以直接输出bts[usr]的值

}

exit()

}

%( "$^arg_execname :default()" != "" %?

}

%)

}

}

probe timer.s($^arg_time) {

nstacks = 0

foreach (bt in bts limit 1) {

nstacks++

}

if (nstacks == 0) {

warn("No backtraces found. Quitting now...n")

exit()

} else {

warn("Time's up. Quitting now...(it may take a while)n")

quit = 1

}

}

probe begin {

warn(sprintf("Start tracing process $^target ($^exec_path)...n"))

}

这脚本实现了perf record功能,统计了每次采样的堆栈。

命令执行方式,其中PID是需要进行采样的进程id

1sudo ./stap++ samples/sample-bt.sxx -x PID -D MAXMAPENTRIES=102400 -D MAXBACKTRACE=100 -D MAXSTRINGLEN=4096 -D MAXACTION=100000 -D STP_OVERLOAD_THRESHOLD=5000000000 -D MAXSKIPPED=100000 --arg time=60 > ~/cpp.bt

采样之后可以使用命令cat ~/cpp.bt|c++filt|~/FlameGraph/stackcollapse-stap.pl|~/sysperf/FlameGraph/flamegraph.pl > ~/cpp.svg生成火焰图

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值