參考資訊:
https://segmentfault.com/a/1190000019602980
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 ===