From 23d51e43a0492112988371df4eeca4881f3bb7ff Mon Sep 17 00:00:00 2001 From: LiuLingze Date: Sun, 9 Jun 2024 03:57:58 +0000 Subject: [PATCH 1/3] update map api Signed-off-by: LiuLingze --- .../Stack_Analyser/bpf/memleak.bpf.c | 6 ++-- .../Stack_Analyser/bpf/off_cpu.bpf.c | 2 +- .../Stack_Analyser/bpf/probe.bpf.c | 2 +- .../Stack_Analyser/bpf/readahead.bpf.c | 4 +-- .../Stack_Analyser/include/sa_ebpf.h | 28 +++++++++---------- 5 files changed, 21 insertions(+), 21 deletions(-) diff --git a/eBPF_Supermarket/Stack_Analyser/bpf/memleak.bpf.c b/eBPF_Supermarket/Stack_Analyser/bpf/memleak.bpf.c index 24f2a14e7..25fa84487 100644 --- a/eBPF_Supermarket/Stack_Analyser/bpf/memleak.bpf.c +++ b/eBPF_Supermarket/Stack_Analyser/bpf/memleak.bpf.c @@ -31,9 +31,9 @@ const volatile bool wa_missing_free = false; const volatile size_t page_size = 4096; const volatile bool trace_all = false; -BPF_HASH(pid_size_map, u32, u64); // 记录了对应进程使用malloc,calloc等函数申请内存的大小 -BPF_HASH(piddr_meminfo_map, piddr, mem_info); // 记录了每次申请的内存空间的起始地址等信息 -BPF_HASH(memptrs_map, u32, u64); +BPF_HASH(pid_size_map, u32, u64, MAX_ENTRIES); // 记录了对应进程使用malloc,calloc等函数申请内存的大小 +BPF_HASH(piddr_meminfo_map, piddr, mem_info, MAX_ENTRIES); // 记录了每次申请的内存空间的起始地址等信息 +BPF_HASH(memptrs_map, u32, u64, MAX_ENTRIES); const char LICENSE[] SEC("license") = "GPL"; diff --git a/eBPF_Supermarket/Stack_Analyser/bpf/off_cpu.bpf.c b/eBPF_Supermarket/Stack_Analyser/bpf/off_cpu.bpf.c index 5f64815e9..cee5be1a6 100644 --- a/eBPF_Supermarket/Stack_Analyser/bpf/off_cpu.bpf.c +++ b/eBPF_Supermarket/Stack_Analyser/bpf/off_cpu.bpf.c @@ -27,7 +27,7 @@ COMMON_MAPS(u32); COMMON_VALS; // 记录进程运行的起始时间 -BPF_HASH(pid_offTs_map, u32, u64); +BPF_HASH(pid_offTs_map, u32, u64, MAX_ENTRIES/10); const char LICENSE[] SEC("license") = "GPL"; diff --git a/eBPF_Supermarket/Stack_Analyser/bpf/probe.bpf.c b/eBPF_Supermarket/Stack_Analyser/bpf/probe.bpf.c index 99f91032c..01f4dd371 100644 --- a/eBPF_Supermarket/Stack_Analyser/bpf/probe.bpf.c +++ b/eBPF_Supermarket/Stack_Analyser/bpf/probe.bpf.c @@ -28,7 +28,7 @@ COMMON_MAPS(time_tuple); COMMON_VALS; -BPF_HASH(starts, u32, u64); +BPF_HASH(starts, u32, u64, MAX_ENTRIES/10); static int entry(void *ctx) { diff --git a/eBPF_Supermarket/Stack_Analyser/bpf/readahead.bpf.c b/eBPF_Supermarket/Stack_Analyser/bpf/readahead.bpf.c index 41e984ba4..92ce2f063 100644 --- a/eBPF_Supermarket/Stack_Analyser/bpf/readahead.bpf.c +++ b/eBPF_Supermarket/Stack_Analyser/bpf/readahead.bpf.c @@ -31,8 +31,8 @@ COMMON_MAPS(ra_tuple); COMMON_VALS; -BPF_HASH(in_ra_map, u32, psid); -BPF_HASH(page_psid_map, struct page *, psid); +BPF_HASH(in_ra_map, u32, psid, MAX_ENTRIES/10); +BPF_HASH(page_psid_map, struct page *, psid, MAX_ENTRIES); SEC("fentry/page_cache_ra_unbounded") // fentry在内核函数page_cache_ra_unbounded进入时触发的挂载点 int BPF_PROG(page_cache_ra_unbounded) diff --git a/eBPF_Supermarket/Stack_Analyser/include/sa_ebpf.h b/eBPF_Supermarket/Stack_Analyser/include/sa_ebpf.h index 56ea5549d..c921d0dfb 100644 --- a/eBPF_Supermarket/Stack_Analyser/include/sa_ebpf.h +++ b/eBPF_Supermarket/Stack_Analyser/include/sa_ebpf.h @@ -39,13 +39,13 @@ /// @param name 新散列表的名字 /// @param type1 键的类型 /// @param type2 值的类型 -#define BPF_HASH(name, type1, type2) \ - struct \ - { \ - __uint(type, BPF_MAP_TYPE_HASH); \ - __uint(key_size, sizeof(type1)); \ - __uint(value_size, sizeof(type2)); \ - __uint(max_entries, MAX_ENTRIES); \ +#define BPF_HASH(name, _kt, _vt, _cap) \ + struct \ + { \ + __uint(type, BPF_MAP_TYPE_HASH); \ + __type(key, _kt); \ + __type(value, _vt); \ + __uint(max_entries, _cap); \ } name SEC(".maps") /** @@ -56,12 +56,12 @@ * pid_comm 存储 键值对,记录pid以及对应的命令名 * type:指定count值的类型 */ -#define COMMON_MAPS(count_type) \ - BPF_HASH(psid_count_map, psid, count_type); \ - BPF_STACK_TRACE(sid_trace_map); \ - BPF_HASH(tgid_cgroup_map, __u32, \ - char[CONTAINER_ID_LEN]); \ - BPF_HASH(pid_info_map, u32, task_info); +#define COMMON_MAPS(count_type) \ + BPF_HASH(psid_count_map, psid, count_type, MAX_ENTRIES); \ + BPF_STACK_TRACE(sid_trace_map); \ + BPF_HASH(tgid_cgroup_map, __u32, \ + char[CONTAINER_ID_LEN], MAX_ENTRIES / 100); \ + BPF_HASH(pid_info_map, u32, task_info, MAX_ENTRIES / 10); #define COMMON_VALS \ const volatile bool trace_user = false; \ @@ -123,7 +123,7 @@ (struct task_struct *)bpf_get_current_task() // 如果没有设置目标进程,则检查被采集进程是否为内核线程,是则退出采集 -#define CHECK_KTHREAD(_task) \ +#define CHECK_KTHREAD(_task) \ if (!target_tgid && BPF_CORE_READ(_task, flags) & PF_KTHREAD) \ return 0; From 0d315d8ddb08147c5c769509ef1f09ac43c79bbc Mon Sep 17 00:00:00 2001 From: LiuLingze Date: Mon, 10 Jun 2024 02:03:02 +0000 Subject: [PATCH 2/3] arrange code Signed-off-by: LiuLingze --- .../include/bpf_wapper/eBPFStackCollector.h | 34 +- .../Stack_Analyser/include/cgroup.h | 9 + .../include/{sa_common.h => common.h} | 13 +- .../Stack_Analyser/include/dt_elf.h | 25 - .../Stack_Analyser/include/dt_symbol.h | 179 ----- .../include/{sa_ebpf.h => ebpf.h} | 0 .../include/{trace_helpers.h => trace.h} | 29 +- .../include/{uprobe_helpers.h => uprobe.h} | 0 .../include/{sa_user.h => user.h} | 24 +- .../src/bpf_wapper/eBPFStackCollector.cpp | 77 +-- .../Stack_Analyser/src/bpf_wapper/memleak.cpp | 2 +- .../Stack_Analyser/src/bpf_wapper/off_cpu.cpp | 12 +- .../Stack_Analyser/src/bpf_wapper/probe.cpp | 4 +- .../Stack_Analyser/src/cgroup.cpp | 56 ++ .../Stack_Analyser/src/dt_elf.cpp | 621 ------------------ .../Stack_Analyser/src/dt_symbol.cpp | 587 ----------------- eBPF_Supermarket/Stack_Analyser/src/main.cpp | 169 ++--- .../src/{trace_helpers.cpp => trace.cpp} | 329 ++++++---- .../src/{uprobe_helpers.cpp => uprobe.cpp} | 0 19 files changed, 434 insertions(+), 1736 deletions(-) create mode 100644 eBPF_Supermarket/Stack_Analyser/include/cgroup.h rename eBPF_Supermarket/Stack_Analyser/include/{sa_common.h => common.h} (83%) delete mode 100644 eBPF_Supermarket/Stack_Analyser/include/dt_elf.h delete mode 100644 eBPF_Supermarket/Stack_Analyser/include/dt_symbol.h rename eBPF_Supermarket/Stack_Analyser/include/{sa_ebpf.h => ebpf.h} (100%) rename eBPF_Supermarket/Stack_Analyser/include/{trace_helpers.h => trace.h} (83%) rename eBPF_Supermarket/Stack_Analyser/include/{uprobe_helpers.h => uprobe.h} (100%) rename eBPF_Supermarket/Stack_Analyser/include/{sa_user.h => user.h} (97%) create mode 100644 eBPF_Supermarket/Stack_Analyser/src/cgroup.cpp delete mode 100644 eBPF_Supermarket/Stack_Analyser/src/dt_elf.cpp delete mode 100644 eBPF_Supermarket/Stack_Analyser/src/dt_symbol.cpp rename eBPF_Supermarket/Stack_Analyser/src/{trace_helpers.cpp => trace.cpp} (82%) rename eBPF_Supermarket/Stack_Analyser/src/{uprobe_helpers.cpp => uprobe.cpp} (100%) diff --git a/eBPF_Supermarket/Stack_Analyser/include/bpf_wapper/eBPFStackCollector.h b/eBPF_Supermarket/Stack_Analyser/include/bpf_wapper/eBPFStackCollector.h index 292225da1..ff07187c6 100644 --- a/eBPF_Supermarket/Stack_Analyser/include/bpf_wapper/eBPFStackCollector.h +++ b/eBPF_Supermarket/Stack_Analyser/include/bpf_wapper/eBPFStackCollector.h @@ -23,7 +23,7 @@ #include #include #include -#include "sa_user.h" +#include "user.h" struct Scale { @@ -62,7 +62,7 @@ class StackCollector uint32_t freq = 49; uint64_t cgroup = 0; uint32_t tgid = 0; - int err = 0; // 用于保存错误代码 + int err = 0; // 用于保存错误代码 bool ustack = false; // 是否跟踪用户栈 bool kstack = false; // 是否跟踪内核栈 @@ -94,25 +94,25 @@ class StackCollector /// @brief 加载、初始化参数并打开指定类型的ebpf程序 /// @param ... 一些ebpf程序全局变量初始化语句 /// @note 失败会使上层函数返回-1 -#define EBPF_LOAD_OPEN_INIT(...) \ - { \ - skel = skel->open(NULL); \ +#define EBPF_LOAD_OPEN_INIT(...) \ + { \ + skel = skel->open(NULL); \ CHECK_ERR_RN1(!skel, "Fail to open BPF skeleton"); \ - __VA_ARGS__; \ - skel->rodata->trace_user = ustack; \ - skel->rodata->trace_kernel = kstack; \ - skel->rodata->self_tgid = self_tgid; \ - skel->rodata->target_tgid = tgid; \ - skel->rodata->target_cgroupid = cgroup; \ - skel->rodata->freq = freq; \ - err = skel->load(skel); \ + __VA_ARGS__; \ + skel->rodata->trace_user = ustack; \ + skel->rodata->trace_kernel = kstack; \ + skel->rodata->self_tgid = self_tgid; \ + skel->rodata->target_tgid = tgid; \ + skel->rodata->target_cgroupid = cgroup; \ + skel->rodata->freq = freq; \ + err = skel->load(skel); \ CHECK_ERR_RN1(err, "Fail to load BPF skeleton"); \ - obj = skel->obj; \ + obj = skel->obj; \ } -#define ATTACH_PROTO \ - { \ - err = skel->attach(skel); \ +#define ATTACH_PROTO \ + { \ + err = skel->attach(skel); \ CHECK_ERR_RN1(err, "Failed to attach BPF skeleton"); \ } diff --git a/eBPF_Supermarket/Stack_Analyser/include/cgroup.h b/eBPF_Supermarket/Stack_Analyser/include/cgroup.h new file mode 100644 index 000000000..a9157a603 --- /dev/null +++ b/eBPF_Supermarket/Stack_Analyser/include/cgroup.h @@ -0,0 +1,9 @@ +#include +struct cgid_file_handle +{ + // struct file_handle handle; + unsigned int handle_bytes; + int handle_type; + uint64_t cgid; +}; +uint64_t get_cgroupid(const char *pathname); \ No newline at end of file diff --git a/eBPF_Supermarket/Stack_Analyser/include/sa_common.h b/eBPF_Supermarket/Stack_Analyser/include/common.h similarity index 83% rename from eBPF_Supermarket/Stack_Analyser/include/sa_common.h rename to eBPF_Supermarket/Stack_Analyser/include/common.h index 449f2f6c3..ad77f45e3 100644 --- a/eBPF_Supermarket/Stack_Analyser/include/sa_common.h +++ b/eBPF_Supermarket/Stack_Analyser/include/common.h @@ -27,22 +27,17 @@ #define CONTAINER_ID_LEN (128) /// @brief 栈计数的键,可以唯一标识一个用户内核栈 -typedef struct { +typedef struct +{ __u32 pid; __s32 ksid, usid; } psid; -typedef struct { +typedef struct +{ __u32 pid; __u32 tgid; char comm[COMM_LEN]; } task_info; -#define _COL_PREFIX "\033[" -#define _BLUE _COL_PREFIX "1;34m" -#define _GREEN _COL_PREFIX "1;32m" -#define _RED _COL_PREFIX "1;35m" -#define _ERED _COL_PREFIX "1;31m" -#define _RE _COL_PREFIX "0m" - #endif diff --git a/eBPF_Supermarket/Stack_Analyser/include/dt_elf.h b/eBPF_Supermarket/Stack_Analyser/include/dt_elf.h deleted file mode 100644 index a6174a376..000000000 --- a/eBPF_Supermarket/Stack_Analyser/include/dt_elf.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Linux内核诊断工具--elf相关函数头文件 - * - * Copyright (C) 2020 Alibaba Ltd. - * - * License terms: GNU General Public License (GPL) version 3 - * - */ - -#ifndef _PERF_ELF_H__ -#define _PERF_ELF_H__ - -#include -#include - -#include "dt_symbol.h" - -#define BUILD_ID_SIZE 40 -bool save_symbol_cache(std::set &ss, const char *path); -bool load_symbol_cache(std::set &ss, const char *path, const char *filename); - -bool get_symbol_from_elf(std::set &ss, const char *path); -bool search_symbol(const std::set &ss, symbol &sym); -int filename__read_build_id(int pid, const char *mnt_ns_name, const char *filename, char *bf, size_t size); -#endif diff --git a/eBPF_Supermarket/Stack_Analyser/include/dt_symbol.h b/eBPF_Supermarket/Stack_Analyser/include/dt_symbol.h deleted file mode 100644 index 3f2c3ffe9..000000000 --- a/eBPF_Supermarket/Stack_Analyser/include/dt_symbol.h +++ /dev/null @@ -1,179 +0,0 @@ -/* - * Linux内核诊断工具--用户态符号表解析 - * - * Copyright (C) 2020 Alibaba Ltd. - * - * License terms: GNU General Public License (GPL) version 3 - * - */ - -#ifndef __PERF_SYMBOL_H__ -#define __PERF_SYMBOL_H__ - -#include -#include -#include - -//#include - -#define INVALID_ADDR ((size_t)(-1)) -enum { - NATIVE_TYPE = 0, - JIT_TYPE = 1, - UNKNOWN = 2, -}; - -struct elf_file { - unsigned char elf_read_error; - size_t eh_frame_hdr_offset; - size_t fde_count; - size_t table_data; - std::string filename; - int type; - - // TODO get builid from elf header or build hash for elf - elf_file(const std::string &name) : filename(name), type(NATIVE_TYPE) { - elf_read_error = 0; - eh_frame_hdr_offset = 0; - fde_count = 0; - table_data = 0; - } - - elf_file() :type(NATIVE_TYPE) {} - - // TODO get builid from elf header or build hash for elf - void reset(const std::string &name) { - filename = name; - elf_read_error = 0; - eh_frame_hdr_offset = 0; - fde_count = 0; - table_data = 0; - } - - bool operator< (const elf_file &rhs) const { - return filename < rhs.filename; - } -}; - -struct symbol { - size_t start; - size_t end; - size_t ip; - std::string name; - - symbol() :start(0), end(0), ip(0) {} - symbol(size_t pc) :start(0), end(0), ip(pc) {} - - void reset(size_t va) { start = end = 0; ip = va; } - bool operator< (const symbol &sym) const { - return sym.ip < start; - } - - bool operator> (const symbol &sym) const { - return sym.ip > end; - } -}; - -struct vma { - size_t start; - size_t end; - size_t offset; - size_t pc; - int type; - std::string name; - struct { - unsigned char elf_read_error; - size_t eh_frame_hdr_offset; - size_t fde_count; - size_t table_data; - }; - - size_t map(size_t pc) { - return pc - start + offset; - } - - void set_type(int t) { type = t; } - - vma(size_t s, size_t e, size_t o, const std::string &n) - :start(s), end(e), offset(o), pc(0), type(NATIVE_TYPE), name(n) {} - - vma() : start(0), end(0), offset(0), pc(0), type(NATIVE_TYPE) {} - - vma(size_t addr) : start(0), end(0), offset(0), pc(addr), type(NATIVE_TYPE) {} - - bool operator<(const vma &vm) { - return vm.start < vm.pc; - } - - vma &operator=(const vma &vm) { - if (this == &vm) { - return *this; - } - start = vm.start; - end = vm.end; - offset = vm.offset; - name = vm.name; - return *this; - } -}; - -static inline bool operator==(const vma &lhs, const vma &rhs) { - return lhs.start == rhs.start && lhs.end == rhs.end && lhs.name == rhs.name; -} - -class symbol_parser { -private: - typedef std::map proc_vma; - - std::map > file_symbols; - std::map > java_symbols; - std::set kernel_symbols; - std::map machine_vma; - std::set java_procs; - std::map > symbols_cache; -public: - bool load_kernel(); - std::set& get_java_procs() { return java_procs; } - - bool find_kernel_symbol(symbol &sym); - bool complete_kernel_symbol(symbol &sym); - - /// @brief 从elf file中查找sym中地址对应的符号名存入sym - /// @param sym 符号对象 - /// @param file 进程对应的elf file - /// @param pid 进程 - /// @param pid_ns 进程的命名空间? - /// @return 查找成功返回true,否则返回false - bool find_elf_symbol(symbol &sym, const elf_file &file, int pid, int pid_ns); - bool find_java_symbol(symbol &sym, int pid, int pid_ns); - - bool get_symbol_info(int pid, symbol &sym, elf_file &file); - - bool find_vma(pid_t pid, vma &vm); - vma* find_vma(pid_t pid, size_t pc); - void clear_symbol_info(int); - bool add_pid_maps(int pid, size_t start, size_t end, size_t offset, const char *name); - - bool find_symbol_in_cache(int tgid, unsigned long addr, std::string &symbol); - bool putin_symbol_cache(int tgid, unsigned long addr, std::string &symbol); - - void dump(void); -private: - bool load_pid_maps(int pid); - /// @brief 对elf_file对应的符号表进行缓存 -/// @param pid 未使用 -/// @param file elf file -/// @return 缓存成功返回true,否则返回false - bool load_elf(pid_t pid, const elf_file& file); - bool load_perf_map(int pid, int pid_ns); -public: - int java_only; - int user_symbol; -}; - -extern symbol_parser g_symbol_parser; - -std::string demangleCppSym(std::string symbol); -void clearSpace(std::string &sym); - -#endif diff --git a/eBPF_Supermarket/Stack_Analyser/include/sa_ebpf.h b/eBPF_Supermarket/Stack_Analyser/include/ebpf.h similarity index 100% rename from eBPF_Supermarket/Stack_Analyser/include/sa_ebpf.h rename to eBPF_Supermarket/Stack_Analyser/include/ebpf.h diff --git a/eBPF_Supermarket/Stack_Analyser/include/trace_helpers.h b/eBPF_Supermarket/Stack_Analyser/include/trace.h similarity index 83% rename from eBPF_Supermarket/Stack_Analyser/include/trace_helpers.h rename to eBPF_Supermarket/Stack_Analyser/include/trace.h index 171bc4ee2..777248f94 100644 --- a/eBPF_Supermarket/Stack_Analyser/include/trace_helpers.h +++ b/eBPF_Supermarket/Stack_Analyser/include/trace.h @@ -4,9 +4,10 @@ #include -#define NSEC_PER_SEC 1000000000ULL +#define NSEC_PER_SEC 1000000000ULL -struct ksym { +struct ksym +{ const char *name; unsigned long addr; }; @@ -16,11 +17,12 @@ struct ksyms; struct ksyms *ksyms__load(void); void ksyms__free(struct ksyms *ksyms); const struct ksym *ksyms__map_addr(const struct ksyms *ksyms, - unsigned long addr); + unsigned long addr); const struct ksym *ksyms__get_symbol(const struct ksyms *ksyms, - const char *name); + const char *name); -struct sym { +struct sym +{ const char *name; unsigned long start; unsigned long size; @@ -30,11 +32,11 @@ struct sym { struct syms; struct syms *syms__load_pid(int tgid); -struct syms *syms__load_file(const char *fname); +struct syms *syms__load_file(const char *fname, int tgid); void syms__free(struct syms *syms); -const struct sym *syms__map_addr(const struct syms *syms, unsigned long addr); +struct sym *syms__map_addr(const struct syms *syms, unsigned long addr); const struct sym *syms__map_addr_dso(const struct syms *syms, unsigned long addr, - char **dso_name, unsigned long *dso_offset); + char **dso_name, unsigned long *dso_offset); struct syms_cache; @@ -42,7 +44,8 @@ struct syms_cache *syms_cache__new(int nr); struct syms *syms_cache__get_syms(struct syms_cache *syms_cache, int tgid); void syms_cache__free(struct syms_cache *syms_cache); -struct partition { +struct partition +{ char *name; unsigned int dev; }; @@ -58,7 +61,7 @@ partitions__get_by_name(const struct partitions *partitions, const char *name); void print_log2_hist(unsigned int *vals, int vals_size, const char *val_type); void print_linear_hist(unsigned int *vals, int vals_size, unsigned int base, - unsigned int step, const char *val_type); + unsigned int step, const char *val_type); unsigned long long get_ktime_ns(void); @@ -100,5 +103,11 @@ bool module_btf_exists(const char *mod); bool probe_tp_btf(const char *name); bool probe_ringbuf(); +const struct ksym *ksyms__find_symbol(const struct ksyms *ksyms, + const char *name); + +extern struct ksyms *ksyms; +extern struct syms_cache *syms_cache; +extern struct syms *syms; #endif /* __TRACE_HELPERS_H */ diff --git a/eBPF_Supermarket/Stack_Analyser/include/uprobe_helpers.h b/eBPF_Supermarket/Stack_Analyser/include/uprobe.h similarity index 100% rename from eBPF_Supermarket/Stack_Analyser/include/uprobe_helpers.h rename to eBPF_Supermarket/Stack_Analyser/include/uprobe.h diff --git a/eBPF_Supermarket/Stack_Analyser/include/sa_user.h b/eBPF_Supermarket/Stack_Analyser/include/user.h similarity index 97% rename from eBPF_Supermarket/Stack_Analyser/include/sa_user.h rename to eBPF_Supermarket/Stack_Analyser/include/user.h index b54352a6c..b46c53a76 100644 --- a/eBPF_Supermarket/Stack_Analyser/include/sa_user.h +++ b/eBPF_Supermarket/Stack_Analyser/include/user.h @@ -26,7 +26,14 @@ #include #include -#include "sa_common.h" +#include "common.h" + +#define _COL_PREFIX "\033[" +#define _BLUE _COL_PREFIX "1;34m" +#define _GREEN _COL_PREFIX "1;32m" +#define _RED _COL_PREFIX "1;35m" +#define _ERED _COL_PREFIX "1;31m" +#define _RE _COL_PREFIX "0m" #define PUT_ERR_REASON \ fprintf(stderr, _ERED " [%s]\n" _RE, strerror(errno)); @@ -49,7 +56,7 @@ /// @param info 要打印的错误信息 #define CHECK_ERR(action, cond, ...) \ if (cond) \ - DEAL_ERR(action, __VA_ARGS__) + DEAL_ERR(action, __VA_ARGS__) /// @brief 检查错误,若错误成立则打印带原因的错误信息并使上层函数返回-1 /// @param cond 被检查的条件表达式 @@ -67,4 +74,17 @@ #define COLLECTOR_INFO(_name) _BLUE "\b\b\b\bCollector for " _name " trace" _RE +inline void clearSpace(char *sym) +{ + for (char *p = sym; *p; p++) + { + if (*p != ' ') + { + *sym = *p; + sym++; + } + } + *sym = '\0'; +} + #endif diff --git a/eBPF_Supermarket/Stack_Analyser/src/bpf_wapper/eBPFStackCollector.cpp b/eBPF_Supermarket/Stack_Analyser/src/bpf_wapper/eBPFStackCollector.cpp index d3aa81547..2f99dcc35 100644 --- a/eBPF_Supermarket/Stack_Analyser/src/bpf_wapper/eBPFStackCollector.cpp +++ b/eBPF_Supermarket/Stack_Analyser/src/bpf_wapper/eBPFStackCollector.cpp @@ -17,14 +17,15 @@ // 包装用于采集调用栈数据的eBPF程序,规定一些抽象接口和通用变量 #include "bpf_wapper/eBPFStackCollector.h" -#include "sa_user.h" -#include "dt_symbol.h" +#include "user.h" +#include "trace.h" #include #include #include #include #include +#include std::string getLocalDateTime(void) { @@ -142,39 +143,36 @@ StackCollector::operator std::string() auto trace_fd = bpf_object__find_map_fd_by_name(obj, "sid_trace_map"); if (id.usid > 0 && traces.find(id.usid) == traces.end()) { - bpf_map_lookup_elem(trace_fd, &id.usid, trace); - for (p = trace + MAX_STACKS - 1; !*p; p--) - ; - std::vector sym_trace(p - trace + 1); - for (int i = 0; p >= trace; p--) + syms = syms_cache__get_syms(syms_cache, id.pid); + if (!syms) + fprintf(stderr, "failed to get syms\n"); + else { - uint64_t &addr = *p; - symbol sym; - sym.reset(addr); - elf_file file; - if (g_symbol_parser.find_symbol_in_cache(id.pid, addr, sym.name)) + bpf_map_lookup_elem(trace_fd, &id.usid, trace); + for (p = trace + MAX_STACKS - 1; !*p; p--) ; - else if (g_symbol_parser.get_symbol_info(id.pid, sym, file) && g_symbol_parser.find_elf_symbol(sym, file, id.pid, id.pid)) - { - if (sym.name[0] == '_' && sym.name[1] == 'Z') - // 代表是C++符号,则调用demangle解析 - sym.name = demangleCppSym(sym.name); - std::stringstream ss(""); - ss << "+0x" << std::hex << (sym.ip - sym.start); - sym.name += ss.str(); - clearSpace(sym.name); - g_symbol_parser.putin_symbol_cache(id.pid, addr, sym.name); - } - else + std::vector sym_trace(p - trace + 1); + for (int i = 0; p >= trace; p--) { - std::stringstream ss(""); - ss << "0x" << std::hex << sym.ip; - sym.name = ss.str(); - g_symbol_parser.putin_symbol_cache(id.pid, addr, sym.name); + struct sym *sym = syms__map_addr(syms, *p); + if (sym) + { + if (sym->name[0] == '_' && sym->name[1] == 'Z') + { + char *demangled = abi::__cxa_demangle(sym->name, NULL, NULL, NULL); + if (demangled) + { + clearSpace(demangled); + sym->name = demangled; + } + } + sym_trace[i++] = std::string(sym->name) + "+" + std::to_string(sym->offset); + } + else + sym_trace[i++] = "[unknown]"; } - sym_trace[i++] = sym.name; + traces[id.usid] = sym_trace; } - traces[id.usid] = sym_trace; } if (id.ksid > 0 && traces.find(id.ksid) == traces.end()) { @@ -184,22 +182,9 @@ StackCollector::operator std::string() std::vector sym_trace(p - trace + 1); for (int i = 0; p >= trace; p--) { - uint64_t &addr = *p; - symbol sym; - sym.reset(addr); - std::stringstream ss(""); - if (g_symbol_parser.find_kernel_symbol(sym)) - { - ss << "+0x" << std::hex << (sym.ip - sym.start); - sym.name += ss.str(); - clearSpace(sym.name); - } - else - { - ss << "0x" << std::hex << addr; - sym.name = ss.str(); - } - sym_trace[i++] = sym.name; + const struct ksym *ksym = ksyms__map_addr(ksyms, *p); + sym_trace[i++] = ksym ? std::string(ksym->name) + "+" + std::to_string(*p - ksym->addr) + : "[unknown]"; } traces[id.ksid] = sym_trace; } diff --git a/eBPF_Supermarket/Stack_Analyser/src/bpf_wapper/memleak.cpp b/eBPF_Supermarket/Stack_Analyser/src/bpf_wapper/memleak.cpp index 9a9c5ae1f..d8224de6d 100644 --- a/eBPF_Supermarket/Stack_Analyser/src/bpf_wapper/memleak.cpp +++ b/eBPF_Supermarket/Stack_Analyser/src/bpf_wapper/memleak.cpp @@ -17,7 +17,7 @@ // mem ebpf程序的包装类,实现接口和一些自定义方法 #include "bpf_wapper/memleak.h" -#include "trace_helpers.h" +#include "trace.h" #include uint64_t *MemleakStackCollector::count_values(void *d) diff --git a/eBPF_Supermarket/Stack_Analyser/src/bpf_wapper/off_cpu.cpp b/eBPF_Supermarket/Stack_Analyser/src/bpf_wapper/off_cpu.cpp index 1d9411b3d..d1cd1d9ba 100644 --- a/eBPF_Supermarket/Stack_Analyser/src/bpf_wapper/off_cpu.cpp +++ b/eBPF_Supermarket/Stack_Analyser/src/bpf_wapper/off_cpu.cpp @@ -17,7 +17,7 @@ // off cpu ebpf程序的包装类,实现接口和一些自定义方法 #include "bpf_wapper/off_cpu.h" -#include "dt_symbol.h" +#include "trace.h" OffCPUStackCollector::OffCPUStackCollector() { @@ -37,13 +37,11 @@ uint64_t *OffCPUStackCollector::count_values(void *data) int OffCPUStackCollector::ready(void) { EBPF_LOAD_OPEN_INIT(); - symbol sym; - sym.name = "finish_task_switch"; - if (!g_symbol_parser.complete_kernel_symbol(sym)) - { + const char *name = "finish_task_switch"; + const struct ksym *ksym = ksyms__find_symbol(ksyms, name); + if (!ksym) return -1; - } - skel->links.do_stack = bpf_program__attach_kprobe(skel->progs.do_stack, false, sym.name.c_str()); + skel->links.do_stack = bpf_program__attach_kprobe(skel->progs.do_stack, false, ksym->name); return 0; } diff --git a/eBPF_Supermarket/Stack_Analyser/src/bpf_wapper/probe.cpp b/eBPF_Supermarket/Stack_Analyser/src/bpf_wapper/probe.cpp index 2fa9e0b67..6b720c6b8 100644 --- a/eBPF_Supermarket/Stack_Analyser/src/bpf_wapper/probe.cpp +++ b/eBPF_Supermarket/Stack_Analyser/src/bpf_wapper/probe.cpp @@ -17,8 +17,8 @@ // ebpf程序包装类的模板,实现接口和一些自定义方法 #include "bpf_wapper/probe.h" -#include "trace_helpers.h" -#include "uprobe_helpers.h" +#include "trace.h" +#include "uprobe.h" void splitStr(const std::string &symbol, const char split, std::vector &res) { diff --git a/eBPF_Supermarket/Stack_Analyser/src/cgroup.cpp b/eBPF_Supermarket/Stack_Analyser/src/cgroup.cpp new file mode 100644 index 000000000..fb6b4ad79 --- /dev/null +++ b/eBPF_Supermarket/Stack_Analyser/src/cgroup.cpp @@ -0,0 +1,56 @@ +#include +#include +#include +#include +#include +#include +#include +#include "cgroup.h" + +uint64_t get_cgroupid(const char *pathname) +{ + struct statfs fs; + int err; + struct cgid_file_handle *h; + int mount_id; + uint64_t ret; + + err = statfs(pathname, &fs); + if (err != 0) + { + fprintf(stderr, "statfs on %s failed: %s\n", pathname, strerror(errno)); + exit(1); + } + + if ((fs.f_type != (typeof(fs.f_type))CGROUP2_SUPER_MAGIC)) + { + fprintf(stderr, "File %s is not on a cgroup2 mount.\n", pathname); + exit(1); + } + + h = (cgid_file_handle *)malloc(sizeof(struct cgid_file_handle)); + if (!h) + { + fprintf(stderr, "Cannot allocate memory.\n"); + exit(1); + } + + h->handle_bytes = 8; + err = name_to_handle_at(AT_FDCWD, pathname, (struct file_handle *)h, &mount_id, 0); + if (err != 0) + { + fprintf(stderr, "name_to_handle_at failed: %s\n", strerror(errno)); + exit(1); + } + + if (h->handle_bytes != 8) + { + fprintf(stderr, "Unexpected handle size: %d. \n", h->handle_bytes); + exit(1); + } + + ret = h->cgid; + free(h); + + return ret; +} \ No newline at end of file diff --git a/eBPF_Supermarket/Stack_Analyser/src/dt_elf.cpp b/eBPF_Supermarket/Stack_Analyser/src/dt_elf.cpp deleted file mode 100644 index d040e8936..000000000 --- a/eBPF_Supermarket/Stack_Analyser/src/dt_elf.cpp +++ /dev/null @@ -1,621 +0,0 @@ -/* - * Linux内核诊断工具--elf相关公共函数 - * - * Copyright (C) 2020 Alibaba Ltd. - * - * License terms: GNU General Public License (GPL) version 3 - * - */ -#include "dt_elf.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define NOTE_ALIGN(n) (((n) + 3) & -4U) - -struct sym_section_ctx -{ - Elf_Data *syms; - Elf_Data *symstrs; - Elf_Data *rel_data; - int is_reloc; - int is_plt; - int sym_count; - int plt_rel_type; - unsigned long plt_offset; - unsigned long plt_entsize; -}; - -struct symbol_sections_ctx -{ - sym_section_ctx symtab; - sym_section_ctx symtab_in_dynsym; - sym_section_ctx dynsymtab; -}; - -struct section_info -{ - Elf_Scn *sec; - GElf_Shdr *hdr; -}; - -struct plt_ctx -{ - section_info dynsym; - section_info plt_rel; - section_info plt; -}; - -__attribute__((unused)) static Elf_Scn *elf_section_by_name(Elf *elf, GElf_Ehdr *ep, - GElf_Shdr *shp, const char *name, - size_t *idx) -{ - Elf_Scn *sec = NULL; - size_t cnt = 1; - - /* Elf is corrupted/truncated, avoid calling elf_strptr. */ - if (!elf_rawdata(elf_getscn(elf, ep->e_shstrndx), NULL)) - return NULL; - - while ((sec = elf_nextscn(elf, sec)) != NULL) - { - char *str; - - gelf_getshdr(sec, shp); - str = elf_strptr(elf, ep->e_shstrndx, shp->sh_name); - - if (!strcmp(name, str)) - { - if (idx) - *idx = cnt; - - break; - } - - ++cnt; - } - - return sec; -} - -__attribute__((unused)) static int elf_read_build_id(Elf *elf, char *bf, size_t size) -{ - int err = -1; - GElf_Ehdr ehdr; - GElf_Shdr shdr; - Elf_Data *data; - Elf_Scn *sec; - Elf_Kind ek; - char *ptr; - - if (size < BUILD_ID_SIZE) - goto out; - - ek = elf_kind(elf); - - if (ek != ELF_K_ELF) - goto out; - - if (gelf_getehdr(elf, &ehdr) == NULL) - { - fprintf(stderr, "%s: cannot get elf header.\n", __func__); - goto out; - } - - /* - * Check following sections for notes: - * '.note.gnu.build-id' - * '.notes' - * '.note' (VDSO specific) - */ - do - { - sec = elf_section_by_name(elf, &ehdr, &shdr, - ".note.gnu.build-id", NULL); - - if (sec) - break; - - sec = elf_section_by_name(elf, &ehdr, &shdr, - ".notes", NULL); - - if (sec) - break; - - sec = elf_section_by_name(elf, &ehdr, &shdr, - ".note", NULL); - - if (sec) - break; - - return err; - - } while (0); - - data = elf_getdata(sec, NULL); - - if (data == NULL) - goto out; - - ptr = (char *)data->d_buf; - - while ((intptr_t)ptr < (intptr_t)((char *)data->d_buf + data->d_size)) - { - GElf_Nhdr *nhdr = (GElf_Nhdr *)ptr; - size_t namesz = NOTE_ALIGN(nhdr->n_namesz), - descsz = NOTE_ALIGN(nhdr->n_descsz); - const char *name; - - ptr += sizeof(*nhdr); - name = (const char *)ptr; - ptr += namesz; - - if (nhdr->n_type == NT_GNU_BUILD_ID && - nhdr->n_namesz == sizeof("GNU")) - { - if (memcmp(name, "GNU", sizeof("GNU")) == 0) - { - size_t sz = size < descsz ? size : descsz; - memcpy(bf, ptr, sz); - memset(bf + sz, 0, size - sz); - err = descsz; - break; - } - } - - ptr += descsz; - } - -out: - return err; -} - -extern int calc_sha1_1M(const char *filename, unsigned char *buf); - -int filename__read_build_id(int pid, const char *mnt_ns_name, const char *filename, char *bf, size_t size) -{ - int fd, err = -1; - struct stat sb; - - if (size < BUILD_ID_SIZE) - goto out; - - fd = open(filename, O_RDONLY); - - if (fd < 0) - goto out; - - if (fstat(fd, &sb) == 0) - { - snprintf(bf, size, "%s[%lu]", filename, sb.st_size); - err = 0; - } - - close(fd); -out: - return err; -} - -static int is_function(const GElf_Sym *sym) -{ - return GELF_ST_TYPE(sym->st_info) == STT_FUNC && - sym->st_name != 0 && - sym->st_shndx != SHN_UNDEF; -} - -static int get_symbols_in_section(sym_section_ctx *sym, Elf *elf, Elf_Scn *sec, GElf_Shdr *shdr, int is_reloc) -{ - sym->syms = elf_getdata(sec, NULL); - if (!sym->syms) - { - return -1; - } - - Elf_Scn *symstrs_sec = elf_getscn(elf, shdr->sh_link); - if (!sec) - { - return -1; - } - - sym->symstrs = elf_getdata(symstrs_sec, NULL); - if (!sym->symstrs) - { - return -1; - } - - sym->sym_count = shdr->sh_size / shdr->sh_entsize; - sym->is_plt = 0; - sym->is_reloc = is_reloc; - - return 0; -} - -static int get_plt_symbols_in_section(sym_section_ctx *sym, Elf *elf, plt_ctx *plt) -{ - sym->syms = elf_getdata(plt->dynsym.sec, NULL); - if (!sym->syms) - { - return -1; - } - - sym->rel_data = elf_getdata(plt->plt_rel.sec, NULL); - if (!sym->rel_data) - { - return -1; - } - - Elf_Scn *symstrs_sec = elf_getscn(elf, plt->dynsym.hdr->sh_link); - if (!symstrs_sec) - { - return -1; - } - - sym->symstrs = elf_getdata(symstrs_sec, NULL); - if (!sym->symstrs) - { - return -1; - } - - sym->is_plt = 1; - sym->plt_entsize = plt->plt.hdr->sh_type; - sym->plt_offset = plt->plt.hdr->sh_offset; - sym->sym_count = plt->plt_rel.hdr->sh_size / plt->plt_rel.hdr->sh_entsize; - sym->plt_rel_type = plt->plt_rel.hdr->sh_type; - - return 0; -} - -static void __get_plt_symbol(std::set &ss, symbol_sections_ctx *si, Elf *elf) -{ - symbol s; - GElf_Sym sym; - int symidx; - int index = 0; - const char *sym_name = NULL; - - s.end = 0; - s.start = 0; - - if (!si->dynsymtab.syms) - { - return; - } - - while (index < si->dynsymtab.sym_count) - { - if (si->dynsymtab.plt_rel_type == SHT_RELA) - { - GElf_Rela pos_mem, *pos; - pos = gelf_getrela(si->dynsymtab.rel_data, index, &pos_mem); - symidx = GELF_R_SYM(pos->r_info); - } - else if (si->dynsymtab.plt_rel_type == SHT_REL) - { - GElf_Rel pos_mem, *pos; - pos = gelf_getrel(si->dynsymtab.rel_data, index, &pos_mem); - symidx = GELF_R_SYM(pos->r_info); - } - else - { - return; - } - index++; - si->dynsymtab.plt_offset += si->dynsymtab.plt_entsize; - gelf_getsym(si->dynsymtab.syms, symidx, &sym); - - sym_name = (const char *)si->dynsymtab.symstrs->d_buf + sym.st_name; - s.start = si->dynsymtab.plt_offset; - s.end = s.start + si->dynsymtab.plt_entsize; - s.ip = s.start; - s.name = sym_name; - ss.insert(s); - } -} - -static void __get_symbol_without_plt(std::set &ss, sym_section_ctx *tab, Elf *elf) -{ - GElf_Sym sym; - int index = 0; - const char *sym_name; - symbol s; - s.end = 0; - s.start = 0; - - while (index < tab->sym_count) - { - gelf_getsym(tab->syms, index, &sym); - index++; - if (sym.st_shndx == SHN_ABS) - { - continue; - } - if (!is_function(&sym)) - { - continue; - } - sym_name = (const char *)tab->symstrs->d_buf + sym.st_name; - if (tab->is_reloc) - { - Elf_Scn *sec = elf_getscn(elf, sym.st_shndx); - if (!sec) - { - continue; - } - GElf_Shdr shdr; - gelf_getshdr(sec, &shdr); - sym.st_value -= shdr.sh_addr - shdr.sh_offset; - } - s.start = sym.st_value & 0xffffffff; - s.end = s.start + sym.st_size; - s.ip = s.start; - s.name = sym_name; - ss.insert(s); - } -} - -static void __get_symbol(std::set &ss, symbol_sections_ctx *si, Elf *elf) -{ - symbol s; - s.end = 0; - s.start = 0; - - if (!si->symtab.syms && !si->dynsymtab.syms) - { - return; - } - - sym_section_ctx *tab = &si->symtab; - __get_symbol_without_plt(ss, tab, elf); - tab = &si->symtab_in_dynsym; - __get_symbol_without_plt(ss, tab, elf); -} - -static void get_all_symbols(std::set &ss, symbol_sections_ctx *si, Elf *elf) -{ - __get_symbol(ss, si, elf); - __get_plt_symbol(ss, si, elf); -} - -bool search_symbol(const std::set &ss, symbol &sym) -{ - std::set::const_iterator it = ss.find(sym); - - if (it != ss.end()) - { - sym.end = it->end; - sym.start = it->start; - sym.name = it->name; - - return true; - } - - return false; -} - -bool get_symbol_from_elf(std::set &ss, const char *path) -{ - // static int first_init = 0; - - // if (!first_init) { - // first_init = true; - // init_global_env(); - // } - - int is_reloc = 0; - elf_version(EV_CURRENT); - int fd = open(path, O_RDONLY); - - Elf *elf = elf_begin(fd, ELF_C_READ, NULL); - if (elf == NULL) - { - close(fd); - return false; - } - - Elf_Kind ek = elf_kind(elf); - if (ek != ELF_K_ELF) - { - elf_end(elf); - close(fd); - return false; - } - GElf_Ehdr hdr; - if (gelf_getehdr(elf, &hdr) == NULL) - { - elf_end(elf); - close(fd); - return false; - } - - if (hdr.e_type == ET_EXEC) - { - is_reloc = 1; - } - - if (!elf_rawdata(elf_getscn(elf, hdr.e_shstrndx), NULL)) - { - elf_end(elf); - close(fd); - return false; - } - - GElf_Shdr shdr; - GElf_Shdr symtab_shdr; - GElf_Shdr dynsym_shdr; - GElf_Shdr plt_shdr; - GElf_Shdr plt_rel_shdr; - memset(&shdr, 0, sizeof(shdr)); - memset(&symtab_shdr, 0, sizeof(symtab_shdr)); - memset(&dynsym_shdr, 0, sizeof(dynsym_shdr)); - memset(&plt_shdr, 0, sizeof(plt_shdr)); - memset(&plt_rel_shdr, 0, sizeof(plt_rel_shdr)); - - Elf_Scn *sec = NULL; - Elf_Scn *dynsym_sec = NULL; - Elf_Scn *symtab_sec = NULL; - Elf_Scn *plt_sec = NULL; - Elf_Scn *plt_rel_sec = NULL; - - while ((sec = elf_nextscn(elf, sec)) != NULL) - { - char *str; - gelf_getshdr(sec, &shdr); - str = elf_strptr(elf, hdr.e_shstrndx, shdr.sh_name); - - if (str && strcmp(".symtab", str) == 0) - { - symtab_sec = sec; - memcpy(&symtab_shdr, &shdr, sizeof(dynsym_shdr)); - } - if (str && strcmp(".dynsym", str) == 0) - { - dynsym_sec = sec; - memcpy(&dynsym_shdr, &shdr, sizeof(dynsym_shdr)); - } - if (str && strcmp(".rela.plt", str) == 0) - { - plt_rel_sec = sec; - memcpy(&plt_rel_shdr, &shdr, sizeof(plt_rel_shdr)); - } - if (str && strcmp(".plt", str) == 0) - { - plt_sec = sec; - memcpy(&plt_shdr, &shdr, sizeof(plt_shdr)); - } - if (str && strcmp(".gnu.prelink_undo", str) == 0) - { - is_reloc = 1; - } - } - - plt_ctx plt; - plt.dynsym.hdr = &dynsym_shdr; - plt.dynsym.sec = dynsym_sec; - plt.plt.hdr = &plt_shdr; - plt.plt.sec = plt_sec; - plt.plt_rel.hdr = &plt_rel_shdr; - plt.plt_rel.sec = plt_rel_sec; - - symbol_sections_ctx si; - memset(&si, 0, sizeof(si)); - if (symtab_sec) - { - get_symbols_in_section(&si.symtab, elf, symtab_sec, &symtab_shdr, is_reloc); - } - if (dynsym_sec) - { - get_symbols_in_section(&si.symtab_in_dynsym, elf, dynsym_sec, &dynsym_shdr, is_reloc); - } - if (dynsym_sec && plt_sec) - { - get_plt_symbols_in_section(&si.dynsymtab, elf, &plt); - } - - get_all_symbols(ss, &si, elf); - elf_end(elf); - close(fd); - return true; -} - -struct symbol_cache_item -{ - int start; - int size; - char name[0]; -}; - -bool save_symbol_cache(std::set &ss, const char *path) -{ - char buf[2048]; - int len = 0; - bool status = true; - - int fd = open(path, O_RDONLY); - if (fd < 0) - { - status = false; - return status; - } - int ret; - ret = read(fd, &len, 4); - if (ret <= 0) - { - close(fd); - status = false; - return status; - } - ret = read(fd, buf, len); - if (ret <= 0) - { - close(fd); - status = false; - return status; - } - - while (1) - { - struct symbol_cache_item *sym; - symbol s; - ret = read(fd, &len, 4); - if (ret <= 0) - { - status = false; - break; - } - ret = read(fd, buf, len); - if (ret < len) - { - status = false; - break; - } - sym = (struct symbol_cache_item *)buf; - s.start = sym->start; - s.end = sym->start + sym->size; - s.ip = sym->start; - s.name = sym->name; - ss.insert(s); - } - close(fd); - return status; -} - -bool load_symbol_cache(std::set &ss, const char *path, const char *filename) -{ - int fd = open(path, O_RDWR | O_EXCL); - if (fd < 0) - { - return false; - } - int len = strlen(filename); - int ret = write(fd, &len, 4); - if (ret < 0) - { - close(fd); - return false; - } - ret = write(fd, filename, len); - if (ret < 0) - { - close(fd); - return false; - } - - std::set::iterator it; - int v; - for (it = ss.begin(); it != ss.end(); ++it) - { - v = it->start; - ret = write(fd, &v, 4); - v = it->end - it->start; - ret = write(fd, &v, 4); - ret = write(fd, it->name.c_str(), it->name.length()); - } - return true; -} diff --git a/eBPF_Supermarket/Stack_Analyser/src/dt_symbol.cpp b/eBPF_Supermarket/Stack_Analyser/src/dt_symbol.cpp deleted file mode 100644 index 07bb4fba6..000000000 --- a/eBPF_Supermarket/Stack_Analyser/src/dt_symbol.cpp +++ /dev/null @@ -1,587 +0,0 @@ -/* - * Linux内核诊断工具--用户态符号表解析 - * - * Copyright (C) 2020 Alibaba Ltd. - * - * License terms: GNU General Public License (GPL) version 3 - * - */ - -#include -#include -#include -#include - -#include "dt_symbol.h" -#include "dt_elf.h" - -void restore_global_env(); -int attach_ns_env(int pid); - -symbol_parser g_symbol_parser; -const bool debug_mode = false; - -bool symbol_parser::add_pid_maps(int pid, size_t start, size_t end, size_t offset, const char *name) -{ - std::map::iterator it; - it = machine_vma.find(pid); - if (it == machine_vma.end()) { - proc_vma proc; - machine_vma.insert(make_pair(pid, proc)); - it = machine_vma.find(pid); - if (it == machine_vma.end()) { - return false; - } - } - - vma vm(start, end, offset, name); - it->second.insert(std::make_pair(vm.start, std::move(vm))); - - return true; -} - -bool symbol_parser::load_pid_maps(int pid) -{ - std::map::iterator it; - it = machine_vma.find(pid); - if (it != machine_vma.end()) { - return true; - } - - proc_vma proc; - char fn[23]; - sprintf(fn, "/proc/%d/maps", pid); - FILE *fp = fopen(fn, "r"); - if (!fp) { - return false; - } - - char buf[4096]; - char exename[4096]; - size_t start, end, offset; - while (fgets(buf, sizeof(buf), fp) != NULL) { - start = end = offset = 0; - exename[0] = '\0'; - sscanf(buf, "%lx-%lx %*s %lx %*x:%*x %*u %s %*s\n", &start, &end, &offset, exename); - if (exename[0] == '\0') { - strcpy(exename, "[anon]"); - } - vma vm(start, end, offset, exename); - proc.insert(std::make_pair(vm.start, std::move(vm))); - } - - fclose(fp); - - machine_vma.insert(std::make_pair(pid, std::move(proc))); - it = machine_vma.find(pid); - if (it == machine_vma.end()) { - return false; - } - - return true; -} - -bool symbol_parser::load_perf_map(int pid, int pid_ns) -{ -#if 0 - if (pid != pid_ns) { - if (attach_ns_env(pid) < 0) { - return false; - } - } -#endif - char perfmapfile[64]; - snprintf(perfmapfile, sizeof(perfmapfile), "/tmp/perf-%d.map", pid); - FILE *fp = fopen(perfmapfile, "r"); - if (fp == NULL) { - if (debug_mode) { - printf("cannot read perf map %d\n", pid); - } - return false; - } - char line[256]; - char *buf; - long start; - int size; - char name[256]; - std::set syms; - symbol sym; - while ((buf = fgets(line, sizeof(line), fp)) != NULL) { - sscanf(buf, "%lx %x %s\n", &start, &size, name); - sym.start = start; - sym.end = sym.start + size; - sym.ip = sym.start; - sym.name = name; - syms.insert(sym); - } - java_symbols.insert(make_pair(pid, std::move(syms))); -#if 0 - if (pid != pid_ns) { - restore_global_env(); - } -#endif - return true; -} - -bool symbol_parser::find_java_symbol(symbol &sym, int pid, int pid_ns) -{ - std::set ss; - std::map >::iterator it; - //bool load_now = false; - it = java_symbols.find(pid); - if (it == java_symbols.end()) { - if (!load_perf_map(pid, pid_ns)) { - return false; - } - //load_now = true; - it = java_symbols.find(pid); - return search_symbol(it->second, sym); - } else { - return search_symbol(it->second, sym); - } - return true; - - //bool ret = search_symbol(syms, sym); -#if 0 - if (!ret && !load_now) { - java_symbols.erase(pid); - if (!load_perf_map(pid)) { - return false; - } - syms = java_symbols.find(pid)->second; - return search_symbol(syms, sym); - } -#endif - //return ret; -} - -static bool load_kernel_symbol_list(std::vector &sym_list) -{ - FILE *fp = fopen("/proc/kallsyms", "r"); - if (!fp) { - return -1; - } - - char buf[256]; - char type; - int len; - while (fgets(buf, sizeof(buf), fp) != NULL) { - sscanf(buf, "%*p %c %*s\n", &type); - if ((type | 0x20) != 't') { - continue; - } - len = strlen(buf); - if (buf[len-1] == '\n') { - buf[len-1] = '\0'; - } - sym_list.push_back(buf); - } - fclose(fp); - - std::sort(sym_list.begin(), sym_list.end()); - return true; -} - -bool is_space(int ch) { - return std::isspace(ch); -} - -static inline void rtrim(std::string &s) -{ - s.erase(std::find_if(s.rbegin(), s.rend(), is_space).base(), s.end()); -} - -static bool get_next_kernel_symbol( - std::set &syms, - std::vector &sym_list, - std::vector::iterator cursor) -{ - if (cursor == sym_list.end()) { - return false; - } - symbol sym; - size_t start, end; - sscanf(cursor->c_str(), "%p %*c %*s\n", (void **)&start); - sym.name = cursor->c_str() + 19; - // rtrim(sym.name); -// #if 0 - // if (sym.name[sym.name.size()-1] == ' ') { - // // sym.name[sym.name.size()-1] = '\0'; - // sym.name.pop_back(); - // } -// #endif - cursor++; - if (cursor != sym_list.end()) { - sscanf(cursor->c_str(), "%p %*c %*s\n", (void **)&end); - } - else { - end = INVALID_ADDR; - } - sym.start = start; - sym.end = end; - sym.ip = start; - - syms.insert(sym); - return true; -} - -bool symbol_parser::load_kernel() -{ - if (kernel_symbols.size() != 0) { - return true; - } - - std::vector sym_list; - if (!load_kernel_symbol_list(sym_list)) { - exit(0); - return false; - } - - std::vector::iterator cursor = sym_list.begin(); - while (get_next_kernel_symbol(kernel_symbols, sym_list, cursor)) { - cursor++; - } - return true; -} - -bool symbol_parser::load_elf(pid_t pid, const elf_file &file) -{ - std::map >::iterator it; - it = file_symbols.find(file); - std::set tmp; - std::set &syms = tmp; - if (it != file_symbols.end()) { - return true; - } - if (get_symbol_from_elf(syms, file.filename.c_str())) { - file_symbols.insert(make_pair(file, std::move(syms))); - return true; - } - return false; -} - -bool symbol_parser::find_kernel_symbol(symbol &sym) -{ - load_kernel(); - sym.end = sym.start = 0; - std::set::iterator it = kernel_symbols.find(sym); - if (it != kernel_symbols.end()) { - sym.end = it->end; - sym.start = it->start; - sym.name = it->name; - return true; - } - return false; -} - -bool symbol_parser::complete_kernel_symbol(symbol &sym) -{ - load_kernel(); - sym.end = sym.start = 0; - for (auto it = kernel_symbols.begin(); it != kernel_symbols.end(); ++it) { - auto size = sym.name.size(), tsize = it->name.size(); - if(size > tsize || it->name.substr(tsize-5, 5) == ".cold") { - continue; - } - if(it->name.substr(0, size) == sym.name) { - sym.end = it->end; - sym.start = it->start; - sym.name = it->name; - return true; - } - } - return false; -} - -bool symbol_parser::find_symbol_in_cache(int tgid, unsigned long addr, std::string &symbol) -{ - std::map >::const_iterator it_pid = - symbols_cache.find(tgid); - - if (it_pid != symbols_cache.end()) { - std::map map = symbols_cache[tgid]; - std::map::const_iterator it_symbol = - map.find(addr); - - if (it_symbol != map.end()) { - symbol = map[addr]; - - return true; - } - } - - return false; -} - -bool symbol_parser::putin_symbol_cache(int tgid, unsigned long addr, std::string &symbol) -{ - std::map >::const_iterator it_pid = - symbols_cache.find(tgid); - - if (it_pid == symbols_cache.end()) { - std::map map; - symbols_cache.insert(std::make_pair(tgid, map)); - } - - std::map &map = symbols_cache[tgid]; - std::map::const_iterator it_symbol = - map.find(addr); - - if (it_symbol == map.end()) { - map[addr] = symbol; - return true; - } - - return false; -} - -/// @brief 找到指定进程中的虚拟地址对应的在可执行文件中相对于文件开始的偏移,赋给sym.ip -/// @param pid 指定进程的pid -/// @param sym 提供进程虚拟地址 -/// @param file 文件信息 -/// @return 成功找到返回true -bool symbol_parser::get_symbol_info(int pid, symbol &sym, elf_file &file) -{ - std::map::iterator proc_vma_info; - - if (java_only) { - file.type = UNKNOWN; - return true; - } - - proc_vma_info = machine_vma.find(pid); - if (proc_vma_info == machine_vma.end()) { - if (!load_pid_maps(pid)) { - if (debug_mode) { - printf("load pid maps failed\n"); - } - return false; - } - } - - vma area(sym.ip); - if (!find_vma(pid, area)) { - if (debug_mode) { - printf("find vma failed\n"); - } - return false; - } - if (area.name == "[anon]") { - file.type = JIT_TYPE; - } - - file.reset(area.name); - if (file.type != JIT_TYPE) { - sym.reset(area.map(sym.ip)); - } - - return true; -} - -bool symbol_parser::find_elf_symbol(symbol &sym, const elf_file &file, int pid, int pid_ns) -{ - if (java_only) { - return find_java_symbol(sym, pid, pid_ns); - } - - if (file.type == JIT_TYPE) { - return find_java_symbol(sym, pid, pid_ns); - } - - std::map >::iterator it; - it = file_symbols.find(file); - std::set ss; - if (it == file_symbols.end()) { - if (!load_elf(pid, file)) { - return false; - } - it = file_symbols.find(file); - } - return search_symbol(it->second, sym); -} - -vma* symbol_parser::find_vma(pid_t pid, size_t pc) -{ - std::map::iterator it; - - it = machine_vma.find(pid); - if (it == machine_vma.end()) { - return NULL; - } - - proc_vma::iterator vma_iter = it->second.upper_bound(pc); - if (vma_iter == it->second.end() || vma_iter->second.end < pc) { - return NULL; - } - - if (vma_iter != it->second.begin()) { - --vma_iter; - } - - return &vma_iter->second; -} - -bool symbol_parser::find_vma(pid_t pid, vma &vm) -{ - std::map::iterator proc_vma_map; - - proc_vma_map = machine_vma.find(pid); - if (proc_vma_map == machine_vma.end()) { - return false; - } - - proc_vma::const_iterator vma_iter = proc_vma_map->second.upper_bound(vm.pc); - if (vma_iter == proc_vma_map->second.end()) { - return false; - } - if (vma_iter->second.end < vm.pc) { - return false; - } - - if (vma_iter != proc_vma_map->second.begin()) { - --vma_iter; - } - - vm.start = vma_iter->second.start; - vm.end = vma_iter->second.end; - vm.name = "/proc/" + std::to_string(pid) + "/root/" + vma_iter->second.name; - vm.offset = vma_iter->second.offset; - - return true; -} - -class pid_cmdline { - private: - std::map cmdlines; - public: - void clear(void); - std::string & get_pid_cmdline(int pid); -}; - -void pid_cmdline::clear(void) -{ - cmdlines.clear(); -} - -void clear_symbol_info(class pid_cmdline &pid_cmdline, std::set &procs, int dist) -{ - pid_cmdline.clear(); - procs.clear(); - g_symbol_parser.clear_symbol_info(dist); -} - -void symbol_parser::clear_symbol_info(int dist) -{ - machine_vma.clear(); - java_symbols.clear(); - if (dist) { - kernel_symbols.clear(); - file_symbols.clear(); - } -} - -void symbol_parser::dump(void) -{ - int count1, count2, count3; - - if (!debug_mode) - return; - - { - count1 = 0; - count2 = 0; - count3 = 0; - std::map >::iterator iter = file_symbols.begin(); - for(; iter != file_symbols.end(); ++iter) { - std::set& map = iter->second; - const elf_file& file = iter->first; - - count1++; - printf("xby-debug, file_symbols: %s, %lu\n", - file.filename.c_str(), - map.size()); - - count2 += map.size(); - std::set::iterator it = map.begin(); - for(; it != map.end(); ++it) { - count3 += it->name.length(); - } - } - printf("xby-debug, file_symbols: %d, %d, %d\n", count1, count2, count3); - printf("xby-debug, sizeof(symbol): %ld\n", sizeof(symbol)); - } - - { - count1 = 0; - count2 = 0; - std::map >::iterator iter = java_symbols.begin(); - for(; iter != java_symbols.end(); ++iter) { - count1++; - std::set& map = iter->second; - count2 += map.size(); - } - printf("xby-debug, java_symbols: %d, %d\n", count1, count2); - } - - { - printf("xby-debug, kernel_symbols: %lu\n", kernel_symbols.size()); - } - - { - count1 = 0; - count2 = 0; - std::map::iterator iter = machine_vma.begin(); - for(; iter != machine_vma.end(); ++iter) { - count1++; - proc_vma map = iter->second; - count2 += map.size(); - } - printf("xby-debug, machine_vma: %d, %d\n", count1, count2); - } - - { - count1 = 0; - count2 = 0; - std::map >::iterator iter = symbols_cache.begin(); - for(; iter != symbols_cache.end(); ++iter) { - count1++; - std::map& map = iter->second; - count2 += map.size(); - } - printf("xby-debug, symbols_cache: %d, %d\n", count1, count2); - } -} - -std::string demangleCppSym(std::string symbol) -{ - size_t size = 0; - int status = 0; - char *demangled = abi::__cxa_demangle(symbol.c_str(), NULL, &size, &status); - - if (status == 0 && demangled != NULL) - { - std::string FuncName(demangled); - free(demangled); - return FuncName; - } - else - { - // 解码失败,返回原始符号 - return symbol; - } -} - -void clearSpace(std::string &sym) -{ - for (auto i = sym.begin(); i != sym.end();) - { - if (isblank(*i)) - { - sym.erase(i); - } - else - { - i++; - } - } -} \ No newline at end of file diff --git a/eBPF_Supermarket/Stack_Analyser/src/main.cpp b/eBPF_Supermarket/Stack_Analyser/src/main.cpp index 2c15e5af6..435d380b9 100644 --- a/eBPF_Supermarket/Stack_Analyser/src/main.cpp +++ b/eBPF_Supermarket/Stack_Analyser/src/main.cpp @@ -29,15 +29,14 @@ #include "bpf_wapper/io.h" #include "bpf_wapper/readahead.h" #include "bpf_wapper/probe.h" -#include "sa_user.h" +#include "user.h" #include "clipp.h" +#include "cgroup.h" +#include "trace.h" -uint64_t stop_time = -1; bool timeout = false; -uint64_t IntTmp; -std::string StrTmp; -clipp::man_page *man_page; std::vector StackCollectorList; +void end_handle(void); namespace MainConfig { @@ -54,89 +53,14 @@ namespace MainConfig bool trace_kernel = false; } -namespace helper -{ -#include -#include - struct cgid_file_handle - { - // struct file_handle handle; - unsigned int handle_bytes; - int handle_type; - uint64_t cgid; - }; - uint64_t get_cgroupid(const char *pathname) - { - struct statfs fs; - int err; - struct cgid_file_handle *h; - int mount_id; - uint64_t ret; - - err = statfs(pathname, &fs); - if (err != 0) - { - fprintf(stderr, "statfs on %s failed: %s\n", pathname, strerror(errno)); - exit(1); - } - - if ((fs.f_type != (typeof(fs.f_type))CGROUP2_SUPER_MAGIC)) - { - fprintf(stderr, "File %s is not on a cgroup2 mount.\n", pathname); - exit(1); - } - - h = (cgid_file_handle *)malloc(sizeof(struct cgid_file_handle)); - if (!h) - { - fprintf(stderr, "Cannot allocate memory.\n"); - exit(1); - } - - h->handle_bytes = 8; - err = name_to_handle_at(AT_FDCWD, pathname, (struct file_handle *)h, &mount_id, 0); - if (err != 0) - { - fprintf(stderr, "name_to_handle_at failed: %s\n", strerror(errno)); - exit(1); - } - - if (h->handle_bytes != 8) - { - fprintf(stderr, "Unexpected handle size: %d. \n", h->handle_bytes); - exit(1); - } - - ret = h->cgid; - free(h); - - return ret; - } -} - -void end_handle(void) -{ - signal(SIGINT, SIG_IGN); - for (auto Item : StackCollectorList) - { - Item->activate(false); - if (!timeout) - { - std::cout << std::string(*Item) << std::endl; - } - Item->finish(); - } - if (MainConfig::command.length()) - { - kill(MainConfig::target_tgid, SIGTERM); - } -} - int main(int argc, char *argv[]) { - man_page = new clipp::man_page(); + uint64_t stop_time = -1; + clipp::man_page man_page; clipp::group cli; { + uint64_t IntTmp; + std::string StrTmp; auto OnCpuOption = (clipp::option("on_cpu") .call([] { StackCollectorList.push_back(new OnCPUStackCollector()); }) % @@ -172,31 +96,31 @@ int main(int argc, char *argv[]) COLLECTOR_INFO("llc_stat") & ((clipp::option("-P") & clipp::value("period", IntTmp) - .call([] + .call([IntTmp] { static_cast(StackCollectorList.back()) ->setScale(IntTmp); })) % "Set sampling period; default is 100"); auto ProbeOption = clipp::option("probe") - .call([] - { StackCollectorList.push_back(new ProbeStackCollector()); }) % - COLLECTOR_INFO("probe") & - (clipp::value("probe", StrTmp) - .call([] - { static_cast(StackCollectorList.back()) - ->setScale(StrTmp); }) % - "Set the probe string; specific use is:\n" - " | p:: -- probe a kernel function;\n" - ": | p:: -- probe a user-space function in the library 'lib';\n" - "t:: -- probe a kernel tracepoint;\n" - "u:: -- probe a USDT tracepoint"); + .call([] + { StackCollectorList.push_back(new ProbeStackCollector()); }) % + COLLECTOR_INFO("probe") & + (clipp::value("probe", StrTmp) + .call([&StrTmp] + { static_cast(StackCollectorList.back()) + ->setScale(StrTmp); }) % + "Set the probe string; specific use is:\n" + " | p:: -- probe a kernel function;\n" + ": | p:: -- probe a user-space function in the library 'lib';\n" + "t:: -- probe a kernel tracepoint;\n" + "u:: -- probe a USDT tracepoint"); auto MainOption = _GREEN "Some overall options" _RE % (( ((clipp::option("-g") & clipp::value("cgroup path", StrTmp) - .call([] - { MainConfig::target_cgroup = helper::get_cgroupid(StrTmp.c_str()); printf("Trace cgroup %ld\n", MainConfig::target_cgroup); })) % + .call([&StrTmp] + { MainConfig::target_cgroup = get_cgroupid(StrTmp.c_str()); printf("Trace cgroup %ld\n", MainConfig::target_cgroup); })) % "Set the cgroup of the process to be tracked; default is -1, which keeps track of all cgroups") | ((clipp::option("-p") & clipp::value("pid", MainConfig::target_tgid)) % @@ -215,7 +139,7 @@ int main(int argc, char *argv[]) "Set the output delay time (seconds); default is 5", (clipp::option("-d") & clipp::value("duration", MainConfig::run_time) - .call([] + .call([&stop_time] { stop_time = time(NULL) + MainConfig::run_time; })) % "Set the total sampling time; default is __INT_MAX__", (clipp::option("-u") @@ -241,8 +165,8 @@ int main(int argc, char *argv[]) { std::cout << "verion 2.0\n\n"; }) % "Show version"), (clipp::option("-h", "--help") - .call([] - { std::cout << *man_page << std::endl; exit(0); }) % + .call([&man_page] + { std::cout << man_page << std::endl; exit(0); }) % "Show man page")); cli = (OnCpuOption, @@ -260,13 +184,13 @@ int main(int argc, char *argv[]) .first_column(3) .doc_column(25) .last_column(128); - *man_page = clipp::make_man_page(cli, argv[0], fmt) - .prepend_section("DESCRIPTION", _RED "Count the function call stack associated with some metric.\n" _RE BANNER) - .append_section("LICENSE", _RED "Apache Licence 2.0" _RE); + man_page = clipp::make_man_page(cli, argv[0], fmt) + .prepend_section("DESCRIPTION", _RED "Count the function call stack associated with some metric.\n" _RE BANNER) + .append_section("LICENSE", _RED "Apache Licence 2.0" _RE); } if (!clipp::parse(argc, argv, cli)) { - std::cerr << *man_page << std::endl; + std::cerr << man_page << std::endl; return -1; } if (StackCollectorList.size() == 0) @@ -306,6 +230,19 @@ int main(int argc, char *argv[]) } } + ksyms = ksyms__load(); + if (!ksyms) + { + fprintf(stderr, "failed to load kallsyms\n"); + exit(1); + } + syms_cache = syms_cache__new(0); + if (!syms_cache) + { + fprintf(stderr, "failed to create syms_cache\n"); + exit(1); + } + for (auto Item = StackCollectorList.begin(); Item != StackCollectorList.end();) { fprintf(stderr, _RED "Attach collecotor%d %s.\n" _RE, @@ -381,4 +318,22 @@ int main(int argc, char *argv[]) } timeout = true; return 0; -} \ No newline at end of file +}; + +void end_handle(void) +{ + signal(SIGINT, SIG_IGN); + for (auto Item : StackCollectorList) + { + Item->activate(false); + if (!timeout) + { + std::cout << std::string(*Item) << std::endl; + } + Item->finish(); + } + if (MainConfig::command.length()) + { + kill(MainConfig::target_tgid, SIGTERM); + } +}; \ No newline at end of file diff --git a/eBPF_Supermarket/Stack_Analyser/src/trace_helpers.cpp b/eBPF_Supermarket/Stack_Analyser/src/trace.cpp similarity index 82% rename from eBPF_Supermarket/Stack_Analyser/src/trace_helpers.cpp rename to eBPF_Supermarket/Stack_Analyser/src/trace.cpp index 6097ec6e7..a8dc45044 100644 --- a/eBPF_Supermarket/Stack_Analyser/src/trace_helpers.cpp +++ b/eBPF_Supermarket/Stack_Analyser/src/trace.cpp @@ -20,8 +20,8 @@ #include #include #include -#include "trace_helpers.h" -#include "uprobe_helpers.h" +#include "trace.h" +#include "uprobe.h" #define min(x, y) ({ \ typeof(x) _min1 = (x); \ @@ -29,14 +29,15 @@ (void) (&_min1 == &_min2); \ _min1 < _min2 ? _min1 : _min2; }) -#define DISK_NAME_LEN 32 +#define DISK_NAME_LEN 32 -#define MINORBITS 20 -#define MINORMASK ((1U << MINORBITS) - 1) +#define MINORBITS 20 +#define MINORMASK ((1U << MINORBITS) - 1) -#define MKDEV(ma, mi) (((ma) << MINORBITS) | (mi)) +#define MKDEV(ma, mi) (((ma) << MINORBITS) | (mi)) -struct ksyms { +struct ksyms +{ struct ksym *syms; int syms_sz; int syms_cap; @@ -51,7 +52,8 @@ static int ksyms__add_symbol(struct ksyms *ksyms, const char *name, unsigned lon struct ksym *ksym; void *tmp; - if (ksyms->strs_sz + name_len > ksyms->strs_cap) { + if (ksyms->strs_sz + name_len > ksyms->strs_cap) + { new_cap = ksyms->strs_cap * 4 / 3; if (new_cap < ksyms->strs_sz + name_len) new_cap = ksyms->strs_sz + name_len; @@ -63,7 +65,8 @@ static int ksyms__add_symbol(struct ksyms *ksyms, const char *name, unsigned lon ksyms->strs = (char *)tmp; ksyms->strs_cap = new_cap; } - if (ksyms->syms_sz + 1 > ksyms->syms_cap) { + if (ksyms->syms_sz + 1 > ksyms->syms_cap) + { new_cap = ksyms->syms_cap * 4 / 3; if (new_cap < 1024) new_cap = 1024; @@ -111,9 +114,10 @@ struct ksyms *ksyms__load(void) if (!ksyms) goto err_out; - while (true) { + while (true) + { ret = fscanf(f, "%lx %c %s%*[^\n]\n", - &sym_addr, &sym_type, sym_name); + &sym_addr, &sym_type, sym_name); if (ret == EOF && feof(f)) break; if (ret != 3) @@ -148,13 +152,14 @@ void ksyms__free(struct ksyms *ksyms) } const struct ksym *ksyms__map_addr(const struct ksyms *ksyms, - unsigned long addr) + unsigned long addr) { int start = 0, end = ksyms->syms_sz - 1, mid; unsigned long sym_addr; /* find largest sym_addr <= addr using binary search */ - while (start < end) { + while (start < end) + { mid = start + (end - start + 1) / 2; sym_addr = ksyms->syms[mid].addr; @@ -170,11 +175,12 @@ const struct ksym *ksyms__map_addr(const struct ksyms *ksyms, } const struct ksym *ksyms__get_symbol(const struct ksyms *ksyms, - const char *name) + const char *name) { int i; - for (i = 0; i < ksyms->syms_sz; i++) { + for (i = 0; i < ksyms->syms_sz; i++) + { if (strcmp(ksyms->syms[i].name, name) == 0) return &ksyms->syms[i]; } @@ -182,13 +188,15 @@ const struct ksym *ksyms__get_symbol(const struct ksyms *ksyms, return NULL; } -struct load_range { +struct load_range +{ uint64_t start; uint64_t end; uint64_t file_off; }; -enum elf_type { +enum elf_type +{ EXEC, DYN, PERF_MAP, @@ -196,7 +204,8 @@ enum elf_type { UNKNOWN, }; -struct dso { +struct dso +{ char *name; struct load_range *ranges; int range_sz; @@ -218,7 +227,8 @@ struct dso { struct btf *btf; }; -struct map { +struct map +{ uint64_t start_addr; uint64_t end_addr; uint64_t file_off; @@ -227,7 +237,8 @@ struct map { uint64_t inode; }; -struct syms { +struct syms +{ struct dso *dsos; int dso_sz; }; @@ -238,14 +249,15 @@ static bool is_file_backed(const char *mapname) (!strncmp(mapname, prefix, sizeof(prefix) - 1)) return mapname[0] && !( - STARTS_WITH(mapname, "//anon") || - STARTS_WITH(mapname, "/dev/zero") || - STARTS_WITH(mapname, "/anon_hugepage") || - STARTS_WITH(mapname, "[stack") || - STARTS_WITH(mapname, "/SYSV") || - STARTS_WITH(mapname, "[heap]") || - STARTS_WITH(mapname, "[uprobes]") || - STARTS_WITH(mapname, "[vsyscall]")); + STARTS_WITH(mapname, "//anon") || + STARTS_WITH(mapname, "/dev/zero") || + STARTS_WITH(mapname, "/anon_hugepage") || + STARTS_WITH(mapname, "[stack") || + STARTS_WITH(mapname, "/SYSV") || + STARTS_WITH(mapname, "[heap]") || + STARTS_WITH(mapname, "[uprobes]") || + STARTS_WITH(mapname, "[vsyscall]") || + STARTS_WITH(mapname, "[vdso]")); } static bool is_perf_map(const char *path) @@ -285,7 +297,7 @@ static int get_elf_type(const char *path) } static int get_elf_text_scn_info(const char *path, uint64_t *addr, - uint64_t *offset) + uint64_t *offset) { Elf_Scn *section = NULL; int fd = -1, err = -1; @@ -302,12 +314,14 @@ static int get_elf_text_scn_info(const char *path, uint64_t *addr, goto err_out; err = -1; - while ((section = elf_nextscn(e, section)) != 0) { + while ((section = elf_nextscn(e, section)) != 0) + { if (!gelf_getshdr(section, &header)) continue; name = elf_strptr(e, stridx, header.sh_name); - if (name && !strcmp(name, ".text")) { + if (name && !strcmp(name, ".text")) + { *addr = (uint64_t)header.sh_addr; *offset = (uint64_t)header.sh_offset; err = 0; @@ -326,16 +340,19 @@ static int syms__add_dso(struct syms *syms, struct map *map, const char *name) int i, type; void *tmp; - for (i = 0; i < syms->dso_sz; i++) { - if (!strcmp(syms->dsos[i].name, name)) { + for (i = 0; i < syms->dso_sz; i++) + { + if (!strcmp(syms->dsos[i].name, name)) + { dso = &syms->dsos[i]; break; } } - if (!dso) { + if (!dso) + { tmp = realloc(syms->dsos, (syms->dso_sz + 1) * - sizeof(*syms->dsos)); + sizeof(*syms->dsos)); if (!tmp) return -1; syms->dsos = (struct dso *)tmp; @@ -354,41 +371,55 @@ static int syms__add_dso(struct syms *syms, struct map *map, const char *name) dso->ranges[dso->range_sz].file_off = map->file_off; dso->range_sz++; type = get_elf_type(name); - if (type == ET_EXEC) { + if (type == ET_EXEC) + { dso->type = EXEC; - } else if (type == ET_DYN) { + } + else if (type == ET_DYN) + { dso->type = DYN; if (get_elf_text_scn_info(name, &dso->sh_addr, &dso->sh_offset) < 0) return -1; - } else if (is_perf_map(name)) { + } + else if (is_perf_map(name)) + { dso->type = PERF_MAP; - } else if (is_vdso(name)) { + } + else if (is_vdso(name)) + { dso->type = VDSO; - } else { + } + else + { dso->type = UNKNOWN; } return 0; } static struct dso *syms__find_dso(const struct syms *syms, unsigned long addr, - uint64_t *offset) + uint64_t *offset) { struct load_range *range; struct dso *dso; int i, j; - for (i = 0; i < syms->dso_sz; i++) { + for (i = 0; i < syms->dso_sz; i++) + { dso = &syms->dsos[i]; - for (j = 0; j < dso->range_sz; j++) { + for (j = 0; j < dso->range_sz; j++) + { range = &dso->ranges[j]; if (addr <= range->start || addr >= range->end) continue; - if (dso->type == DYN || dso->type == VDSO) { + if (dso->type == DYN || dso->type == VDSO) + { /* Offset within the mmap */ *offset = addr - range->start + range->file_off; /* Offset within the ELF for dyn symbol lookup */ *offset += dso->sh_addr - dso->sh_offset; - } else { + } + else + { *offset = addr; } @@ -405,7 +436,7 @@ static int dso__load_sym_table_from_perf_map(struct dso *dso) } static int dso__add_sym(struct dso *dso, const char *name, uint64_t start, - uint64_t size) + uint64_t size) { struct sym *sym; size_t new_cap; @@ -416,7 +447,8 @@ static int dso__add_sym(struct dso *dso, const char *name, uint64_t start, if (off < 0) return off; - if (dso->syms_sz + 1 > dso->syms_cap) { + if (dso->syms_sz + 1 > dso->syms_cap) + { new_cap = dso->syms_cap * 4 / 3; if (new_cap < 1024) new_cap = 1024; @@ -447,17 +479,19 @@ static int sym_cmp(const void *p1, const void *p2) } static int dso__add_syms(struct dso *dso, Elf *e, Elf_Scn *section, - size_t stridx, size_t symsize) + size_t stridx, size_t symsize) { Elf_Data *data = NULL; - while ((data = elf_getdata(section, data)) != 0) { + while ((data = elf_getdata(section, data)) != 0) + { size_t i, symcount = data->d_size / symsize; if (data->d_size % symsize) return -1; - for (i = 0; i < symcount; ++i) { + for (i = 0; i < symcount; ++i) + { const char *name; GElf_Sym sym; @@ -503,18 +537,19 @@ static int dso__load_sym_table_from_elf(struct dso *dso, int fd) if (!e) return -1; - while ((section = elf_nextscn(e, section)) != 0) { + while ((section = elf_nextscn(e, section)) != 0) + { GElf_Shdr header; if (!gelf_getshdr(section, &header)) continue; if (header.sh_type != SHT_SYMTAB && - header.sh_type != SHT_DYNSYM) + header.sh_type != SHT_DYNSYM) continue; if (dso__add_syms(dso, e, section, header.sh_link, - header.sh_entsize)) + header.sh_entsize)) goto err_out; } @@ -522,7 +557,7 @@ static int dso__load_sym_table_from_elf(struct dso *dso, int fd) for (i = 0; i < dso->syms_sz; i++) dso->syms[i].name = btf__name_by_offset(dso->btf, - (unsigned long)dso->syms[i].name); + (unsigned long)dso->syms[i].name); qsort(dso->syms, dso->syms_sz, sizeof(*dso->syms), sym_cmp); @@ -552,10 +587,11 @@ static int create_tmp_vdso_image(struct dso *dso) if (!f) return -1; - while (true) { + while (true) + { ret = fscanf(f, "%llx-%llx %*s %*x %*x:%*x %*u%[^\n]", - (long long*)&start_addr, (long long*)&end_addr, - buf); + (long long *)&start_addr, (long long *)&end_addr, + buf); if (ret == EOF && feof(f)) break; if (ret != 3) @@ -577,20 +613,22 @@ static int create_tmp_vdso_image(struct dso *dso) memcpy(image, (void *)start_addr, sz); snprintf(tmpfile, sizeof(tmpfile), - "/tmp/libbpf_%ld_vdso_image_XXXXXX", pid); + "/tmp/libbpf_%ld_vdso_image_XXXXXX", pid); fd = mkostemp(tmpfile, O_CLOEXEC); - if (fd < 0) { + if (fd < 0) + { fprintf(stderr, "failed to create temp file: %s\n", - strerror(errno)); + strerror(errno)); goto err_out; } /* Unlink the file to avoid leaking */ if (unlink(tmpfile) == -1) fprintf(stderr, "failed to unlink %s: %s\n", tmpfile, - strerror(errno)); - if (write(fd, image, sz) == -1) { + strerror(errno)); + if (write(fd, image, sz) == -1) + { fprintf(stderr, "failed to write to vDSO image: %s\n", - strerror(errno)); + strerror(errno)); close(fd); fd = -1; goto err_out; @@ -636,7 +674,8 @@ static struct sym *dso__find_sym(struct dso *dso, uint64_t offset) end = dso->syms_sz - 1; /* find largest sym_addr <= addr using binary search */ - while (start < end) { + while (start < end) + { mid = start + (end - start + 1) / 2; sym_addr = dso->syms[mid].start; @@ -647,16 +686,17 @@ static struct sym *dso__find_sym(struct dso *dso, uint64_t offset) } if (start == end && dso->syms[start].start <= offset && - offset < dso->syms[start].start + dso->syms[start].size) { + offset < dso->syms[start].start + dso->syms[start].size) + { (dso->syms[start]).offset = offset - dso->syms[start].start; return &dso->syms[start]; } return NULL; } -struct syms *syms__load_file(const char *fname) +struct syms *syms__load_file(const char *fname, pid_t tgid) { - char buf[PATH_MAX], perm[5]; + char buf[PATH_MAX], perm[5], path[PATH_MAX]; struct syms *syms; struct map map; char *name; @@ -671,17 +711,18 @@ struct syms *syms__load_file(const char *fname) if (!syms) goto err_out; - while (true) { + while (true) + { ret = fscanf(f, "%llx-%llx %4s %llx %llx:%llx %llu%[^\n]", - (long long*)&map.start_addr, - (long long*)&map.end_addr, perm, - (long long*)&map.file_off, - (long long*)&map.dev_major, - (long long*)&map.dev_minor, - (long long*)&map.inode, buf); + (long long *)&map.start_addr, + (long long *)&map.end_addr, perm, + (long long *)&map.file_off, + (long long *)&map.dev_major, + (long long *)&map.dev_minor, + (long long *)&map.inode, buf); if (ret == EOF && feof(f)) break; - if (ret != 8) /* perf-.map */ + if (ret != 8) /* perf-.map */ goto err_out; if (perm[2] != 'x') @@ -693,7 +734,8 @@ struct syms *syms__load_file(const char *fname) if (!is_file_backed(name)) continue; - if (syms__add_dso(syms, &map, name)) + sprintf(path, "/proc/%d/root/%s", tgid, name); + if (syms__add_dso(syms, &map, path)) goto err_out; } @@ -711,7 +753,7 @@ struct syms *syms__load_pid(pid_t tgid) char fname[128]; snprintf(fname, sizeof(fname), "/proc/%ld/maps", (long)tgid); - return syms__load_file(fname); + return syms__load_file(fname, tgid); } void syms__free(struct syms *syms) @@ -727,7 +769,7 @@ void syms__free(struct syms *syms) free(syms); } -const struct sym *syms__map_addr(const struct syms *syms, unsigned long addr) +struct sym *syms__map_addr(const struct syms *syms, unsigned long addr) { struct dso *dso; uint64_t offset; @@ -739,7 +781,7 @@ const struct sym *syms__map_addr(const struct syms *syms, unsigned long addr) } const struct sym *syms__map_addr_dso(const struct syms *syms, unsigned long addr, - char **dso_name, unsigned long *dso_offset) + char **dso_name, unsigned long *dso_offset) { struct dso *dso; uint64_t offset; @@ -754,8 +796,10 @@ const struct sym *syms__map_addr_dso(const struct syms *syms, unsigned long addr return dso__find_sym(dso, offset); } -struct syms_cache { - struct { +struct syms_cache +{ + struct + { struct syms *syms; int tgid; } *data; @@ -792,13 +836,14 @@ struct syms *syms_cache__get_syms(struct syms_cache *syms_cache, int tgid) void *tmp; int i; - for (i = 0; i < syms_cache->nr; i++) { + for (i = 0; i < syms_cache->nr; i++) + { if (syms_cache->data[i].tgid == tgid) return syms_cache->data[i].syms; } tmp = realloc(syms_cache->data, (syms_cache->nr + 1) * - sizeof(*syms_cache->data)); + sizeof(*syms_cache->data)); if (!tmp) return NULL; syms_cache->data = (typeof(syms_cache->data))tmp; @@ -807,19 +852,20 @@ struct syms *syms_cache__get_syms(struct syms_cache *syms_cache, int tgid) return syms_cache->data[syms_cache->nr++].syms; } -struct partitions { +struct partitions +{ struct partition *items; int sz; }; static int partitions__add_partition(struct partitions *partitions, - const char *name, unsigned int dev) + const char *name, unsigned int dev) { struct partition *partition; void *tmp; tmp = realloc(partitions->items, (partitions->sz + 1) * - sizeof(*partitions->items)); + sizeof(*partitions->items)); if (!tmp) return -1; partitions->items = (struct partition *)tmp; @@ -848,15 +894,16 @@ struct partitions *partitions__load(void) if (!partitions) goto err_out; - while (fgets(buf, sizeof(buf), f) != NULL) { + while (fgets(buf, sizeof(buf), f) != NULL) + { /* skip heading */ if (buf[0] != ' ' || buf[0] == '\n') continue; if (sscanf(buf, "%u %u %llu %s", &devmaj, &devmin, &nop, - part_name) != 4) + part_name) != 4) goto err_out; if (partitions__add_partition(partitions, part_name, - MKDEV(devmaj, devmin))) + MKDEV(devmaj, devmin))) goto err_out; } @@ -887,7 +934,8 @@ partitions__get_by_dev(const struct partitions *partitions, unsigned int dev) { int i; - for (i = 0; i < partitions->sz; i++) { + for (i = 0; i < partitions->sz; i++) + { if (partitions->items[i].dev == dev) return &partitions->items[i]; } @@ -900,7 +948,8 @@ partitions__get_by_name(const struct partitions *partitions, const char *name) { int i; - for (i = 0; i < partitions->sz; i++) { + for (i = 0; i < partitions->sz; i++) + { if (strcmp(partitions->items[i].name, name) == 0) return &partitions->items[i]; } @@ -932,7 +981,8 @@ void print_log2_hist(unsigned int *vals, int vals_size, const char *val_type) unsigned long long low, high; int stars, width, i; - for (i = 0; i < vals_size; i++) { + for (i = 0; i < vals_size; i++) + { val = vals[i]; if (val > 0) idx_max = i; @@ -944,14 +994,15 @@ void print_log2_hist(unsigned int *vals, int vals_size, const char *val_type) return; printf("%*s%-*s : count distribution\n", idx_max <= 32 ? 5 : 15, "", - idx_max <= 32 ? 19 : 29, val_type); + idx_max <= 32 ? 19 : 29, val_type); if (idx_max <= 32) stars = stars_max; else stars = stars_max / 2; - for (i = 0; i <= idx_max; i++) { + for (i = 0; i <= idx_max; i++) + { low = (1ULL << (i + 1)) >> 1; high = (1ULL << (i + 1)) - 1; if (low == high) @@ -965,14 +1016,16 @@ void print_log2_hist(unsigned int *vals, int vals_size, const char *val_type) } void print_linear_hist(unsigned int *vals, int vals_size, unsigned int base, - unsigned int step, const char *val_type) + unsigned int step, const char *val_type) { int i, stars_max = 40, idx_min = -1, idx_max = -1; unsigned int val, val_max = 0; - for (i = 0; i < vals_size; i++) { + for (i = 0; i < vals_size; i++) + { val = vals[i]; - if (val > 0) { + if (val > 0) + { idx_max = i; if (idx_min < 0) idx_min = i; @@ -985,7 +1038,8 @@ void print_linear_hist(unsigned int *vals, int vals_size, unsigned int base, return; printf(" %-13s : count distribution\n", val_type); - for (i = idx_min; i <= idx_max; i++) { + for (i = idx_min; i <= idx_max; i++) + { val = vals[i]; if (!val) continue; @@ -1013,10 +1067,12 @@ bool is_kernel_module(const char *name) if (!f) return false; - while (fgets(buf, sizeof(buf), f) != NULL) { + while (fgets(buf, sizeof(buf), f) != NULL) + { if (sscanf(buf, "%s %*s\n", buf) != 1) break; - if (!strcmp(buf, name)) { + if (!strcmp(buf, name)) + { found = true; break; } @@ -1031,18 +1087,17 @@ static bool fentry_try_attach(int id) int prog_fd, attach_fd; char error[4096]; struct bpf_insn insns[] = { - { .code = BPF_ALU64 | BPF_MOV | BPF_K, .dst_reg = BPF_REG_0, .imm = 0 }, - { .code = BPF_JMP | BPF_EXIT }, + {.code = BPF_ALU64 | BPF_MOV | BPF_K, .dst_reg = BPF_REG_0, .imm = 0}, + {.code = BPF_JMP | BPF_EXIT}, }; LIBBPF_OPTS(bpf_prog_load_opts, opts, - .expected_attach_type = BPF_TRACE_FENTRY, - .attach_btf_id = (__u32)id, - .log_size = sizeof(error), - .log_buf = error, - ); + .expected_attach_type = BPF_TRACE_FENTRY, + .attach_btf_id = (__u32)id, + .log_size = sizeof(error), + .log_buf = error, ); prog_fd = bpf_prog_load(BPF_PROG_TYPE_TRACING, "test", "GPL", insns, - sizeof(insns) / sizeof(struct bpf_insn), &opts); + sizeof(insns) / sizeof(struct bpf_insn), &opts); if (prog_fd < 0) return false; @@ -1066,7 +1121,8 @@ bool fentry_can_attach(const char *name, const char *mod) btf = vmlinux_btf; - if (mod) { + if (mod) + { module_btf = btf__load_module_btf(mod, vmlinux_btf); err = libbpf_get_error(module_btf); if (!err) @@ -1100,8 +1156,7 @@ static const char *tracefs_path(void) static const char *tracefs_available_filter_functions(void) { - return use_debugfs() ? DEBUGFS"/available_filter_functions" : - TRACEFS"/available_filter_functions"; + return use_debugfs() ? DEBUGFS "/available_filter_functions" : TRACEFS "/available_filter_functions"; } bool kprobe_exists(const char *name) @@ -1115,15 +1170,18 @@ bool kprobe_exists(const char *name) if (!f) goto avail_filter; - while (true) { + while (true) + { ret = fscanf(f, "%s %s%*[^\n]\n", addr_range, sym_name); if (ret == EOF && feof(f)) break; - if (ret != 2) { + if (ret != 2) + { fprintf(stderr, "failed to read symbol from kprobe blacklist\n"); break; } - if (!strcmp(name, sym_name)) { + if (!strcmp(name, sym_name)) + { fclose(f); return false; } @@ -1135,15 +1193,18 @@ bool kprobe_exists(const char *name) if (!f) goto slow_path; - while (true) { + while (true) + { ret = fscanf(f, "%s%*[^\n]\n", sym_name); if (ret == EOF && feof(f)) break; - if (ret != 1) { + if (ret != 1) + { fprintf(stderr, "failed to read symbol from available_filter_functions\n"); break; } - if (!strcmp(name, sym_name)) { + if (!strcmp(name, sym_name)) + { fclose(f); return true; } @@ -1157,15 +1218,18 @@ bool kprobe_exists(const char *name) if (!f) return false; - while (true) { + while (true) + { ret = fscanf(f, "%*x %*c %s%*[^\n]\n", sym_name); if (ret == EOF && feof(f)) break; - if (ret != 1) { + if (ret != 1) + { fprintf(stderr, "failed to read symbol from kallsyms\n"); break; } - if (!strcmp(name, sym_name)) { + if (!strcmp(name, sym_name)) + { fclose(f); return true; } @@ -1203,7 +1267,8 @@ bool module_btf_exists(const char *mod) { char sysfs_mod[80]; - if (mod) { + if (mod) + { snprintf(sysfs_mod, sizeof(sysfs_mod), "/sys/kernel/btf/%s", mod); if (!access(sysfs_mod, R_OK)) return true; @@ -1215,8 +1280,8 @@ bool probe_tp_btf(const char *name) { LIBBPF_OPTS(bpf_prog_load_opts, opts, .expected_attach_type = BPF_TRACE_RAW_TP); struct bpf_insn insns[] = { - { .code = BPF_ALU64 | BPF_MOV | BPF_K, .dst_reg = BPF_REG_0, .imm = 0 }, - { .code = BPF_JMP | BPF_EXIT }, + {.code = BPF_ALU64 | BPF_MOV | BPF_K, .dst_reg = BPF_REG_0, .imm = 0}, + {.code = BPF_JMP | BPF_EXIT}, }; int fd, insn_cnt = sizeof(insns) / sizeof(struct bpf_insn); @@ -1238,3 +1303,21 @@ bool probe_ringbuf() close(map_fd); return true; } + +const struct ksym *ksyms__find_symbol(const struct ksyms *ksyms, + const char *name) +{ + for (int i = 0; i < ksyms->syms_sz; i++) + { + int j; + for (j = 0; name[j] && name[j] == ksyms->syms[i].name[j]; j++) + ; + if (!name[j]) + return &ksyms->syms[i]; + } + return NULL; +} + +struct ksyms *ksyms; +struct syms_cache *syms_cache; +struct syms *syms; \ No newline at end of file diff --git a/eBPF_Supermarket/Stack_Analyser/src/uprobe_helpers.cpp b/eBPF_Supermarket/Stack_Analyser/src/uprobe.cpp similarity index 100% rename from eBPF_Supermarket/Stack_Analyser/src/uprobe_helpers.cpp rename to eBPF_Supermarket/Stack_Analyser/src/uprobe.cpp From 5574943b6a2965e020dee2dd93742b3d3feb6b75 Mon Sep 17 00:00:00 2001 From: legendlliu Date: Thu, 20 Jun 2024 14:38:02 +0800 Subject: [PATCH 3/3] fix bug Signed-off-by: legendlliu --- eBPF_Supermarket/Stack_Analyser/Makefile | 14 +++++++++----- eBPF_Supermarket/Stack_Analyser/bpf/io.bpf.c | 2 +- eBPF_Supermarket/Stack_Analyser/bpf/llc_stat.bpf.c | 2 +- eBPF_Supermarket/Stack_Analyser/bpf/memleak.bpf.c | 2 +- eBPF_Supermarket/Stack_Analyser/bpf/off_cpu.bpf.c | 2 +- eBPF_Supermarket/Stack_Analyser/bpf/on_cpu.bpf.c | 2 +- eBPF_Supermarket/Stack_Analyser/bpf/probe.bpf.c | 2 +- .../Stack_Analyser/bpf/readahead.bpf.c | 2 +- eBPF_Supermarket/Stack_Analyser/bpf/template.bpf.c | 2 +- eBPF_Supermarket/Stack_Analyser/include/ebpf.h | 2 +- 10 files changed, 18 insertions(+), 14 deletions(-) diff --git a/eBPF_Supermarket/Stack_Analyser/Makefile b/eBPF_Supermarket/Stack_Analyser/Makefile index 83731b94e..4c357c824 100644 --- a/eBPF_Supermarket/Stack_Analyser/Makefile +++ b/eBPF_Supermarket/Stack_Analyser/Makefile @@ -45,6 +45,10 @@ ALL_LDFLAGS := $(LDFLAGS) $(EXTRA_LDFLAGS) BIN = $(patsubst src/%.cpp, %, ${wildcard src/*.cpp}) BPF = $(patsubst bpf/%.bpf.c, %, ${wildcard bpf/*.bpf.c}) +BPF_OBJ = $(patsubst %,$(OUTPUT)/%.bpf.o,$(BPF)) +BPF_SKEL_H = $(patsubst %,$(BPF_SKEL)/%.skel.h,$(BPF)) +BPF_WAPPER = $(patsubst %,$(OUTPUT)/%.o,$(BPF)) +BIN_OBJ = $(patsubst %,$(OUTPUT)/%.o,$(BIN)) TARGETS = stack_analyzer @@ -117,7 +121,7 @@ $(BPFTOOL): $(BPFTOOL_SRC) | $(BPFTOOL_OUTPUT) $(Q)$(MAKE) ARCH= CROSS_COMPILE= OUTPUT=$(BPFTOOL_OUTPUT)/ -C $(BPFTOOL_SRC) bootstrap # Build BPF code -$(OUTPUT)/%.bpf.o: bpf/%.bpf.c include/sa_ebpf.h $(LIBBPF_OBJ) $(VMLINUX) | $(OUTPUT) $(BPFTOOL) +$(BPF_OBJ): $(OUTPUT)/%.bpf.o: bpf/%.bpf.c include/ebpf.h $(LIBBPF_OBJ) $(VMLINUX) | $(OUTPUT) $(BPFTOOL) $(call msg,BPF,$@) $(Q)$(CLANG) -g -O2 -target bpf -D__TARGET_ARCH_$(ARCH) \ $(INCLUDES) $(CLANG_BPF_SYS_INCLUDES) \ @@ -125,16 +129,16 @@ $(OUTPUT)/%.bpf.o: bpf/%.bpf.c include/sa_ebpf.h $(LIBBPF_OBJ) $(VMLINUX) | $(OU $(Q)$(BPFTOOL) gen object $@ $(patsubst %.bpf.o,%.tmp.bpf.o,$@) # Generate BPF skeletons -$(BPF_SKEL)/%.skel.h: $(OUTPUT)/%.bpf.o | $(OUTPUT) $(BPFTOOL) $(BPF_SKEL) +$(BPF_SKEL_H): $(BPF_SKEL)/%.skel.h: $(OUTPUT)/%.bpf.o | $(OUTPUT) $(BPFTOOL) $(BPF_SKEL) $(call msg,GEN-SKEL,$@) $(Q)$(BPFTOOL) gen skeleton $< > $@ -$(patsubst %,$(OUTPUT)/%.o,$(BPF)): $(OUTPUT)/%.o: src/bpf_wapper/%.cpp include/bpf_wapper/%.h $(BPF_SKEL)/%.skel.h $(OUTPUT)/eBPFStackCollector.o +$(BPF_WAPPER): $(OUTPUT)/%.o: src/bpf_wapper/%.cpp include/bpf_wapper/%.h $(BPF_SKEL)/%.skel.h $(OUTPUT)/eBPFStackCollector.o $(call msg,CXX,$@) $(Q)$(CXX) $(CFLAGS) $(INCLUDES) -c $< -o $@ # Build depending library -$(patsubst %,$(OUTPUT)/%.o,$(BIN)): $(OUTPUT)/%.o: src/%.cpp $(patsubst %,$(BPF_SKEL)/%.skel.h,$(BPF)) +$(BIN_OBJ): $(OUTPUT)/%.o: src/%.cpp $(BPF_SKEL_H) $(call msg,CXX,$@) $(Q)$(CXX) $(CFLAGS) $(INCLUDES) -c $< -o $@ @@ -143,7 +147,7 @@ $(OUTPUT)/eBPFStackCollector.o: src/bpf_wapper/eBPFStackCollector.cpp include/bp $(Q)$(CXX) $(CFLAGS) $(INCLUDES) -c $< -o $@ # Build application binary -$(TARGETS): $(OUTPUT)/eBPFStackCollector.o $(patsubst %,$(OUTPUT)/%.o,$(BIN)) $(patsubst %,$(OUTPUT)/%.o,$(BPF)) $(LIBBPF_OBJ) +$(TARGETS): $(OUTPUT)/eBPFStackCollector.o $(BIN_OBJ) $(BPF_WAPPER) $(LIBBPF_OBJ) $(call msg,BINARY,$@) $(Q)$(CXX) $^ $(ALL_LDFLAGS) -lstdc++ -lelf -lz -o $@ diff --git a/eBPF_Supermarket/Stack_Analyser/bpf/io.bpf.c b/eBPF_Supermarket/Stack_Analyser/bpf/io.bpf.c index 0406c510e..2469004fe 100644 --- a/eBPF_Supermarket/Stack_Analyser/bpf/io.bpf.c +++ b/eBPF_Supermarket/Stack_Analyser/bpf/io.bpf.c @@ -21,7 +21,7 @@ #include #include -#include "sa_ebpf.h" +#include "ebpf.h" #include "bpf_wapper/io.h" #include "task.h" diff --git a/eBPF_Supermarket/Stack_Analyser/bpf/llc_stat.bpf.c b/eBPF_Supermarket/Stack_Analyser/bpf/llc_stat.bpf.c index eefa368db..b48d433d0 100644 --- a/eBPF_Supermarket/Stack_Analyser/bpf/llc_stat.bpf.c +++ b/eBPF_Supermarket/Stack_Analyser/bpf/llc_stat.bpf.c @@ -21,7 +21,7 @@ #include #include -#include "sa_ebpf.h" +#include "ebpf.h" #include "bpf_wapper/llc_stat.h" #include "task.h" diff --git a/eBPF_Supermarket/Stack_Analyser/bpf/memleak.bpf.c b/eBPF_Supermarket/Stack_Analyser/bpf/memleak.bpf.c index 25fa84487..d94b29d97 100644 --- a/eBPF_Supermarket/Stack_Analyser/bpf/memleak.bpf.c +++ b/eBPF_Supermarket/Stack_Analyser/bpf/memleak.bpf.c @@ -21,7 +21,7 @@ #include #include -#include "sa_ebpf.h" +#include "ebpf.h" #include "task.h" #include "bpf_wapper/memleak.h" diff --git a/eBPF_Supermarket/Stack_Analyser/bpf/off_cpu.bpf.c b/eBPF_Supermarket/Stack_Analyser/bpf/off_cpu.bpf.c index cee5be1a6..80877b067 100644 --- a/eBPF_Supermarket/Stack_Analyser/bpf/off_cpu.bpf.c +++ b/eBPF_Supermarket/Stack_Analyser/bpf/off_cpu.bpf.c @@ -21,7 +21,7 @@ #include #include -#include "sa_ebpf.h" +#include "ebpf.h" #include "task.h" COMMON_MAPS(u32); diff --git a/eBPF_Supermarket/Stack_Analyser/bpf/on_cpu.bpf.c b/eBPF_Supermarket/Stack_Analyser/bpf/on_cpu.bpf.c index d70b7c23b..c1b103f19 100644 --- a/eBPF_Supermarket/Stack_Analyser/bpf/on_cpu.bpf.c +++ b/eBPF_Supermarket/Stack_Analyser/bpf/on_cpu.bpf.c @@ -21,7 +21,7 @@ #include #include -#include "sa_ebpf.h" +#include "ebpf.h" #include "task.h" const char LICENSE[] SEC("license") = "GPL"; diff --git a/eBPF_Supermarket/Stack_Analyser/bpf/probe.bpf.c b/eBPF_Supermarket/Stack_Analyser/bpf/probe.bpf.c index 01f4dd371..623bb5ae0 100644 --- a/eBPF_Supermarket/Stack_Analyser/bpf/probe.bpf.c +++ b/eBPF_Supermarket/Stack_Analyser/bpf/probe.bpf.c @@ -22,7 +22,7 @@ #include #include -#include "sa_ebpf.h" +#include "ebpf.h" #include "bpf_wapper/probe.h" #include "task.h" diff --git a/eBPF_Supermarket/Stack_Analyser/bpf/readahead.bpf.c b/eBPF_Supermarket/Stack_Analyser/bpf/readahead.bpf.c index 92ce2f063..69925f805 100644 --- a/eBPF_Supermarket/Stack_Analyser/bpf/readahead.bpf.c +++ b/eBPF_Supermarket/Stack_Analyser/bpf/readahead.bpf.c @@ -21,7 +21,7 @@ #include #include -#include "sa_ebpf.h" +#include "ebpf.h" #include "task.h" #include "bpf_wapper/readahead.h" diff --git a/eBPF_Supermarket/Stack_Analyser/bpf/template.bpf.c b/eBPF_Supermarket/Stack_Analyser/bpf/template.bpf.c index 8f741746f..108412609 100644 --- a/eBPF_Supermarket/Stack_Analyser/bpf/template.bpf.c +++ b/eBPF_Supermarket/Stack_Analyser/bpf/template.bpf.c @@ -21,7 +21,7 @@ #include #include -#include "sa_ebpf.h" +#include "ebpf.h" #include "bpf_wapper/template.h" #include "task.h" diff --git a/eBPF_Supermarket/Stack_Analyser/include/ebpf.h b/eBPF_Supermarket/Stack_Analyser/include/ebpf.h index c921d0dfb..84ee017f6 100644 --- a/eBPF_Supermarket/Stack_Analyser/include/ebpf.h +++ b/eBPF_Supermarket/Stack_Analyser/include/ebpf.h @@ -19,7 +19,7 @@ #ifndef STACK_ANALYZER_EBPF #define STACK_ANALYZER_EBPF -#include "sa_common.h" +#include "common.h" #include #define PF_KTHREAD 0x00200000