xref: /aosp_15_r20/external/bcc/tests/python/test_usdt2.py (revision 387f9dfdfa2baef462e92476d413c7bc2470293e)
1*387f9dfdSAndroid Build Coastguard Worker#!/usr/bin/env python3
2*387f9dfdSAndroid Build Coastguard Worker#
3*387f9dfdSAndroid Build Coastguard Worker# USAGE: test_usdt2.py
4*387f9dfdSAndroid Build Coastguard Worker#
5*387f9dfdSAndroid Build Coastguard Worker# Copyright 2017 Facebook, Inc
6*387f9dfdSAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License")
7*387f9dfdSAndroid Build Coastguard Worker
8*387f9dfdSAndroid Build Coastguard Workerfrom __future__ import print_function
9*387f9dfdSAndroid Build Coastguard Workerfrom bcc import BPF, USDT
10*387f9dfdSAndroid Build Coastguard Workerfrom unittest import main, TestCase
11*387f9dfdSAndroid Build Coastguard Workerfrom subprocess import Popen, PIPE
12*387f9dfdSAndroid Build Coastguard Workerfrom tempfile import NamedTemporaryFile
13*387f9dfdSAndroid Build Coastguard Workerimport ctypes as ct
14*387f9dfdSAndroid Build Coastguard Workerimport inspect
15*387f9dfdSAndroid Build Coastguard Workerimport os
16*387f9dfdSAndroid Build Coastguard Workerimport signal
17*387f9dfdSAndroid Build Coastguard Worker
18*387f9dfdSAndroid Build Coastguard Workerclass TestUDST(TestCase):
19*387f9dfdSAndroid Build Coastguard Worker    def setUp(self):
20*387f9dfdSAndroid Build Coastguard Worker        # Application, minimum, to define three trace points
21*387f9dfdSAndroid Build Coastguard Worker        app_text = b"""
22*387f9dfdSAndroid Build Coastguard Worker#include <stdlib.h>
23*387f9dfdSAndroid Build Coastguard Worker#include <unistd.h>
24*387f9dfdSAndroid Build Coastguard Worker#include "folly/tracing/StaticTracepoint.h"
25*387f9dfdSAndroid Build Coastguard Worker
26*387f9dfdSAndroid Build Coastguard Workerint main(int argc, char **argv) {
27*387f9dfdSAndroid Build Coastguard Worker  int t = atoi(argv[1]);
28*387f9dfdSAndroid Build Coastguard Worker  while (1) {
29*387f9dfdSAndroid Build Coastguard Worker    FOLLY_SDT(test, probe_point_1, t);
30*387f9dfdSAndroid Build Coastguard Worker    FOLLY_SDT(test, probe_point_2, t + 1);
31*387f9dfdSAndroid Build Coastguard Worker    FOLLY_SDT(test, probe_point_3, t + 2);
32*387f9dfdSAndroid Build Coastguard Worker    sleep(1);
33*387f9dfdSAndroid Build Coastguard Worker  }
34*387f9dfdSAndroid Build Coastguard Worker  return 1;
35*387f9dfdSAndroid Build Coastguard Worker}
36*387f9dfdSAndroid Build Coastguard Worker"""
37*387f9dfdSAndroid Build Coastguard Worker        # BPF program
38*387f9dfdSAndroid Build Coastguard Worker        self.bpf_text = b"""
39*387f9dfdSAndroid Build Coastguard Worker#include <uapi/linux/ptrace.h>
40*387f9dfdSAndroid Build Coastguard Worker
41*387f9dfdSAndroid Build Coastguard WorkerBPF_PERF_OUTPUT(event1);
42*387f9dfdSAndroid Build Coastguard WorkerBPF_PERF_OUTPUT(event2);
43*387f9dfdSAndroid Build Coastguard WorkerBPF_PERF_OUTPUT(event3);
44*387f9dfdSAndroid Build Coastguard WorkerBPF_PERF_OUTPUT(event4);
45*387f9dfdSAndroid Build Coastguard WorkerBPF_PERF_OUTPUT(event5);
46*387f9dfdSAndroid Build Coastguard WorkerBPF_PERF_OUTPUT(event6);
47*387f9dfdSAndroid Build Coastguard Worker
48*387f9dfdSAndroid Build Coastguard Workerint do_trace1(struct pt_regs *ctx) {
49*387f9dfdSAndroid Build Coastguard Worker    u32 pid = bpf_get_current_pid_tgid();
50*387f9dfdSAndroid Build Coastguard Worker    int result = 0;
51*387f9dfdSAndroid Build Coastguard Worker    bpf_usdt_readarg(1, ctx, &result);
52*387f9dfdSAndroid Build Coastguard Worker    if (FILTER)
53*387f9dfdSAndroid Build Coastguard Worker      event1.perf_submit(ctx, &result, sizeof(result));
54*387f9dfdSAndroid Build Coastguard Worker    else
55*387f9dfdSAndroid Build Coastguard Worker      event4.perf_submit(ctx, &result, sizeof(result));
56*387f9dfdSAndroid Build Coastguard Worker    return 0;
57*387f9dfdSAndroid Build Coastguard Worker};
58*387f9dfdSAndroid Build Coastguard Workerint do_trace2(struct pt_regs *ctx) {
59*387f9dfdSAndroid Build Coastguard Worker    u32 pid = bpf_get_current_pid_tgid();
60*387f9dfdSAndroid Build Coastguard Worker    int result = 0;
61*387f9dfdSAndroid Build Coastguard Worker    bpf_usdt_readarg(1, ctx, &result);
62*387f9dfdSAndroid Build Coastguard Worker    if (FILTER)
63*387f9dfdSAndroid Build Coastguard Worker      event2.perf_submit(ctx, &result, sizeof(result));
64*387f9dfdSAndroid Build Coastguard Worker    else
65*387f9dfdSAndroid Build Coastguard Worker      event5.perf_submit(ctx, &result, sizeof(result));
66*387f9dfdSAndroid Build Coastguard Worker    return 0;
67*387f9dfdSAndroid Build Coastguard Worker}
68*387f9dfdSAndroid Build Coastguard Workerint do_trace3(struct pt_regs *ctx) {
69*387f9dfdSAndroid Build Coastguard Worker    u32 pid = bpf_get_current_pid_tgid();
70*387f9dfdSAndroid Build Coastguard Worker    int result = 0;
71*387f9dfdSAndroid Build Coastguard Worker    bpf_usdt_readarg(1, ctx, &result);
72*387f9dfdSAndroid Build Coastguard Worker    if (FILTER)
73*387f9dfdSAndroid Build Coastguard Worker      event3.perf_submit(ctx, &result, sizeof(result));
74*387f9dfdSAndroid Build Coastguard Worker    else
75*387f9dfdSAndroid Build Coastguard Worker      event6.perf_submit(ctx, &result, sizeof(result));
76*387f9dfdSAndroid Build Coastguard Worker    return 0;
77*387f9dfdSAndroid Build Coastguard Worker}
78*387f9dfdSAndroid Build Coastguard Worker"""
79*387f9dfdSAndroid Build Coastguard Worker
80*387f9dfdSAndroid Build Coastguard Worker        # Compile and run the application
81*387f9dfdSAndroid Build Coastguard Worker        self.ftemp = NamedTemporaryFile(delete=False)
82*387f9dfdSAndroid Build Coastguard Worker        self.ftemp.close()
83*387f9dfdSAndroid Build Coastguard Worker        comp = Popen(["gcc", "-I", "%s/include" % os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))),
84*387f9dfdSAndroid Build Coastguard Worker                      "-x", "c++", "-o", self.ftemp.name, "-"],
85*387f9dfdSAndroid Build Coastguard Worker                     stdin=PIPE)
86*387f9dfdSAndroid Build Coastguard Worker        comp.stdin.write(app_text)
87*387f9dfdSAndroid Build Coastguard Worker        comp.stdin.close()
88*387f9dfdSAndroid Build Coastguard Worker        self.assertEqual(comp.wait(), 0)
89*387f9dfdSAndroid Build Coastguard Worker
90*387f9dfdSAndroid Build Coastguard Worker        # create 3 applications, 2 applications will have usdt attached and
91*387f9dfdSAndroid Build Coastguard Worker        # the third one does not, and the third one should not call into
92*387f9dfdSAndroid Build Coastguard Worker        # bpf program.
93*387f9dfdSAndroid Build Coastguard Worker        self.app = Popen([self.ftemp.name, "1"])
94*387f9dfdSAndroid Build Coastguard Worker        self.app2 = Popen([self.ftemp.name, "11"])
95*387f9dfdSAndroid Build Coastguard Worker        self.app3 = Popen([self.ftemp.name, "21"])
96*387f9dfdSAndroid Build Coastguard Worker
97*387f9dfdSAndroid Build Coastguard Worker    def test_attach1(self):
98*387f9dfdSAndroid Build Coastguard Worker        # Enable USDT probe from given PID and verifier generated BPF programs.
99*387f9dfdSAndroid Build Coastguard Worker        u = USDT(pid=int(self.app.pid))
100*387f9dfdSAndroid Build Coastguard Worker        u.enable_probe(probe="probe_point_1", fn_name="do_trace1")
101*387f9dfdSAndroid Build Coastguard Worker        u.enable_probe(probe="probe_point_2", fn_name="do_trace2")
102*387f9dfdSAndroid Build Coastguard Worker        u2 = USDT(pid=int(self.app2.pid))
103*387f9dfdSAndroid Build Coastguard Worker        u2.enable_probe(probe="probe_point_2", fn_name="do_trace2")
104*387f9dfdSAndroid Build Coastguard Worker        u2.enable_probe(probe="probe_point_3", fn_name="do_trace3")
105*387f9dfdSAndroid Build Coastguard Worker        self.bpf_text = self.bpf_text.replace(b"FILTER", b"pid == %d" % self.app.pid)
106*387f9dfdSAndroid Build Coastguard Worker        b = BPF(text=self.bpf_text, usdt_contexts=[u, u2])
107*387f9dfdSAndroid Build Coastguard Worker
108*387f9dfdSAndroid Build Coastguard Worker        # Event states for each event:
109*387f9dfdSAndroid Build Coastguard Worker        # 0 - probe not caught, 1 - probe caught with correct value,
110*387f9dfdSAndroid Build Coastguard Worker        # 2 - probe caught with incorrect value
111*387f9dfdSAndroid Build Coastguard Worker        self.evt_st_1 = 0
112*387f9dfdSAndroid Build Coastguard Worker        self.evt_st_2 = 0
113*387f9dfdSAndroid Build Coastguard Worker        self.evt_st_3 = 0
114*387f9dfdSAndroid Build Coastguard Worker        self.evt_st_4 = 0
115*387f9dfdSAndroid Build Coastguard Worker        self.evt_st_5 = 0
116*387f9dfdSAndroid Build Coastguard Worker        self.evt_st_6 = 0
117*387f9dfdSAndroid Build Coastguard Worker
118*387f9dfdSAndroid Build Coastguard Worker        def check_event_val(data, event_state, expected_val):
119*387f9dfdSAndroid Build Coastguard Worker            result = ct.cast(data, ct.POINTER(ct.c_int)).contents
120*387f9dfdSAndroid Build Coastguard Worker            if result.value == expected_val:
121*387f9dfdSAndroid Build Coastguard Worker                if (event_state == 0 or event_state == 1):
122*387f9dfdSAndroid Build Coastguard Worker                    return 1
123*387f9dfdSAndroid Build Coastguard Worker            return 2
124*387f9dfdSAndroid Build Coastguard Worker
125*387f9dfdSAndroid Build Coastguard Worker        def print_event1(cpu, data, size):
126*387f9dfdSAndroid Build Coastguard Worker            self.evt_st_1 = check_event_val(data, self.evt_st_1, 1)
127*387f9dfdSAndroid Build Coastguard Worker
128*387f9dfdSAndroid Build Coastguard Worker        def print_event2(cpu, data, size):
129*387f9dfdSAndroid Build Coastguard Worker            self.evt_st_2 = check_event_val(data, self.evt_st_2, 2)
130*387f9dfdSAndroid Build Coastguard Worker
131*387f9dfdSAndroid Build Coastguard Worker        def print_event3(cpu, data, size):
132*387f9dfdSAndroid Build Coastguard Worker            self.evt_st_3 = check_event_val(data, self.evt_st_3, 3)
133*387f9dfdSAndroid Build Coastguard Worker
134*387f9dfdSAndroid Build Coastguard Worker        def print_event4(cpu, data, size):
135*387f9dfdSAndroid Build Coastguard Worker            self.evt_st_4 = check_event_val(data, self.evt_st_4, 11)
136*387f9dfdSAndroid Build Coastguard Worker
137*387f9dfdSAndroid Build Coastguard Worker        def print_event5(cpu, data, size):
138*387f9dfdSAndroid Build Coastguard Worker            self.evt_st_5 = check_event_val(data, self.evt_st_5, 12)
139*387f9dfdSAndroid Build Coastguard Worker
140*387f9dfdSAndroid Build Coastguard Worker        def print_event6(cpu, data, size):
141*387f9dfdSAndroid Build Coastguard Worker            self.evt_st_6 = check_event_val(data, self.evt_st_6, 13)
142*387f9dfdSAndroid Build Coastguard Worker
143*387f9dfdSAndroid Build Coastguard Worker        # loop with callback to print_event
144*387f9dfdSAndroid Build Coastguard Worker        b[b"event1"].open_perf_buffer(print_event1)
145*387f9dfdSAndroid Build Coastguard Worker        b[b"event2"].open_perf_buffer(print_event2)
146*387f9dfdSAndroid Build Coastguard Worker        b[b"event3"].open_perf_buffer(print_event3)
147*387f9dfdSAndroid Build Coastguard Worker        b[b"event4"].open_perf_buffer(print_event4)
148*387f9dfdSAndroid Build Coastguard Worker        b[b"event5"].open_perf_buffer(print_event5)
149*387f9dfdSAndroid Build Coastguard Worker        b[b"event6"].open_perf_buffer(print_event6)
150*387f9dfdSAndroid Build Coastguard Worker
151*387f9dfdSAndroid Build Coastguard Worker        # three iterations to make sure we get some probes and have time to process them
152*387f9dfdSAndroid Build Coastguard Worker        for i in range(5):
153*387f9dfdSAndroid Build Coastguard Worker            b.perf_buffer_poll()
154*387f9dfdSAndroid Build Coastguard Worker
155*387f9dfdSAndroid Build Coastguard Worker        # note that event1 and event4 do not really fire, so their state should be 0
156*387f9dfdSAndroid Build Coastguard Worker        # use separate asserts so that if test fails we know which one is the culprit
157*387f9dfdSAndroid Build Coastguard Worker        self.assertTrue(self.evt_st_1 == 1)
158*387f9dfdSAndroid Build Coastguard Worker        self.assertTrue(self.evt_st_2 == 1)
159*387f9dfdSAndroid Build Coastguard Worker        self.assertTrue(self.evt_st_3 == 0)
160*387f9dfdSAndroid Build Coastguard Worker        self.assertTrue(self.evt_st_4 == 0)
161*387f9dfdSAndroid Build Coastguard Worker        self.assertTrue(self.evt_st_5 == 1)
162*387f9dfdSAndroid Build Coastguard Worker        self.assertTrue(self.evt_st_6 == 1)
163*387f9dfdSAndroid Build Coastguard Worker
164*387f9dfdSAndroid Build Coastguard Worker    def tearDown(self):
165*387f9dfdSAndroid Build Coastguard Worker        # kill the subprocess, clean the environment
166*387f9dfdSAndroid Build Coastguard Worker        self.app.kill()
167*387f9dfdSAndroid Build Coastguard Worker        self.app.wait()
168*387f9dfdSAndroid Build Coastguard Worker        self.app2.kill()
169*387f9dfdSAndroid Build Coastguard Worker        self.app2.wait()
170*387f9dfdSAndroid Build Coastguard Worker        self.app3.kill()
171*387f9dfdSAndroid Build Coastguard Worker        self.app3.wait()
172*387f9dfdSAndroid Build Coastguard Worker        os.unlink(self.ftemp.name)
173*387f9dfdSAndroid Build Coastguard Worker
174*387f9dfdSAndroid Build Coastguard Workerif __name__ == "__main__":
175*387f9dfdSAndroid Build Coastguard Worker    main()
176