1#!/usr/bin/env python3 2# Copyright (c) PLUMgrid, Inc. 3# Licensed under the Apache License, Version 2.0 (the "License") 4 5import bcc 6import os 7import unittest 8from utils import mayFail, kernel_version_ge 9import subprocess 10 11 12@unittest.skipUnless(kernel_version_ge(4,6), "requires kernel >= 4.6") 13class TestStackid(unittest.TestCase): 14 @mayFail("This fails on github actions environment, and needs to be fixed") 15 def test_simple(self): 16 b = bcc.BPF(text=""" 17#include <uapi/linux/ptrace.h> 18struct bpf_map; 19BPF_STACK_TRACE(stack_traces, 10240); 20BPF_HASH(stack_entries, int, int); 21BPF_HASH(stub); 22int kprobe__htab_map_lookup_elem(struct pt_regs *ctx, struct bpf_map *map, u64 *k) { 23 int id = stack_traces.get_stackid(ctx, BPF_F_REUSE_STACKID); 24 if (id < 0) 25 return 0; 26 int key = 1; 27 stack_entries.update(&key, &id); 28 return 0; 29} 30""") 31 stub = b["stub"] 32 stack_traces = b["stack_traces"] 33 stack_entries = b["stack_entries"] 34 try: x = stub[stub.Key(1)] 35 except: pass 36 k = stack_entries.Key(1) 37 self.assertIn(k, stack_entries) 38 stackid = stack_entries[k] 39 self.assertIsNotNone(stackid) 40 stack = stack_traces[stackid].ip 41 self.assertEqual(b.ksym(stack[0]), b"htab_map_lookup_elem") 42 43def Get_libc_path(): 44 cmd = 'cat /proc/self/maps | grep libc | awk \'{print $6}\' | uniq' 45 output = subprocess.check_output(cmd, shell=True) 46 if not isinstance(output, str): 47 output = output.decode() 48 return output.split('\n')[0] 49 50@unittest.skipUnless(kernel_version_ge(4,17), "requires kernel >= 4.17") 51class TestStackBuildid(unittest.TestCase): 52 def test_simple(self): 53 b = bcc.BPF(text=""" 54#include <uapi/linux/ptrace.h> 55struct bpf_map; 56BPF_STACK_TRACE_BUILDID(stack_traces, 10240); 57BPF_HASH(stack_entries, int, int); 58BPF_HASH(stub); 59int kprobe__sys_getuid(struct pt_regs *ctx, struct bpf_map *map, u64 *k) { 60 int id = stack_traces.get_stackid(ctx, BPF_F_USER_STACK); 61 if (id < 0) 62 return 0; 63 int key = 1; 64 stack_entries.update(&key, &id); 65 return 0; 66} 67""") 68 os.getuid() 69 stub = b["stub"] 70 stack_traces = b["stack_traces"] 71 stack_entries = b["stack_entries"] 72 b.add_module(Get_libc_path()) 73 try: x = stub[stub.Key(1)] 74 except: pass 75 k = stack_entries.Key(1) 76 self.assertIn(k, stack_entries) 77 stackid = stack_entries[k] 78 self.assertIsNotNone(stackid) 79 stack = stack_traces[stackid] 80 self.assertTrue(b.sym(stack.trace[0], -1).find(b"getuid")!=-1) 81 82if __name__ == "__main__": 83 unittest.main() 84