xref: /aosp_15_r20/external/bcc/tests/python/test_usdt3.py (revision 387f9dfdfa2baef462e92476d413c7bc2470293e)
1*387f9dfdSAndroid Build Coastguard Worker#!/usr/bin/env python3
2*387f9dfdSAndroid Build Coastguard Worker#
3*387f9dfdSAndroid Build Coastguard Worker# USAGE: test_usdt3.py
4*387f9dfdSAndroid Build Coastguard Worker#
5*387f9dfdSAndroid Build Coastguard Worker# Copyright 2018 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 Workerimport ctypes as ct
13*387f9dfdSAndroid Build Coastguard Workerimport inspect, os, tempfile
14*387f9dfdSAndroid Build Coastguard Worker
15*387f9dfdSAndroid Build Coastguard Workerclass TestUDST(TestCase):
16*387f9dfdSAndroid Build Coastguard Worker    def setUp(self):
17*387f9dfdSAndroid Build Coastguard Worker        common_h = b"""
18*387f9dfdSAndroid Build Coastguard Worker#include "folly/tracing/StaticTracepoint.h"
19*387f9dfdSAndroid Build Coastguard Worker
20*387f9dfdSAndroid Build Coastguard Workerstatic inline void record_val(int val)
21*387f9dfdSAndroid Build Coastguard Worker{
22*387f9dfdSAndroid Build Coastguard Worker  FOLLY_SDT(test, probe, val);
23*387f9dfdSAndroid Build Coastguard Worker  FOLLY_SDT(test_dup_name, probe, val);
24*387f9dfdSAndroid Build Coastguard Worker}
25*387f9dfdSAndroid Build Coastguard Worker
26*387f9dfdSAndroid Build Coastguard Workerextern void record_a(int val);
27*387f9dfdSAndroid Build Coastguard Workerextern void record_b(int val);
28*387f9dfdSAndroid Build Coastguard Worker"""
29*387f9dfdSAndroid Build Coastguard Worker
30*387f9dfdSAndroid Build Coastguard Worker        a_c = b"""
31*387f9dfdSAndroid Build Coastguard Worker#include <stdio.h>
32*387f9dfdSAndroid Build Coastguard Worker#include "common.h"
33*387f9dfdSAndroid Build Coastguard Worker
34*387f9dfdSAndroid Build Coastguard Workervoid record_a(int val)
35*387f9dfdSAndroid Build Coastguard Worker{
36*387f9dfdSAndroid Build Coastguard Worker    record_val(val);
37*387f9dfdSAndroid Build Coastguard Worker}
38*387f9dfdSAndroid Build Coastguard Worker"""
39*387f9dfdSAndroid Build Coastguard Worker
40*387f9dfdSAndroid Build Coastguard Worker        b_c = b"""
41*387f9dfdSAndroid Build Coastguard Worker#include <stdio.h>
42*387f9dfdSAndroid Build Coastguard Worker#include "common.h"
43*387f9dfdSAndroid Build Coastguard Worker
44*387f9dfdSAndroid Build Coastguard Workervoid record_b(int val)
45*387f9dfdSAndroid Build Coastguard Worker{
46*387f9dfdSAndroid Build Coastguard Worker    record_val(val);
47*387f9dfdSAndroid Build Coastguard Worker}
48*387f9dfdSAndroid Build Coastguard Worker"""
49*387f9dfdSAndroid Build Coastguard Worker
50*387f9dfdSAndroid Build Coastguard Worker        m_c = b"""
51*387f9dfdSAndroid Build Coastguard Worker#include <stdio.h>
52*387f9dfdSAndroid Build Coastguard Worker#include <unistd.h>
53*387f9dfdSAndroid Build Coastguard Worker#include "common.h"
54*387f9dfdSAndroid Build Coastguard Worker
55*387f9dfdSAndroid Build Coastguard Workerint main() {
56*387f9dfdSAndroid Build Coastguard Worker   while (1) {
57*387f9dfdSAndroid Build Coastguard Worker     record_a(1);
58*387f9dfdSAndroid Build Coastguard Worker     record_b(2);
59*387f9dfdSAndroid Build Coastguard Worker     record_val(3);
60*387f9dfdSAndroid Build Coastguard Worker     sleep(1);
61*387f9dfdSAndroid Build Coastguard Worker   }
62*387f9dfdSAndroid Build Coastguard Worker   return 0;
63*387f9dfdSAndroid Build Coastguard Worker}
64*387f9dfdSAndroid Build Coastguard Worker"""
65*387f9dfdSAndroid Build Coastguard Worker        # BPF program
66*387f9dfdSAndroid Build Coastguard Worker        self.bpf_text = b"""
67*387f9dfdSAndroid Build Coastguard WorkerBPF_PERF_OUTPUT(event);
68*387f9dfdSAndroid Build Coastguard Workerint do_trace(struct pt_regs *ctx) {
69*387f9dfdSAndroid Build Coastguard Worker    int result = 0;
70*387f9dfdSAndroid Build Coastguard Worker    bpf_usdt_readarg(1, ctx, &result);
71*387f9dfdSAndroid Build Coastguard Worker    event.perf_submit(ctx, &result, sizeof(result));
72*387f9dfdSAndroid Build Coastguard Worker    return 0;
73*387f9dfdSAndroid Build Coastguard Worker};
74*387f9dfdSAndroid Build Coastguard Worker"""
75*387f9dfdSAndroid Build Coastguard Worker
76*387f9dfdSAndroid Build Coastguard Worker        def _create_file(name, text):
77*387f9dfdSAndroid Build Coastguard Worker            text_file = open(name, "wb")
78*387f9dfdSAndroid Build Coastguard Worker            text_file.write(text)
79*387f9dfdSAndroid Build Coastguard Worker            text_file.close()
80*387f9dfdSAndroid Build Coastguard Worker
81*387f9dfdSAndroid Build Coastguard Worker        # Create source files
82*387f9dfdSAndroid Build Coastguard Worker        self.tmp_dir = tempfile.mkdtemp()
83*387f9dfdSAndroid Build Coastguard Worker        print("temp directory: " + self.tmp_dir)
84*387f9dfdSAndroid Build Coastguard Worker        _create_file(self.tmp_dir + "/common.h", common_h)
85*387f9dfdSAndroid Build Coastguard Worker        _create_file(self.tmp_dir + "/a.cpp", a_c)
86*387f9dfdSAndroid Build Coastguard Worker        _create_file(self.tmp_dir + "/b.cpp", b_c)
87*387f9dfdSAndroid Build Coastguard Worker        _create_file(self.tmp_dir + "/m.cpp", m_c)
88*387f9dfdSAndroid Build Coastguard Worker
89*387f9dfdSAndroid Build Coastguard Worker        # Compilation
90*387f9dfdSAndroid Build Coastguard Worker        # the usdt test:probe exists in liba.so, libb.so and a.out
91*387f9dfdSAndroid Build Coastguard Worker        include_path = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))) + "/include"
92*387f9dfdSAndroid Build Coastguard Worker        a_src = self.tmp_dir + "/a.cpp"
93*387f9dfdSAndroid Build Coastguard Worker        a_obj = self.tmp_dir + "/a.o"
94*387f9dfdSAndroid Build Coastguard Worker        a_lib = self.tmp_dir + "/liba.so"
95*387f9dfdSAndroid Build Coastguard Worker        b_src = self.tmp_dir + "/b.cpp"
96*387f9dfdSAndroid Build Coastguard Worker        b_obj = self.tmp_dir + "/b.o"
97*387f9dfdSAndroid Build Coastguard Worker        b_lib = self.tmp_dir + "/libb.so"
98*387f9dfdSAndroid Build Coastguard Worker        m_src = self.tmp_dir + "/m.cpp"
99*387f9dfdSAndroid Build Coastguard Worker        m_bin = self.tmp_dir + "/a.out"
100*387f9dfdSAndroid Build Coastguard Worker        m_linker_opt = " -L" + self.tmp_dir + " -la -lb"
101*387f9dfdSAndroid Build Coastguard Worker        self.assertEqual(os.system("gcc -I" + include_path + " -fpic -c -o " + a_obj + " " + a_src), 0)
102*387f9dfdSAndroid Build Coastguard Worker        self.assertEqual(os.system("gcc -I" + include_path + " -fpic -c -o " + b_obj + " " + b_src), 0)
103*387f9dfdSAndroid Build Coastguard Worker        self.assertEqual(os.system("gcc -shared -o " + a_lib + " " + a_obj), 0)
104*387f9dfdSAndroid Build Coastguard Worker        self.assertEqual(os.system("gcc -shared -o " + b_lib + " " + b_obj), 0)
105*387f9dfdSAndroid Build Coastguard Worker        self.assertEqual(os.system("gcc -I" + include_path + " " + m_src + " -o " + m_bin + m_linker_opt), 0)
106*387f9dfdSAndroid Build Coastguard Worker
107*387f9dfdSAndroid Build Coastguard Worker        # Run the application
108*387f9dfdSAndroid Build Coastguard Worker        self.app = Popen([m_bin], env=dict(os.environ, LD_LIBRARY_PATH=self.tmp_dir))
109*387f9dfdSAndroid Build Coastguard Worker        os.system("../../tools/tplist.py -vvv -p " + str(self.app.pid))
110*387f9dfdSAndroid Build Coastguard Worker
111*387f9dfdSAndroid Build Coastguard Worker    def test_attach1(self):
112*387f9dfdSAndroid Build Coastguard Worker        # enable USDT probe from given PID and verifier generated BPF programs
113*387f9dfdSAndroid Build Coastguard Worker        u = USDT(pid=int(self.app.pid))
114*387f9dfdSAndroid Build Coastguard Worker        u.enable_probe(probe="test:probe", fn_name="do_trace")
115*387f9dfdSAndroid Build Coastguard Worker        b = BPF(text=self.bpf_text, usdt_contexts=[u])
116*387f9dfdSAndroid Build Coastguard Worker
117*387f9dfdSAndroid Build Coastguard Worker        # processing events
118*387f9dfdSAndroid Build Coastguard Worker        self.probe_value_1 = 0
119*387f9dfdSAndroid Build Coastguard Worker        self.probe_value_2 = 0
120*387f9dfdSAndroid Build Coastguard Worker        self.probe_value_3 = 0
121*387f9dfdSAndroid Build Coastguard Worker        self.probe_value_other = 0
122*387f9dfdSAndroid Build Coastguard Worker
123*387f9dfdSAndroid Build Coastguard Worker        def print_event(cpu, data, size):
124*387f9dfdSAndroid Build Coastguard Worker            result = ct.cast(data, ct.POINTER(ct.c_int)).contents
125*387f9dfdSAndroid Build Coastguard Worker            if result.value == 1:
126*387f9dfdSAndroid Build Coastguard Worker                self.probe_value_1 = 1
127*387f9dfdSAndroid Build Coastguard Worker            elif result.value == 2:
128*387f9dfdSAndroid Build Coastguard Worker                self.probe_value_2 = 1
129*387f9dfdSAndroid Build Coastguard Worker            elif result.value == 3:
130*387f9dfdSAndroid Build Coastguard Worker                self.probe_value_3 = 1
131*387f9dfdSAndroid Build Coastguard Worker            else:
132*387f9dfdSAndroid Build Coastguard Worker                self.probe_value_other = 1
133*387f9dfdSAndroid Build Coastguard Worker
134*387f9dfdSAndroid Build Coastguard Worker        b[b"event"].open_perf_buffer(print_event)
135*387f9dfdSAndroid Build Coastguard Worker        for i in range(100):
136*387f9dfdSAndroid Build Coastguard Worker            if (self.probe_value_1 == 0 or
137*387f9dfdSAndroid Build Coastguard Worker                self.probe_value_2 == 0 or
138*387f9dfdSAndroid Build Coastguard Worker                self.probe_value_3 == 0 or
139*387f9dfdSAndroid Build Coastguard Worker                self.probe_value_other != 0):
140*387f9dfdSAndroid Build Coastguard Worker                b.perf_buffer_poll()
141*387f9dfdSAndroid Build Coastguard Worker            else:
142*387f9dfdSAndroid Build Coastguard Worker                break;
143*387f9dfdSAndroid Build Coastguard Worker
144*387f9dfdSAndroid Build Coastguard Worker        self.assertTrue(self.probe_value_1 != 0)
145*387f9dfdSAndroid Build Coastguard Worker        self.assertTrue(self.probe_value_2 != 0)
146*387f9dfdSAndroid Build Coastguard Worker        self.assertTrue(self.probe_value_3 != 0)
147*387f9dfdSAndroid Build Coastguard Worker        self.assertTrue(self.probe_value_other == 0)
148*387f9dfdSAndroid Build Coastguard Worker
149*387f9dfdSAndroid Build Coastguard Worker    def tearDown(self):
150*387f9dfdSAndroid Build Coastguard Worker        # kill the subprocess, clean the environment
151*387f9dfdSAndroid Build Coastguard Worker        self.app.kill()
152*387f9dfdSAndroid Build Coastguard Worker        self.app.wait()
153*387f9dfdSAndroid Build Coastguard Worker        os.system("rm -rf " + self.tmp_dir)
154*387f9dfdSAndroid Build Coastguard Worker
155*387f9dfdSAndroid Build Coastguard Workerif __name__ == "__main__":
156*387f9dfdSAndroid Build Coastguard Worker    main()
157