Systemtap Special probe points (begin, end, error, never)

3 minute read

背景

The probe points begin and end are defined by the translator to refer to the time of session startup and shutdown.

There are no target variables available in either context.

begin和end探针在stap会话开始和结束时触发, 显然这类探针没有target variable.

4.11.1 begin  
The begin probe is the start of the SystemTap session. All begin probe handlers are run during the startup of the session.  
  
4.11.2 end  
The end probe is the end of the SystemTap session.   
All end probes are run during the normal shutdown of a session, such as in the aftermath of a SystemTap exit() function call, or an interruption from the user.   
In the case of an shutdown triggered by error, end probes are not run.  

end探针在正常的会话退出时触发, 如果是发生错误的情况下退出stap会话, 那么不会触发end探针, 这种情况下如果启用了error探针那么会触发error探针.

例如 :

[root@db-172-16-3-39 ~]# stap -e 'probe begin {exit()} probe end {printf("endprobe\n") }'  
endprobe  

exit()函数被调用后, 触发end探针.

如下用户使用Ctrl+C退出stap进程, 也会触发end探针.

[root@db-172-16-3-39 ~]# stap -e 'probe end {printf("endprobe\n") }'  
endprobe  

使用kill 关闭stap进程, 触发end探针.

[root@db-172-16-3-39 ~]# stap -e 'probe end {printf("endprobe\n") }'  
  
[root@db-172-16-3-39 ~]# ps -ewf|grep stap  
root     19895 18140  2 20:35 pts/1    00:00:00 stap -e probe end {printf("endprobe\n") }  
root     19896 19895  0 20:35 pts/1    00:00:00 /usr/libexec/systemtap/stapio -R stap_3b85e14e7aa8d5cc9dc48f854a127851_612  
root     19910 18273  0 20:35 pts/2    00:00:00 grep stap  
[root@db-172-16-3-39 ~]# kill 19895  

探针handler输出 :

endprobe  

使用kill-9 关闭stap进程, 不会触发end探针.

[root@db-172-16-3-39 ~]# stap -e 'probe end {printf("endprobe\n") }'  
  
[root@db-172-16-3-39 ~]# ps -ewf|grep stap  
root     19946 18140  4 20:35 pts/1    00:00:00 stap -e probe end {printf("endprobe\n") }  
root     19947 19946  0 20:35 pts/1    00:00:00 /usr/libexec/systemtap/stapio -R stap_3b85e14e7aa8d5cc9dc48f854a127851_612  
root     19960 18273  0 20:35 pts/2    00:00:00 grep stap  
[root@db-172-16-3-39 ~]# kill -9 19946  

探针handler输出 :

Killed  

注意 : 使用kill -9 杀死stap进程会造成stap临时模块无法卸载.

[root@db-172-16-3-39 ~]# stap -e 'probe end {printf("endprobe\n") }'  
Error inserting module '/tmp/stapj6rK9K/stap_3b85e14e7aa8d5cc9dc48f854a127851_612.ko': File exists  
WARNING: /usr/bin/staprun exited with status: 1  
Pass 5: run failed.  Try again with another '--vp 00001' option.  
[root@db-172-16-3-39 ~]# lsmod|grep stap  
stap_3b85e14e7aa8d5cc9dc48f854a127851_612    68864  2   
[root@db-172-16-3-39 ~]# rmmod stap_3b85e14e7aa8d5cc9dc48f854a127851_612  
ERROR: Module stap_3b85e14e7aa8d5cc9dc48f854a127851_612 is in use  
[root@db-172-16-3-39 ~]# rmmod -f stap_3b85e14e7aa8d5cc9dc48f854a127851_612  
ERROR: Removing 'stap_3b85e14e7aa8d5cc9dc48f854a127851_612': Resource temporarily unavailable  
  
4.11.3 error  
The error probe point is similar to the end probe, except the probe handler runs when the session ends if an error occurred.   
In this case, an end probe is skipped, but each error probe is still attempted.   
You can use an error probe to clean up or perform a final action on script termination.  
Here is a simple example:  
probe error { println ("Oops, errors occurred. Here's a report anyway.")  
              foreach (coin in mint) { println (coin) } }  

error探针在stap会话发生错误并且退出会话时触发, 如果触发了error探针, 那么end探针不会被触发.

[root@db-172-16-3-39 ~]# stap -e 'probe begin {error("1.error funn\n")} probe end {printf("2.end probe\n")} probe error {printf("3.error probe\n") }'  
ERROR: 1.error funn  
  
3.error probe  
WARNING: Number of errors: 1, skipped probes: 0  
WARNING: /usr/bin/staprun exited with status: 1  
Pass 5: run failed.  Try again with another '--vp 00001' option.  
  
4.11.4 begin, end, and error probe sequence  
begin, end, and error probes can be specified with an optional sequence number that controls the order in which they are run.   
If no sequence number is provided, the sequence number defaults to zero and probes are run in the order that they occur in the script file. Sequence numbers may be either positive or negative, and are especially useful for tapset writers who want to do initialization in a begin probe.   
The following are examples.  
# In a tapset file:  
probe begin(-1000) { ... }  
# In a user script:  
probe begin { ... }  
The user script begin probe defaults to sequence number zero, so the tapset begin probe will run first.  

使用begin, end, error时, 还可以加上序列号, 例如begin(10), 使用序列号的目的是当有多个begin探针时, 区分触发的先后顺序. 序列从小到大执行.

例如 :

[root@db-172-16-3-39 ~]# stap -e 'probe begin {printf ("a\n")} probe begin(0) {printf ("b\n")} probe begin(10) {printf ("c\n")}'   
a  
b  
c  
[root@db-172-16-3-39 ~]# stap -e 'probe begin {printf ("a\n")} probe begin(0) {printf ("b\n")} probe begin(-10) {printf ("c\n")}'   
c  
a  
b  
4.11.5 never  
The never probe point is defined by the translator to mean never.   
Its statements are analyzed for symbol and type correctness, but its probe handler is never run.   
This probe point may be useful in conjunction with optional probes.  

never探针的handler不会执行.

参考

1. https://sourceware.org/systemtap/langref/Probe_points.html

2. https://sourceware.org/systemtap/langref/Probe_points.html#sub:Optional-probe-points

3. https://sourceware.org/systemtap/tapsets/API-error.html

Flag Counter

digoal’s 大量PostgreSQL文章入口