Linux Device Driver >> SystemTap
oneshot、begin的差異
參考資訊:
1. spacewander
main.stp
probe oneshot { printf("=== oneshot ===\n"); } probe begin { printf("=== begin ===\n"); } probe end { printf("=== end ===\n"); }
執行
$ sudo stap main.stp === oneshot === === end ===
為何begin沒有被執行到?
經由轉換成C語言,可以發現,oneshot和begin都是屬於同一個state和type,因此,誰先出現誰就先被執行
static struct stap_probe stap_probes[] = { STAP_PROBE_INIT(0, &probe_6362, "begin", "oneshot", "main.stp:1:7", " from: oneshot from: oneshot"), STAP_PROBE_INIT(1, &probe_6363, "begin", "begin", "main.stp:6:1", " from: begin"), STAP_PROBE_INIT(2, &probe_6364, "end", "end", "main.stp:11:1", " from: end"), }; static struct stap_be_probe { const struct stap_probe * const probe; int state, type; } stap_be_probes[] = { { .probe=(&stap_probes[0]), .state=STAP_SESSION_STARTING, .type=0 }, { .probe=(&stap_probes[1]), .state=STAP_SESSION_STARTING, .type=0 }, { .probe=(&stap_probes[2]), .state=STAP_SESSION_STOPPING, .type=1 }, };
oneshot
static void probe_6362 (struct context * __restrict__ c) { __label__ deref_fault; __label__ out; struct probe_6362_locals * __restrict__ l = & c->probe_locals.probe_6362; (void) l; if (c->actionremaining < 2) { c->last_error = "MAXACTION exceeded"; goto out; } { (void) ({ _stp_print ("=== oneshot ===\n"); }); (void) ({ c->last_stmt = "identifier 'exit' at /usr/local/share/systemtap/tapset/oneshot.stp:4:3"; function___global_exit__overload_0(c); if (unlikely(c->last_error || c->aborted)) goto out; (void) 0; }); } deref_fault: __attribute__((unused)); out: _stp_print_flush(); }
P.S. function___global_exit__overload_0()
begin
static void probe_6363 (struct context * __restrict__ c) { __label__ deref_fault; __label__ out; struct probe_6363_locals * __restrict__ l = & c->probe_locals.probe_6363; (void) l; if (c->actionremaining < 1) { c->last_error = "MAXACTION exceeded"; goto out; } (void) ({ _stp_print ("=== begin ===\n"); }); deref_fault: __attribute__((unused)); out: _stp_print_flush(); }
oneshot和begin的差異就是,oneshot會呼叫function___global_exit__overload_0(),進而呼叫_stp_exit()結束執行,這也是為何oneshot執行後,程式直接結束的原因
static void function___global_exit__overload_0(struct context* __restrict__ c) { ... atomic_set(session_state(), STAP_SESSION_STOPPING); _stp_exit(); ... }
重新改寫位置
probe begin { printf("=== begin ===\n"); } probe oneshot { printf("=== oneshot ===\n"); } probe end { printf("=== end ===\n"); }
執行
$ sudo stap main.stp === begin === === oneshot === === end ===