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